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(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
|
||||
###########################################################
|
||||
set(CPPDAP_LIST
|
||||
${CPPDAP_SRC_DIR}/content_stream.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}/null_json_serializer.cpp
|
||||
${CPPDAP_SRC_DIR}/protocol_events.cpp
|
||||
${CPPDAP_SRC_DIR}/protocol_requests.cpp
|
||||
${CPPDAP_SRC_DIR}/protocol_response.cpp
|
||||
@ -117,6 +137,11 @@ function(cppdap_set_target_options target)
|
||||
)
|
||||
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
|
||||
if(CPPDAP_WARNINGS_AS_ERRORS)
|
||||
if(MSVC)
|
||||
@ -151,9 +176,7 @@ endfunction(cppdap_set_target_options)
|
||||
|
||||
# dap
|
||||
add_library(cppdap STATIC ${CPPDAP_LIST})
|
||||
set_target_properties(cppdap PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE 1
|
||||
)
|
||||
set_target_properties(cppdap PROPERTIES POSITION_INDEPENDENT_CODE 1)
|
||||
|
||||
target_include_directories(cppdap PRIVATE "${CPPDAP_JSON_DIR}/include/")
|
||||
|
||||
|
@ -87,4 +87,4 @@ void Chan<T>::put(const T& in) {
|
||||
|
||||
} // namespace dap
|
||||
|
||||
#endif // dap_chan_h
|
||||
#endif // dap_chan_h
|
||||
|
@ -145,7 +145,7 @@ class File : public dap::ReaderWriter {
|
||||
const bool closable;
|
||||
std::mutex readMutex;
|
||||
std::mutex writeMutex;
|
||||
std::atomic<bool> closed = { false };
|
||||
std::atomic<bool> closed = {false};
|
||||
};
|
||||
|
||||
class ReaderSpy : public dap::Reader {
|
||||
@ -254,4 +254,4 @@ bool writef(const std::shared_ptr<Writer>& w, const char* msg, ...) {
|
||||
return w->write(buf, strlen(buf));
|
||||
}
|
||||
|
||||
} // namespace dap
|
||||
} // namespace dap
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2019 Google LLC
|
||||
// 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.
|
||||
@ -15,119 +15,28 @@
|
||||
#ifndef dap_json_serializer_h
|
||||
#define dap_json_serializer_h
|
||||
|
||||
#include "dap/protocol.h"
|
||||
#include "dap/serialization.h"
|
||||
#include "dap/types.h"
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#if defined(CPPDAP_JSON_NLOHMANN)
|
||||
#include "nlohmann_json_serializer.h"
|
||||
#elif defined(CPPDAP_JSON_RAPID)
|
||||
#include "rapid_json_serializer.h"
|
||||
#else
|
||||
#error "Unrecognised cppdap JSON library"
|
||||
#endif
|
||||
|
||||
namespace dap {
|
||||
namespace json {
|
||||
|
||||
struct Deserializer : public dap::Deserializer {
|
||||
explicit Deserializer(const std::string&);
|
||||
~Deserializer();
|
||||
|
||||
// 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:
|
||||
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;
|
||||
};
|
||||
#if defined(CPPDAP_JSON_NLOHMANN)
|
||||
using Deserializer = NlohmannDeserializer;
|
||||
using Serializer = NlohmannSerializer;
|
||||
#elif defined(CPPDAP_JSON_RAPID)
|
||||
using Deserializer = RapidDeserializer;
|
||||
using Serializer = RapidSerializer;
|
||||
#else
|
||||
#error "Unrecognised cppdap JSON library"
|
||||
#endif
|
||||
|
||||
} // namespace json
|
||||
} // namespace dap
|
||||
|
||||
#endif // dap_json_serializer_h
|
||||
#endif // dap_json_serializer_h
|
||||
|
@ -12,55 +12,32 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// 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
|
||||
// fired in this file.
|
||||
#define JSON_NOEXCEPTION 1
|
||||
#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 json {
|
||||
|
||||
Deserializer::Deserializer(const std::string& str)
|
||||
NlohmannDeserializer::NlohmannDeserializer(const std::string& str)
|
||||
: json(new nlohmann::json(nlohmann::json::parse(str, nullptr, false))),
|
||||
ownsJson(true) {}
|
||||
|
||||
Deserializer::Deserializer(const nlohmann::json* json)
|
||||
NlohmannDeserializer::NlohmannDeserializer(const nlohmann::json* json)
|
||||
: json(json), ownsJson(false) {}
|
||||
|
||||
Deserializer::~Deserializer() {
|
||||
NlohmannDeserializer::~NlohmannDeserializer() {
|
||||
if (ownsJson) {
|
||||
delete json;
|
||||
}
|
||||
}
|
||||
|
||||
bool Deserializer::deserialize(dap::boolean* v) const {
|
||||
bool NlohmannDeserializer::deserialize(dap::boolean* v) const {
|
||||
if (!json->is_boolean()) {
|
||||
return false;
|
||||
}
|
||||
@ -68,7 +45,7 @@ bool Deserializer::deserialize(dap::boolean* v) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Deserializer::deserialize(dap::integer* v) const {
|
||||
bool NlohmannDeserializer::deserialize(dap::integer* v) const {
|
||||
if (!json->is_number_integer()) {
|
||||
return false;
|
||||
}
|
||||
@ -76,7 +53,7 @@ bool Deserializer::deserialize(dap::integer* v) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Deserializer::deserialize(dap::number* v) const {
|
||||
bool NlohmannDeserializer::deserialize(dap::number* v) const {
|
||||
if (!json->is_number()) {
|
||||
return false;
|
||||
}
|
||||
@ -84,7 +61,7 @@ bool Deserializer::deserialize(dap::number* v) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Deserializer::deserialize(dap::string* v) const {
|
||||
bool NlohmannDeserializer::deserialize(dap::string* v) const {
|
||||
if (!json->is_string()) {
|
||||
return false;
|
||||
}
|
||||
@ -92,10 +69,10 @@ bool Deserializer::deserialize(dap::string* v) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Deserializer::deserialize(dap::object* v) const {
|
||||
bool NlohmannDeserializer::deserialize(dap::object* v) const {
|
||||
v->reserve(json->size());
|
||||
for (auto& el : json->items()) {
|
||||
Deserializer d(&el.value());
|
||||
NlohmannDeserializer d(&el.value());
|
||||
dap::any val;
|
||||
if (!d.deserialize(&val)) {
|
||||
return false;
|
||||
@ -105,7 +82,7 @@ bool Deserializer::deserialize(dap::object* v) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Deserializer::deserialize(dap::any* v) const {
|
||||
bool NlohmannDeserializer::deserialize(dap::any* v) const {
|
||||
if (json->is_boolean()) {
|
||||
*v = dap::boolean(json->get<bool>());
|
||||
} else if (json->is_number_float()) {
|
||||
@ -122,17 +99,17 @@ bool Deserializer::deserialize(dap::any* v) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t Deserializer::count() const {
|
||||
size_t NlohmannDeserializer::count() const {
|
||||
return json->size();
|
||||
}
|
||||
|
||||
bool Deserializer::array(
|
||||
bool NlohmannDeserializer::array(
|
||||
const std::function<bool(dap::Deserializer*)>& cb) const {
|
||||
if (!json->is_array()) {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < json->size(); i++) {
|
||||
Deserializer d(&(*json)[i]);
|
||||
NlohmannDeserializer d(&(*json)[i]);
|
||||
if (!cb(&d)) {
|
||||
return false;
|
||||
}
|
||||
@ -140,7 +117,7 @@ bool Deserializer::array(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Deserializer::field(
|
||||
bool NlohmannDeserializer::field(
|
||||
const std::string& name,
|
||||
const std::function<bool(dap::Deserializer*)>& cb) const {
|
||||
if (!json->is_structured()) {
|
||||
@ -151,47 +128,49 @@ bool Deserializer::field(
|
||||
return cb(&NullDeserializer::instance);
|
||||
}
|
||||
auto obj = *it;
|
||||
Deserializer d(&obj);
|
||||
NlohmannDeserializer d(&obj);
|
||||
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) {
|
||||
delete json;
|
||||
}
|
||||
}
|
||||
|
||||
std::string Serializer::dump() const {
|
||||
std::string NlohmannSerializer::dump() const {
|
||||
return json->dump();
|
||||
}
|
||||
|
||||
bool Serializer::serialize(dap::boolean v) {
|
||||
bool NlohmannSerializer::serialize(dap::boolean v) {
|
||||
*json = (bool)v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serializer::serialize(dap::integer v) {
|
||||
bool NlohmannSerializer::serialize(dap::integer v) {
|
||||
*json = (int)v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serializer::serialize(dap::number v) {
|
||||
bool NlohmannSerializer::serialize(dap::number v) {
|
||||
*json = (double)v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serializer::serialize(const dap::string& v) {
|
||||
bool NlohmannSerializer::serialize(const dap::string& v) {
|
||||
*json = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serializer::serialize(const dap::object& v) {
|
||||
bool NlohmannSerializer::serialize(const dap::object& v) {
|
||||
for (auto& it : v) {
|
||||
Serializer s(&(*json)[it.first]);
|
||||
NlohmannSerializer s(&(*json)[it.first]);
|
||||
if (!s.serialize(it.second)) {
|
||||
return false;
|
||||
}
|
||||
@ -199,7 +178,7 @@ bool Serializer::serialize(const dap::object& v) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serializer::serialize(const dap::any& v) {
|
||||
bool NlohmannSerializer::serialize(const dap::any& v) {
|
||||
if (v.is<dap::boolean>()) {
|
||||
*json = (bool)v.get<dap::boolean>();
|
||||
} else if (v.is<dap::integer>()) {
|
||||
@ -216,11 +195,12 @@ bool Serializer::serialize(const dap::any& v) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Serializer::array(size_t count,
|
||||
const std::function<bool(dap::Serializer*)>& cb) {
|
||||
bool NlohmannSerializer::array(
|
||||
size_t count,
|
||||
const std::function<bool(dap::Serializer*)>& cb) {
|
||||
*json = std::vector<int>();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
Serializer s(&(*json)[i]);
|
||||
NlohmannSerializer s(&(*json)[i]);
|
||||
if (!cb(&s)) {
|
||||
return false;
|
||||
}
|
||||
@ -228,13 +208,14 @@ bool Serializer::array(size_t count,
|
||||
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 {
|
||||
nlohmann::json* const json;
|
||||
|
||||
FS(nlohmann::json* json) : json(json) {}
|
||||
bool field(const std::string& name, const SerializeFunc& cb) override {
|
||||
Serializer s(&(*json)[name]);
|
||||
NlohmannSerializer s(&(*json)[name]);
|
||||
auto res = cb(&s);
|
||||
if (s.removed) {
|
||||
json->erase(name);
|
||||
@ -248,7 +229,7 @@ bool Serializer::object(const std::function<bool(dap::FieldSerializer*)>& cb) {
|
||||
return cb(&fs);
|
||||
}
|
||||
|
||||
void Serializer::remove() {
|
||||
void NlohmannSerializer::remove() {
|
||||
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;
|
||||
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);
|
||||
if (res > 0 && !errored(socket) && setBlocking(socket, true)) {
|
||||
out = shared;
|
||||
|
@ -130,7 +130,7 @@ const TypeInfo* TypeOf<null>::type() {
|
||||
}
|
||||
|
||||
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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user