Mercurial > code
diff C++/Json.h @ 244:777bc3cb665a
Add Json, a jansson wrapper
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 13 Sep 2014 19:42:15 +0200 |
parents | |
children | ed3cc10761e4 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/C++/Json.h Sat Sep 13 19:42:15 2014 +0200 @@ -0,0 +1,426 @@ +/* + * Json.h -- jansson C++11 wrapper + * + * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _JSON_H_ +#define _JSON_H_ + +#include <initializer_list> +#include <memory> +#include <stdexcept> +#include <string> +#include <utility> +#include <vector> +#include <unordered_map> + +#include <jansson.h> + +/** + * @file Json.h + * @brief A jansson C++ modern wrapper + */ + +/** + * @class Json + * @brief Json value + * + * This class contains one or more json values. + */ +class Json final { +public: + using Handle = std::unique_ptr<json_t, void (*)(json_t *)>; + using Array = std::vector<Json>; + using Map = std::unordered_map<std::string, Json>; + + /** + * @class Error + * @brief Json error + */ + class Error : public std::exception { + private: + friend class Json; + + std::string m_text; + std::string m_source; + int m_line; + int m_column; + unsigned m_position; + + Error(const json_error_t error) + : m_text(error.text) + , m_source(error.source) + , m_line(error.line) + , m_column(error.column) + , m_position(error.position) + { + } + + public: + const char *what() const noexcept override + { + return m_text.c_str(); + } + }; + +private: + Handle m_handle; + Array m_list; + Map m_map; + + Json(Handle &&handle) + : m_handle(std::move(handle)) + { + } + + template <typename Func, typename... Args> + static Json from(Func func, Args&&... args) + { + json_error_t error; + json_t *value = func(std::forward<Args>(args)..., &error); + + if (!value) + throw Error(error); + + return Json(Handle(value, json_decref)); + } + +public: + /** + * Load data from a string. + * + * @param data the data + * @param flags the optional flags + * @return the json value + * @throw Error on failures + */ + static Json fromString(const std::string &data, int flags = 0); + + /** + * Load data from a file. + * + * @param path the path + * @param flags the optional flags + * @return the json value + * @throw Error on failures + */ + static Json fromFile(const std::string &path, int flags = 0); + + /** + * Create a json value of type JSON_OBJECT. + */ + explicit Json(); + + /** + * Create a JSON_NULL object. + * + * @param n the null value (nullptr) + */ + explicit Json(std::nullptr_t n); + + /** + * Create a boolean object. + * + * @param value the boolean value + */ + explicit Json(bool value); + + /** + * Create a JSON_INTEGER object. + * + * @param value the value + */ + explicit Json(int value); + + /** + * Create a JSON_REAL object. + * + * @param value the value + */ + explicit Json(double value); + + /** + * Create a JSON_STRING object. + * + * @param value the value + */ + explicit Json(const std::string &value); + + /** + * Create a JSON_ARRAY object. + * + * @param list the list of children + */ + explicit Json(std::initializer_list<Json> list); + + /** + * Create a JSON_STRING object. + * + * @param str the string + */ + template <size_t N> + explicit Json(const char str[N]) + : m_handle(json_string(str), json_decref) + { + } + + /** + * Copy the object, this does a deep copy. + * + * @param json the other value + */ + Json(const Json &json); + + /** + * Copy the object, this does a deep copy. + * + * @param json the other value + * @return *this + */ + Json &operator=(const Json &json); + + /** + * Move the object. + * + * @param json the other value + */ + Json(Json &&); + + /** + * Move the object. + * + * @param json the other value + * @return *this + */ + Json &operator=(Json &&); + + /** + * Get the type of value. + * + * @return the type + */ + int typeOf() const; + + /** + * Tells if the json value is an JSON_OBJECT. + * + * @return true or false + */ + bool isObject() const; + + /** + * Tells if the json value is an JSON_ARRAY. + * + * @return true or false + */ + bool isArray() const; + + /** + * Tells if the json value is an JSON_STRING. + * + * @return true or false + */ + bool isString() const; + + /** + * Tells if the json value is an JSON_REAL. + * + * @return true or false + */ + bool isReal() const; + + /** + * Tells if the json value is an JSON_TRUE. + * + * @return true or false + */ + bool isTrue() const; + + /** + * Tells if the json value is an JSON_FALSE. + * + * @return true or false + */ + bool isFalse() const; + + /** + * Tells if the json value is an JSON_NULL. + * + * @return true or false + */ + bool isNull() const; + + /** + * Tells if the json value is an JSON_INTEGER or JSON_REAL. + * + * @return true or false + */ + bool isNumber() const; + + /** + * Tells if the json value is an JSON_INTEGER. + * + * @return true or false + */ + bool isInteger() const; + + /** + * Tells if the json value is an JSON_TRUE or JSON_FALSE. + * + * @return true or false + */ + bool isBoolean() const; + + /** + * Get the number of values in the array + * + * @return the number or 0 + */ + unsigned size() const noexcept; + + /** + * Insert a copy of the value at the end. + * + * @param value the value to insert + */ + void append(const Json &value); + + /** + * Move the value at the end. + * + * @param value the value to insert + */ + void append(Json &&value); + + /** + * Insert a copy of the value at the specified index. + * + * @param value the value to insert + * @param index the position + */ + void insert(const Json &value, int index); + + /** + * Move the value at the specified index. + * + * @param value the value to insert + * @param index the position + */ + void insert(Json &&value, int index); + + /** + * Set a copy of value to the key 'name'. + * + * @param value the value + * @param name the key name. + */ + void set(const Json &value, const std::string &name); + + /** + * Move value to the key 'name'. + * + * @param value the value + * @param name the key name. + */ + void set(Json &&value, const std::string &name); + + /** + * Get the string value. + * + * @return the string + */ + std::string toString() const; + + /** + * Get the integer value. + * + * @return the value or 0 + */ + int toInteger() const noexcept; + + /** + * Get the real value. + * + * @return the value or 0 + */ + double toReal() const noexcept; + + /** + * Dump the value as a string. + * + * @param flags the optional flags + * @return the string + */ + std::string dump(int flags = 0); + + /** + * Dump the value to a path. + * + * @param path the path + * @param flags the optional flags + */ + void dump(const std::string &path, int flags = 0); + + /** + * Get the value at the specified index. + * + * @param index the position + * @return the reference to the value + * @throw std::invalid_argument on error + * @throw std::out_of_range on bad arguments + */ + Json &operator[](int index); + + /** + * Get the value at the specified index. + * + * @param index the position + * @return the reference to the value + * @throw std::invalid_argument on error + * @throw std::out_of_range on bad arguments + */ + const Json &operator[](int index) const; + + /** + * Get the value at the specified key. + * + * @param name the key + * @return the reference to the value + * @throw std::invalid_argument on error + * @throw std::out_of_range on bad arguments + */ + Json &operator[](const std::string &name); + + /** + * Get the value at the specified key. + * + * @param name the key + * @return the reference to the value + * @throw std::invalid_argument on error + * @throw std::out_of_range on bad arguments + */ + const Json &operator[](const std::string &name) const; + + /** + * Compare the values. + * + * @param j1 the first value + * @param j2 the second value + */ + friend bool operator==(const Json &j1, const Json &j2); +}; + +#endif // !_JSON_H_