Commit 873ecbba authored by Lefebvre, Jordan's avatar Lefebvre, Jordan

Merge branch 'json_parser' into 'master'

Json parser

See merge request !92
parents 2ce6ce48 ccb9ebe0
Pipeline #96790 passed with stages
in 20 minutes and 36 seconds
......@@ -143,6 +143,14 @@
throw std::runtime_error(stream.str()); \
}
#define radix_not_implemented(msg) \
{ \
std::ostringstream stream; \
stream << __FILE__ << ":" << __LINE__ << " : " << msg \
<< " is not implemented. " << std::endl; \
throw std::runtime_error(stream.str()); \
}
/// set default timing to off
#ifndef RADIX_TIMING
#define RADIX_TIMING 0
......@@ -206,7 +214,10 @@ class Timer
return seconds(mDuration).count();
}
}; // class Timer
bool running() const { return mRunning; };
};
// class Timer
} // namespace radix
#if RADIX_TIMING > 0
......
......@@ -3,13 +3,16 @@ TRIBITS_SUBPACKAGE(core)
TRIBITS_CONFIGURE_FILE(visibility.hh)
SET(HEADERS
json.hh
system.hh
stringfunctions.i.hh
stringfunctions.hh
value.hh
)
SET(SOURCES
system.cc
stringfunctions.cc
value.cc
)
TRIBITS_ADD_LIBRARY(radixcore
......
This diff is collapsed.
INCLUDE(GoogleTest)
ADD_GOOGLE_TEST(tstSystem.cc NP 1)
ADD_GOOGLE_TEST(tstJson.cc NP 1)
ADD_GOOGLE_TEST(tstString.cc NP 1)
ADD_GOOGLE_TEST(tstSystem.cc NP 1)
ADD_GOOGLE_TEST(tstValue.cc NP 1)
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
"A JSON payload should be an object or array, not a string."
\ No newline at end of file
["Unclosed array"
\ No newline at end of file
{unquoted_key: "keys must be quoted"}
\ No newline at end of file
["double extra comma",,]
\ No newline at end of file
[ , "<-- missing value"]
\ No newline at end of file
["Comma after the close"],
\ No newline at end of file
["Extra close"]]
\ No newline at end of file
{"Extra value after close": true} "misplaced quoted value"
\ No newline at end of file
{"Illegal expression": 1 + 2}
\ No newline at end of file
{"Illegal invocation": alert()}
\ No newline at end of file
{"Numbers cannot have leading zeroes": 013}
\ No newline at end of file
{"Numbers cannot be hex": 0x14}
\ No newline at end of file
["Illegal backslash escape: \x15"]
\ No newline at end of file
[\naked]
\ No newline at end of file
["Illegal backslash escape: \017"]
\ No newline at end of file
[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]
\ No newline at end of file
{"Missing colon" null}
\ No newline at end of file
{"Double colon":: null}
\ No newline at end of file
{"Comma instead of colon", null}
\ No newline at end of file
["Colon instead of comma": false]
\ No newline at end of file
["Bad value", truth]
\ No newline at end of file
['single quote']
\ No newline at end of file
[" tab character in string "]
\ No newline at end of file
["tab\ character\ in\ string\ "]
\ No newline at end of file
["line
break"]
\ No newline at end of file
["line\
break"]
\ No newline at end of file
[0e]
\ No newline at end of file
[0e+]
\ No newline at end of file
[0e+-1]
\ No newline at end of file
{"Comma instead if closing brace": true,
\ No newline at end of file
["mismatch"}
\ No newline at end of file
[
"JSON Test Pattern pass1",
{"object with 1 member":["array with 1 element"]},
{},
[],
-42,
true,
false,
null,
{
"integer": 1234567890,
"real": -9876.543210,
"e": 0.123456789e-12,
"E": 1.234567890E+34,
"": 23456789012E66,
"zero": 0,
"one": 1,
"space": " ",
"quote": "\"",
"backslash": "\\",
"controls": "\b\f\n\r\t",
"slash": "/ & \/",
"alpha": "abcdefghijklmnopqrstuvwyz",
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
"digit": "0123456789",
"0123456789": "digit",
"special": "`1~!@#$%^&*()_+-={':[,]}|;.</>?",
"hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A",
"true": true,
"false": false,
"null": null,
"array":[ ],
"object":{ },
"address": "50 St. James Street",
"url": "http://www.JSON.org/",
"comment": "// /* <!-- --",
"# -- --> */": " ",
" s p a c e d " :[1,2 , 3
,
4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7],
"jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}",
"quotes": "&#34; \u0022 %22 0x22 034 &#x22;",
"\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?"
: "A key can be any string"
},
0.5 ,98.6
,
99.44
,
1066,
1e1,
0.1e1,
1e-1,
1e00,2e+00,2e-00
,"rosebud"]
\ No newline at end of file
[[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]]
\ No newline at end of file
{
"JSON Test Pattern pass3": {
"The outermost value": "must be an object or array.",
"In this test": "It is an object."
}
}
["extra comma",]
\ No newline at end of file
{"Extra comma": true,}
\ No newline at end of file
[null]
\ No newline at end of file
[true]
\ No newline at end of file
[false]
\ No newline at end of file
[0]
\ No newline at end of file
["foo"]
\ No newline at end of file
[]
\ No newline at end of file
{}
\ No newline at end of file
[0,1]
\ No newline at end of file
{"foo":"bar"}
\ No newline at end of file
{"a":null,"foo":"bar"}
\ No newline at end of file
[-1]
\ No newline at end of file
[-2147483648]
\ No newline at end of file
[-1234567890123456789]
\ No newline at end of file
[-9223372036854775808]
\ No newline at end of file
[1]
\ No newline at end of file
[2147483647]
\ No newline at end of file
[4294967295]
\ No newline at end of file
[1234567890123456789]
\ No newline at end of file
[9223372036854775807]
\ No newline at end of file
[0.0]
\ No newline at end of file
[-0.0]
\ No newline at end of file
[1.2345]
\ No newline at end of file
[-1.2345]
\ No newline at end of file
[5e-324]
\ No newline at end of file
[2.225073858507201e-308]
\ No newline at end of file
[2.2250738585072014e-308]
\ No newline at end of file
[1.7976931348623157e308]
\ No newline at end of file
{
"root object": {
"bool": true,
"int": 1,
"double": 2.34,
"string": "This is a string!",
"array": [
"Array of JSON values.",
1,
2.34,
true
]
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#ifndef RADIX_RADIXCORE_VALUE_HH_
#define RADIX_RADIXCORE_VALUE_HH_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "radixcore/visibility.hh"
namespace radix
{
/**
* @brief The Value class represents values of objects (null, integer, double,
* string, array, or object)
*/
class RADIX_PUBLIC Value
{
public:
typedef std::shared_ptr<Value> SP;
enum Type : unsigned char
{
TYPE_NULL,
TYPE_BOOLEAN,
TYPE_INTEGER,
TYPE_DOUBLE,
TYPE_STRING,
TYPE_ARRAY,
TYPE_OBJECT
};
private:
bool m_allocated;
Type m_type;
union DataUnion {
bool m_bool;
double m_double;
int m_int;
char* m_string;
class DataArray* m_array;
class DataObject* m_object;
} m_data;
public:
/// null constructor
Value();
/// copy constructor
Value(const Value& orig);
// move constructor
Value(Value&& orig);
// boolean
Value(bool v);
// integer
Value(int v);
// double
Value(double v);
// const char *
Value(const char* v);
// string
Value(const std::string& v);
// data array
Value(const DataArray& v);
// data object
Value(const DataObject& v);
~Value();
// assignment operators
Value& operator=(const Value& orig);
Value& operator=(Value&& orig);
Value& operator=(bool v);
Value& operator=(int v);
Value& operator=(double v);
Value& operator=(const char* v);
Value& operator=(const std::string& v);
Value& operator=(const DataArray& v);
Value& operator=(const DataObject& v);
Value::Type type() const;
/**
* @brief categoryString
* @return Returns a string for type display (object, array, number,
* boolean, null)
*/
std::string categoryString() const;
bool is_null() const { return m_type == TYPE_NULL; }
bool is_int() const { return m_type == TYPE_INTEGER; }
bool is_double() const { return m_type == TYPE_DOUBLE; }
bool is_number() const { return is_int() || is_double(); }
bool is_bool() const { return m_type == TYPE_BOOLEAN; }
bool is_string() const { return m_type == TYPE_STRING; }
bool is_array() const { return m_type == TYPE_ARRAY; }
bool is_object() const { return m_type == TYPE_OBJECT; }
bool is_primitive() const { return !(is_array() || is_object()); }
bool convertable(Value::Type to) const;
int to_int() const;
double to_double() const;
bool to_bool() const;
const char* to_cstring() const;
std::string to_string() const;
DataArray* to_array() const;
DataObject* to_object() const;
const DataArray& as_array() const;
DataArray& as_array();
const DataObject& as_object() const;
DataObject& as_object();
Value& operator[](const std::string& name);
const Value& operator[](const std::string& name) const;
Value& operator[](size_t i);
const Value& operator[](size_t i) const;
/**
* @brief empty whether the value is empty
* @return false when value is null or empty object/array
*/
bool empty() const;
/**
* @brief size the number of elements (object keys or array indices)
* @return size_t array element count, object member count, or 0
*/
size_t size() const;
bool format_json(std::ostream& out, int indent_level = 2,
int level = 0) const;
bool pack_json(std::ostream& out) const;
private:
friend class JSONObjectParser;
void assign(DataObject* obj);
void assign(DataArray* array);
/**
* @brief nullify deletes and nullifies this object
*/
void nullify();
/**
* @brief copy_from copies the given value to this value
* @param orig the value from which data will be copied
*/
void copy_from(const Value& orig);
};
class RADIX_PUBLIC DataArray
{
public:
typedef std::shared_ptr<DataArray> SP;
typedef std::vector<Value> storage_type;
private:
storage_type m_data;
public:
DataArray();
DataArray(const DataArray& orig);
~DataArray();
size_t size() const;
bool empty() const;
storage_type::const_iterator begin() const { return m_data.begin(); }
storage_type::const_iterator end() const { return m_data.end(); }
storage_type::iterator begin() { return m_data.begin(); }
storage_type::iterator end() { return m_data.end(); }
const Value& operator[](size_t i) const
{
return m_data.at(i);
} // at(i) for exception
Value& operator[](size_t i)
{
if (size() <= i) resize(i + 1);
return m_data[i];
}
const Value& front() const { return m_data.front(); }
Value& front() { return m_data.front(); }
const Value& back() const { return m_data.back(); }
Value& back() { return m_data.back(); }
Value& at(size_t i) { return m_data.at(i); }
const Value& at(size_t i) const { return m_data.at(i); }
void push_back(const Value& n) { m_data.push_back(n); }
void resize(size_t nsize) { m_data.resize(nsize); }
bool format_json(std::ostream& out, int indent_level = 2,
int level = 0) const;
bool pack_json(std::ostream& out) const;
void merge(const DataArray& rhs);
};
class RADIX_PUBLIC DataObject
{
public:
typedef std::shared_ptr<DataObject> SP;
typedef std::map<std::string, Value> storage_type;
private:
storage_type m_data;
public:
DataObject();
DataObject(const DataObject& orig);
~DataObject();
size_t size() const;
bool empty() const;
storage_type::const_iterator find(const std::string& name) const
{
return m_data.find(name);
}
storage_type::iterator find(const std::string& name)
{
return m_data.find(name);
}
storage_type::const_iterator begin() const { return m_data.begin(); }
storage_type::const_iterator end() const { return m_data.end(); }
storage_type::iterator begin() { return m_data.begin(); }
storage_type::iterator end() { return m_data.end(); }
Value& operator[](const std::string& name);
const Value& operator[](const std::string& name) const;
bool contains(const std::string& name) const
{
return m_data.find(name) != end();
}
std::pair<storage_type::iterator, bool> insert(
const std::pair<std::string, Value>& v)
{
return m_data.insert(v);
}
bool format_json(std::ostream& out, int indent_level = 2,
int level = 0) const;
bool pack_json(std::ostream& out) const;
void merge(const DataObject& rhs);
};
template <class Interp>
RADIX_PUBLIC bool generate_object(DataObject::SP& obj, std::istream& input,
std::ostream& errors)
{
Interp interpreter(obj, input, errors, nullptr);
bool parsed = interpreter.parse() == 0;
return parsed;
}
} // namespace radix
#endif /** RADIX_RADIXCORE_VALUE_HH_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment