From 502ed31ef775fc98a070d6247affc361ca46b591 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Mon, 8 May 2017 09:53:43 +0200 Subject: [PATCH] Improvements to JSON library --- lib/json.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/json.h | 7 +++++ 2 files changed, 94 insertions(+) diff --git a/lib/json.cpp b/lib/json.cpp index cc4f3ee6..1c4b9483 100644 --- a/lib/json.cpp +++ b/lib/json.cpp @@ -77,6 +77,20 @@ unsigned int JSON::Iter::num() const{ return i; } +/// Delete the current indice from the parent JSON::Value. +void JSON::Iter::remove(){ + if (*this){ + if (myType == JSON::ARRAY){ + r->removeMember(aIt); + return; + } + if (myType == JSON::OBJECT){ + r->removeMember(oIt); + return; + } + } +} + /// Construct from a root Value to iterate over. JSON::ConstIter::ConstIter(const Value & root){ myType = root.myType; @@ -565,6 +579,40 @@ bool JSON::Value::operator!=(const JSON::Value & rhs) const { return !((*this) == rhs); } +bool JSON::Value::compareExcept(const Value & rhs, const std::set & skip) const { + if (myType != OBJECT) { + return ((*this) == rhs); + } + jsonForEachConst(*this, it){ + if (skip.count(it.key())){continue;} + if (!rhs.isMember(it.key()) || !(*it).compareExcept(rhs[it.key()], skip)) { + return false; + } + } + jsonForEachConst(rhs, it){ + if (skip.count(it.key())){continue;} + if (!(*this).isMember(it.key())){return false;} + } + return true; +} + +bool JSON::Value::compareOnly(const Value & rhs, const std::set & check) const { + if (myType != OBJECT) { + return ((*this) == rhs); + } + jsonForEachConst(*this, it){ + if (!check.count(it.key())){continue;} + if (!rhs.isMember(it.key()) || !(*it).compareOnly(rhs[it.key()], check)) { + return false; + } + } + jsonForEachConst(rhs, it){ + if (!check.count(it.key())){continue;} + if (!(*this).isMember(it.key())){return false;} + } + return true; +} + /// Completely clears the contents of this value, /// changing its type to NULL in the process. void JSON::Value::null() { @@ -574,6 +622,35 @@ void JSON::Value::null() { myType = EMPTY; } +/// Assigns this JSON::Value to the given JSON::Value, skipping given member recursively. +JSON::Value & JSON::Value::assignFrom(const Value & rhs, const std::set & skip){ + null(); + myType = rhs.myType; + if (myType == STRING){ + strVal = rhs.strVal; + } + if (myType == BOOL || myType == INTEGER){ + intVal = rhs.intVal; + } + if (myType == OBJECT){ + jsonForEachConst(rhs, i){ + if (!skip.count(i.key())){ + JSON::Value tmp; + tmp.assignFrom(*i, skip); + (*this)[i.key()] = tmp; + } + } + } + if (myType == ARRAY){ + jsonForEachConst(rhs, i){ + JSON::Value tmp; + tmp.assignFrom(*i, skip); + append(tmp); + } + } + return *this; +} + /// Sets this JSON::Value to be equal to the given JSON::Value. JSON::Value & JSON::Value::operator=(const JSON::Value & rhs) { null(); @@ -1207,6 +1284,16 @@ void JSON::Value::removeMember(const std::string & name) { } } +void JSON::Value::removeMember(const std::deque::iterator & it){ + delete (*it); + arrVal.erase(it); +} + +void JSON::Value::removeMember(const std::map::iterator & it){ + delete it->second; + objVal.erase(it); +} + /// For object JSON::Value objects, returns true if the /// given name is a member. Returns false otherwise. bool JSON::Value::isMember(const std::string & name) const { diff --git a/lib/json.h b/lib/json.h index d73360fb..6ec14341 100644 --- a/lib/json.h +++ b/lib/json.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "socket.h" /// JSON-related classes and functions @@ -42,7 +43,10 @@ namespace JSON { //comparison operators bool operator==(const Value & rhs) const; bool operator!=(const Value & rhs) const; + bool compareExcept(const Value & rhs, const std::set & skip) const; + bool compareOnly(const Value & rhs, const std::set & check) const; //assignment operators + Value & assignFrom(const Value & rhs, const std::set & skip); Value & operator=(const Value & rhs); Value & operator=(const std::string & rhs); Value & operator=(const char * rhs); @@ -78,6 +82,8 @@ namespace JSON { void prepend(const Value & rhs); void shrink(unsigned int size); void removeMember(const std::string & name); + void removeMember(const std::deque::iterator & it); + void removeMember(const std::map::iterator & it); bool isMember(const std::string & name) const; bool isInt() const; bool isString() const; @@ -110,6 +116,7 @@ namespace JSON { Iter & operator++();///