/
niceSOFT
/
cmake
Обзор
Документация
Войти
/
niceSOFT
/
cmake
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Utilities/cmcppdap/src/rapid_json_serializer.cpp
289 строк
7 KB
Glen Chung
Merge branch 'upstream-cppdap' into import-cppdap
26 май 2023, 16:36
26 май 2023, 16:36
3381e6b
Код
Авторство
О чём код?
// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "rapid_json_serializer.h" #include "null_json_serializer.h" #include <rapidjson/document.h> #include <rapidjson/prettywriter.h> namespace dap { namespace json { RapidDeserializer::RapidDeserializer(const std::string& str) : doc(new rapidjson::Document()) { doc->Parse(str.c_str()); } RapidDeserializer::RapidDeserializer(rapidjson::Value* json) : val(json) {} RapidDeserializer::~RapidDeserializer() { delete doc; } bool RapidDeserializer::deserialize(dap::boolean* v) const { if (!json()->IsBool()) { return false; } *v = json()->GetBool(); return true; } bool RapidDeserializer::deserialize(dap::integer* v) const { if (json()->IsInt()) { *v = json()->GetInt(); return true; } else if (json()->IsUint()) { *v = static_cast<int64_t>(json()->GetUint()); return true; } else if (json()->IsInt64()) { *v = json()->GetInt64(); return true; } else if (json()->IsUint64()) { *v = static_cast<int64_t>(json()->GetUint64()); return true; } return false; } bool RapidDeserializer::deserialize(dap::number* v) const { if (!json()->IsNumber()) { return false; } *v = json()->GetDouble(); return true; } bool RapidDeserializer::deserialize(dap::string* v) const { if (!json()->IsString()) { return false; } *v = json()->GetString(); return true; } bool RapidDeserializer::deserialize(dap::object* v) const { v->reserve(json()->MemberCount()); for (auto el = json()->MemberBegin(); el != json()->MemberEnd(); el++) { dap::any el_val; RapidDeserializer d(&(el->value)); if (!d.deserialize(&el_val)) { return false; } (*v)[el->name.GetString()] = el_val; } return true; } bool RapidDeserializer::deserialize(dap::any* v) const { if (json()->IsBool()) { *v = dap::boolean(json()->GetBool()); } else if (json()->IsDouble()) { *v = dap::number(json()->GetDouble()); } else if (json()->IsInt()) { *v = dap::integer(json()->GetInt()); } else if (json()->IsString()) { *v = dap::string(json()->GetString()); } else if (json()->IsNull()) { *v = null(); } else if (json()->IsObject()) { dap::object obj; if (!deserialize(&obj)) { return false; } *v = obj; } else if (json()->IsArray()){ dap::array<any> arr; if (!deserialize(&arr)){ return false; } *v = arr; } else { return false; } return true; } size_t RapidDeserializer::count() const { return json()->Size(); } bool RapidDeserializer::array( const std::function<bool(dap::Deserializer*)>& cb) const { if (!json()->IsArray()) { return false; } for (uint32_t i = 0; i < json()->Size(); i++) { RapidDeserializer d(&(*json())[i]); if (!cb(&d)) { return false; } } return true; } bool RapidDeserializer::field( const std::string& name, const std::function<bool(dap::Deserializer*)>& cb) const { if (!json()->IsObject()) { return false; } auto it = json()->FindMember(name.c_str()); if (it == json()->MemberEnd()) { return cb(&NullDeserializer::instance); } RapidDeserializer d(&(it->value)); return cb(&d); } RapidSerializer::RapidSerializer() : doc(new rapidjson::Document(rapidjson::kObjectType)), allocator(doc->GetAllocator()) {} RapidSerializer::RapidSerializer(rapidjson::Value* json, rapidjson::Document::AllocatorType& allocator) : val(json), allocator(allocator) {} RapidSerializer::~RapidSerializer() { delete doc; } std::string RapidSerializer::dump() const { rapidjson::StringBuffer sb; rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb); json()->Accept(writer); return sb.GetString(); } bool RapidSerializer::serialize(dap::boolean v) { json()->SetBool(v); return true; } bool RapidSerializer::serialize(dap::integer v) { json()->SetInt64(v); return true; } bool RapidSerializer::serialize(dap::number v) { json()->SetDouble(v); return true; } bool RapidSerializer::serialize(const dap::string& v) { json()->SetString(v.data(), static_cast<uint32_t>(v.length()), allocator); return true; } bool RapidSerializer::serialize(const dap::object& v) { if (!json()->IsObject()) { json()->SetObject(); } for (auto& it : v) { if (!json()->HasMember(it.first.c_str())) { rapidjson::Value name_value{it.first.c_str(), allocator}; json()->AddMember(name_value, rapidjson::Value(), allocator); } rapidjson::Value& member = (*json())[it.first.c_str()]; RapidSerializer s(&member, allocator); if (!s.serialize(it.second)) { return false; } } return true; } bool RapidSerializer::serialize(const dap::any& v) { if (v.is<dap::boolean>()) { json()->SetBool((bool)v.get<dap::boolean>()); } else if (v.is<dap::integer>()) { json()->SetInt64(v.get<dap::integer>()); } else if (v.is<dap::number>()) { json()->SetDouble((double)v.get<dap::number>()); } else if (v.is<dap::string>()) { auto s = v.get<dap::string>(); json()->SetString(s.data(), static_cast<uint32_t>(s.length()), allocator); } else if (v.is<dap::object>()) { // reachable if dap::object nested is inside other dap::object return serialize(v.get<dap::object>()); } else if (v.is<dap::null>()) { } else { // reachable if array or custom serialized type is nested inside other dap::object auto type = get_any_type(v); auto value = get_any_val(v); if (type && value) { return type->serialize(this, value); } return false; } return true; } bool RapidSerializer::array(size_t count, const std::function<bool(dap::Serializer*)>& cb) { if (!json()->IsArray()) { json()->SetArray(); } while (count > json()->Size()) { json()->PushBack(rapidjson::Value(), allocator); } for (uint32_t i = 0; i < count; i++) { RapidSerializer s(&(*json())[i], allocator); if (!cb(&s)) { return false; } } return true; } bool RapidSerializer::object( const std::function<bool(dap::FieldSerializer*)>& cb) { struct FS : public FieldSerializer { rapidjson::Value* const json; rapidjson::Document::AllocatorType& allocator; FS(rapidjson::Value* json, rapidjson::Document::AllocatorType& allocator) : json(json), allocator(allocator) {} bool field(const std::string& name, const SerializeFunc& cb) override { if (!json->HasMember(name.c_str())) { rapidjson::Value name_value{name.c_str(), allocator}; json->AddMember(name_value, rapidjson::Value(), allocator); } rapidjson::Value& member = (*json)[name.c_str()]; RapidSerializer s(&member, allocator); auto res = cb(&s); if (s.removed) { json->RemoveMember(name.c_str()); } return res; } }; if (!json()->IsObject()) { json()->SetObject(); } FS fs{json(), allocator}; return cb(&fs); } void RapidSerializer::remove() { removed = true; } } // namespace json } // namespace dap