Created
July 23, 2015 08:42
-
-
Save VictorLaskin/1fb078d7f4ac78857f48 to your computer and use it in GitHub Desktop.
MVJSON - my old lib for JSON reading / writing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* | |
* Compact JSON format parsing lib (native cross-platform c++) | |
* | |
* Copyright (C) 2013 Victor Laskin ([email protected]) | |
* Details: http://vitiy.info/?p=102 | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions | |
* are met: | |
* 1. Redistributions of source code must retain the above copyright | |
* notice, this list of conditions and the following disclaimer. | |
* 2. Redistributions in binary form must reproduce the above copyright | |
* notice, this list of conditions and the following disclaimer in | |
* the documentation and/or other materials provided with the | |
* distribution. | |
* 3. The names of the authors may not be used to endorse or promote | |
* products derived from this software without specific prior | |
* written permission. | |
* | |
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS | |
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY | |
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | |
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER | |
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | |
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
* | |
*/ | |
#include "MVJSON.h" | |
namespace JSON { | |
MVJSONReader::MVJSONReader(const string & source) { | |
root = nullptr; | |
if (source == "") return; | |
if (source[0] == '{') | |
root = parse(source); | |
if (source[0] == '[') | |
root = parse("{\"root\":" + source + "}"); | |
} | |
MVJSONReader::~MVJSONReader() { | |
if (root != NULL) | |
delete root; | |
} | |
MVJSONNode::~MVJSONNode() { | |
if (values.size() > 0) | |
for (int i = 0; i < values.size(); i++) | |
delete values.at(i); | |
} | |
MVJSONNode* MVJSONReader::parse(string text) | |
{ | |
string s = trim(text); | |
if (s.length() < 2) return NULL; | |
// object | |
if ((s[0] == '{') && (s[s.length() - 1] == '}')) | |
{ | |
// erase last and first symbols | |
s.erase(0, 1); | |
s.erase(s.length() - 1, 1); | |
vector<string> parts; | |
splitList(s, parts); | |
MVJSONNode* node = new MVJSONNode(); | |
for (int i = 0; i < parts.size(); i++) | |
node->values.push_back(parseValue(parts.at(i), false)); | |
return node; | |
} | |
return NULL; | |
} | |
MVJSONValue* MVJSONReader::parseValue(string text, bool hasNoName) | |
{ | |
string key; | |
string s; | |
splitInHalf(text, ":", key, s); | |
key = trim(key); | |
s = trim(s); | |
if (key.length() > 2) | |
{ | |
// strip " | |
key.erase(0, 1); | |
key.erase(key.length() - 1, 1); | |
} | |
if (hasNoName) | |
{ | |
s = text; | |
key = ""; | |
} | |
if (s == "false") // bool | |
return new MVJSONValue(key, false); | |
if (s == "true") // bool | |
return new MVJSONValue(key, true); | |
if (s == "null") // null | |
return new MVJSONValue(key, MVJSON_TYPE_NULL); | |
char first = s[0]; | |
if (first == '"') // string | |
return new MVJSONValue(key, s.substr(1, s.length() - 2)); | |
if (first == '{') // object | |
return new MVJSONValue(key, parse(s)); | |
if (first == '[') // array | |
{ | |
s.erase(0, 1); | |
s.erase(s.length() - 1, 1); | |
MVJSONValue* val = new MVJSONValue(key, MVJSON_TYPE_ARRAY); | |
if (s != "") | |
{ | |
vector<string> parts; | |
splitList(s, parts); | |
for (int i = 0; i < parts.size(); i++) | |
val->arrayValue.push_back(parseValue(parts.at(i), true)); | |
} | |
return val; | |
} | |
// else its number! | |
if (s.find(".") == string::npos) | |
return new MVJSONValue(key, s, stringToLongLong(s)); | |
else | |
return new MVJSONValue(key, s, stringToDouble(s)); | |
return NULL; | |
} | |
MVJSONValue::~MVJSONValue() | |
{ | |
if (objValue != NULL) | |
delete objValue; | |
if (arrayValue.size() > 0) | |
for (int i = 0; i < arrayValue.size(); i++) | |
delete arrayValue.at(i); | |
} | |
void MVJSONValue::init(MVJSON_TYPE valueType) | |
{ | |
this->valueType = valueType; | |
objValue = NULL; | |
name = ""; | |
} | |
MVJSONValue::MVJSONValue(const string& name, MVJSON_TYPE valueType) | |
{ | |
init(valueType); | |
this->name = name; | |
} | |
MVJSONValue::MVJSONValue(const string& name, bool value) | |
{ | |
init(MVJSON_TYPE_BOOL); | |
this->name = name; | |
boolValue = value; | |
} | |
MVJSONValue::MVJSONValue(const string& name, const string& value) | |
{ | |
init(MVJSON_TYPE_STRING); | |
this->name = name; | |
stringValue = value; | |
// here we switch back special chars | |
// \" \\ \/ \b \f \n \r \t \u four-hex-digits | |
replace(stringValue, "\\\"", "\""); | |
replace(stringValue, "\\\\", "\\"); | |
replace(stringValue, "\\/", "/"); | |
replace(stringValue, "\\b", "\b"); | |
replace(stringValue, "\\f", "\f"); | |
replace(stringValue, "\\n", "\n"); | |
replace(stringValue, "\\r", "\r"); | |
replace(stringValue, "\\t", "\t"); | |
// TODO - \u four-hex-digits | |
// SS::replace(stringValue, "\\\\", "\\"); | |
} | |
MVJSONValue::MVJSONValue(const string& name, const string& source, long long value) | |
{ | |
init(MVJSON_TYPE_INT); | |
this->name = name; | |
stringValue = source; | |
intValue = value; | |
} | |
MVJSONValue::MVJSONValue(const string& name, const string& source, double value) | |
{ | |
init(MVJSON_TYPE_DOUBLE); | |
this->name = name; | |
stringValue = source; | |
doubleValue = value; | |
} | |
MVJSONValue::MVJSONValue(const string& name, MVJSONNode* value) | |
{ | |
init(MVJSON_TYPE_OBJECT); | |
this->name = name; | |
objValue = value; | |
} | |
bool MVJSONNode::hasField(const string& name) | |
{ | |
if (values.size() == 0) return false; | |
for (int i = 0; i < values.size(); i++) | |
if (values.at(i)->name == name) | |
return true; | |
return false; | |
} | |
MVJSONValue* MVJSONNode::getField(const string& name) | |
{ | |
if (values.size() == 0) return NULL; | |
for (int i = 0; i < values.size(); i++) | |
if (values.at(i)->name == name) | |
return values.at(i); | |
return NULL; | |
} | |
MVJSONValue* MVJSONValue::field(const string& name) { | |
return objValue->getField(name); | |
} | |
double MVJSONNode::getFieldDouble(const string& name) | |
{ | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return 0; | |
if (value->valueType == MVJSON_TYPE_INT) return value->intValue; | |
if (value->valueType == MVJSON_TYPE_DOUBLE) return value->doubleValue; | |
return 0; | |
} | |
int MVJSONNode::getFieldInt(const string& name) | |
{ | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return 0; | |
if (value->valueType == MVJSON_TYPE_INT) return (int)value->intValue; | |
return 0; | |
} | |
long long MVJSONNode::getFieldLongLong(const string& name) | |
{ | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return 0; | |
if (value->valueType == MVJSON_TYPE_INT) return value->intValue; | |
return 0; | |
} | |
string MVJSONNode::getFieldString(const string& name) | |
{ | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return ""; | |
if (value->valueType == MVJSON_TYPE_STRING) return value->stringValue; | |
if (value->valueType == MVJSON_TYPE_DOUBLE) return value->stringValue; | |
if (value->valueType == MVJSON_TYPE_INT) return value->stringValue; | |
return ""; | |
} | |
bool MVJSONNode::getFieldBool(const string& name) | |
{ | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return false; | |
if (value->valueType == MVJSON_TYPE_INT) return (bool)value->intValue; | |
if (value->valueType == MVJSON_TYPE_BOOL) return value->boolValue; | |
return false; | |
} | |
double MVJSONValue::getFieldDouble(const string& name) | |
{ | |
if (objValue == NULL) return 0; | |
return objValue->getFieldDouble(name); | |
} | |
int MVJSONValue::getFieldInt(const string& name) | |
{ | |
if (objValue == NULL) return 0; | |
return objValue->getFieldInt(name); | |
} | |
long long MVJSONValue::getFieldLongLong(const string& name) | |
{ | |
if (objValue == NULL) return 0; | |
return objValue->getFieldLongLong(name); | |
} | |
string MVJSONValue::getFieldString(const string& name) | |
{ | |
if (objValue == NULL) return ""; | |
return objValue->getFieldString(name); | |
} | |
bool MVJSONValue::getFieldBool(const string& name) | |
{ | |
if (objValue == NULL) return false; | |
return objValue->getFieldBool(name); | |
} | |
// -------------------- writer --------------------------> | |
MVJSONWriter::MVJSONWriter() | |
{ | |
result = ""; | |
depth = 0; | |
counts.resize(50); | |
std::fill(counts.begin(), counts.end(), 0); | |
} | |
} /* namespace F2 */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* | |
* Compact JSON format parsing lib (native cross-platform c++) | |
* | |
* Copyright (C) 2013 Victor Laskin ([email protected]) | |
* Details: http://vitiy.info/compact-lib-for-json-parsing-cross-platform-c/ | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions | |
* are met: | |
* 1. Redistributions of source code must retain the above copyright | |
* notice, this list of conditions and the following disclaimer. | |
* 2. Redistributions in binary form must reproduce the above copyright | |
* notice, this list of conditions and the following disclaimer in | |
* the documentation and/or other materials provided with the | |
* distribution. | |
* 3. The names of the authors may not be used to endorse or promote | |
* products derived from this software without specific prior | |
* written permission. | |
* | |
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS | |
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY | |
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE | |
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER | |
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | |
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
* | |
*/ | |
#include <string> | |
#include <vector> | |
#include <sstream> | |
#include <stdlib.h> | |
#ifndef MVJSON_H_ | |
#define MVJSON_H_ | |
using namespace std; | |
namespace JSON { | |
/// JSON node types | |
enum MVJSON_TYPE | |
{ | |
MVJSON_TYPE_NULL, | |
MVJSON_TYPE_OBJECT, | |
MVJSON_TYPE_ARRAY, | |
MVJSON_TYPE_STRING, | |
MVJSON_TYPE_INT, | |
MVJSON_TYPE_DOUBLE, | |
MVJSON_TYPE_BOOL | |
}; | |
class MVJSONUtils { | |
protected: | |
// string parsing functions | |
inline static long long stringToLongLong(const string & s); ///< convert string to long long | |
inline static double stringToDouble(const string & s); ///< convert string to float | |
inline static bool symbolToBeTrimmed(const char& c); ///< check if symbol is space, tab or new line break | |
inline static string trim(const string & text); ///< trim spaces, tabs and line break | |
inline static void replace(string & target, const string & oldStr, const string & newStr); ///< replace all occurrences of substring | |
inline static void splitInHalf(const string & s, const string & separator, string & begin, string & end); ///< second half (output) | |
inline static void splitList(const string & s, vector<string> & parts); | |
}; | |
class MVJSONNode; | |
/// JSON Value | |
class MVJSONValue : public MVJSONUtils { | |
public: | |
MVJSONValue(const string& name, MVJSON_TYPE valueType); | |
MVJSONValue(const string& name, bool value); | |
MVJSONValue(const string& name, const string& value); | |
MVJSONValue(const string& name, const string& source, long long value); | |
MVJSONValue(const string& name, const string& source, double value); | |
MVJSONValue(const string& name, MVJSONNode* value); | |
virtual ~MVJSONValue(); | |
string name; ///< value name [optional] | |
MVJSON_TYPE valueType; ///< type of node | |
string stringValue; ///< value if data has string type | |
bool boolValue; ///< value if data has bool type | |
long long intValue; ///< value if data has int type | |
double doubleValue; ///< value if data has double type | |
MVJSONNode* objValue; ///< value if data has object type | |
vector<MVJSONValue*> arrayValue; ///< array of values | |
MVJSONValue* field(const string& name); | |
double getFieldDouble(const string& name); ///< get value of double field of VALUE OBJECT (objValue) | |
int getFieldInt(const string& name); ///< get value of int field of VALUE OBJECT (objValue) | |
string getFieldString(const string& name); ///< get value of string field of VALUE OBJECT (objValue) | |
bool getFieldBool(const string& name); ///< get value of bool field of VALUE OBJECT (objValue) | |
long long getFieldLongLong(const string& name); ///< get long long value from field | |
inline MVJSONValue* at(unsigned int i){ return arrayValue.at(i); } | |
inline int size() { if (valueType == MVJSON_TYPE_ARRAY) return arrayValue.size(); else return 1; } | |
private: | |
void init(MVJSON_TYPE valueType); | |
}; | |
template <typename T> struct is_vector { static const bool value = false; }; | |
template <typename T> struct is_vector< std::vector<T> > { static const bool value = true; }; | |
template <typename T> struct is_vector< const std::vector<T> > { static const bool value = true; }; | |
/// JSON Node (Object) | |
class MVJSONNode { | |
public: | |
virtual ~MVJSONNode(); | |
vector<MVJSONValue*> values; ///< values (props) | |
bool hasField(const string& name); ///< check that object has field | |
MVJSONValue* getField(const string& name); ///< get field by name | |
template<class T> | |
inline T getValue(const string& name, typename enable_if<!is_vector<T>::value, T>::type* = nullptr); ///< get value of specified type | |
template<class T> | |
inline T getValue(const string& name, typename enable_if<is_vector<T>::value, T>::type* = nullptr); ///< get value of specified type | |
double getFieldDouble(const string& name); ///< get value of double field | |
int getFieldInt(const string& name); ///< get value of int field | |
long long getFieldLongLong(const string& name); ///< get value of int field | |
string getFieldString(const string& name); ///< get value of string field | |
bool getFieldBool(const string& name); ///< get value of bool field | |
}; | |
/// Compact JSON parser (based on specification: http://www.json.org/) | |
class MVJSONReader : public MVJSONUtils { | |
public: | |
MVJSONReader(const string & source); ///< constructor from json source | |
virtual ~MVJSONReader(); | |
MVJSONNode* root; ///< root object (if its null - parsing was failed) | |
private: | |
MVJSONValue* parseValue(string text, bool hasNoName); ///< parse value | |
MVJSONNode* parse(string text); ///< parse node | |
}; | |
/// Simple writer into JSON format | |
class MVJSONWriter : public MVJSONUtils { | |
public: | |
MVJSONWriter(); | |
string result; | |
inline MVJSONWriter& begin(); | |
inline MVJSONWriter& begin(const string& name); | |
inline MVJSONWriter& end(); | |
inline MVJSONWriter& beginList(const string& name); | |
inline MVJSONWriter& endList(); | |
template< typename T > | |
inline MVJSONWriter& add(const string& name, const T& value); | |
template< typename T > | |
inline MVJSONWriter& add(const T& value); | |
inline MVJSONWriter& include(const string& json); | |
private: | |
inline void addComma(); | |
vector<int> counts; | |
int depth; | |
template< typename T > | |
inline string toString(const T& value); | |
template< typename T > | |
inline string toString(const vector<T>& value); | |
}; | |
// --------------- reader -------------------------------------> | |
template<class T> | |
//inline typename enable_if<!is_vector<T>::value, T>::type | |
inline T | |
MVJSONNode::getValue(const string& name, typename enable_if<!is_vector<T>::value, T>::type*) | |
{ | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return ""; | |
return value->stringValue; | |
} | |
template<class T> | |
//inline typename enable_if<is_vector<T>::value, T>::type | |
inline T | |
MVJSONNode::getValue(const string& name, typename enable_if<is_vector<T>::value, T>::type*) | |
{ | |
typename std::remove_const<T>::type result; | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return result; | |
for (auto item : value->arrayValue) | |
{ | |
result.push_back(remove_pointer<decltype(std::declval<T>().at(0).get())>::type::fromJSON(item->objValue)); | |
} | |
return result; | |
} | |
template<> | |
//inline typename enable_if<is_vector<T>::value, T>::type | |
inline const vector<int> | |
MVJSONNode::getValue(const string& name, typename enable_if<is_vector<const vector<int>>::value, const vector<int>>::type*) | |
{ | |
vector<int> result; | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return result; | |
for (auto item : value->arrayValue) | |
{ | |
result.push_back((int)item->intValue); | |
} | |
return result; | |
} | |
template<> | |
inline const long long MVJSONNode::getValue(const string& name, typename enable_if<!is_vector<const long long>::value, const long long>::type*) | |
{ | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return 0; | |
return value->intValue; | |
} | |
template<> | |
inline const long MVJSONNode::getValue(const string& name, typename enable_if<!is_vector<const long>::value, const long>::type*) | |
{ | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return 0; | |
return (long)value->intValue; | |
} | |
template<> | |
inline const int MVJSONNode::getValue(const string& name, typename enable_if<!is_vector<const int>::value, const int>::type*) | |
{ | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return 0; | |
return (int)value->intValue; | |
} | |
template<> | |
inline const bool MVJSONNode::getValue(const string& name, typename enable_if<!is_vector<const bool>::value, const bool>::type*) | |
{ | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return false; | |
return value->boolValue; | |
} | |
template<> | |
inline const double MVJSONNode::getValue(const string& name, typename enable_if<!is_vector<const double>::value, const double>::type*) | |
{ | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return 0.0; | |
return value->doubleValue; | |
} | |
template<> | |
inline const float MVJSONNode::getValue(const string& name, typename enable_if<!is_vector<const float>::value, const float>::type*) | |
{ | |
MVJSONValue* value = getField(name); | |
if (value == NULL) return 0.0; | |
return value->doubleValue; | |
} | |
// ------------------- inlined string processing functions -------------> | |
inline long long MVJSONUtils::stringToLongLong(const string & s) | |
{ | |
return atoll(s.c_str()); | |
} | |
inline double MVJSONUtils::stringToDouble(const string & s) | |
{ | |
return atof(s.c_str()); | |
} | |
inline bool MVJSONUtils::symbolToBeTrimmed(const char& c ///< the char to test | |
) | |
{ | |
if (c == ' ') return true; | |
if (c == '\n') return true; | |
if (c == '\r') return true; | |
if (c == '\t') return true; | |
return false; | |
} | |
inline string MVJSONUtils::trim(const string & text ///< the text to trim | |
) | |
{ | |
if (text.length() == 0) return ""; | |
int start = 0; | |
while ((start < text.length()) && (symbolToBeTrimmed(text[start]))) start++; | |
int end = text.length() - 1; | |
while ((end > 0) && (symbolToBeTrimmed(text[end]))) end--; | |
if (start > end) return ""; | |
return text.substr(start, end - start + 1); | |
} | |
inline void MVJSONUtils::splitInHalf(const string & s, ///< source string to split up | |
const string & separator, ///< separator string) | |
string & begin, ///< first part (output) | |
string & end ///< second half (output) | |
) | |
{ | |
int pos = s.find(separator); | |
if (pos == string::npos) { begin = s; end = ""; return; } | |
begin = s.substr(0, pos); | |
end = s.substr(pos + separator.length(), s.length() - pos - separator.length()); | |
} | |
/// split string by "," - ignore content inside of "{", "}", "[", "]" and quotations "...." | |
/// also take \" into account | |
/// (Code should be cleared of comments beforehand) | |
inline void MVJSONUtils::splitList(const string & s, ///< string to be splitted | |
vector<string> & parts ///< result parts | |
) | |
{ | |
bool isNotInQuotes = true; | |
int b1 = 0; | |
int b2 = 0; | |
int lastPos = 0; | |
const char* start = s.c_str(); | |
const char* ps = start; | |
while (*ps) // *ps != 0 | |
{ | |
if ((*ps == ',') && (isNotInQuotes) && (b1 == 0) && (b2 == 0)) | |
{ | |
parts.push_back(s.substr(lastPos, ps - start - lastPos)); | |
lastPos = ps - start + 1; | |
} | |
if (isNotInQuotes) | |
{ | |
if (*ps == '{') b1++; | |
if (*ps == '}') b1--; | |
if (*ps == '[') b2++; | |
if (*ps == ']') b2--; | |
} | |
if (*ps == '"') | |
{ | |
isNotInQuotes = !isNotInQuotes; | |
if (ps != start) | |
if (*(ps-1) == '\\') | |
isNotInQuotes = !isNotInQuotes; | |
} | |
ps++; | |
} | |
parts.push_back(s.substr(lastPos, s.length() - lastPos)); | |
} | |
inline void MVJSONUtils::replace(string & target, ///< text to be modified | |
const string & oldStr, ///< old string | |
const string & newStr ///< new string | |
) | |
{ | |
unsigned int pos = 0; | |
unsigned int oldLen = oldStr.length(); | |
unsigned int newLen = newStr.length(); | |
for (;;) | |
{ | |
pos = target.find(oldStr, pos); | |
if (pos == string::npos) break; | |
target.replace(pos, oldLen, newStr); | |
pos += newLen; | |
} | |
} | |
// ------------------------ writer -----------------------> | |
inline void MVJSONWriter::addComma() | |
{ | |
if (depth < 0) return; | |
if (counts[depth] > 0) result += ","; | |
} | |
inline MVJSONWriter& MVJSONWriter::begin() | |
{ | |
addComma(); | |
result += "{"; | |
counts[depth]++; | |
depth++; | |
counts[depth] = 0; | |
return *this; | |
} | |
inline MVJSONWriter& MVJSONWriter::begin(const string& name) | |
{ | |
addComma(); | |
result += "\"" + name + "\":{"; | |
counts[depth]++; | |
depth++; | |
counts[depth] = 0; | |
return *this; | |
} | |
inline MVJSONWriter& MVJSONWriter::end() | |
{ | |
result += "}"; | |
depth--; | |
return *this; | |
} | |
template< typename T > | |
inline MVJSONWriter& MVJSONWriter::add(const string& name, const T& value) | |
{ | |
addComma(); | |
result += "\"" + name + "\":" + toString(value); | |
counts[depth]++; | |
return *this; | |
} | |
template< typename T > | |
inline MVJSONWriter& MVJSONWriter::add(const T& value) | |
{ | |
addComma(); | |
result += toString(value); | |
counts[depth]++; | |
return *this; | |
} | |
inline MVJSONWriter& MVJSONWriter::include(const string& json) | |
{ | |
addComma(); | |
result += json; | |
counts[depth]++; | |
return *this; | |
} | |
inline MVJSONWriter& MVJSONWriter::beginList(const string& name) | |
{ | |
addComma(); | |
result += "\"" + name + "\":["; | |
counts[depth]++; | |
depth++; | |
counts[depth] = 0; | |
return *this; | |
} | |
inline MVJSONWriter& MVJSONWriter::endList() | |
{ | |
result += "]"; | |
depth--; | |
return *this; | |
} | |
template< typename T > | |
inline string MVJSONWriter::toString(const T& value) | |
{ | |
// default overload is for string-like types! | |
return "\"" + value + "\""; | |
/* | |
std::stringstream ss; | |
//ss.precision(6); | |
ss << value; | |
return ss.str(); | |
*/ | |
} | |
template< typename T > | |
inline string MVJSONWriter::toString(const vector<T>& value) | |
{ | |
string result = "["; | |
for (auto item : value) | |
result += ((result != "[") ? "," : "") + item->toJSON(); | |
result += "]"; | |
return result; | |
} | |
template<> | |
inline string MVJSONWriter::toString(const vector<int>& value) | |
{ | |
string result = "["; | |
for (auto item : value) | |
result += ((result != "[") ? "," : "") + std::to_string(item); | |
result += "]"; | |
return result; | |
} | |
template<> | |
inline string MVJSONWriter::toString(const int& value) | |
{ | |
return std::to_string(value); | |
} | |
template<> | |
inline string MVJSONWriter::toString(const double& value) | |
{ | |
std::ostringstream os ; | |
os.precision(10); | |
os << value ; | |
return os.str() ; | |
} | |
template<> | |
inline string MVJSONWriter::toString(const float& value) | |
{ | |
return std::to_string(value); | |
} | |
template<> | |
inline string MVJSONWriter::toString(const long long& value) | |
{ | |
return std::to_string(value); | |
} | |
template<> | |
inline string MVJSONWriter::toString(const bool& value) | |
{ | |
return value ? "true" : "false"; | |
} | |
#if defined(OS_LINUX) || defined(F2_EMSCRIPTEN) | |
template<> | |
inline string MVJSONWriter::toString(const time_t& value) | |
{ | |
return std::to_string(value); | |
} | |
#endif | |
template<> | |
inline string MVJSONWriter::toString(const string& value) | |
{ | |
return "\"" + value + "\""; | |
} | |
template<> | |
inline string MVJSONWriter::toString(const char* const & value) | |
{ | |
return "\"" + string(value) + "\""; | |
} | |
} /* namespace F2 */ | |
#endif /* MVJSON_H_ */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment