/////////////////////////////////////////////////////////////////////////////// // Copyright(c) 2015, 2016 Sequence Logic. /////////////////////////////////////////////////////////////////////////////// /** * A helper class to help with JSON objects. */ #ifndef JSON_OBJECT_H #define JSON_OBJECT_H #include #include "json.h" namespace sequencelogic { class JSONObject; typedef std::shared_ptr JSONObjectPtr; class JSONArray; class JSONObject : public T_JSON { public: JSONObject(T_JSON::JSONTYPE type = T_JSON::J_OBJECT) : T_JSON(type) {} JSONObject(const std::string &jsonStr); virtual ~JSONObject() {} // Load JSON from a file. bool LoadFromFile(const std::string &fileName); // Save JSON to a file. bool SaveToFile(const std::string &fileName, bool bPretty = true); /* * Add/set a value in the JSON object. */ void setJSONValue(const char *pKey, int nVal) { setnumber(pKey, static_cast(nVal)); } void setJSONValue(const char *pKey, unsigned int nVal) { setnumber(pKey, static_cast(nVal)); } void setJSONValue(const char *pKey, long long nVal) { setnumber(pKey, static_cast(nVal)); } void setJSONValue(const char *pKey, unsigned long long nVal) { setnumber(pKey, static_cast(nVal)); } void setJSONValue(const char *pKey, double nVal) { setnumber(pKey, nVal); } void setJSONValue(const char *pKey, const char *pVal) { setstring(pKey, pVal); } void setJSONValue(const char *pKey, bool bVal) { setboolean(pKey, bVal); } void setJSONValue(const std::string &key, int nVal) { setJSONValue(key.c_str(), nVal); } void setJSONValue(const std::string &key, unsigned int nVal) { setJSONValue(key.c_str(), nVal); } void setJSONValue(const std::string &key, long long nVal) { setJSONValue(key.c_str(), nVal); } void setJSONValue(const std::string &key, unsigned long long nVal) { setJSONValue(key.c_str(), nVal); } void setJSONValue(const std::string &key, double nVal) { setJSONValue(key.c_str(), nVal); } void setJSONValue(const std::string &key, bool bVal) { setJSONValue(key.c_str(), bVal); } void setJSONValue(const std::string &key, const char *pVal) { setJSONValue(key.c_str(), pVal); } // The stupid Visual Studio compiler can't determine which setJSONValue to use when you pass in a std::string // as a value! //1>c:\ionu\ionu-cpp\client\peerservice.cpp(103): error C2666: 'ionu::JSONObject::setJSONValue' : 5 overloads have similar conversions //1> c:\ionu\ionu-json\jsonobject.h(63): could be 'void ionu::JSONObject::setJSONValue(const std::string &,const ionu::JSONObject &)' //1> c:\ionu\ionu-json\jsonobject.h(62): or 'void ionu::JSONObject::setJSONValue(const char *,const ionu::JSONObject &)' //1> c:\ionu\ionu-json\jsonobject.h(58): or 'void ionu::JSONObject::setJSONValue(const std::string &,const ionu::JSONArray &)' //1> c:\ionu\ionu-json\jsonobject.h(57): or 'void ionu::JSONObject::setJSONValue(const char *,const ionu::JSONArray &)' //1> c:\ionu\ionu-json\jsonobject.h(46): or 'void ionu::JSONObject::setJSONValue(const std::string &,const std::string &)' //1> while trying to match the argument list '(const char [6], std::string)' // So, just comment it out... //void setJSONValue(const std::string &key, const std::string &val) { setJSONValue(key.c_str(), val.c_str()); } /* * Create an empty array with the provided key. If an array already exists, it is not touched. */ void setJSONArray(const char *pKey); void setJSONArray(const std::string &key) { setJSONArray(key.c_str()); } /* * Set a JSON array. */ void setJSONValue(const char *pKey, const JSONArray &value); void setJSONValue(const std::string &key, const JSONArray &value) { setJSONValue(key.c_str(), value); } /* * Set a JSON object. */ void setJSONValue(const char *pKey, const JSONObject &value); void setJSONValue(const std::string &key, const JSONObject &value) { setJSONValue(key.c_str(), value); } /* * Get a string value from the JSON object. */ std::string getJSONString(const char *pKey, const std::string &altVal = "") const; #ifdef WIN32 std::string getJSONStringPath(const char *pKey, const std::string &altVal = "") const; bool getJSONBoolPath(const char *pKey, bool bAltVal = true) const; unsigned int getJSONUIntPath(const char *pKey, unsigned int nAltVal = 0) const; unsigned long long getJSONUInt64Path(const char *pKey, unsigned long long nAltVal = 0) const; void setJSONValuePath(const char *pKey, const std::string &value) { setJSONValuePath(pKey, value.c_str()); } void setJSONValuePath(const char *pKey, const char *pValue); void setJSONValuePath(const std::string &key, const std::string &value) { setJSONValuePath(key.c_str(), value); } void setJSONValuePath(const char *pKey, bool bVal); void setJSONValuePath(const std::string &key, bool bVal) { setJSONValuePath(key.c_str(), bVal); } void setJSONValuePath(const char *pKey, unsigned long long nVal); void setJSONValuePath(const std::string &key, unsigned long long nVal) { setJSONValuePath(key.c_str(), nVal); } #endif /* * Get a numeric value from the JSON object */ int getJSONInt(const char *pKey, int altVal = 0) const { if (search(pKey) != NULL) return static_cast(operator[](pKey).getint()); else return altVal; } int getJSONInt(const std::string &key, int altVal = 0) const { return getJSONInt(key.c_str(), altVal); } unsigned int getJSONUInt(const char *pKey, unsigned int altVal = 0) const { if (search(pKey) != NULL) return static_cast(operator[](pKey).getint()); else return altVal; } unsigned int getJSONUInt(const std::string &key, unsigned int altVal = 0) const { return getJSONUInt(key.c_str(), altVal); } long long getJSONInt64(const char *pKey, long long altVal = 0) const { if (search(pKey) != NULL) return static_cast(operator[](pKey).getint()); else return altVal; } long long getJSONInt64(const std::string &key, long long altVal = 0) const { return getJSONInt64(key.c_str(), altVal); } unsigned long long getJSONUInt64(const char *pKey, unsigned long long altVal = 0) const { if (search(pKey) != NULL) return static_cast(operator[](pKey).getint()); else return altVal; } unsigned long long getJSONUInt64(const std::string &key, unsigned long long altVal = 0) const { return getJSONUInt64(key.c_str(), altVal); } double getJSONDouble(const char *pKey, double altVal = 0.0) const { if (search(pKey) != NULL) return static_cast(operator[](pKey).getdouble()); else return altVal; } double getJSONDouble(const std::string &key, double altVal = 0.0) const { return getJSONDouble(key.c_str(), altVal); } /** * Get a bool value from the JSON object. */ bool getJSONBool(const char *pKey, bool altVal = false) const { if (search(pKey) != NULL) return (operator[](pKey).getboolean()); else return altVal; } bool getJSONBool(const std::string &key, bool altVal = false) const { return getJSONBool(key.c_str(), altVal); } /* * Get a JSON object from this one. */ JSONObject& getJSONObject(const char *pKey); const JSONObject& getJSONObject(const char *pKey) const { return const_cast(this)->getJSONObject (pKey); } JSONObject& getJSONObject(const std::string &key) { return getJSONObject(key.c_str()); } const JSONObject& getJSONObject(const std::string &key) const { return getJSONObject(key.c_str()); } /* * Get a JSON array from this one. */ JSONArray& getJSONArray(const char *pKey); const JSONArray& getJSONArray(const char *pKey) const { return const_cast(this)->getJSONArray (pKey); } JSONArray& getJSONArray(const std::string &key) { return getJSONArray(key.c_str()); } const JSONArray& getJSONArray(const std::string &key) const { return getJSONArray(key.c_str()); } /* * Get the "string" version of this object. */ std::string toString(bool bPrettyPrint = false) const; /* * Merge another JSON object with this one. Replace any data in this object with the other, if keys match. */ void mergeWith(const JSONObject &other); /** * Is this object empty? */ bool empty() const { return ((gettype() == T_JSON::J_NULL) || (((gettype() == T_JSON::J_OBJECT) || (gettype() == T_JSON::J_ARRAY)) && (data.size() == 0))); } /** * Get a pointer to the "raw" data type (T_JSON). You can query the returned pointer for type, value, etc. */ const T_JSON *getRawValue(const char *pKey) const { return const_cast(this)->search(pKey); } const T_JSON *getRawValue(const std::string &key) const { return getRawValue(key.c_str()); } private: #ifdef WIN32 T_JSON *findValuePath(T_JSON *pStartVal, const char *pPath, bool bCreateIfNecessary); #endif std::string writeObj(const JSONObject &obj); }; class JSONArray : public JSONObject { public: JSONArray() : JSONObject(T_JSON::J_ARRAY) {} JSONArray(const std::string &jsonStr) : JSONObject(jsonStr) {} /** * Does this array contain the passed in string? */ bool hasString(const std::string &str) const; /** * Remove an element from the array... */ void removeElement(const std::string &elem); /** * Add an element to the array... */ void addElement(const std::string &elem) { add(new T_JSON("", elem.c_str())); } void addElement(int nVal) { add(new T_JSON("", static_cast(nVal))); } void addElement(unsigned int nVal) { add(new T_JSON("", static_cast(nVal))); } void addElement(long long nVal) { add(new T_JSON("", static_cast(nVal))); } void addElement(unsigned long long nVal) { add(new T_JSON("", static_cast(nVal))); } void addElement(double nVal) { add(new T_JSON("", nVal)); } void addElement(const JSONObject &obj) { add(new T_JSON(static_cast(obj))); } void addElement(const JSONArray &obj) { add(new T_JSON(static_cast(obj))); } /** * Clear the array. */ void clear() { settype(J_ARRAY); } private: }; std::ostream& operator<<(std::ostream &out, const JSONObject &obj); std::ostream& operator<<(std::ostream &out, const JSONArray &obj); }; #endif