303 lines · c
1//===---------------------JSON.h --------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H10#define LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H11 12#include "StdStringExtractor.h"13 14// C includes15#include <cinttypes>16#include <cstdint>17 18// C++ includes19#include <map>20#include <memory>21#include <ostream>22#include <string>23#include <vector>24 25class JSONValue {26public:27 virtual void Write(std::ostream &s) = 0;28 29 typedef std::shared_ptr<JSONValue> SP;30 31 enum class Kind { String, Number, True, False, Null, Object, Array };32 33 JSONValue(Kind k) : m_kind(k) {}34 35 Kind GetKind() const { return m_kind; }36 37 virtual ~JSONValue() = default;38 39private:40 const Kind m_kind;41};42 43class JSONString : public JSONValue {44public:45 JSONString();46 JSONString(const char *s);47 JSONString(const std::string &s);48 49 JSONString(const JSONString &s) = delete;50 JSONString &operator=(const JSONString &s) = delete;51 52 void Write(std::ostream &s) override;53 54 typedef std::shared_ptr<JSONString> SP;55 56 std::string GetData() { return m_data; }57 58 static bool classof(const JSONValue *V) {59 return V->GetKind() == JSONValue::Kind::String;60 }61 62 ~JSONString() override = default;63 64private:65 static std::string json_string_quote_metachars(const std::string &);66 67 std::string m_data;68};69 70class JSONNumber : public JSONValue {71public:72 typedef std::shared_ptr<JSONNumber> SP;73 74 // We create a constructor for all integer and floating point type with using75 // templates and76 // SFINAE to avoid having ambiguous overloads because of the implicit type77 // promotion. If we78 // would have constructors only with int64_t, uint64_t and double types then79 // constructing a80 // JSONNumber from an int32_t (or any other similar type) would fail to81 // compile.82 83 template <typename T, typename std::enable_if<84 std::is_integral<T>::value &&85 std::is_unsigned<T>::value>::type * = nullptr>86 explicit JSONNumber(T u)87 : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Unsigned) {88 m_data.m_unsigned = u;89 }90 91 template <typename T,92 typename std::enable_if<std::is_integral<T>::value &&93 std::is_signed<T>::value>::type * = nullptr>94 explicit JSONNumber(T s)95 : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Signed) {96 m_data.m_signed = s;97 }98 99 template <typename T, typename std::enable_if<100 std::is_floating_point<T>::value>::type * = nullptr>101 explicit JSONNumber(T d)102 : JSONValue(JSONValue::Kind::Number), m_data_type(DataType::Double) {103 m_data.m_double = d;104 }105 106 ~JSONNumber() override = default;107 108 JSONNumber(const JSONNumber &s) = delete;109 JSONNumber &operator=(const JSONNumber &s) = delete;110 111 void Write(std::ostream &s) override;112 113 uint64_t GetAsUnsigned() const;114 115 int64_t GetAsSigned() const;116 117 double GetAsDouble() const;118 119 static bool classof(const JSONValue *V) {120 return V->GetKind() == JSONValue::Kind::Number;121 }122 123private:124 enum class DataType : uint8_t { Unsigned, Signed, Double } m_data_type;125 126 union {127 uint64_t m_unsigned;128 int64_t m_signed;129 double m_double;130 } m_data;131};132 133class JSONTrue : public JSONValue {134public:135 JSONTrue();136 137 JSONTrue(const JSONTrue &s) = delete;138 JSONTrue &operator=(const JSONTrue &s) = delete;139 140 void Write(std::ostream &s) override;141 142 typedef std::shared_ptr<JSONTrue> SP;143 144 static bool classof(const JSONValue *V) {145 return V->GetKind() == JSONValue::Kind::True;146 }147 148 ~JSONTrue() override = default;149};150 151class JSONFalse : public JSONValue {152public:153 JSONFalse();154 155 JSONFalse(const JSONFalse &s) = delete;156 JSONFalse &operator=(const JSONFalse &s) = delete;157 158 void Write(std::ostream &s) override;159 160 typedef std::shared_ptr<JSONFalse> SP;161 162 static bool classof(const JSONValue *V) {163 return V->GetKind() == JSONValue::Kind::False;164 }165 166 ~JSONFalse() override = default;167};168 169class JSONNull : public JSONValue {170public:171 JSONNull();172 173 JSONNull(const JSONNull &s) = delete;174 JSONNull &operator=(const JSONNull &s) = delete;175 176 void Write(std::ostream &s) override;177 178 typedef std::shared_ptr<JSONNull> SP;179 180 static bool classof(const JSONValue *V) {181 return V->GetKind() == JSONValue::Kind::Null;182 }183 184 ~JSONNull() override = default;185};186 187class JSONObject : public JSONValue {188public:189 JSONObject();190 191 JSONObject(const JSONObject &s) = delete;192 JSONObject &operator=(const JSONObject &s) = delete;193 194 void Write(std::ostream &s) override;195 196 typedef std::shared_ptr<JSONObject> SP;197 198 static bool classof(const JSONValue *V) {199 return V->GetKind() == JSONValue::Kind::Object;200 }201 202 bool SetObject(const std::string &key, JSONValue::SP value);203 204 JSONValue::SP GetObject(const std::string &key) const;205 206 /// Return keyed value as bool207 ///208 /// \param[in] key209 /// The value of the key to lookup210 ///211 /// \param[out] value212 /// The value of the key as a bool. Undefined if the key doesn't213 /// exist or if the key is not either true or false.214 ///215 /// \return216 /// true if the key existed as was a bool value; false otherwise.217 /// Note the return value is *not* the value of the bool, use218 /// \b value for that.219 bool GetObjectAsBool(const std::string &key, bool &value) const;220 221 bool GetObjectAsString(const std::string &key, std::string &value) const;222 223 ~JSONObject() override = default;224 225private:226 typedef std::map<std::string, JSONValue::SP> Map;227 typedef Map::iterator Iterator;228 Map m_elements;229};230 231class JSONArray : public JSONValue {232public:233 JSONArray();234 235 JSONArray(const JSONArray &s) = delete;236 JSONArray &operator=(const JSONArray &s) = delete;237 238 void Write(std::ostream &s) override;239 240 typedef std::shared_ptr<JSONArray> SP;241 242 static bool classof(const JSONValue *V) {243 return V->GetKind() == JSONValue::Kind::Array;244 }245 246private:247 typedef std::vector<JSONValue::SP> Vector;248 typedef Vector::iterator Iterator;249 typedef Vector::size_type Index;250 typedef Vector::size_type Size;251 252public:253 bool SetObject(Index i, JSONValue::SP value);254 255 bool AppendObject(JSONValue::SP value);256 257 JSONValue::SP GetObject(Index i);258 259 Size GetNumElements();260 261 ~JSONArray() override = default;262 263 Vector m_elements;264};265 266class JSONParser : public StdStringExtractor {267public:268 enum Token {269 Invalid,270 Status,271 ObjectStart,272 ObjectEnd,273 ArrayStart,274 ArrayEnd,275 Comma,276 Colon,277 String,278 Integer,279 Float,280 True,281 False,282 Null,283 EndOfFile284 };285 286 JSONParser(const char *cstr);287 288 int GetEscapedChar(bool &was_escaped);289 290 Token GetToken(std::string &value);291 292 JSONValue::SP ParseJSONValue();293 294protected:295 JSONValue::SP ParseJSONValue(const std::string &value, const Token &token);296 297 JSONValue::SP ParseJSONObject();298 299 JSONValue::SP ParseJSONArray();300};301 302#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_JSON_H303