Path: blob/master/Utilities/cmcppdap/src/jsoncpp_json_serializer.cpp
3153 views
// Copyright 2023 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 "jsoncpp_json_serializer.h"1516#include "null_json_serializer.h"1718#include <cm3p/json/json.h>19#include <cstdlib>20#include <memory>2122namespace dap {23namespace json {2425JsonCppDeserializer::JsonCppDeserializer(const std::string& str)26: json(new Json::Value(JsonCppDeserializer::parse(str))), ownsJson(true) {}2728JsonCppDeserializer::JsonCppDeserializer(const Json::Value* json)29: json(json), ownsJson(false) {}3031JsonCppDeserializer::~JsonCppDeserializer() {32if (ownsJson) {33delete json;34}35}3637bool JsonCppDeserializer::deserialize(dap::boolean* v) const {38if (!json->isBool()) {39return false;40}41*v = json->asBool();42return true;43}4445bool JsonCppDeserializer::deserialize(dap::integer* v) const {46if (!json->isInt64()) {47return false;48}49*v = json->asInt64();50return true;51}5253bool JsonCppDeserializer::deserialize(dap::number* v) const {54if (!json->isNumeric()) {55return false;56}57*v = json->asDouble();58return true;59}6061bool JsonCppDeserializer::deserialize(dap::string* v) const {62if (!json->isString()) {63return false;64}65*v = json->asString();66return true;67}6869bool JsonCppDeserializer::deserialize(dap::object* v) const {70v->reserve(json->size());71for (auto i = json->begin(); i != json->end(); i++) {72JsonCppDeserializer d(&*i);73dap::any val;74if (!d.deserialize(&val)) {75return false;76}77(*v)[i.name()] = val;78}79return true;80}8182bool JsonCppDeserializer::deserialize(dap::any* v) const {83if (json->isBool()) {84*v = dap::boolean(json->asBool());85} else if (json->type() == Json::ValueType::realValue) {86// json->isDouble() returns true for integers as well, so we need to87// explicitly look for the realValue type.88*v = dap::number(json->asDouble());89} else if (json->isInt64()) {90*v = dap::integer(json->asInt64());91} else if (json->isString()) {92*v = json->asString();93} else if (json->isObject()) {94dap::object obj;95if (!deserialize(&obj)) {96return false;97}98*v = obj;99} else if (json->isArray()) {100dap::array<any> arr;101if (!deserialize(&arr)) {102return false;103}104*v = arr;105} else if (json->isNull()) {106*v = null();107} else {108return false;109}110return true;111}112113size_t JsonCppDeserializer::count() const {114return json->size();115}116117bool JsonCppDeserializer::array(118const std::function<bool(dap::Deserializer*)>& cb) const {119if (!json->isArray()) {120return false;121}122for (const auto& value : *json) {123JsonCppDeserializer d(&value);124if (!cb(&d)) {125return false;126}127}128return true;129}130131bool JsonCppDeserializer::field(132const std::string& name,133const std::function<bool(dap::Deserializer*)>& cb) const {134if (!json->isObject()) {135return false;136}137auto value = json->find(name.data(), name.data() + name.size());138if (value == nullptr) {139return cb(&NullDeserializer::instance);140}141JsonCppDeserializer d(value);142return cb(&d);143}144145Json::Value JsonCppDeserializer::parse(const std::string& text) {146Json::CharReaderBuilder builder;147auto jsonReader = std::unique_ptr<Json::CharReader>(builder.newCharReader());148Json::Value json;149std::string error;150if (!jsonReader->parse(text.data(), text.data() + text.size(), &json,151&error)) {152// cppdap expects that the JSON layer does not throw exceptions.153std::abort();154}155return json;156}157158JsonCppSerializer::JsonCppSerializer()159: json(new Json::Value()), ownsJson(true) {}160161JsonCppSerializer::JsonCppSerializer(Json::Value* json)162: json(json), ownsJson(false) {}163164JsonCppSerializer::~JsonCppSerializer() {165if (ownsJson) {166delete json;167}168}169170std::string JsonCppSerializer::dump() const {171Json::StreamWriterBuilder writer;172return Json::writeString(writer, *json);173}174175bool JsonCppSerializer::serialize(dap::boolean v) {176*json = (bool)v;177return true;178}179180bool JsonCppSerializer::serialize(dap::integer v) {181*json = (Json::LargestInt)v;182return true;183}184185bool JsonCppSerializer::serialize(dap::number v) {186*json = (double)v;187return true;188}189190bool JsonCppSerializer::serialize(const dap::string& v) {191*json = v;192return true;193}194195bool JsonCppSerializer::serialize(const dap::object& v) {196if (!json->isObject()) {197*json = Json::Value(Json::objectValue);198}199for (auto& it : v) {200JsonCppSerializer s(&(*json)[it.first]);201if (!s.serialize(it.second)) {202return false;203}204}205return true;206}207208bool JsonCppSerializer::serialize(const dap::any& v) {209if (v.is<dap::boolean>()) {210*json = (bool)v.get<dap::boolean>();211} else if (v.is<dap::integer>()) {212*json = (Json::LargestInt)v.get<dap::integer>();213} else if (v.is<dap::number>()) {214*json = (double)v.get<dap::number>();215} else if (v.is<dap::string>()) {216*json = v.get<dap::string>();217} else if (v.is<dap::object>()) {218// reachable if dap::object nested is inside other dap::object219return serialize(v.get<dap::object>());220} else if (v.is<dap::null>()) {221} else {222// reachable if array or custom serialized type is nested inside other223auto type = get_any_type(v);224auto value = get_any_val(v);225if (type && value) {226return type->serialize(this, value);227}228return false;229}230return true;231}232233bool JsonCppSerializer::array(size_t count,234const std::function<bool(dap::Serializer*)>& cb) {235*json = Json::Value(Json::arrayValue);236for (size_t i = 0; i < count; i++) {237JsonCppSerializer s(&(*json)[Json::Value::ArrayIndex(i)]);238if (!cb(&s)) {239return false;240}241}242return true;243}244245bool JsonCppSerializer::object(246const std::function<bool(dap::FieldSerializer*)>& cb) {247struct FS : public FieldSerializer {248Json::Value* const json;249250FS(Json::Value* json) : json(json) {}251bool field(const std::string& name, const SerializeFunc& cb) override {252JsonCppSerializer s(&(*json)[name]);253auto res = cb(&s);254if (s.removed) {255json->removeMember(name);256}257return res;258}259};260261*json = Json::Value(Json::objectValue);262FS fs{json};263return cb(&fs);264}265266void JsonCppSerializer::remove() {267removed = true;268}269270} // namespace json271} // namespace dap272273274