Path: blob/master/Utilities/cmcppdap/src/nlohmann_json_serializer.cpp
3153 views
// Copyright 2019 Google LLC1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// https://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314#include "nlohmann_json_serializer.h"1516#include "null_json_serializer.h"1718// Disable JSON exceptions. We should be guarding against any exceptions being19// fired in this file.20#define JSON_NOEXCEPTION 121#include <nlohmann/json.hpp>2223namespace dap {24namespace json {2526NlohmannDeserializer::NlohmannDeserializer(const std::string& str)27: json(new nlohmann::json(nlohmann::json::parse(str, nullptr, false))),28ownsJson(true) {}2930NlohmannDeserializer::NlohmannDeserializer(const nlohmann::json* json)31: json(json), ownsJson(false) {}3233NlohmannDeserializer::~NlohmannDeserializer() {34if (ownsJson) {35delete json;36}37}3839bool NlohmannDeserializer::deserialize(dap::boolean* v) const {40if (!json->is_boolean()) {41return false;42}43*v = json->get<bool>();44return true;45}4647bool NlohmannDeserializer::deserialize(dap::integer* v) const {48if (!json->is_number_integer()) {49return false;50}51*v = json->get<int64_t>();52return true;53}5455bool NlohmannDeserializer::deserialize(dap::number* v) const {56if (!json->is_number()) {57return false;58}59*v = json->get<double>();60return true;61}6263bool NlohmannDeserializer::deserialize(dap::string* v) const {64if (!json->is_string()) {65return false;66}67*v = json->get<std::string>();68return true;69}7071bool NlohmannDeserializer::deserialize(dap::object* v) const {72v->reserve(json->size());73for (auto& el : json->items()) {74NlohmannDeserializer d(&el.value());75dap::any val;76if (!d.deserialize(&val)) {77return false;78}79(*v)[el.key()] = val;80}81return true;82}8384bool NlohmannDeserializer::deserialize(dap::any* v) const {85if (json->is_boolean()) {86*v = dap::boolean(json->get<bool>());87} else if (json->is_number_float()) {88*v = dap::number(json->get<double>());89} else if (json->is_number_integer()) {90*v = dap::integer(json->get<int64_t>());91} else if (json->is_string()) {92*v = json->get<std::string>();93} else if (json->is_object()) {94dap::object obj;95if (!deserialize(&obj)) {96return false;97}98*v = obj;99} else if (json->is_array()) {100dap::array<any> arr;101if (!deserialize(&arr)) {102return false;103}104*v = arr;105} else if (json->is_null()) {106*v = null();107} else {108return false;109}110return true;111}112113size_t NlohmannDeserializer::count() const {114return json->size();115}116117bool NlohmannDeserializer::array(118const std::function<bool(dap::Deserializer*)>& cb) const {119if (!json->is_array()) {120return false;121}122for (size_t i = 0; i < json->size(); i++) {123NlohmannDeserializer d(&(*json)[i]);124if (!cb(&d)) {125return false;126}127}128return true;129}130131bool NlohmannDeserializer::field(132const std::string& name,133const std::function<bool(dap::Deserializer*)>& cb) const {134if (!json->is_structured()) {135return false;136}137auto it = json->find(name);138if (it == json->end()) {139return cb(&NullDeserializer::instance);140}141auto obj = *it;142NlohmannDeserializer d(&obj);143return cb(&d);144}145146NlohmannSerializer::NlohmannSerializer()147: json(new nlohmann::json()), ownsJson(true) {}148149NlohmannSerializer::NlohmannSerializer(nlohmann::json* json)150: json(json), ownsJson(false) {}151152NlohmannSerializer::~NlohmannSerializer() {153if (ownsJson) {154delete json;155}156}157158std::string NlohmannSerializer::dump() const {159return json->dump();160}161162bool NlohmannSerializer::serialize(dap::boolean v) {163*json = (bool)v;164return true;165}166167bool NlohmannSerializer::serialize(dap::integer v) {168*json = (int64_t)v;169return true;170}171172bool NlohmannSerializer::serialize(dap::number v) {173*json = (double)v;174return true;175}176177bool NlohmannSerializer::serialize(const dap::string& v) {178*json = v;179return true;180}181182bool NlohmannSerializer::serialize(const dap::object& v) {183if (!json->is_object()) {184*json = nlohmann::json::object();185}186for (auto& it : v) {187NlohmannSerializer s(&(*json)[it.first]);188if (!s.serialize(it.second)) {189return false;190}191}192return true;193}194195bool NlohmannSerializer::serialize(const dap::any& v) {196if (v.is<dap::boolean>()) {197*json = (bool)v.get<dap::boolean>();198} else if (v.is<dap::integer>()) {199*json = (int64_t)v.get<dap::integer>();200} else if (v.is<dap::number>()) {201*json = (double)v.get<dap::number>();202} else if (v.is<dap::string>()) {203*json = v.get<dap::string>();204} else if (v.is<dap::object>()) {205// reachable if dap::object nested is inside other dap::object206return serialize(v.get<dap::object>());207} else if (v.is<dap::null>()) {208} else {209// reachable if array or custom serialized type is nested inside other210auto type = get_any_type(v);211auto value = get_any_val(v);212if (type && value) {213return type->serialize(this, value);214}215return false;216}217return true;218}219220bool NlohmannSerializer::array(221size_t count,222const std::function<bool(dap::Serializer*)>& cb) {223*json = std::vector<int>();224for (size_t i = 0; i < count; i++) {225NlohmannSerializer s(&(*json)[i]);226if (!cb(&s)) {227return false;228}229}230return true;231}232233bool NlohmannSerializer::object(234const std::function<bool(dap::FieldSerializer*)>& cb) {235struct FS : public FieldSerializer {236nlohmann::json* const json;237238FS(nlohmann::json* json) : json(json) {}239bool field(const std::string& name, const SerializeFunc& cb) override {240NlohmannSerializer s(&(*json)[name]);241auto res = cb(&s);242if (s.removed) {243json->erase(name);244}245return res;246}247};248249*json = nlohmann::json({}, false, nlohmann::json::value_t::object);250FS fs{json};251return cb(&fs);252}253254void NlohmannSerializer::remove() {255removed = true;256}257258} // namespace json259} // namespace dap260261262