filedat: add merge()
This commit is contained in:
parent
861aab58cd
commit
1c71b8c90c
2 changed files with 70 additions and 4 deletions
|
|
@ -188,14 +188,25 @@ namespace ztd
|
|||
inline void add(std::vector<chunkdat> const& vec) { addToList(vec); }
|
||||
//! @brief Concatenate chunks of data
|
||||
/*! Effective only if the two chunks are of the same type\n
|
||||
Map: combines two maps into a single map\n
|
||||
List: combines into a single list\n
|
||||
Map: Combines into a single map. Error on colliding keys\n
|
||||
List: Append input list to current chunk\n
|
||||
String: Concatenate strings
|
||||
*/
|
||||
void concatenate(chunkdat const& chk);
|
||||
|
||||
//! @brief Merge chk into current chunk
|
||||
/*! Merge is performed recursively\n
|
||||
Map: combines into a single map. Colliding keys get merged\n
|
||||
List: Append input list to current chunk\n
|
||||
String: Error\n
|
||||
@param overwrite In case of collisions or type mismatch, input overwrites current chunk
|
||||
*/
|
||||
void merge(chunkdat const& chk, bool overwrite=false);
|
||||
|
||||
//! @brief Erase key from map
|
||||
void erase(const std::string& key);
|
||||
|
||||
//! @brief Erase index from list
|
||||
void erase(const unsigned int index);
|
||||
|
||||
|
||||
|
|
@ -285,6 +296,10 @@ namespace ztd
|
|||
//! @brief substract
|
||||
inline chunkdat operator-(const chunkdat& a, const unsigned int b) { chunkdat ret(a); ret -= b; return ret; }
|
||||
|
||||
//! @brief Merge chunks
|
||||
inline chunkdat merge(chunkdat a, chunkdat const& b, bool overwrite) { a.merge(b, overwrite); return a; }
|
||||
|
||||
|
||||
//! @brief File data object
|
||||
/*!
|
||||
Object for importing, reading, altering and writing of file data\n
|
||||
|
|
@ -413,6 +428,7 @@ namespace ztd
|
|||
inline std::ostream& operator<<(std::ostream& stream, chunkdat const& a) { return stream << a.strval(); }
|
||||
inline std::ostream& operator<<(std::ostream& stream, filedat const& a) { return stream << a.strval(); }
|
||||
|
||||
|
||||
void printErrorIndex(const char* in, const int index, const std::string& message, const std::string& origin);
|
||||
//! @brief Print exception to console
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -252,7 +252,6 @@ std::pair<std::string, size_t> _skip(const std::string& str)
|
|||
}
|
||||
|
||||
|
||||
// TODO TODO TODO
|
||||
// value, rest, start of rest, start of value, delim found
|
||||
static std::tuple<std::string, std::string, int, int, bool> _getstrval(const std::string& str, const char delim=0, const char altdelim=0)
|
||||
{
|
||||
|
|
@ -748,6 +747,57 @@ void ztd::chunkdat::concatenate(chunkdat const& chk)
|
|||
}
|
||||
}
|
||||
|
||||
// overwrite: chk replaces this when conflict
|
||||
void ztd::chunkdat::merge(chunkdat const& chk, bool overwrite)
|
||||
{
|
||||
if(this->type() == ztd::chunk_abstract::none) //nothing: copy
|
||||
{
|
||||
this->set(chk);
|
||||
}
|
||||
else if(this->type()==ztd::chunk_abstract::map && chk.type()==ztd::chunk_abstract::map) //map
|
||||
{
|
||||
ztd::chunk_map* ci = dynamic_cast<chunk_map*>(chk.getp());
|
||||
ztd::chunk_map* cc = dynamic_cast<chunk_map*>(m_achunk);
|
||||
for(auto it: ci->values) // iterate keys
|
||||
{
|
||||
auto fi = cc->values.find(it.first);
|
||||
if(fi == cc->values.end()) // new key
|
||||
{
|
||||
this->addToMap(it.first, *it.second);
|
||||
}
|
||||
else // key already present
|
||||
{
|
||||
fi->second->merge(*it.second, overwrite); // merge subchunks
|
||||
}
|
||||
}
|
||||
//map merge
|
||||
}
|
||||
else if(this->type()==ztd::chunk_abstract::list && chk.type()==ztd::chunk_abstract::list) //list
|
||||
{
|
||||
ztd::chunk_list* ci = dynamic_cast<chunk_list*>(chk.getp());
|
||||
for(auto it : ci->list)
|
||||
{
|
||||
this->add(*it);
|
||||
}
|
||||
}
|
||||
else if(this->type()==ztd::chunk_abstract::string && chk.type()==ztd::chunk_abstract::string) //string
|
||||
{
|
||||
ztd::chunk_string* cc = dynamic_cast<chunk_string*>(m_achunk);
|
||||
if(overwrite)
|
||||
cc->val = chk.str();
|
||||
else
|
||||
throw ztd::format_error("Cannot merge string chunks", "", "", -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(overwrite)
|
||||
this->set(chk);
|
||||
else
|
||||
throw ztd::format_error("Cannot merge chunks of different types", "", "", -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ztd::chunkdat::erase(const std::string& key)
|
||||
{
|
||||
if(this->type()==ztd::chunk_abstract::map)
|
||||
|
|
@ -867,7 +917,7 @@ ztd::chunkdat* ztd::chunkdat::subChunkPtr(std::string const& in) const
|
|||
ztd::chunk_map* dc = dynamic_cast<chunk_map*>(m_achunk);
|
||||
auto fi = dc->values.find(in);
|
||||
if(fi == dc->values.end()) //none found
|
||||
return nullptr;
|
||||
return nullptr;
|
||||
return fi->second;
|
||||
}
|
||||
else //not a chunk
|
||||
|
|
|
|||
Loading…
Reference in a new issue