Advertisement
microwerx

kasl_json.hpp

Dec 30th, 2017
656
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.62 KB | None | 0 0
  1. // SSPHH/Fluxions/Unicornfish/Viperfish/Hatchetfish/Sunfish/KASL/GLUT Extensions
  2. // Copyright (C) 2017 Jonathan Metzgar
  3. // All rights reserved.
  4. //
  5. // This program is free software : you can redistribute it and/or modify
  6. // it under the terms of the GNU Affero General Public License as
  7. // published by the Free Software Foundation, either version 3 of the
  8. // License, or (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
  13. // GNU Affero General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU Affero General Public License
  16. // along with this program.If not, see <https://www.gnu.org/licenses/>.
  17. //
  18. // For any other type of licensing, please contact me at jmetzgar@outlook.com
  19. #ifndef KASL_JSON_HPP
  20. #define KASL_JSON_HPP
  21.  
  22.  
  23. #include <memory>
  24. #include <vector>
  25. #include <map>
  26. #include <string>
  27. #include <initializer_list>
  28. #include <kasl.hpp>
  29.  
  30.  
  31. namespace KASL
  32. {
  33.     class JSON;
  34.     using JSONPtr = std::shared_ptr<JSON>;
  35.  
  36.     class JSON : public std::enable_shared_from_this<JSON>
  37.     {
  38.     public:
  39.         using SharedPtr = shared_ptr<JSON>;
  40.  
  41.         enum class Type
  42.         {
  43.             Object,
  44.             Array,
  45.             String,
  46.             Number,
  47.             True,
  48.             False,
  49.             Null
  50.         };
  51.  
  52.     protected:
  53.         JSON() { }
  54.         JSON(const JSON &json);
  55.     public:
  56.         JSON(Type whichType);
  57.         JSON(const int ival) { type_ = Type::Number; dval_ = ival; }
  58.         JSON(const double dval) { type_ = Type::Number; dval_ = dval; }
  59.         JSON(const std::string &sval) { type_ = Type::String; sval_ = sval; }
  60.        
  61.         explicit JSON(initializer_list<int> numberList)
  62.         {
  63.             type_ = Type::Array;
  64.             for (auto it = numberList.begin(); it != numberList.end(); it++)
  65.             {
  66.                 array_.push_back(JSON::MakeNumber(*it));
  67.             }
  68.         }
  69.        
  70.         explicit JSON(const vector<int> & numberList)
  71.         {
  72.             type_ = Type::Array;
  73.             for (auto it = numberList.begin(); it != numberList.end(); it++)
  74.             {
  75.                 array_.push_back(JSON::MakeNumber(*it));
  76.             }
  77.         }
  78.        
  79.         explicit JSON(initializer_list<float> numberList)
  80.         {
  81.             type_ = Type::Array;
  82.             for (auto it = numberList.begin(); it != numberList.end(); it++)
  83.             {
  84.                 array_.push_back(JSON::MakeNumber(*it));
  85.             }
  86.         }
  87.  
  88.         explicit JSON(const vector<float> & numberList)
  89.         {
  90.             type_ = Type::Array;
  91.             for (auto it = numberList.begin(); it != numberList.end(); it++)
  92.             {
  93.                 array_.push_back(JSON::MakeNumber(*it));
  94.             }
  95.         }
  96.  
  97.         explicit JSON(initializer_list<double> numberList)
  98.         {
  99.             type_ = Type::Array;
  100.             for (auto it = numberList.begin(); it != numberList.end(); it++)
  101.             {
  102.                 array_.push_back(JSON::MakeNumber(*it));
  103.             }
  104.         }
  105.  
  106.         explicit JSON(const vector<double> & numberList)
  107.         {
  108.             type_ = Type::Array;
  109.             for (auto it = numberList.begin(); it != numberList.end(); it++)
  110.             {
  111.                 array_.push_back(JSON::MakeNumber(*it));
  112.             }
  113.         }
  114.  
  115.         explicit JSON(initializer_list<string> stringList)
  116.         {
  117.             type_ = Type::Array;
  118.             for (auto it = stringList.begin(); it != stringList.end(); it++)
  119.             {
  120.                 array_.push_back(JSON::MakeString(*it));
  121.             }
  122.         }
  123.  
  124.         explicit JSON(const vector<string> & stringList)
  125.         {
  126.             type_ = Type::Array;
  127.             for (auto it = stringList.begin(); it != stringList.end(); it++)
  128.             {
  129.                 array_.push_back(JSON::MakeString(*it));
  130.             }
  131.         }
  132.  
  133.         explicit JSON(initializer_list<pair<string, JSONPtr>> members)
  134.         {
  135.             type_ = Type::Object;
  136.             for (auto it = members.begin(); it != members.end(); it++)
  137.             {
  138.                 map_[it->first] = it->second;
  139.             }
  140.         }
  141.  
  142.         explicit JSON(const map<string, JSONPtr> & members)
  143.         {
  144.             type_ = Type::Object;
  145.             for (auto it = members.begin(); it != members.end(); it++)
  146.             {
  147.                 map_[it->first] = it->second;
  148.             }
  149.         }
  150.  
  151.         JSON(const JSONPtr & json);
  152.         ~JSON();
  153.  
  154.         static JSONPtr MakeNull() { return make_shared<JSON>(Type::Null); }
  155.         static JSONPtr MakeBool(bool state = false) { return make_shared<JSON>(state ? Type::True : Type::False); }
  156.         static JSONPtr MakeString(const string & sval) { return make_shared<JSON>(sval); }
  157.         static JSONPtr MakeString() { return make_shared<JSON>(""); }
  158.         static JSONPtr MakeNumber(int ival = 0) { return make_shared<JSON>(ival); }
  159.         static JSONPtr MakeNumber(double dval = 0.0) { return make_shared<JSON>(dval); }
  160.         static JSONPtr MakeArray() { return make_shared<JSON>(Type::Array); }
  161.         static JSONPtr MakeArray(const vector<int> & numberList) { return make_shared<JSON>(numberList); }
  162.         static JSONPtr MakeArray(initializer_list<int> numberList) { return make_shared<JSON>(numberList); }
  163.         static JSONPtr MakeArray(const vector<float> & numberList) { return make_shared<JSON>(numberList); }
  164.         static JSONPtr MakeArray(initializer_list<float> numberList) { return make_shared<JSON>(numberList); }
  165.         static JSONPtr MakeArray(const vector<double> & numberList) { return make_shared<JSON>(numberList); }
  166.         static JSONPtr MakeArray(initializer_list<double> numberList) { return make_shared<JSON>(numberList); }
  167.         static JSONPtr MakeArray(const vector<string> & stringList) { return make_shared<JSON>(stringList); }
  168.         static JSONPtr MakeArray(initializer_list<string> stringList) { return make_shared<JSON>(stringList); }
  169.         static JSONPtr MakeObject() { return make_shared<JSON>(Type::Object); }
  170.         static JSONPtr MakeObject(initializer_list<pair<string, JSONPtr>> members) { return make_shared<JSON>(members); }
  171.         static JSONPtr MakeObject(const map<string, JSONPtr> members) { return make_shared<JSON>(members); }
  172.  
  173.         const JSONPtr &operator = (const JSONPtr &rhs);
  174.         inline const JSONPtr &operator = (int ival) { Clear();  dval_ = ival; type_ = Type::Number; return shared_from_this(); }
  175.         inline const JSONPtr &operator = (double dval) { Clear(); dval_ = dval; type_ = Type::Number; return shared_from_this(); }
  176.         inline const JSONPtr &operator = (const std::string &sval) { Clear(); sval_ = sval; type_ = Type::String; return shared_from_this(); }
  177.  
  178.         inline const bool operator==(int ival) const { return IsNumber() && dval_ == (double)ival; }
  179.         inline const bool operator==(const std::string &sval) const { return IsString() && sval_ == sval; }
  180.         inline const bool operator==(bool bval) const { return (bval && IsTrue()) ? true : (!bval && IsFalse()) ? true : false; }
  181.         inline const bool operator==(const JSONPtr &rhs) const { return Equals(rhs); }
  182.         inline const bool operator==(const void *ptr) const { if (ptr == nullptr && IsNull()) return true; if (ptr == this) return true; return false; }
  183.  
  184.         std::string Serialize() const;
  185.         bool Deserialize(const std::string &json);
  186.         long DeserializeParseTokens(const TokenVector &tokens, long i = 0);
  187.  
  188.         inline bool IsNull() const { return type_ == Type::Null; }
  189.         inline bool IsTrue() const { return type_ == Type::True; }
  190.         inline bool IsFalse() const { return type_ == Type::False; }
  191.         inline bool IsBoolean() const { return type_ == Type::True || type_ == Type::False; }
  192.         inline bool IsFinite() const { return type_ == Type::Number && isfinite(dval_); }
  193.         inline bool IsNaN() const { return type_ == Type::Number && isnan(dval_); }
  194.         inline bool IsNumber() const { return type_ == Type::Number; }
  195.         inline bool IsString() const { return type_ == Type::String; }
  196.         inline bool IsArray() const { return type_ == Type::Array; }
  197.         inline bool IsObject() const { return type_ == Type::Object; }
  198.  
  199.         static JSONPtr NewArray() { return make_shared<JSON>(Type::Array); }
  200.         static JSONPtr NewObject() { return make_shared<JSON>(Type::Object); }
  201.         static JSONPtr NewNumber(const double value) { return make_shared<JSON>(value); }
  202.         static JSONPtr NewBoolean(const bool value) { return make_shared<JSON>(value); }
  203.         static JSONPtr NewString(const string & value) { return make_shared<JSON>(value); }
  204.         static JSONPtr New(const JSONPtr & value) { return make_shared<JSON>(value); }
  205.         static JSONPtr New() { return make_shared<JSON>(Type::Null); }
  206.  
  207.         inline int Size() const { if (IsArray()) return (int)array_.size(); if (IsObject()) return (int)map_.size(); return 0; }
  208.         inline bool Empty() const { if (IsArray()) return array_.empty(); if (IsObject()) return map_.empty(); return true; }
  209.         void Clear() { type_ = Type::Null; dval_ = 0.0; sval_.clear(); array_.clear(); map_.clear(); }
  210.  
  211.         inline int AsInt() const { return IsNumber() ? (int)dval_ : 0; }
  212.         inline int64_t AsInt64() const { return IsNumber() ? (int64_t)dval_ : 0; }
  213.         inline double AsDouble() const { return IsNumber() ? dval_ : 0.0; }
  214.         inline float AsFloat() const { return IsNumber() ? float(dval_) : 0.0f; }
  215.         inline size_t Length() const { return IsArray() ? array_.size() : IsObject() ? map_.size() : 0; }
  216.         inline std::map<std::string, JSONPtr> & AsObject() noexcept { return map_; }
  217.         inline const std::map<std::string, JSONPtr> & AsObject() const noexcept { return map_; }
  218.         inline std::vector<JSONPtr> & AsArray() noexcept { return array_; }
  219.         inline const std::vector<JSONPtr> & AsArray() const noexcept { return array_; }
  220.  
  221.         inline vector<int> AsIntArray() const noexcept
  222.         {
  223.             vector<int> result;
  224.             for (auto & e : array_)
  225.             {
  226.                 if (e)
  227.                     result.push_back(e->AsInt());
  228.             }
  229.             return result;
  230.         }
  231.  
  232.         inline vector<float> AsFloatArray() const noexcept
  233.         {
  234.             vector<float> result;
  235.             for (auto & e : array_)
  236.             {
  237.                 if (e)
  238.                     result.push_back(e->AsFloat());
  239.             }
  240.             return result;
  241.         }
  242.  
  243.         inline vector<double> AsDoubleArray() const noexcept
  244.         {
  245.             vector<double> result;
  246.             for (auto & e : array_)
  247.             {
  248.                 if (e)
  249.                     result.push_back(e->AsDouble());
  250.             }
  251.             return result;
  252.         }
  253.         inline JSON & AsJSON() noexcept { return *this; }
  254.         inline const JSON & AsJSON() const noexcept { return *this; }
  255.  
  256.         inline bool Has(const string & key) const noexcept { if (!IsObject()) return false; if (map_.find(key) == map_.end()) return false; return true; }
  257.         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; }
  258.  
  259.         inline JSONPtr & operator[] (int index) { if (IsArray()) return array_.at(index); throw std::runtime_error("JSON object is not an array"); }
  260.         inline const JSONPtr & operator[] (int index) const { if (IsArray()) return array_.at(index); throw std::runtime_error("JSON object is not an array"); }
  261.         inline JSONPtr & operator[] (const string & key) { if (IsObject()) return map_.at(key); throw std::runtime_error("JSON object is not an object"); }
  262.         inline const JSONPtr & operator[] (const string & key) const { if (IsObject()) return map_.at(key); throw std::runtime_error("JSON object is not an object"); }
  263.  
  264.         inline JSONPtr & getElement(int index) { if (IsArray()) return array_.at(index); throw std::runtime_error("JSON object is not an array"); }
  265.         inline const JSONPtr & getElement(int index) const { if (IsArray()) return array_.at(index); throw std::runtime_error("JSON object is not an array"); }
  266.         inline JSONPtr & getMember(const string & key) { if (IsObject()) return map_.at(key); throw std::runtime_error("JSON object is not an object"); }
  267.         inline const JSONPtr & getMember(const string & key) const { if (IsObject()) return map_.at(key); throw std::runtime_error("JSON object is not an object"); }
  268.  
  269.         inline JSONPtr & set(Type whichType)
  270.         {
  271.             Clear();
  272.             type_ = whichType;
  273.             return shared_from_this();
  274.         }
  275.  
  276.         inline JSONPtr & set(const int ival)
  277.         {
  278.             Clear();
  279.             type_ = Type::Number;
  280.             dval_ = ival;
  281.             return shared_from_this();
  282.         }
  283.  
  284.         inline JSONPtr & set(const double dval)
  285.         {
  286.             Clear();
  287.             type_ = Type::Number;
  288.             dval_ = dval;
  289.             return shared_from_this();
  290.         }
  291.        
  292.         inline JSONPtr & set(const std::string &sval)
  293.         {
  294.             Clear();
  295.             type_ = Type::String;
  296.             sval_ = sval;
  297.             return shared_from_this();
  298.         }
  299.  
  300.         inline JSONPtr & set(initializer_list<int> numberList)
  301.         {
  302.             Clear();
  303.             type_ = Type::Array;
  304.             for (auto it = numberList.begin(); it != numberList.end(); it++)
  305.             {
  306.                 array_.push_back(JSON::MakeNumber(*it));
  307.             }
  308.             return shared_from_this();
  309.         }
  310.  
  311.         inline JSONPtr & set(const vector<int> & numberList)
  312.         {
  313.             Clear();
  314.             type_ = Type::Array;
  315.             for (auto it = numberList.begin(); it != numberList.end(); it++)
  316.             {
  317.                 array_.push_back(JSON::MakeNumber(*it));
  318.             }
  319.             return shared_from_this();
  320.         }
  321.  
  322.         inline JSONPtr & set(initializer_list<float> numberList)
  323.         {
  324.             Clear();
  325.             type_ = Type::Array;
  326.             for (auto it = numberList.begin(); it != numberList.end(); it++)
  327.             {
  328.                 array_.push_back(JSON::MakeNumber(*it));
  329.             }
  330.             return shared_from_this();
  331.         }
  332.  
  333.         inline JSONPtr & set(const vector<float> & numberList)
  334.         {
  335.             Clear();
  336.             type_ = Type::Array;
  337.             for (auto it = numberList.begin(); it != numberList.end(); it++)
  338.             {
  339.                 array_.push_back(JSON::MakeNumber(*it));
  340.             }
  341.             return shared_from_this();
  342.         }
  343.  
  344.         inline JSONPtr & set(initializer_list<double> numberList)
  345.         {
  346.             Clear();
  347.             type_ = Type::Array;
  348.             for (auto it = numberList.begin(); it != numberList.end(); it++)
  349.             {
  350.                 array_.push_back(JSON::MakeNumber(*it));
  351.             }
  352.             return shared_from_this();
  353.         }
  354.  
  355.         inline JSONPtr & set(const vector<double> & numberList)
  356.         {
  357.             Clear();
  358.             type_ = Type::Array;
  359.             for (auto it = numberList.begin(); it != numberList.end(); it++)
  360.             {
  361.                 array_.push_back(JSON::MakeNumber(*it));
  362.             }
  363.             return shared_from_this();
  364.         }
  365.  
  366.         inline JSONPtr & set(initializer_list<string> stringList)
  367.         {
  368.             Clear();
  369.             type_ = Type::Array;
  370.             for (auto it = stringList.begin(); it != stringList.end(); it++)
  371.             {
  372.                 array_.push_back(JSON::MakeString(*it));
  373.             }
  374.             return shared_from_this();
  375.         }
  376.  
  377.         inline JSONPtr & set(const vector<string> & stringList)
  378.         {
  379.             Clear();
  380.             type_ = Type::Array;
  381.             for (auto it = stringList.begin(); it != stringList.end(); it++)
  382.             {
  383.                 array_.push_back(JSON::MakeString(*it));
  384.             }
  385.             return shared_from_this();
  386.         }
  387.  
  388.         inline JSONPtr & set (initializer_list<pair<string, JSONPtr>> members)
  389.         {
  390.             Clear();
  391.             type_ = Type::Object;
  392.             for (auto it = members.begin(); it != members.end(); it++)
  393.             {
  394.                 map_[it->first] = it->second;
  395.             }
  396.             return shared_from_this();
  397.         }
  398.  
  399.         inline JSONPtr & set(const map<string, JSONPtr> & members)
  400.         {
  401.             Clear();
  402.             type_ = Type::Object;
  403.             for (auto it = members.begin(); it != members.end(); it++)
  404.             {
  405.                 map_[it->first] = it->second;
  406.             }
  407.             return shared_from_this();
  408.         }
  409.  
  410.         inline JSONPtr & set(const JSONPtr & json)
  411.         {
  412.             Clear();
  413.             if (!json)
  414.                 return shared_from_this();
  415.  
  416.             type_ = json->type_;
  417.             if (IsNumber()) dval_ = json->dval_;
  418.             if (IsString()) sval_ = json->sval_;
  419.             if (IsArray()) array_ = json->array_;
  420.             if (IsObject()) map_ = json->map_;
  421.             return shared_from_this();
  422.         }
  423.  
  424.         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(); }
  425.         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; }
  426.  
  427.         inline Type GetType() const { return type_; }
  428.         inline bool InstanceOf(const Type t) const { return type_ == t; }
  429.         bool Equals(const JSONPtr &rhs) const;
  430.     private:
  431.         Type type_ = Type::Null;
  432.         double dval_ = 0.0;
  433.         std::string sval_;
  434.         std::vector<JSONPtr> array_;
  435.         std::map<std::string, JSONPtr> map_;
  436.  
  437.         void copyArray(const std::vector<JSONPtr> &a);
  438.         void copyMap(const std::map<std::string, JSONPtr> &m);
  439.     };
  440.  
  441.  
  442.     inline bool operator == (const JSONPtr &lhs, const JSONPtr &rhs)
  443.     {
  444.         if (!lhs || !rhs) return false;
  445.         return lhs->Equals(rhs);
  446.     }
  447.  
  448.  
  449.     inline bool operator != (const JSONPtr &lhs, const JSONPtr &rhs)
  450.     {
  451.         if (!lhs || !rhs) return false;
  452.         return !lhs->Equals(rhs);
  453.     }
  454. }
  455.  
  456. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement