205 lines
11 KiB
C
205 lines
11 KiB
C
|
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
|
// Copyright(c) 2015, 2016 Sequence Logic.
|
||
|
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A helper class to help with JSON objects.
|
||
|
|
*/
|
||
|
|
#ifndef JSON_OBJECT_H
|
||
|
|
#define JSON_OBJECT_H
|
||
|
|
|
||
|
|
#include <memory>
|
||
|
|
#include "json.h"
|
||
|
|
|
||
|
|
namespace sequencelogic
|
||
|
|
{
|
||
|
|
class JSONObject;
|
||
|
|
typedef std::shared_ptr<JSONObject> 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<double>(nVal)); }
|
||
|
|
void setJSONValue(const char *pKey, unsigned int nVal) { setnumber(pKey, static_cast<double>(nVal)); }
|
||
|
|
void setJSONValue(const char *pKey, long long nVal) { setnumber(pKey, static_cast<double>(nVal)); }
|
||
|
|
void setJSONValue(const char *pKey, unsigned long long nVal) { setnumber(pKey, static_cast<double>(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<int>(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<unsigned int>(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<long long>(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<unsigned long long>(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<double>(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<JSONObject *>(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<JSONObject *>(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<JSONObject*>(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<double>(nVal))); }
|
||
|
|
void addElement(unsigned int nVal) { add(new T_JSON("", static_cast<double>(nVal))); }
|
||
|
|
void addElement(long long nVal) { add(new T_JSON("", static_cast<double>(nVal))); }
|
||
|
|
void addElement(unsigned long long nVal) { add(new T_JSON("", static_cast<double>(nVal))); }
|
||
|
|
void addElement(double nVal) { add(new T_JSON("", nVal)); }
|
||
|
|
void addElement(const JSONObject &obj) { add(new T_JSON(static_cast<const T_JSON &>(obj))); }
|
||
|
|
void addElement(const JSONArray &obj) { add(new T_JSON(static_cast<const T_JSON &>(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
|