Path: blob/master/Utilities/cmcppdap/src/rapid_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 "rapid_json_serializer.h"1516#include "null_json_serializer.h"1718#include <rapidjson/document.h>19#include <rapidjson/prettywriter.h>2021namespace dap {22namespace json {2324RapidDeserializer::RapidDeserializer(const std::string& str)25: doc(new rapidjson::Document()) {26doc->Parse(str.c_str());27}2829RapidDeserializer::RapidDeserializer(rapidjson::Value* json) : val(json) {}3031RapidDeserializer::~RapidDeserializer() {32delete doc;33}3435bool RapidDeserializer::deserialize(dap::boolean* v) const {36if (!json()->IsBool()) {37return false;38}39*v = json()->GetBool();40return true;41}4243bool RapidDeserializer::deserialize(dap::integer* v) const {44if (json()->IsInt()) {45*v = json()->GetInt();46return true;47} else if (json()->IsUint()) {48*v = static_cast<int64_t>(json()->GetUint());49return true;50} else if (json()->IsInt64()) {51*v = json()->GetInt64();52return true;53} else if (json()->IsUint64()) {54*v = static_cast<int64_t>(json()->GetUint64());55return true;56}57return false;58}5960bool RapidDeserializer::deserialize(dap::number* v) const {61if (!json()->IsNumber()) {62return false;63}64*v = json()->GetDouble();65return true;66}6768bool RapidDeserializer::deserialize(dap::string* v) const {69if (!json()->IsString()) {70return false;71}72*v = json()->GetString();73return true;74}7576bool RapidDeserializer::deserialize(dap::object* v) const {77v->reserve(json()->MemberCount());78for (auto el = json()->MemberBegin(); el != json()->MemberEnd(); el++) {79dap::any el_val;80RapidDeserializer d(&(el->value));81if (!d.deserialize(&el_val)) {82return false;83}84(*v)[el->name.GetString()] = el_val;85}86return true;87}8889bool RapidDeserializer::deserialize(dap::any* v) const {90if (json()->IsBool()) {91*v = dap::boolean(json()->GetBool());92} else if (json()->IsDouble()) {93*v = dap::number(json()->GetDouble());94} else if (json()->IsInt()) {95*v = dap::integer(json()->GetInt());96} else if (json()->IsString()) {97*v = dap::string(json()->GetString());98} else if (json()->IsNull()) {99*v = null();100} else if (json()->IsObject()) {101dap::object obj;102if (!deserialize(&obj)) {103return false;104}105*v = obj;106} else if (json()->IsArray()){107dap::array<any> arr;108if (!deserialize(&arr)){109return false;110}111*v = arr;112} else {113return false;114}115return true;116}117118size_t RapidDeserializer::count() const {119return json()->Size();120}121122bool RapidDeserializer::array(123const std::function<bool(dap::Deserializer*)>& cb) const {124if (!json()->IsArray()) {125return false;126}127for (uint32_t i = 0; i < json()->Size(); i++) {128RapidDeserializer d(&(*json())[i]);129if (!cb(&d)) {130return false;131}132}133return true;134}135136bool RapidDeserializer::field(137const std::string& name,138const std::function<bool(dap::Deserializer*)>& cb) const {139if (!json()->IsObject()) {140return false;141}142auto it = json()->FindMember(name.c_str());143if (it == json()->MemberEnd()) {144return cb(&NullDeserializer::instance);145}146RapidDeserializer d(&(it->value));147return cb(&d);148}149150RapidSerializer::RapidSerializer()151: doc(new rapidjson::Document(rapidjson::kObjectType)),152allocator(doc->GetAllocator()) {}153154RapidSerializer::RapidSerializer(rapidjson::Value* json,155rapidjson::Document::AllocatorType& allocator)156: val(json), allocator(allocator) {}157158RapidSerializer::~RapidSerializer() {159delete doc;160}161162std::string RapidSerializer::dump() const {163rapidjson::StringBuffer sb;164rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);165json()->Accept(writer);166return sb.GetString();167}168169bool RapidSerializer::serialize(dap::boolean v) {170json()->SetBool(v);171return true;172}173174bool RapidSerializer::serialize(dap::integer v) {175json()->SetInt64(v);176return true;177}178179bool RapidSerializer::serialize(dap::number v) {180json()->SetDouble(v);181return true;182}183184bool RapidSerializer::serialize(const dap::string& v) {185json()->SetString(v.data(), static_cast<uint32_t>(v.length()), allocator);186return true;187}188189bool RapidSerializer::serialize(const dap::object& v) {190if (!json()->IsObject()) {191json()->SetObject();192}193for (auto& it : v) {194if (!json()->HasMember(it.first.c_str())) {195rapidjson::Value name_value{it.first.c_str(), allocator};196json()->AddMember(name_value, rapidjson::Value(), allocator);197}198rapidjson::Value& member = (*json())[it.first.c_str()];199RapidSerializer s(&member, allocator);200if (!s.serialize(it.second)) {201return false;202}203}204return true;205}206207bool RapidSerializer::serialize(const dap::any& v) {208if (v.is<dap::boolean>()) {209json()->SetBool((bool)v.get<dap::boolean>());210} else if (v.is<dap::integer>()) {211json()->SetInt64(v.get<dap::integer>());212} else if (v.is<dap::number>()) {213json()->SetDouble((double)v.get<dap::number>());214} else if (v.is<dap::string>()) {215auto s = v.get<dap::string>();216json()->SetString(s.data(), static_cast<uint32_t>(s.length()), allocator);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 other dap::object223auto type = get_any_type(v);224auto value = get_any_val(v);225if (type && value) {226return type->serialize(this, value);227}228return false;229}230231return true;232}233234bool RapidSerializer::array(size_t count,235const std::function<bool(dap::Serializer*)>& cb) {236if (!json()->IsArray()) {237json()->SetArray();238}239240while (count > json()->Size()) {241json()->PushBack(rapidjson::Value(), allocator);242}243244for (uint32_t i = 0; i < count; i++) {245RapidSerializer s(&(*json())[i], allocator);246if (!cb(&s)) {247return false;248}249}250return true;251}252253bool RapidSerializer::object(254const std::function<bool(dap::FieldSerializer*)>& cb) {255struct FS : public FieldSerializer {256rapidjson::Value* const json;257rapidjson::Document::AllocatorType& allocator;258259FS(rapidjson::Value* json, rapidjson::Document::AllocatorType& allocator)260: json(json), allocator(allocator) {}261bool field(const std::string& name, const SerializeFunc& cb) override {262if (!json->HasMember(name.c_str())) {263rapidjson::Value name_value{name.c_str(), allocator};264json->AddMember(name_value, rapidjson::Value(), allocator);265}266rapidjson::Value& member = (*json)[name.c_str()];267RapidSerializer s(&member, allocator);268auto res = cb(&s);269if (s.removed) {270json->RemoveMember(name.c_str());271}272return res;273}274};275276if (!json()->IsObject()) {277json()->SetObject();278}279FS fs{json(), allocator};280return cb(&fs);281}282283void RapidSerializer::remove() {284removed = true;285}286287} // namespace json288} // namespace dap289290291