| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- // Copyright 2023 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 "jsoncpp_json_serializer.h"
- #include "null_json_serializer.h"
- #include <cm3p/json/json.h>
- #include <cstdlib>
- #include <memory>
- namespace dap {
- namespace json {
- JsonCppDeserializer::JsonCppDeserializer(const std::string& str)
- : json(new Json::Value(JsonCppDeserializer::parse(str))), ownsJson(true) {}
- JsonCppDeserializer::JsonCppDeserializer(const Json::Value* json)
- : json(json), ownsJson(false) {}
- JsonCppDeserializer::~JsonCppDeserializer() {
- if (ownsJson) {
- delete json;
- }
- }
- bool JsonCppDeserializer::deserialize(dap::boolean* v) const {
- if (!json->isBool()) {
- return false;
- }
- *v = json->asBool();
- return true;
- }
- bool JsonCppDeserializer::deserialize(dap::integer* v) const {
- if (!json->isInt64()) {
- return false;
- }
- *v = json->asInt64();
- return true;
- }
- bool JsonCppDeserializer::deserialize(dap::number* v) const {
- if (!json->isNumeric()) {
- return false;
- }
- *v = json->asDouble();
- return true;
- }
- bool JsonCppDeserializer::deserialize(dap::string* v) const {
- if (!json->isString()) {
- return false;
- }
- *v = json->asString();
- return true;
- }
- bool JsonCppDeserializer::deserialize(dap::object* v) const {
- v->reserve(json->size());
- for (auto i = json->begin(); i != json->end(); i++) {
- JsonCppDeserializer d(&*i);
- dap::any val;
- if (!d.deserialize(&val)) {
- return false;
- }
- (*v)[i.name()] = val;
- }
- return true;
- }
- bool JsonCppDeserializer::deserialize(dap::any* v) const {
- if (json->isBool()) {
- *v = dap::boolean(json->asBool());
- } else if (json->type() == Json::ValueType::realValue) {
- // json->isDouble() returns true for integers as well, so we need to
- // explicitly look for the realValue type.
- *v = dap::number(json->asDouble());
- } else if (json->isInt64()) {
- *v = dap::integer(json->asInt64());
- } else if (json->isString()) {
- *v = json->asString();
- } 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 if (json->isNull()) {
- *v = null();
- } else {
- return false;
- }
- return true;
- }
- size_t JsonCppDeserializer::count() const {
- return json->size();
- }
- bool JsonCppDeserializer::array(
- const std::function<bool(dap::Deserializer*)>& cb) const {
- if (!json->isArray()) {
- return false;
- }
- for (const auto& value : *json) {
- JsonCppDeserializer d(&value);
- if (!cb(&d)) {
- return false;
- }
- }
- return true;
- }
- bool JsonCppDeserializer::field(
- const std::string& name,
- const std::function<bool(dap::Deserializer*)>& cb) const {
- if (!json->isObject()) {
- return false;
- }
- auto value = json->find(name.data(), name.data() + name.size());
- if (value == nullptr) {
- return cb(&NullDeserializer::instance);
- }
- JsonCppDeserializer d(value);
- return cb(&d);
- }
- Json::Value JsonCppDeserializer::parse(const std::string& text) {
- Json::CharReaderBuilder builder;
- auto jsonReader = std::unique_ptr<Json::CharReader>(builder.newCharReader());
- Json::Value json;
- std::string error;
- if (!jsonReader->parse(text.data(), text.data() + text.size(), &json,
- &error)) {
- // cppdap expects that the JSON layer does not throw exceptions.
- std::abort();
- }
- return json;
- }
- JsonCppSerializer::JsonCppSerializer()
- : json(new Json::Value()), ownsJson(true) {}
- JsonCppSerializer::JsonCppSerializer(Json::Value* json)
- : json(json), ownsJson(false) {}
- JsonCppSerializer::~JsonCppSerializer() {
- if (ownsJson) {
- delete json;
- }
- }
- std::string JsonCppSerializer::dump() const {
- Json::StreamWriterBuilder writer;
- return Json::writeString(writer, *json);
- }
- bool JsonCppSerializer::serialize(dap::boolean v) {
- *json = (bool)v;
- return true;
- }
- bool JsonCppSerializer::serialize(dap::integer v) {
- *json = (Json::LargestInt)v;
- return true;
- }
- bool JsonCppSerializer::serialize(dap::number v) {
- *json = (double)v;
- return true;
- }
- bool JsonCppSerializer::serialize(const dap::string& v) {
- *json = v;
- return true;
- }
- bool JsonCppSerializer::serialize(const dap::object& v) {
- if (!json->isObject()) {
- *json = Json::Value(Json::objectValue);
- }
- for (auto& it : v) {
- JsonCppSerializer s(&(*json)[it.first]);
- if (!s.serialize(it.second)) {
- return false;
- }
- }
- return true;
- }
- bool JsonCppSerializer::serialize(const dap::any& v) {
- if (v.is<dap::boolean>()) {
- *json = (bool)v.get<dap::boolean>();
- } else if (v.is<dap::integer>()) {
- *json = (Json::LargestInt)v.get<dap::integer>();
- } else if (v.is<dap::number>()) {
- *json = (double)v.get<dap::number>();
- } else if (v.is<dap::string>()) {
- *json = v.get<dap::string>();
- } 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
- 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 JsonCppSerializer::array(size_t count,
- const std::function<bool(dap::Serializer*)>& cb) {
- *json = Json::Value(Json::arrayValue);
- for (size_t i = 0; i < count; i++) {
- JsonCppSerializer s(&(*json)[Json::Value::ArrayIndex(i)]);
- if (!cb(&s)) {
- return false;
- }
- }
- return true;
- }
- bool JsonCppSerializer::object(
- const std::function<bool(dap::FieldSerializer*)>& cb) {
- struct FS : public FieldSerializer {
- Json::Value* const json;
- FS(Json::Value* json) : json(json) {}
- bool field(const std::string& name, const SerializeFunc& cb) override {
- JsonCppSerializer s(&(*json)[name]);
- auto res = cb(&s);
- if (s.removed) {
- json->removeMember(name);
- }
- return res;
- }
- };
- *json = Json::Value(Json::objectValue);
- FS fs{json};
- return cb(&fs);
- }
- void JsonCppSerializer::remove() {
- removed = true;
- }
- } // namespace json
- } // namespace dap
|