Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // SSPHH/Fluxions/Unicornfish/Viperfish/Hatchetfish/Sunfish/KASL/GLUT Extensions
- // Copyright (C) 2017 Jonathan Metzgar
- // All rights reserved.
- //
- // This program is free software : you can redistribute it and/or modify
- // it under the terms of the GNU Affero General Public License as
- // published by the Free Software Foundation, either version 3 of the
- // License, or (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
- // GNU Affero General Public License for more details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with this program.If not, see <https://www.gnu.org/licenses/>.
- //
- // For any other type of licensing, please contact me at jmetzgar@outlook.com
- #ifndef KASL_JSON_HPP
- #define KASL_JSON_HPP
- #include <memory>
- #include <vector>
- #include <map>
- #include <string>
- #include <initializer_list>
- #include <kasl.hpp>
- namespace KASL
- {
- class JSON;
- using JSONPtr = std::shared_ptr<JSON>;
- class JSON : public std::enable_shared_from_this<JSON>
- {
- public:
- using SharedPtr = shared_ptr<JSON>;
- enum class Type
- {
- Object,
- Array,
- String,
- Number,
- True,
- False,
- Null
- };
- protected:
- JSON() { }
- JSON(const JSON &json);
- public:
- JSON(Type whichType);
- JSON(const int ival) { type_ = Type::Number; dval_ = ival; }
- JSON(const double dval) { type_ = Type::Number; dval_ = dval; }
- JSON(const std::string &sval) { type_ = Type::String; sval_ = sval; }
- explicit JSON(initializer_list<int> numberList)
- {
- type_ = Type::Array;
- for (auto it = numberList.begin(); it != numberList.end(); it++)
- {
- array_.push_back(JSON::MakeNumber(*it));
- }
- }
- explicit JSON(const vector<int> & numberList)
- {
- type_ = Type::Array;
- for (auto it = numberList.begin(); it != numberList.end(); it++)
- {
- array_.push_back(JSON::MakeNumber(*it));
- }
- }
- explicit JSON(initializer_list<float> numberList)
- {
- type_ = Type::Array;
- for (auto it = numberList.begin(); it != numberList.end(); it++)
- {
- array_.push_back(JSON::MakeNumber(*it));
- }
- }
- explicit JSON(const vector<float> & numberList)
- {
- type_ = Type::Array;
- for (auto it = numberList.begin(); it != numberList.end(); it++)
- {
- array_.push_back(JSON::MakeNumber(*it));
- }
- }
- explicit JSON(initializer_list<double> numberList)
- {
- type_ = Type::Array;
- for (auto it = numberList.begin(); it != numberList.end(); it++)
- {
- array_.push_back(JSON::MakeNumber(*it));
- }
- }
- explicit JSON(const vector<double> & numberList)
- {
- type_ = Type::Array;
- for (auto it = numberList.begin(); it != numberList.end(); it++)
- {
- array_.push_back(JSON::MakeNumber(*it));
- }
- }
- explicit JSON(initializer_list<string> stringList)
- {
- type_ = Type::Array;
- for (auto it = stringList.begin(); it != stringList.end(); it++)
- {
- array_.push_back(JSON::MakeString(*it));
- }
- }
- explicit JSON(const vector<string> & stringList)
- {
- type_ = Type::Array;
- for (auto it = stringList.begin(); it != stringList.end(); it++)
- {
- array_.push_back(JSON::MakeString(*it));
- }
- }
- explicit JSON(initializer_list<pair<string, JSONPtr>> members)
- {
- type_ = Type::Object;
- for (auto it = members.begin(); it != members.end(); it++)
- {
- map_[it->first] = it->second;
- }
- }
- explicit JSON(const map<string, JSONPtr> & members)
- {
- type_ = Type::Object;
- for (auto it = members.begin(); it != members.end(); it++)
- {
- map_[it->first] = it->second;
- }
- }
- JSON(const JSONPtr & json);
- ~JSON();
- static JSONPtr MakeNull() { return make_shared<JSON>(Type::Null); }
- static JSONPtr MakeBool(bool state = false) { return make_shared<JSON>(state ? Type::True : Type::False); }
- static JSONPtr MakeString(const string & sval) { return make_shared<JSON>(sval); }
- static JSONPtr MakeString() { return make_shared<JSON>(""); }
- static JSONPtr MakeNumber(int ival = 0) { return make_shared<JSON>(ival); }
- static JSONPtr MakeNumber(double dval = 0.0) { return make_shared<JSON>(dval); }
- static JSONPtr MakeArray() { return make_shared<JSON>(Type::Array); }
- static JSONPtr MakeArray(const vector<int> & numberList) { return make_shared<JSON>(numberList); }
- static JSONPtr MakeArray(initializer_list<int> numberList) { return make_shared<JSON>(numberList); }
- static JSONPtr MakeArray(const vector<float> & numberList) { return make_shared<JSON>(numberList); }
- static JSONPtr MakeArray(initializer_list<float> numberList) { return make_shared<JSON>(numberList); }
- static JSONPtr MakeArray(const vector<double> & numberList) { return make_shared<JSON>(numberList); }
- static JSONPtr MakeArray(initializer_list<double> numberList) { return make_shared<JSON>(numberList); }
- static JSONPtr MakeArray(const vector<string> & stringList) { return make_shared<JSON>(stringList); }
- static JSONPtr MakeArray(initializer_list<string> stringList) { return make_shared<JSON>(stringList); }
- static JSONPtr MakeObject() { return make_shared<JSON>(Type::Object); }
- static JSONPtr MakeObject(initializer_list<pair<string, JSONPtr>> members) { return make_shared<JSON>(members); }
- static JSONPtr MakeObject(const map<string, JSONPtr> members) { return make_shared<JSON>(members); }
- const JSONPtr &operator = (const JSONPtr &rhs);
- inline const JSONPtr &operator = (int ival) { Clear(); dval_ = ival; type_ = Type::Number; return shared_from_this(); }
- inline const JSONPtr &operator = (double dval) { Clear(); dval_ = dval; type_ = Type::Number; return shared_from_this(); }
- inline const JSONPtr &operator = (const std::string &sval) { Clear(); sval_ = sval; type_ = Type::String; return shared_from_this(); }
- inline const bool operator==(int ival) const { return IsNumber() && dval_ == (double)ival; }
- inline const bool operator==(const std::string &sval) const { return IsString() && sval_ == sval; }
- inline const bool operator==(bool bval) const { return (bval && IsTrue()) ? true : (!bval && IsFalse()) ? true : false; }
- inline const bool operator==(const JSONPtr &rhs) const { return Equals(rhs); }
- inline const bool operator==(const void *ptr) const { if (ptr == nullptr && IsNull()) return true; if (ptr == this) return true; return false; }
- std::string Serialize() const;
- bool Deserialize(const std::string &json);
- long DeserializeParseTokens(const TokenVector &tokens, long i = 0);
- inline bool IsNull() const { return type_ == Type::Null; }
- inline bool IsTrue() const { return type_ == Type::True; }
- inline bool IsFalse() const { return type_ == Type::False; }
- inline bool IsBoolean() const { return type_ == Type::True || type_ == Type::False; }
- inline bool IsFinite() const { return type_ == Type::Number && isfinite(dval_); }
- inline bool IsNaN() const { return type_ == Type::Number && isnan(dval_); }
- inline bool IsNumber() const { return type_ == Type::Number; }
- inline bool IsString() const { return type_ == Type::String; }
- inline bool IsArray() const { return type_ == Type::Array; }
- inline bool IsObject() const { return type_ == Type::Object; }
- static JSONPtr NewArray() { return make_shared<JSON>(Type::Array); }
- static JSONPtr NewObject() { return make_shared<JSON>(Type::Object); }
- static JSONPtr NewNumber(const double value) { return make_shared<JSON>(value); }
- static JSONPtr NewBoolean(const bool value) { return make_shared<JSON>(value); }
- static JSONPtr NewString(const string & value) { return make_shared<JSON>(value); }
- static JSONPtr New(const JSONPtr & value) { return make_shared<JSON>(value); }
- static JSONPtr New() { return make_shared<JSON>(Type::Null); }
- inline int Size() const { if (IsArray()) return (int)array_.size(); if (IsObject()) return (int)map_.size(); return 0; }
- inline bool Empty() const { if (IsArray()) return array_.empty(); if (IsObject()) return map_.empty(); return true; }
- void Clear() { type_ = Type::Null; dval_ = 0.0; sval_.clear(); array_.clear(); map_.clear(); }
- inline int AsInt() const { return IsNumber() ? (int)dval_ : 0; }
- inline int64_t AsInt64() const { return IsNumber() ? (int64_t)dval_ : 0; }
- inline double AsDouble() const { return IsNumber() ? dval_ : 0.0; }
- inline float AsFloat() const { return IsNumber() ? float(dval_) : 0.0f; }
- inline size_t Length() const { return IsArray() ? array_.size() : IsObject() ? map_.size() : 0; }
- inline std::map<std::string, JSONPtr> & AsObject() noexcept { return map_; }
- inline const std::map<std::string, JSONPtr> & AsObject() const noexcept { return map_; }
- inline std::vector<JSONPtr> & AsArray() noexcept { return array_; }
- inline const std::vector<JSONPtr> & AsArray() const noexcept { return array_; }
- inline vector<int> AsIntArray() const noexcept
- {
- vector<int> result;
- for (auto & e : array_)
- {
- if (e)
- result.push_back(e->AsInt());
- }
- return result;
- }
- inline vector<float> AsFloatArray() const noexcept
- {
- vector<float> result;
- for (auto & e : array_)
- {
- if (e)
- result.push_back(e->AsFloat());
- }
- return result;
- }
- inline vector<double> AsDoubleArray() const noexcept
- {
- vector<double> result;
- for (auto & e : array_)
- {
- if (e)
- result.push_back(e->AsDouble());
- }
- return result;
- }
- inline JSON & AsJSON() noexcept { return *this; }
- inline const JSON & AsJSON() const noexcept { return *this; }
- inline bool Has(const string & key) const noexcept { if (!IsObject()) return false; if (map_.find(key) == map_.end()) return false; return true; }
- inline bool HasKeyOfType(const string & key, Type type) const noexcept { auto it = map_.find(key); if (it != map_.end() && it->second->type_ == type) return true; return false; }
- inline JSONPtr & operator[] (int index) { if (IsArray()) return array_.at(index); throw std::runtime_error("JSON object is not an array"); }
- inline const JSONPtr & operator[] (int index) const { if (IsArray()) return array_.at(index); throw std::runtime_error("JSON object is not an array"); }
- inline JSONPtr & operator[] (const string & key) { if (IsObject()) return map_.at(key); throw std::runtime_error("JSON object is not an object"); }
- inline const JSONPtr & operator[] (const string & key) const { if (IsObject()) return map_.at(key); throw std::runtime_error("JSON object is not an object"); }
- inline JSONPtr & getElement(int index) { if (IsArray()) return array_.at(index); throw std::runtime_error("JSON object is not an array"); }
- inline const JSONPtr & getElement(int index) const { if (IsArray()) return array_.at(index); throw std::runtime_error("JSON object is not an array"); }
- inline JSONPtr & getMember(const string & key) { if (IsObject()) return map_.at(key); throw std::runtime_error("JSON object is not an object"); }
- inline const JSONPtr & getMember(const string & key) const { if (IsObject()) return map_.at(key); throw std::runtime_error("JSON object is not an object"); }
- inline JSONPtr & set(Type whichType)
- {
- Clear();
- type_ = whichType;
- return shared_from_this();
- }
- inline JSONPtr & set(const int ival)
- {
- Clear();
- type_ = Type::Number;
- dval_ = ival;
- return shared_from_this();
- }
- inline JSONPtr & set(const double dval)
- {
- Clear();
- type_ = Type::Number;
- dval_ = dval;
- return shared_from_this();
- }
- inline JSONPtr & set(const std::string &sval)
- {
- Clear();
- type_ = Type::String;
- sval_ = sval;
- return shared_from_this();
- }
- inline JSONPtr & set(initializer_list<int> numberList)
- {
- Clear();
- type_ = Type::Array;
- for (auto it = numberList.begin(); it != numberList.end(); it++)
- {
- array_.push_back(JSON::MakeNumber(*it));
- }
- return shared_from_this();
- }
- inline JSONPtr & set(const vector<int> & numberList)
- {
- Clear();
- type_ = Type::Array;
- for (auto it = numberList.begin(); it != numberList.end(); it++)
- {
- array_.push_back(JSON::MakeNumber(*it));
- }
- return shared_from_this();
- }
- inline JSONPtr & set(initializer_list<float> numberList)
- {
- Clear();
- type_ = Type::Array;
- for (auto it = numberList.begin(); it != numberList.end(); it++)
- {
- array_.push_back(JSON::MakeNumber(*it));
- }
- return shared_from_this();
- }
- inline JSONPtr & set(const vector<float> & numberList)
- {
- Clear();
- type_ = Type::Array;
- for (auto it = numberList.begin(); it != numberList.end(); it++)
- {
- array_.push_back(JSON::MakeNumber(*it));
- }
- return shared_from_this();
- }
- inline JSONPtr & set(initializer_list<double> numberList)
- {
- Clear();
- type_ = Type::Array;
- for (auto it = numberList.begin(); it != numberList.end(); it++)
- {
- array_.push_back(JSON::MakeNumber(*it));
- }
- return shared_from_this();
- }
- inline JSONPtr & set(const vector<double> & numberList)
- {
- Clear();
- type_ = Type::Array;
- for (auto it = numberList.begin(); it != numberList.end(); it++)
- {
- array_.push_back(JSON::MakeNumber(*it));
- }
- return shared_from_this();
- }
- inline JSONPtr & set(initializer_list<string> stringList)
- {
- Clear();
- type_ = Type::Array;
- for (auto it = stringList.begin(); it != stringList.end(); it++)
- {
- array_.push_back(JSON::MakeString(*it));
- }
- return shared_from_this();
- }
- inline JSONPtr & set(const vector<string> & stringList)
- {
- Clear();
- type_ = Type::Array;
- for (auto it = stringList.begin(); it != stringList.end(); it++)
- {
- array_.push_back(JSON::MakeString(*it));
- }
- return shared_from_this();
- }
- inline JSONPtr & set (initializer_list<pair<string, JSONPtr>> members)
- {
- Clear();
- type_ = Type::Object;
- for (auto it = members.begin(); it != members.end(); it++)
- {
- map_[it->first] = it->second;
- }
- return shared_from_this();
- }
- inline JSONPtr & set(const map<string, JSONPtr> & members)
- {
- Clear();
- type_ = Type::Object;
- for (auto it = members.begin(); it != members.end(); it++)
- {
- map_[it->first] = it->second;
- }
- return shared_from_this();
- }
- inline JSONPtr & set(const JSONPtr & json)
- {
- Clear();
- if (!json)
- return shared_from_this();
- type_ = json->type_;
- if (IsNumber()) dval_ = json->dval_;
- if (IsString()) sval_ = json->sval_;
- if (IsArray()) array_ = json->array_;
- if (IsObject()) map_ = json->map_;
- return shared_from_this();
- }
- inline JSONPtr & PushBack(JSONPtr & json) { if (!json || !IsArray()) throw std::runtime_error("JSON object is not an array"); array_.push_back(json); return shared_from_this(); }
- inline JSONPtr & PopBack() { if (!IsArray()) std::runtime_error("JSON object is not an array"); if (array_.empty()) return JSONPtr(); JSONPtr json = array_.back(); array_.pop_back(); return json; }
- inline Type GetType() const { return type_; }
- inline bool InstanceOf(const Type t) const { return type_ == t; }
- bool Equals(const JSONPtr &rhs) const;
- private:
- Type type_ = Type::Null;
- double dval_ = 0.0;
- std::string sval_;
- std::vector<JSONPtr> array_;
- std::map<std::string, JSONPtr> map_;
- void copyArray(const std::vector<JSONPtr> &a);
- void copyMap(const std::map<std::string, JSONPtr> &m);
- };
- inline bool operator == (const JSONPtr &lhs, const JSONPtr &rhs)
- {
- if (!lhs || !rhs) return false;
- return lhs->Equals(rhs);
- }
- inline bool operator != (const JSONPtr &lhs, const JSONPtr &rhs)
- {
- if (!lhs || !rhs) return false;
- return !lhs->Equals(rhs);
- }
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement