json/src/JSON.h

357 lines
11 KiB
C
Raw Normal View History

2013-07-04 08:49:03 +00:00
#pragma once
// a helper macro to detect C++11 compliant compilers
#if __cplusplus >= 201103L
#define __cplusplus11
#endif
// STL containers
2013-07-04 08:49:03 +00:00
#include <string>
#include <vector>
#include <map>
// additional C++11 headers
2013-07-04 08:49:03 +00:00
#ifdef __cplusplus11
#include <mutex>
#include <initializer_list>
#endif
class JSON {
// forward declaration to friend this class
2013-07-05 12:16:47 +00:00
public:
class iterator;
class const_iterator;
2013-07-04 08:49:03 +00:00
#ifdef __cplusplus11
private:
2013-07-04 08:49:03 +00:00
/// mutex to guard payload
static std::mutex _token;
#endif
public:
/// possible types of a JSON object
typedef enum {
2013-07-05 14:15:29 +00:00
array, object, null, string, boolean, number, number_float
2013-07-04 08:49:03 +00:00
} json_t;
public:
2013-07-05 14:15:29 +00:00
/// a type for an object
typedef std::map<std::string, JSON> object_t;
/// a type for an array
typedef std::vector<JSON> array_t;
2013-07-10 12:33:17 +00:00
/// a type for a string
typedef std::string string_t;
/// a type for a Boolean
typedef bool boolean_t;
/// a type for an integer number
typedef int number_t;
/// a type for a floating point number
typedef double number_float_t;
/// a JSON value
union value {
/// array as pointer to array_t
2013-07-10 12:33:17 +00:00
array_t* array;
/// object as pointer to object_t
2013-07-10 12:33:17 +00:00
object_t* object;
/// string as pointer to string_t
2013-07-10 12:33:17 +00:00
string_t* string;
/// Boolean
boolean_t boolean;
/// number (integer)
number_t number;
/// number (float)
number_float_t number_float;
2013-07-10 12:33:17 +00:00
/// default constructor
2013-07-10 12:33:17 +00:00
value() {}
/// constructor for arrays
2013-07-10 12:33:17 +00:00
value(array_t* array): array(array) {}
/// constructor for objects
2013-07-10 12:33:17 +00:00
value(object_t* object): object(object) {}
/// constructor for strings
2013-07-10 12:33:17 +00:00
value(string_t* string): string(string) {}
/// constructor for Booleans
value(boolean_t boolean) : boolean(boolean) {}
/// constructor for numbers (integer)
value(number_t number) : number(number) {}
/// constructor for numbers (float)
value(number_float_t number_float) : number_float(number_float) {}
2013-07-10 12:33:17 +00:00
};
private:
/// the type of this object
json_t _type;
/// the payload
value _value;
2013-07-04 08:49:03 +00:00
#ifdef __cplusplus11
2013-07-05 14:15:29 +00:00
/// a type for array initialization
typedef std::initializer_list<JSON> array_init_t;
2013-07-04 08:49:03 +00:00
#endif
public:
/// create a null object
2013-07-04 08:49:03 +00:00
JSON();
/// create an object according to given type
2013-07-05 14:15:29 +00:00
JSON(json_t);
/// create a string object from a C++ string
2013-07-04 08:49:03 +00:00
JSON(const std::string&);
/// create a string object from a C string
2013-07-04 08:49:03 +00:00
JSON(char*);
/// create a string object from a C string
2013-07-04 08:49:03 +00:00
JSON(const char*);
/// create a Boolean object
JSON(const bool);
/// create a number object
JSON(const int);
/// create a number object
JSON(const double);
2013-07-05 14:15:29 +00:00
/// create an array
2013-07-04 08:49:03 +00:00
JSON(array_t);
2013-07-05 14:15:29 +00:00
/// create an object
2013-07-04 08:49:03 +00:00
JSON(object_t);
2013-07-05 14:15:29 +00:00
#ifdef __cplusplus11
/// create from an initializer list (to an array)
JSON(array_init_t);
2013-07-04 08:49:03 +00:00
#endif
/// copy constructor
JSON(const JSON&);
#ifdef __cplusplus11
/// move constructor
JSON(JSON&&);
#endif
/// copy assignment
#ifdef __cplusplus11
JSON& operator=(JSON);
#else
JSON& operator=(const JSON&);
#endif
/// destructor
~JSON();
/// implicit conversion to string representation
operator const std::string() const;
/// implicit conversion to integer (only for numbers)
operator int() const;
/// implicit conversion to double (only for numbers)
operator double() const;
/// implicit conversion to Boolean (only for Booleans)
operator bool() const;
/// implicit conversion to JSON vector (not for objects)
operator std::vector<JSON>() const;
/// implicit conversion to JSON map (only for objects)
operator std::map<std::string, JSON>() const;
2013-07-04 08:49:03 +00:00
/// write to stream
friend std::ostream& operator<<(std::ostream& o, const JSON& j) {
o << j.toString();
return o;
}
/// write to stream
friend std::ostream& operator>>(const JSON& j, std::ostream& o) {
o << j.toString();
return o;
}
/// read from stream
friend std::istream& operator>>(std::istream& i, JSON& j) {
parser(i).parse(j);
return i;
}
/// read from stream
friend std::istream& operator<<(JSON& j, std::istream& i) {
parser(i).parse(j);
return i;
}
/// explicit conversion to string representation (C++ style)
const std::string toString() const;
/// add an object/array to an array
JSON& operator+=(const JSON&);
/// add a string to an array
JSON& operator+=(const std::string&);
/// add a string to an array
JSON& operator+=(const char*);
/// add a Boolean to an array
JSON& operator+=(bool);
/// add a number to an array
JSON& operator+=(int);
/// add a number to an array
JSON& operator+=(double);
2013-07-05 14:15:29 +00:00
/// add an object/array to an array
void push_back(const JSON&);
/// add a string to an array
void push_back(const std::string&);
/// add a string to an array
void push_back(const char*);
/// add a Boolean to an array
void push_back(bool);
/// add a number to an array
void push_back(int);
/// add a number to an array
void push_back(double);
2013-07-04 08:49:03 +00:00
/// operator to set an element in an array
JSON& operator[](int);
/// operator to get an element in an array
const JSON& operator[](const int) const;
/// operator to set an element in an object
JSON& operator[](const std::string&);
/// operator to set an element in an object
JSON& operator[](const char*);
/// operator to get an element in an object
const JSON& operator[](const std::string&) const;
/// return the number of stored values
size_t size() const;
/// checks whether object is empty
bool empty() const;
/// return the type of the object
json_t type() const;
2013-07-05 12:16:47 +00:00
/// find an element in an object (returns end() iterator otherwise)
iterator find(const std::string&);
/// find an element in an object (returns end() iterator otherwise)
2013-07-05 12:16:47 +00:00
const_iterator find(const std::string&) const;
/// find an element in an object (returns end() iterator otherwise)
2013-07-05 14:15:29 +00:00
iterator find(const char*);
/// find an element in an object (returns end() iterator otherwise)
2013-07-05 14:15:29 +00:00
const_iterator find(const char*) const;
2013-07-05 12:16:47 +00:00
2013-07-04 08:49:03 +00:00
/// direct access to the underlying payload
2013-07-10 12:33:17 +00:00
value data();
2013-07-04 08:49:03 +00:00
/// direct access to the underlying payload
2013-07-10 12:33:17 +00:00
const value data() const;
2013-07-04 08:49:03 +00:00
/// lexicographically compares the values
bool operator==(const JSON&) const;
/// lexicographically compares the values
bool operator!=(const JSON&) const;
2013-07-04 08:49:03 +00:00
private:
/// return the type as string
std::string _typename() const;
public:
/// an iterator
class iterator {
2013-07-05 14:15:29 +00:00
friend class JSON;
friend class JSON::const_iterator;
2013-07-04 08:49:03 +00:00
public:
iterator();
iterator(JSON*);
iterator(const iterator&);
~iterator();
iterator& operator=(const iterator&);
bool operator==(const iterator&) const;
bool operator!=(const iterator&) const;
iterator& operator++();
JSON& operator*() const;
JSON* operator->() const;
/// getter for the key (in case of objects)
std::string key() const;
/// getter for the value
JSON& value() const;
private:
/// a JSON value
JSON* _object;
/// an iterator for JSON arrays
2013-07-05 14:15:29 +00:00
array_t::iterator* _vi;
2013-07-04 08:49:03 +00:00
/// an iterator for JSON objects
2013-07-05 14:15:29 +00:00
object_t::iterator* _oi;
2013-07-04 08:49:03 +00:00
};
/// a const iterator
class const_iterator {
2013-07-05 14:15:29 +00:00
friend class JSON;
2013-07-04 08:49:03 +00:00
public:
const_iterator();
const_iterator(const JSON*);
const_iterator(const const_iterator&);
const_iterator(const iterator&);
~const_iterator();
const_iterator& operator=(const const_iterator&);
bool operator==(const const_iterator&) const;
bool operator!=(const const_iterator&) const;
const_iterator& operator++();
const JSON& operator*() const;
const JSON* operator->() const;
/// getter for the key (in case of objects)
std::string key() const;
/// getter for the value
const JSON& value() const;
private:
/// a JSON value
const JSON* _object;
/// an iterator for JSON arrays
2013-07-05 14:15:29 +00:00
array_t::const_iterator* _vi;
2013-07-04 08:49:03 +00:00
/// an iterator for JSON objects
2013-07-05 14:15:29 +00:00
object_t::const_iterator* _oi;
2013-07-04 08:49:03 +00:00
};
public:
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
const_iterator cbegin() const;
const_iterator cend() const;
private:
/// a helper class to parse a JSON object
2013-07-04 08:49:03 +00:00
class parser {
public:
/// a parser reading from a C string
2013-07-04 08:49:03 +00:00
parser(char*);
/// a parser reading from a C++ string
2013-07-04 08:49:03 +00:00
parser(std::string&);
/// a parser reading from an input stream
2013-07-04 08:49:03 +00:00
parser(std::istream&);
/// destructor of the parser
2013-07-04 08:49:03 +00:00
~parser();
/// parse into a given JSON object
2013-07-04 08:49:03 +00:00
void parse(JSON&);
private:
/// read the next character, stripping whitespace
2013-07-04 08:49:03 +00:00
bool next();
/// raise an exception with an error message
void error(std::string) __attribute__((noreturn));
/// parse a quoted string
2013-07-04 08:49:03 +00:00
std::string parseString();
/// parse a Boolean "true"
2013-07-04 08:49:03 +00:00
void parseTrue();
/// parse a Boolean "false"
2013-07-04 08:49:03 +00:00
void parseFalse();
/// parse a null object
2013-07-04 08:49:03 +00:00
void parseNull();
/// a helper function to expect a certain character
2013-07-04 08:49:03 +00:00
void expect(char);
/// the current character
2013-07-04 08:49:03 +00:00
char _current;
/// a buffer of the input
2013-07-04 08:49:03 +00:00
char* _buffer;
/// the position inside the input buffer
2013-07-04 08:49:03 +00:00
size_t _pos;
/// the length of the input buffer
2013-07-05 10:32:23 +00:00
size_t _length;
2013-07-04 08:49:03 +00:00
};
};