filedat: add merge()

This commit is contained in:
zawz 2020-03-06 11:34:59 +01:00
parent 861aab58cd
commit 1c71b8c90c
2 changed files with 70 additions and 4 deletions

View file

@ -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
/*!

View file

@ -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