272 lines
6.2 KiB
C++
272 lines
6.2 KiB
C++
/*
|
|
* This file is a part of Winix
|
|
* and is distributed under the 2-Clause BSD licence.
|
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
|
*/
|
|
|
|
/*
|
|
* 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 <algorithm>
|
|
#include <limits>
|
|
#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 ; i<groups->sort_value.size() ; ++i)
|
|
// if( val == groups->sort_value[i] )
|
|
// return i;
|
|
//
|
|
//return std::numeric_limits<size_t>::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
|
|
|