Add support for rapidjson as the JSON library
nlohmann is still the default, but if `CPPDAP_JSON_DIR` points to rapidjson, then this will be used instead Most of this was upstreamed from: https://fuchsia-review.googlesource.com/c/third_party/github.com/google/cppdap/+/456566
This commit is contained in:
parent
77209caf04
commit
6d6cbf17d7
@ -64,14 +64,34 @@ if(CPPDAP_BUILD_TESTS)
|
|||||||
endif()
|
endif()
|
||||||
endif(CPPDAP_BUILD_TESTS)
|
endif(CPPDAP_BUILD_TESTS)
|
||||||
|
|
||||||
|
###########################################################
|
||||||
|
# JSON library
|
||||||
|
###########################################################
|
||||||
|
if(NOT DEFINED CPPDAP_JSON_LIBRARY)
|
||||||
|
# Attempt to detect JSON library from CPPDAP_JSON_DIR
|
||||||
|
if(NOT EXISTS "${CPPDAP_JSON_DIR}")
|
||||||
|
message(FATAL_ERROR "CPPDAP_JSON_DIR '${CPPDAP_JSON_DIR}' does not exist")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(EXISTS "${CPPDAP_JSON_DIR}/include/nlohmann")
|
||||||
|
set(CPPDAP_JSON_LIBRARY "nlohmann")
|
||||||
|
elseif(EXISTS "${CPPDAP_JSON_DIR}/include/rapidjson")
|
||||||
|
set(CPPDAP_JSON_LIBRARY "rapid")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Could not determine JSON library from ${CPPDAP_JSON_LIBRARY}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
string(TOUPPER ${CPPDAP_JSON_LIBRARY} CPPDAP_JSON_LIBRARY_UPPER)
|
||||||
|
|
||||||
###########################################################
|
###########################################################
|
||||||
# File lists
|
# File lists
|
||||||
###########################################################
|
###########################################################
|
||||||
set(CPPDAP_LIST
|
set(CPPDAP_LIST
|
||||||
${CPPDAP_SRC_DIR}/content_stream.cpp
|
${CPPDAP_SRC_DIR}/content_stream.cpp
|
||||||
${CPPDAP_SRC_DIR}/io.cpp
|
${CPPDAP_SRC_DIR}/io.cpp
|
||||||
${CPPDAP_SRC_DIR}/json_serializer.cpp
|
${CPPDAP_SRC_DIR}/${CPPDAP_JSON_LIBRARY}_json_serializer.cpp
|
||||||
${CPPDAP_SRC_DIR}/network.cpp
|
${CPPDAP_SRC_DIR}/network.cpp
|
||||||
|
${CPPDAP_SRC_DIR}/null_json_serializer.cpp
|
||||||
${CPPDAP_SRC_DIR}/protocol_events.cpp
|
${CPPDAP_SRC_DIR}/protocol_events.cpp
|
||||||
${CPPDAP_SRC_DIR}/protocol_requests.cpp
|
${CPPDAP_SRC_DIR}/protocol_requests.cpp
|
||||||
${CPPDAP_SRC_DIR}/protocol_response.cpp
|
${CPPDAP_SRC_DIR}/protocol_response.cpp
|
||||||
@ -117,6 +137,11 @@ function(cppdap_set_target_options target)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Add define for JSON library in use
|
||||||
|
set_target_properties(${target} PROPERTIES
|
||||||
|
COMPILE_DEFINITIONS "CPPDAP_JSON_${CPPDAP_JSON_LIBRARY_UPPER}=1"
|
||||||
|
)
|
||||||
|
|
||||||
# Treat all warnings as errors
|
# Treat all warnings as errors
|
||||||
if(CPPDAP_WARNINGS_AS_ERRORS)
|
if(CPPDAP_WARNINGS_AS_ERRORS)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
@ -151,9 +176,7 @@ endfunction(cppdap_set_target_options)
|
|||||||
|
|
||||||
# dap
|
# dap
|
||||||
add_library(cppdap STATIC ${CPPDAP_LIST})
|
add_library(cppdap STATIC ${CPPDAP_LIST})
|
||||||
set_target_properties(cppdap PROPERTIES
|
set_target_properties(cppdap PROPERTIES POSITION_INDEPENDENT_CODE 1)
|
||||||
POSITION_INDEPENDENT_CODE 1
|
|
||||||
)
|
|
||||||
|
|
||||||
target_include_directories(cppdap PRIVATE "${CPPDAP_JSON_DIR}/include/")
|
target_include_directories(cppdap PRIVATE "${CPPDAP_JSON_DIR}/include/")
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ class File : public dap::ReaderWriter {
|
|||||||
const bool closable;
|
const bool closable;
|
||||||
std::mutex readMutex;
|
std::mutex readMutex;
|
||||||
std::mutex writeMutex;
|
std::mutex writeMutex;
|
||||||
std::atomic<bool> closed = { false };
|
std::atomic<bool> closed = {false};
|
||||||
};
|
};
|
||||||
|
|
||||||
class ReaderSpy : public dap::Reader {
|
class ReaderSpy : public dap::Reader {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2019 Google LLC
|
// Copyright 2020 Google LLC
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@ -15,117 +15,26 @@
|
|||||||
#ifndef dap_json_serializer_h
|
#ifndef dap_json_serializer_h
|
||||||
#define dap_json_serializer_h
|
#define dap_json_serializer_h
|
||||||
|
|
||||||
#include "dap/protocol.h"
|
#if defined(CPPDAP_JSON_NLOHMANN)
|
||||||
#include "dap/serialization.h"
|
#include "nlohmann_json_serializer.h"
|
||||||
#include "dap/types.h"
|
#elif defined(CPPDAP_JSON_RAPID)
|
||||||
|
#include "rapid_json_serializer.h"
|
||||||
#include <nlohmann/json_fwd.hpp>
|
#else
|
||||||
|
#error "Unrecognised cppdap JSON library"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace dap {
|
namespace dap {
|
||||||
namespace json {
|
namespace json {
|
||||||
|
|
||||||
struct Deserializer : public dap::Deserializer {
|
#if defined(CPPDAP_JSON_NLOHMANN)
|
||||||
explicit Deserializer(const std::string&);
|
using Deserializer = NlohmannDeserializer;
|
||||||
~Deserializer();
|
using Serializer = NlohmannSerializer;
|
||||||
|
#elif defined(CPPDAP_JSON_RAPID)
|
||||||
// dap::Deserializer compliance
|
using Deserializer = RapidDeserializer;
|
||||||
bool deserialize(boolean* v) const override;
|
using Serializer = RapidSerializer;
|
||||||
bool deserialize(integer* v) const override;
|
#else
|
||||||
bool deserialize(number* v) const override;
|
#error "Unrecognised cppdap JSON library"
|
||||||
bool deserialize(string* v) const override;
|
#endif
|
||||||
bool deserialize(object* v) const override;
|
|
||||||
bool deserialize(any* v) const override;
|
|
||||||
size_t count() const override;
|
|
||||||
bool array(const std::function<bool(dap::Deserializer*)>&) const override;
|
|
||||||
bool field(const std::string& name,
|
|
||||||
const std::function<bool(dap::Deserializer*)>&) const override;
|
|
||||||
|
|
||||||
// Unhide base overloads
|
|
||||||
template <typename T>
|
|
||||||
inline bool field(const std::string& name, T* v) {
|
|
||||||
return dap::Deserializer::field(name, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T,
|
|
||||||
typename = std::enable_if<TypeOf<T>::has_custom_serialization>>
|
|
||||||
inline bool deserialize(T* v) const {
|
|
||||||
return dap::Deserializer::deserialize(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool deserialize(dap::array<T>* v) const {
|
|
||||||
return dap::Deserializer::deserialize(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool deserialize(dap::optional<T>* v) const {
|
|
||||||
return dap::Deserializer::deserialize(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T0, typename... Types>
|
|
||||||
inline bool deserialize(dap::variant<T0, Types...>* v) const {
|
|
||||||
return dap::Deserializer::deserialize(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool field(const std::string& name, T* v) const {
|
|
||||||
return dap::Deserializer::deserialize(name, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Deserializer(const nlohmann::json*);
|
|
||||||
const nlohmann::json* const json;
|
|
||||||
const bool ownsJson;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Serializer : public dap::Serializer {
|
|
||||||
Serializer();
|
|
||||||
~Serializer();
|
|
||||||
|
|
||||||
std::string dump() const;
|
|
||||||
|
|
||||||
// dap::Serializer compliance
|
|
||||||
bool serialize(boolean v) override;
|
|
||||||
bool serialize(integer v) override;
|
|
||||||
bool serialize(number v) override;
|
|
||||||
bool serialize(const string& v) override;
|
|
||||||
bool serialize(const dap::object& v) override;
|
|
||||||
bool serialize(const any& v) override;
|
|
||||||
bool array(size_t count,
|
|
||||||
const std::function<bool(dap::Serializer*)>&) override;
|
|
||||||
bool object(const std::function<bool(dap::FieldSerializer*)>&) override;
|
|
||||||
void remove() override;
|
|
||||||
|
|
||||||
// Unhide base overloads
|
|
||||||
template <typename T,
|
|
||||||
typename = std::enable_if<TypeOf<T>::has_custom_serialization>>
|
|
||||||
inline bool serialize(const T& v) {
|
|
||||||
return dap::Serializer::serialize(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool serialize(const dap::array<T>& v) {
|
|
||||||
return dap::Serializer::serialize(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline bool serialize(const dap::optional<T>& v) {
|
|
||||||
return dap::Serializer::serialize(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T0, typename... Types>
|
|
||||||
inline bool serialize(const dap::variant<T0, Types...>& v) {
|
|
||||||
return dap::Serializer::serialize(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool serialize(const char* v) { return dap::Serializer::serialize(v); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Serializer(nlohmann::json*);
|
|
||||||
nlohmann::json* const json;
|
|
||||||
const bool ownsJson;
|
|
||||||
bool removed = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace json
|
} // namespace json
|
||||||
} // namespace dap
|
} // namespace dap
|
||||||
|
@ -12,55 +12,32 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "json_serializer.h"
|
#include "nlohmann_json_serializer.h"
|
||||||
|
|
||||||
|
#include "null_json_serializer.h"
|
||||||
|
|
||||||
// Disable JSON exceptions. We should be guarding against any exceptions being
|
// Disable JSON exceptions. We should be guarding against any exceptions being
|
||||||
// fired in this file.
|
// fired in this file.
|
||||||
#define JSON_NOEXCEPTION 1
|
#define JSON_NOEXCEPTION 1
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
struct NullDeserializer : public dap::Deserializer {
|
|
||||||
static NullDeserializer instance;
|
|
||||||
|
|
||||||
bool deserialize(dap::boolean*) const override { return false; }
|
|
||||||
bool deserialize(dap::integer*) const override { return false; }
|
|
||||||
bool deserialize(dap::number*) const override { return false; }
|
|
||||||
bool deserialize(dap::string*) const override { return false; }
|
|
||||||
bool deserialize(dap::object*) const override { return false; }
|
|
||||||
bool deserialize(dap::any*) const override { return false; }
|
|
||||||
size_t count() const override { return 0; }
|
|
||||||
bool array(const std::function<bool(dap::Deserializer*)>&) const override {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool field(const std::string&,
|
|
||||||
const std::function<bool(dap::Deserializer*)>&) const override {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NullDeserializer NullDeserializer::instance;
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
namespace dap {
|
namespace dap {
|
||||||
namespace json {
|
namespace json {
|
||||||
|
|
||||||
Deserializer::Deserializer(const std::string& str)
|
NlohmannDeserializer::NlohmannDeserializer(const std::string& str)
|
||||||
: json(new nlohmann::json(nlohmann::json::parse(str, nullptr, false))),
|
: json(new nlohmann::json(nlohmann::json::parse(str, nullptr, false))),
|
||||||
ownsJson(true) {}
|
ownsJson(true) {}
|
||||||
|
|
||||||
Deserializer::Deserializer(const nlohmann::json* json)
|
NlohmannDeserializer::NlohmannDeserializer(const nlohmann::json* json)
|
||||||
: json(json), ownsJson(false) {}
|
: json(json), ownsJson(false) {}
|
||||||
|
|
||||||
Deserializer::~Deserializer() {
|
NlohmannDeserializer::~NlohmannDeserializer() {
|
||||||
if (ownsJson) {
|
if (ownsJson) {
|
||||||
delete json;
|
delete json;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Deserializer::deserialize(dap::boolean* v) const {
|
bool NlohmannDeserializer::deserialize(dap::boolean* v) const {
|
||||||
if (!json->is_boolean()) {
|
if (!json->is_boolean()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -68,7 +45,7 @@ bool Deserializer::deserialize(dap::boolean* v) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Deserializer::deserialize(dap::integer* v) const {
|
bool NlohmannDeserializer::deserialize(dap::integer* v) const {
|
||||||
if (!json->is_number_integer()) {
|
if (!json->is_number_integer()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -76,7 +53,7 @@ bool Deserializer::deserialize(dap::integer* v) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Deserializer::deserialize(dap::number* v) const {
|
bool NlohmannDeserializer::deserialize(dap::number* v) const {
|
||||||
if (!json->is_number()) {
|
if (!json->is_number()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -84,7 +61,7 @@ bool Deserializer::deserialize(dap::number* v) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Deserializer::deserialize(dap::string* v) const {
|
bool NlohmannDeserializer::deserialize(dap::string* v) const {
|
||||||
if (!json->is_string()) {
|
if (!json->is_string()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -92,10 +69,10 @@ bool Deserializer::deserialize(dap::string* v) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Deserializer::deserialize(dap::object* v) const {
|
bool NlohmannDeserializer::deserialize(dap::object* v) const {
|
||||||
v->reserve(json->size());
|
v->reserve(json->size());
|
||||||
for (auto& el : json->items()) {
|
for (auto& el : json->items()) {
|
||||||
Deserializer d(&el.value());
|
NlohmannDeserializer d(&el.value());
|
||||||
dap::any val;
|
dap::any val;
|
||||||
if (!d.deserialize(&val)) {
|
if (!d.deserialize(&val)) {
|
||||||
return false;
|
return false;
|
||||||
@ -105,7 +82,7 @@ bool Deserializer::deserialize(dap::object* v) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Deserializer::deserialize(dap::any* v) const {
|
bool NlohmannDeserializer::deserialize(dap::any* v) const {
|
||||||
if (json->is_boolean()) {
|
if (json->is_boolean()) {
|
||||||
*v = dap::boolean(json->get<bool>());
|
*v = dap::boolean(json->get<bool>());
|
||||||
} else if (json->is_number_float()) {
|
} else if (json->is_number_float()) {
|
||||||
@ -122,17 +99,17 @@ bool Deserializer::deserialize(dap::any* v) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Deserializer::count() const {
|
size_t NlohmannDeserializer::count() const {
|
||||||
return json->size();
|
return json->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Deserializer::array(
|
bool NlohmannDeserializer::array(
|
||||||
const std::function<bool(dap::Deserializer*)>& cb) const {
|
const std::function<bool(dap::Deserializer*)>& cb) const {
|
||||||
if (!json->is_array()) {
|
if (!json->is_array()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < json->size(); i++) {
|
for (size_t i = 0; i < json->size(); i++) {
|
||||||
Deserializer d(&(*json)[i]);
|
NlohmannDeserializer d(&(*json)[i]);
|
||||||
if (!cb(&d)) {
|
if (!cb(&d)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -140,7 +117,7 @@ bool Deserializer::array(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Deserializer::field(
|
bool NlohmannDeserializer::field(
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::function<bool(dap::Deserializer*)>& cb) const {
|
const std::function<bool(dap::Deserializer*)>& cb) const {
|
||||||
if (!json->is_structured()) {
|
if (!json->is_structured()) {
|
||||||
@ -151,47 +128,49 @@ bool Deserializer::field(
|
|||||||
return cb(&NullDeserializer::instance);
|
return cb(&NullDeserializer::instance);
|
||||||
}
|
}
|
||||||
auto obj = *it;
|
auto obj = *it;
|
||||||
Deserializer d(&obj);
|
NlohmannDeserializer d(&obj);
|
||||||
return cb(&d);
|
return cb(&d);
|
||||||
}
|
}
|
||||||
|
|
||||||
Serializer::Serializer() : json(new nlohmann::json()), ownsJson(true) {}
|
NlohmannSerializer::NlohmannSerializer()
|
||||||
|
: json(new nlohmann::json()), ownsJson(true) {}
|
||||||
|
|
||||||
Serializer::Serializer(nlohmann::json* json) : json(json), ownsJson(false) {}
|
NlohmannSerializer::NlohmannSerializer(nlohmann::json* json)
|
||||||
|
: json(json), ownsJson(false) {}
|
||||||
|
|
||||||
Serializer::~Serializer() {
|
NlohmannSerializer::~NlohmannSerializer() {
|
||||||
if (ownsJson) {
|
if (ownsJson) {
|
||||||
delete json;
|
delete json;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Serializer::dump() const {
|
std::string NlohmannSerializer::dump() const {
|
||||||
return json->dump();
|
return json->dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Serializer::serialize(dap::boolean v) {
|
bool NlohmannSerializer::serialize(dap::boolean v) {
|
||||||
*json = (bool)v;
|
*json = (bool)v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Serializer::serialize(dap::integer v) {
|
bool NlohmannSerializer::serialize(dap::integer v) {
|
||||||
*json = (int)v;
|
*json = (int)v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Serializer::serialize(dap::number v) {
|
bool NlohmannSerializer::serialize(dap::number v) {
|
||||||
*json = (double)v;
|
*json = (double)v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Serializer::serialize(const dap::string& v) {
|
bool NlohmannSerializer::serialize(const dap::string& v) {
|
||||||
*json = v;
|
*json = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Serializer::serialize(const dap::object& v) {
|
bool NlohmannSerializer::serialize(const dap::object& v) {
|
||||||
for (auto& it : v) {
|
for (auto& it : v) {
|
||||||
Serializer s(&(*json)[it.first]);
|
NlohmannSerializer s(&(*json)[it.first]);
|
||||||
if (!s.serialize(it.second)) {
|
if (!s.serialize(it.second)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -199,7 +178,7 @@ bool Serializer::serialize(const dap::object& v) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Serializer::serialize(const dap::any& v) {
|
bool NlohmannSerializer::serialize(const dap::any& v) {
|
||||||
if (v.is<dap::boolean>()) {
|
if (v.is<dap::boolean>()) {
|
||||||
*json = (bool)v.get<dap::boolean>();
|
*json = (bool)v.get<dap::boolean>();
|
||||||
} else if (v.is<dap::integer>()) {
|
} else if (v.is<dap::integer>()) {
|
||||||
@ -216,11 +195,12 @@ bool Serializer::serialize(const dap::any& v) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Serializer::array(size_t count,
|
bool NlohmannSerializer::array(
|
||||||
const std::function<bool(dap::Serializer*)>& cb) {
|
size_t count,
|
||||||
|
const std::function<bool(dap::Serializer*)>& cb) {
|
||||||
*json = std::vector<int>();
|
*json = std::vector<int>();
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
Serializer s(&(*json)[i]);
|
NlohmannSerializer s(&(*json)[i]);
|
||||||
if (!cb(&s)) {
|
if (!cb(&s)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -228,13 +208,14 @@ bool Serializer::array(size_t count,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Serializer::object(const std::function<bool(dap::FieldSerializer*)>& cb) {
|
bool NlohmannSerializer::object(
|
||||||
|
const std::function<bool(dap::FieldSerializer*)>& cb) {
|
||||||
struct FS : public FieldSerializer {
|
struct FS : public FieldSerializer {
|
||||||
nlohmann::json* const json;
|
nlohmann::json* const json;
|
||||||
|
|
||||||
FS(nlohmann::json* json) : json(json) {}
|
FS(nlohmann::json* json) : json(json) {}
|
||||||
bool field(const std::string& name, const SerializeFunc& cb) override {
|
bool field(const std::string& name, const SerializeFunc& cb) override {
|
||||||
Serializer s(&(*json)[name]);
|
NlohmannSerializer s(&(*json)[name]);
|
||||||
auto res = cb(&s);
|
auto res = cb(&s);
|
||||||
if (s.removed) {
|
if (s.removed) {
|
||||||
json->erase(name);
|
json->erase(name);
|
||||||
@ -248,7 +229,7 @@ bool Serializer::object(const std::function<bool(dap::FieldSerializer*)>& cb) {
|
|||||||
return cb(&fs);
|
return cb(&fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Serializer::remove() {
|
void NlohmannSerializer::remove() {
|
||||||
removed = true;
|
removed = true;
|
||||||
}
|
}
|
||||||
|
|
133
src/nlohmann_json_serializer.h
Normal file
133
src/nlohmann_json_serializer.h
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#ifndef dap_nlohmann_json_serializer_h
|
||||||
|
#define dap_nlohmann_json_serializer_h
|
||||||
|
|
||||||
|
#include "dap/protocol.h"
|
||||||
|
#include "dap/serialization.h"
|
||||||
|
#include "dap/types.h"
|
||||||
|
|
||||||
|
#include <nlohmann/json_fwd.hpp>
|
||||||
|
|
||||||
|
namespace dap {
|
||||||
|
namespace json {
|
||||||
|
|
||||||
|
struct NlohmannDeserializer : public dap::Deserializer {
|
||||||
|
explicit NlohmannDeserializer(const std::string&);
|
||||||
|
~NlohmannDeserializer();
|
||||||
|
|
||||||
|
// dap::Deserializer compliance
|
||||||
|
bool deserialize(boolean* v) const override;
|
||||||
|
bool deserialize(integer* v) const override;
|
||||||
|
bool deserialize(number* v) const override;
|
||||||
|
bool deserialize(string* v) const override;
|
||||||
|
bool deserialize(object* v) const override;
|
||||||
|
bool deserialize(any* v) const override;
|
||||||
|
size_t count() const override;
|
||||||
|
bool array(const std::function<bool(dap::Deserializer*)>&) const override;
|
||||||
|
bool field(const std::string& name,
|
||||||
|
const std::function<bool(dap::Deserializer*)>&) const override;
|
||||||
|
|
||||||
|
// Unhide base overloads
|
||||||
|
template <typename T>
|
||||||
|
inline bool field(const std::string& name, T* v) {
|
||||||
|
return dap::Deserializer::field(name, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T,
|
||||||
|
typename = std::enable_if<TypeOf<T>::has_custom_serialization>>
|
||||||
|
inline bool deserialize(T* v) const {
|
||||||
|
return dap::Deserializer::deserialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool deserialize(dap::array<T>* v) const {
|
||||||
|
return dap::Deserializer::deserialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool deserialize(dap::optional<T>* v) const {
|
||||||
|
return dap::Deserializer::deserialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T0, typename... Types>
|
||||||
|
inline bool deserialize(dap::variant<T0, Types...>* v) const {
|
||||||
|
return dap::Deserializer::deserialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool field(const std::string& name, T* v) const {
|
||||||
|
return dap::Deserializer::deserialize(name, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
NlohmannDeserializer(const nlohmann::json*);
|
||||||
|
const nlohmann::json* const json;
|
||||||
|
const bool ownsJson;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NlohmannSerializer : public dap::Serializer {
|
||||||
|
NlohmannSerializer();
|
||||||
|
~NlohmannSerializer();
|
||||||
|
|
||||||
|
std::string dump() const;
|
||||||
|
|
||||||
|
// dap::Serializer compliance
|
||||||
|
bool serialize(boolean v) override;
|
||||||
|
bool serialize(integer v) override;
|
||||||
|
bool serialize(number v) override;
|
||||||
|
bool serialize(const string& v) override;
|
||||||
|
bool serialize(const dap::object& v) override;
|
||||||
|
bool serialize(const any& v) override;
|
||||||
|
bool array(size_t count,
|
||||||
|
const std::function<bool(dap::Serializer*)>&) override;
|
||||||
|
bool object(const std::function<bool(dap::FieldSerializer*)>&) override;
|
||||||
|
void remove() override;
|
||||||
|
|
||||||
|
// Unhide base overloads
|
||||||
|
template <typename T,
|
||||||
|
typename = std::enable_if<TypeOf<T>::has_custom_serialization>>
|
||||||
|
inline bool serialize(const T& v) {
|
||||||
|
return dap::Serializer::serialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool serialize(const dap::array<T>& v) {
|
||||||
|
return dap::Serializer::serialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool serialize(const dap::optional<T>& v) {
|
||||||
|
return dap::Serializer::serialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T0, typename... Types>
|
||||||
|
inline bool serialize(const dap::variant<T0, Types...>& v) {
|
||||||
|
return dap::Serializer::serialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool serialize(const char* v) { return dap::Serializer::serialize(v); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
NlohmannSerializer(nlohmann::json*);
|
||||||
|
nlohmann::json* const json;
|
||||||
|
const bool ownsJson;
|
||||||
|
bool removed = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace json
|
||||||
|
} // namespace dap
|
||||||
|
|
||||||
|
#endif // dap_nlohmann_json_serializer_h
|
23
src/null_json_serializer.cpp
Normal file
23
src/null_json_serializer.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2020 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 "null_json_serializer.h"
|
||||||
|
|
||||||
|
namespace dap {
|
||||||
|
namespace json {
|
||||||
|
|
||||||
|
NullDeserializer NullDeserializer::instance;
|
||||||
|
|
||||||
|
} // namespace json
|
||||||
|
} // namespace dap
|
47
src/null_json_serializer.h
Normal file
47
src/null_json_serializer.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2020 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.
|
||||||
|
|
||||||
|
#ifndef dap_null_json_serializer_h
|
||||||
|
#define dap_null_json_serializer_h
|
||||||
|
|
||||||
|
#include "dap/protocol.h"
|
||||||
|
#include "dap/serialization.h"
|
||||||
|
#include "dap/types.h"
|
||||||
|
|
||||||
|
namespace dap {
|
||||||
|
namespace json {
|
||||||
|
|
||||||
|
struct NullDeserializer : public dap::Deserializer {
|
||||||
|
static NullDeserializer instance;
|
||||||
|
|
||||||
|
bool deserialize(dap::boolean*) const override { return false; }
|
||||||
|
bool deserialize(dap::integer*) const override { return false; }
|
||||||
|
bool deserialize(dap::number*) const override { return false; }
|
||||||
|
bool deserialize(dap::string*) const override { return false; }
|
||||||
|
bool deserialize(dap::object*) const override { return false; }
|
||||||
|
bool deserialize(dap::any*) const override { return false; }
|
||||||
|
size_t count() const override { return 0; }
|
||||||
|
bool array(const std::function<bool(dap::Deserializer*)>&) const override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool field(const std::string&,
|
||||||
|
const std::function<bool(dap::Deserializer*)>&) const override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace json
|
||||||
|
} // namespace dap
|
||||||
|
|
||||||
|
#endif // dap_null_json_serializer_h
|
259
src/rapid_json_serializer.cpp
Normal file
259
src/rapid_json_serializer.cpp
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
// 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()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*v = json()->GetInt();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 val;
|
||||||
|
RapidDeserializer d(&(el->value));
|
||||||
|
if (!d.deserialize(&val)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
(*v)[el->name.GetString()] = 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 {
|
||||||
|
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()->SetInt((int)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::null>()) {
|
||||||
|
} else {
|
||||||
|
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
|
138
src/rapid_json_serializer.h
Normal file
138
src/rapid_json_serializer.h
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#ifndef dap_rapid_json_serializer_h
|
||||||
|
#define dap_rapid_json_serializer_h
|
||||||
|
|
||||||
|
#include "dap/protocol.h"
|
||||||
|
#include "dap/serialization.h"
|
||||||
|
#include "dap/types.h"
|
||||||
|
|
||||||
|
#include <rapidjson/document.h>
|
||||||
|
|
||||||
|
namespace dap {
|
||||||
|
namespace json {
|
||||||
|
|
||||||
|
struct RapidDeserializer : public dap::Deserializer {
|
||||||
|
explicit RapidDeserializer(const std::string&);
|
||||||
|
~RapidDeserializer();
|
||||||
|
|
||||||
|
// dap::Deserializer compliance
|
||||||
|
bool deserialize(boolean* v) const override;
|
||||||
|
bool deserialize(integer* v) const override;
|
||||||
|
bool deserialize(number* v) const override;
|
||||||
|
bool deserialize(string* v) const override;
|
||||||
|
bool deserialize(object* v) const override;
|
||||||
|
bool deserialize(any* v) const override;
|
||||||
|
size_t count() const override;
|
||||||
|
bool array(const std::function<bool(dap::Deserializer*)>&) const override;
|
||||||
|
bool field(const std::string& name,
|
||||||
|
const std::function<bool(dap::Deserializer*)>&) const override;
|
||||||
|
|
||||||
|
// Unhide base overloads
|
||||||
|
template <typename T>
|
||||||
|
inline bool field(const std::string& name, T* v) {
|
||||||
|
return dap::Deserializer::field(name, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T,
|
||||||
|
typename = std::enable_if<TypeOf<T>::has_custom_serialization>>
|
||||||
|
inline bool deserialize(T* v) const {
|
||||||
|
return dap::Deserializer::deserialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool deserialize(dap::array<T>* v) const {
|
||||||
|
return dap::Deserializer::deserialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool deserialize(dap::optional<T>* v) const {
|
||||||
|
return dap::Deserializer::deserialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T0, typename... Types>
|
||||||
|
inline bool deserialize(dap::variant<T0, Types...>* v) const {
|
||||||
|
return dap::Deserializer::deserialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool field(const std::string& name, T* v) const {
|
||||||
|
return dap::Deserializer::deserialize(name, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline rapidjson::Value* json() const { return (val == nullptr) ? doc : val; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
RapidDeserializer(rapidjson::Value*);
|
||||||
|
rapidjson::Document* const doc = nullptr;
|
||||||
|
rapidjson::Value* const val = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RapidSerializer : public dap::Serializer {
|
||||||
|
RapidSerializer();
|
||||||
|
~RapidSerializer();
|
||||||
|
|
||||||
|
std::string dump() const;
|
||||||
|
|
||||||
|
// dap::Serializer compliance
|
||||||
|
bool serialize(boolean v) override;
|
||||||
|
bool serialize(integer v) override;
|
||||||
|
bool serialize(number v) override;
|
||||||
|
bool serialize(const string& v) override;
|
||||||
|
bool serialize(const dap::object& v) override;
|
||||||
|
bool serialize(const any& v) override;
|
||||||
|
bool array(size_t count,
|
||||||
|
const std::function<bool(dap::Serializer*)>&) override;
|
||||||
|
bool object(const std::function<bool(dap::FieldSerializer*)>&) override;
|
||||||
|
void remove() override;
|
||||||
|
|
||||||
|
// Unhide base overloads
|
||||||
|
template <typename T,
|
||||||
|
typename = std::enable_if<TypeOf<T>::has_custom_serialization>>
|
||||||
|
inline bool serialize(const T& v) {
|
||||||
|
return dap::Serializer::serialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool serialize(const dap::array<T>& v) {
|
||||||
|
return dap::Serializer::serialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool serialize(const dap::optional<T>& v) {
|
||||||
|
return dap::Serializer::serialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T0, typename... Types>
|
||||||
|
inline bool serialize(const dap::variant<T0, Types...>& v) {
|
||||||
|
return dap::Serializer::serialize(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool serialize(const char* v) { return dap::Serializer::serialize(v); }
|
||||||
|
|
||||||
|
inline rapidjson::Value* json() const { return (val == nullptr) ? doc : val; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
RapidSerializer(rapidjson::Value*, rapidjson::Document::AllocatorType&);
|
||||||
|
rapidjson::Document* const doc = nullptr;
|
||||||
|
rapidjson::Value* const val = nullptr;
|
||||||
|
rapidjson::Document::AllocatorType& allocator;
|
||||||
|
bool removed = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace json
|
||||||
|
} // namespace dap
|
||||||
|
|
||||||
|
#endif // dap_rapid_json_serializer_h
|
@ -302,7 +302,7 @@ std::shared_ptr<ReaderWriter> Socket::connect(const char* address,
|
|||||||
|
|
||||||
timeval tv;
|
timeval tv;
|
||||||
tv.tv_sec = microseconds / 1000000;
|
tv.tv_sec = microseconds / 1000000;
|
||||||
tv.tv_usec = microseconds - (tv.tv_sec * 1000000);
|
tv.tv_usec = microseconds - static_cast<uint32_t>(tv.tv_sec * 1000000);
|
||||||
res = select(static_cast<int>(socket + 1), nullptr, &fdset, nullptr, &tv);
|
res = select(static_cast<int>(socket + 1), nullptr, &fdset, nullptr, &tv);
|
||||||
if (res > 0 && !errored(socket) && setBlocking(socket, true)) {
|
if (res > 0 && !errored(socket) && setBlocking(socket, true)) {
|
||||||
out = shared;
|
out = shared;
|
||||||
|
@ -130,7 +130,7 @@ const TypeInfo* TypeOf<null>::type() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TypeInfo::deleteOnExit(TypeInfo* ti) {
|
void TypeInfo::deleteOnExit(TypeInfo* ti) {
|
||||||
return TypeInfos::get()->types.emplace_back(std::unique_ptr<TypeInfo>(ti));
|
TypeInfos::get()->types.emplace_back(std::unique_ptr<TypeInfo>(ti));
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize() {
|
void initialize() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user