/* * This file is a part of Winix * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2011-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include "groups.h" #include "core/log.h" namespace Winix { namespace GroupItem { pt::Space * Groups::GetSpace() { return &space; } void Groups::Reindex() { set_index.clear(); group_index_tab.clear(); size_t seti = 0; pt::Space::TableType * sets_table = space.get_table(L"sets"); if( sets_table ) { for(size_t i = 0 ; i < sets_table->size() ; ++i) { pt::Space * set = (*sets_table)[i]; const std::wstring * set_name = set->get_wstr(L"name"); pt::Space::TableType * set_groups = set->get_table(L"groups"); sort_by = set->to_wstr(L"sort_by"); sort_asc = set->is_equal(L"sort_asc", L"true"); if( set_name && set_groups ) { std::wstring key = set->to_wstr(L"key", L"value"); if( set_index.find(*set_name) == set_index.end() ) { set_index[*set_name] = seti; group_index_tab.push_back(GroupIndex()); ReindexGroups(group_index_tab.back(), *set_name, *set_groups, key); seti += 1; } else { slog << logerror << "set: " << set_name << " already defined (skipping)" << logend; //space.remove_child_space(seti); } } } } } void Groups::ReindexGroups(GroupIndex & group_index, const std::wstring & set_name, pt::Space::TableType & groups, const std::wstring & key) { size_t i, v; for(i=0 ; i < groups.size() ; ++i) { pt::Space::TableType * group = groups[i]->get_table(); if( group ) { for(v=0 ; v < group->size() ; ++v) { std::wstring * vali = (*group)[v]->get_wstr(key.c_str()); if( vali ) { GroupIndex::iterator g = group_index.find(*vali); if( g == group_index.end() ) { group_index[*vali] = i; } else { slog << logwarning << "set: " << set_name << " has a group with a duplicated value: " << *vali << " (skipping)" << logend; } } else { log << log1 << "key: " << key << " was not found" << logend; slog << logwarning << "set: " << set_name << " has a group without a value (skipping)" << logend; } } SortValues(*group); } } } void Groups::SortValues(pt::Space::TableType & group) { if( !sort_by.empty() ) { //group.to_list(L"sort", sort_value, true); std::sort(group.begin(), group.end(), SortFunHelper(this)); } } bool Groups::SortFunHelper::operator()(pt::Space * sp1, pt::Space * sp2) { const std::wstring * val1 = sp1->get_wstr(groups->sort_by.c_str()); const std::wstring * val2 = sp2->get_wstr(groups->sort_by.c_str()); if( !val1 || !val2 ) return false; if( groups->sort_asc ) return *val1 < *val2; else return *val1 > *val2; // CHECKME I am not sure how it was sorted, for what was SortValue(...) // if( groups->sort_asc ) // return SortValue(*val1) < SortValue(*val2); // else // return SortValue(*val1) > SortValue(*val2); } //size_t Groups::SortFunHelper::SortValue(const std::wstring & val) //{ // for(size_t i=0 ; isort_value.size() ; ++i) // if( val == groups->sort_value[i] ) // return i; // //return std::numeric_limits::max(); //} bool Groups::Find(const std::wstring & set, const std::wstring & value, size_t & seti, size_t & groupi) { SetIndex::iterator i = set_index.find(set); if( i != set_index.end() ) { if( i->second < group_index_tab.size() ) { GroupIndex::iterator viter = group_index_tab[i->second].find(value); if( viter != group_index_tab[i->second].end() ) { seti = i->second; groupi = viter->second; return true; } } } return false; } const std::wstring & Groups::GetOption(size_t seti, size_t groupi, size_t valuei, const wchar_t * option) { pt::Space::TableType * sets = space.get_table(L"sets"); if( sets && seti < sets->size() ) { pt::Space::TableType * groups = (*sets)[seti]->get_table(L"groups");; if( groups && groupi < groups->size() ) { pt::Space::TableType * group = (*groups)[groupi]->get_table(); if( group && valuei < group->size() ) { pt::Space * value_child = (*group)[valuei]; const std::wstring * res = value_child->get_wstr(option); if( res ) return *res; } } } return empty_str; } const std::wstring & Groups::GetOption(size_t seti, size_t groupi, size_t valuei, const std::wstring & option) { return GetOption(seti, groupi, valuei, option.c_str()); } size_t Groups::Size(size_t seti, size_t groupi) { pt::Space::TableType * sets_table = space.get_table(L"sets"); if( sets_table && seti < sets_table->size() ) { pt::Space::TableType * groups_table = (*sets_table)[seti]->get_table(L"groups"); if( groups_table && groupi < groups_table->size() ) { pt::Space * value = (*groups_table)[groupi]; return value->table_size(); } } return 0; } void Groups::Clear() { space.clear(); set_index.clear(); group_index_tab.clear(); } } } // namespace Winix