aboutsummaryrefslogtreecommitdiff
path: root/source/Common/RapidJsonHelper.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Common/RapidJsonHelper.hpp')
-rw-r--r--source/Common/RapidJsonHelper.hpp110
1 files changed, 110 insertions, 0 deletions
diff --git a/source/Common/RapidJsonHelper.hpp b/source/Common/RapidJsonHelper.hpp
new file mode 100644
index 0000000..75cd93a
--- /dev/null
+++ b/source/Common/RapidJsonHelper.hpp
@@ -0,0 +1,110 @@
+#pragma once
+
+#include <rapidjson/document.h>
+#include <cstring>
+#include <string>
+#include <string_view>
+
+#define BRUSSEL_JSON_GET(object, name, type, out, failAction) \
+ { \
+ auto it = (object).FindMember(name); \
+ if (it == (object).MemberEnd()) failAction; \
+ auto& value = it->value; \
+ if (!value.Is<type>()) failAction; \
+ (out) = value.Get<type>(); \
+ }
+
+#define BRUSSEL_JSON_GET_DEFAULT(object, name, type, out, theDefault) \
+ do { \
+ auto it = (object).FindMember(name); \
+ if (it == (object).MemberEnd()) { \
+ (out) = theDefault; \
+ break; \
+ } \
+ auto& value = it->value; \
+ if (!value.Is<type>()) { \
+ (out) = theDefault; \
+ break; \
+ } \
+ (out) = value.Get<type>(); \
+ } while (0);
+
+namespace rapidjson {
+
+inline const Value* GetProperty(const Value& value, std::string_view name) {
+ for (auto it = value.MemberBegin(); it != value.MemberEnd(); ++it) {
+ if (it->name.GetStringLength() != name.size()) continue;
+ if (std::memcmp(it->name.GetString(), name.data(), name.size())) continue;
+
+ return &it->value;
+ }
+ return nullptr;
+}
+
+inline const Value* GetProperty(const Value& value, Type type, std::string_view name) {
+ for (auto it = value.MemberBegin(); it != value.MemberEnd(); ++it) {
+ if (it->name.GetStringLength() != name.size()) continue;
+ if (it->value.GetType() != type) continue;
+ if (std::memcmp(it->name.GetString(), name.data(), name.size())) continue;
+
+ return &it->value;
+ }
+ return nullptr;
+}
+
+inline std::string_view AsStringView(const Value& value) {
+ return std::string_view(value.GetString(), value.GetStringLength());
+}
+
+inline std::string_view AsStringView(const GenericStringRef<char>& strRef) {
+ return std::string_view(strRef.s, strRef.length);
+}
+
+inline std::string AsString(const Value& value) {
+ return std::string(value.GetString(), value.GetStringLength());
+}
+
+inline std::string AsString(const GenericStringRef<char>& strRef) {
+ return std::string(strRef.s, strRef.length);
+}
+
+// RapidJson itself already provides std::string and const char* overloads
+inline GenericStringRef<char> StringRef(std::string_view str) {
+ return GenericStringRef<char>(
+ str.data() ? str.data() : "",
+ str.size());
+}
+
+template <class TIter, class TSentienl>
+rapidjson::Value WriteVectorPrimitives(rapidjson::Document& root, TIter begin, TSentienl end) {
+ using TElement = typename TIter::value_type;
+
+ rapidjson::Value list;
+ while (begin != end) {
+ if constexpr (std::is_same_v<TElement, std::string>) {
+ auto& elm = *begin;
+ list.PushBack(rapidjson::Value(elm.c_str(), elm.size()), root.GetAllocator());
+ } else {
+ list.PushBack(*begin, root.GetAllocator());
+ }
+ ++begin;
+ }
+ return list;
+}
+
+template <class TContainer>
+bool ReadVectorPrimitives(const rapidjson::Value& value, TContainer& list) {
+ using TElement = typename TContainer::value_type;
+
+ if (!value.IsArray()) return false;
+
+ list.reserve(value.Size());
+ for (auto& elm : value.GetArray()) {
+ if (!elm.Is<TElement>()) return {};
+ list.push_back(elm.Get<TElement>());
+ }
+
+ return true;
+}
+
+} // namespace rapidjson