diff --git a/libs/libcommon/include/common/JSON.h b/libs/libcommon/include/common/JSON.h index 58dbc7270ec166da1be7ce8e97ed3cf86a34fdf1..6c68f2fd7d3afd8784b7f56267d73c81f8e9db55 100644 --- a/libs/libcommon/include/common/JSON.h +++ b/libs/libcommon/include/common/JSON.h @@ -5,8 +5,6 @@ #include #include -#define PURE __attribute__((pure)) - /** Очень простой класс для чтения JSON (или его кусочков). * Представляет собой ссылку на кусок памяти, в котором содержится JSON (или его кусочек). @@ -67,8 +65,8 @@ public: /// Для вставки в контейнеры (создаёт некорректный объект) JSON() : ptr_begin(nullptr), ptr_end(ptr_begin + 1) {} - const char * data() const PURE { return ptr_begin; } - const char * dataEnd() const PURE { return ptr_end; } + const char * data() const { return ptr_begin; } + const char * dataEnd() const { return ptr_end; } enum ElementType { @@ -82,112 +80,112 @@ public: TYPE_NOTYPE, }; - ElementType getType() const PURE; + ElementType getType() const; - bool isObject() const PURE { return getType() == TYPE_OBJECT; }; - bool isArray() const PURE { return getType() == TYPE_ARRAY; }; - bool isNumber() const PURE { return getType() == TYPE_NUMBER; }; - bool isString() const PURE { return getType() == TYPE_STRING; }; - bool isBool() const PURE { return getType() == TYPE_BOOL; }; - bool isNull() const PURE { return getType() == TYPE_NULL; }; - bool isNameValuePair() const PURE { return getType() == TYPE_NAME_VALUE_PAIR; }; + bool isObject() const { return getType() == TYPE_OBJECT; }; + bool isArray() const { return getType() == TYPE_ARRAY; }; + bool isNumber() const { return getType() == TYPE_NUMBER; }; + bool isString() const { return getType() == TYPE_STRING; }; + bool isBool() const { return getType() == TYPE_BOOL; }; + bool isNull() const { return getType() == TYPE_NULL; }; + bool isNameValuePair() const { return getType() == TYPE_NAME_VALUE_PAIR; }; /// Количество элементов в массиве или объекте; если элемент - не массив или объект, то исключение. - size_t size() const PURE; + size_t size() const; /// Является ли массив или объект пустыми; если элемент - не массив или объект, то исключение. - bool empty() const PURE; + bool empty() const; /// Получить элемент массива по индексу; если элемент - не массив, то исключение. - JSON operator[] (size_t n) const PURE; + JSON operator[] (size_t n) const; /// Получить элемент объекта по имени; если элемент - не объект, то исключение. - JSON operator[] (const std::string & name) const PURE; + JSON operator[] (const std::string & name) const; /// Есть ли в объекте элемент с заданным именем; если элемент - не объект, то исключение. - bool has(const std::string & name) const PURE { return has(name.data(), name.size()); } - bool has(const char * data, size_t size) const PURE; + bool has(const std::string & name) const { return has(name.data(), name.size()); } + bool has(const char * data, size_t size) const; /// Получить значение элемента; исключение, если элемент имеет неправильный тип. template - T get() const PURE; + T get() const; /// если значения нет, или тип неверный, то возвращает дефолтное значение template - T getWithDefault(const std::string & key, const T & default_ = T()) const PURE; + T getWithDefault(const std::string & key, const T & default_ = T()) const; - double getDouble() const PURE; - Int64 getInt() const PURE; /// Отбросить дробную часть. - UInt64 getUInt() const PURE; /// Отбросить дробную часть. Если число отрицательное - исключение. - std::string getString() const PURE; - bool getBool() const PURE; - std::string getName() const PURE; /// Получить имя name-value пары. - JSON getValue() const PURE; /// Получить значение name-value пары. + double getDouble() const; + Int64 getInt() const; /// Отбросить дробную часть. + UInt64 getUInt() const; /// Отбросить дробную часть. Если число отрицательное - исключение. + std::string getString() const; + bool getBool() const; + std::string getName() const; /// Получить имя name-value пары. + JSON getValue() const; /// Получить значение name-value пары. - StringRef getRawString() const PURE; - StringRef getRawName() const PURE; + StringRef getRawString() const; + StringRef getRawName() const; /// Получить значение элемента; если элемент - строка, то распарсить значение из строки; если не строка или число - то исключение. - double toDouble() const PURE; - Int64 toInt() const PURE; - UInt64 toUInt() const PURE; + double toDouble() const; + Int64 toInt() const; + UInt64 toUInt() const; /** Преобразовать любой элемент в строку. * Для строки возвращается её значение, для всех остальных элементов - сериализованное представление. */ - std::string toString() const PURE; + std::string toString() const; /// Класс JSON одновременно является итератором по самому себе. using iterator = JSON; using const_iterator = JSON; - iterator operator* () const PURE { return *this; } - const JSON * operator-> () const PURE { return this; } - bool operator== (const JSON & rhs) const PURE { return ptr_begin == rhs.ptr_begin; } - bool operator!= (const JSON & rhs) const PURE { return ptr_begin != rhs.ptr_begin; } + iterator operator* () const { return *this; } + const JSON * operator-> () const { return this; } + bool operator== (const JSON & rhs) const { return ptr_begin == rhs.ptr_begin; } + bool operator!= (const JSON & rhs) const { return ptr_begin != rhs.ptr_begin; } /** Если элемент - массив или объект, то begin() возвращает iterator, * который указывает на первый элемент массива или первую name-value пару объекта. */ - iterator begin() const PURE; + iterator begin() const; /** end() - значение, которое нельзя использовать; сигнализирует о том, что элементы закончились. */ - iterator end() const PURE; + iterator end() const; /// Перейти к следующему элементу массива или следующей name-value паре объекта. iterator & operator++(); iterator operator++(int); /// Есть ли в строке escape-последовательности - bool hasEscapes() const PURE; + bool hasEscapes() const; /// Есть ли в строке спец-символы из набора \, ', \0, \b, \f, \r, \n, \t, возможно, заэскейпленные. - bool hasSpecialChars() const PURE; + bool hasSpecialChars() const; private: /// Проверить глубину рекурсии, а также корректность диапазона памяти. - void checkInit() const PURE; + void checkInit() const; /// Проверить, что pos лежит внутри диапазона памяти. - void checkPos(Pos pos) const PURE; + void checkPos(Pos pos) const; /// Вернуть позицию после заданного элемента. - Pos skipString() const PURE; - Pos skipNumber() const PURE; - Pos skipBool() const PURE; - Pos skipNull() const PURE; - Pos skipNameValuePair() const PURE; - Pos skipObject() const PURE; - Pos skipArray() const PURE; + Pos skipString() const; + Pos skipNumber() const; + Pos skipBool() const; + Pos skipNull() const; + Pos skipNameValuePair() const; + Pos skipObject() const; + Pos skipArray() const; - Pos skipElement() const PURE; + Pos skipElement() const; /// Найти name-value пару с заданным именем в объекте. - Pos searchField(const std::string & name) const PURE { return searchField(name.data(), name.size()); } - Pos searchField(const char * data, size_t size) const PURE; + Pos searchField(const std::string & name) const { return searchField(name.data(), name.size()); } + Pos searchField(const char * data, size_t size) const; template - bool isType() const PURE; + bool isType() const; }; template @@ -205,5 +203,3 @@ T JSON::getWithDefault(const std::string & key, const T & default_) const else return default_; } - -#undef PURE diff --git a/libs/libcommon/src/tests/json_test.cpp b/libs/libcommon/src/tests/json_test.cpp index 5fd23546092b35250a2656c76194cb8c1fbd4759..609cab5f953458e868065e760c7ee6dc35faefb0 100644 --- a/libs/libcommon/src/tests/json_test.cpp +++ b/libs/libcommon/src/tests/json_test.cpp @@ -513,7 +513,7 @@ void get_string() { "\"/734859/samolet-radioupravlyaemyy-istrebitel-rabotaet-o\0k"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s }, { "\"/kosmetika-i-parfyum/parfyumeriya/mu\0t"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s }, { "\"/ko\0\x04"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s }, - { ""s, ResultType::Throw, "JSON: expected \", got \0"s }, + { ""s, ResultType::Throw, "JSON: begin >= end."s }, { "\"/stroitelstvo-i-remont/stroit\0t"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s }, { "\"/stroitelstvo-i-remont/stroitelnyy-instrument/av\0k"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s }, { "\"/s\0a"s, ResultType::Throw, "JSON: incorrect syntax (expected end of string, found end of JSON)."s }, @@ -636,15 +636,15 @@ void get_string() { static_cast(i); - for (auto &r : test_data) + for (auto & r : test_data) { - JSON j(r.input.c_str(), r.input.c_str() + r.input.size()); try { + JSON j(r.input.c_str(), r.input.c_str() + r.input.size()); Test::compare(j.getString(), r.result); Test::compare(r.result_type == ResultType::Return, true); } - catch (JSONException &e) + catch (JSONException & e) { Test::compare(r.result_type == ResultType::Throw, true); Test::compare(e.message(), r.result);