/workspaces/astro/sol3-sdk/cpp/sol3/core/fb_json.h Source File

Space-ng SDK: /workspaces/astro/sol3-sdk/cpp/sol3/core/fb_json.h Source File
Space-ng SDK
fb_json.h
Go to the documentation of this file.
1 // Copyright (c) Space-ng, inc. All rights reserved.
2 
3 #pragma once
4 
5 #include "sol3/cpp/filesystem.h"
6 
7 #include <flatbuffers/base.h>
8 #include <flatbuffers/idl.h>
9 #include <fmt/format.h>
10 
11 #include <fstream>
12 namespace sol3::core {
13 
14 enum class JsonFormat { SINGLE_LINE = 0, MULTI_LINE = 1 };
15 
16 void toJson(
17  flatbuffers::Parser const& parser,
18  uint8_t const* buffer,
19  std::string& out_json);
20 std::string toJson(flatbuffers::Parser const& parser, uint8_t const* buffer);
21 flatbuffers::span<uint8_t const> bufferSpanFromJson(
22  flatbuffers::Parser& parser, std::string const& json_str);
23 
24 template <typename TMessage>
25 flatbuffers::Parser deserializeReflectionParser() {
26  flatbuffers::Parser parser;
27  parser.opts.strict_json = true;
28  parser.opts.skip_unexpected_fields_in_json = false;
29  parser.opts.output_default_scalars_in_json = true;
30  parser.opts.indent_step = -1;
31  parser.opts.size_prefixed = true;
32  flatbuffers::span<uint8_t const> schema_data =
33  TMessage::NativeTableType::GetSchemaData();
34  parser.Deserialize(schema_data.data(), schema_data.size());
35  return parser;
36 }
37 
38 template <typename TMessage>
39 flatbuffers::Parser& reflectionParser(
41  // thread local parser, populated with schema data, once per thread.
42  // thread local so we can change single line to multi_line without being
43  // surprised when emitting json from multiple threads.
44  thread_local static flatbuffers::Parser s_parser =
45  deserializeReflectionParser<TMessage>();
46  if (format == JsonFormat::MULTI_LINE) {
47  s_parser.opts.indent_step = 2;
48  } else {
49  s_parser.opts.indent_step = -1;
50  }
51  return s_parser;
52 }
53 
54 template <typename TMessage>
55 void toJson(
56  uint8_t const* buffer,
57  std::string& out_json,
59  toJson(reflectionParser<TMessage>(format), buffer, out_json);
60 }
61 
62 template <typename TMessage>
63 std::string toJson(
64  uint8_t const* buffer, JsonFormat format = JsonFormat::SINGLE_LINE) {
65  return toJson(reflectionParser<TMessage>(format), buffer);
66 }
67 
68 template <typename TMessage>
69 void toJson(
70  TMessage const* table,
71  std::string& out_json,
73  out_json.clear();
74  char const* error_str = flatbuffers::GenTextFromTable(
75  reflectionParser<TMessage>(format),
76  table,
77  TMessage::GetFullyQualifiedName(),
78  &out_json);
79  if (error_str != nullptr) {
80  out_json.clear();
81  throw std::runtime_error(error_str);
82  }
83 }
84 
85 template <typename TMessage>
86 std::string toJson(
87  TMessage const* table, JsonFormat format = JsonFormat::SINGLE_LINE) {
88  std::string out_json;
89  toJson<TMessage>(table, out_json, format);
90  return out_json;
91 }
92 
93 template <typename TMessageT>
94 void toJson(
95  TMessageT const& object,
96  std::string& out_json,
98  using TableType = typename TMessageT::TableType;
99  flatbuffers::FlatBufferBuilder builder;
100  builder.FinishSizePrefixed(TableType::Pack(builder, &object));
101  toJson(
102  reflectionParser<TableType>(format),
103  builder.GetBufferPointer(),
104  out_json);
105 }
106 
107 template <typename TMessageT>
108 std::string toJson(
109  TMessageT const& object, JsonFormat format = JsonFormat::SINGLE_LINE) {
110  std::string out_json;
111  toJson<TMessageT>(object, out_json, format);
112  return out_json;
113 }
114 
118 template <typename TMessage>
119 TMessage const* fromJson(std::string const& json_str) {
120  auto span = bufferSpanFromJson(reflectionParser<TMessage>(), json_str);
121  return flatbuffers::GetSizePrefixedRoot<TMessage>(span.data());
122 }
123 
124 template <typename TMessageT>
125 void fromJson(std::string const& json_str, TMessageT& out_message) {
126  fromJson<typename TMessageT::TableType>(json_str)->UnPackTo(&out_message);
127 }
128 
129 namespace impl {
130 std::string loadJsonFile(cpp::fs::path const& json_path);
131 }
132 
133 template <typename TMessage>
134 TMessage const* fromJsonFile(cpp::fs::path const& json_path) {
135  try {
136  return fromJson<TMessage>(impl::loadJsonFile(json_path));
137  } catch (std::runtime_error const& e) {
138  throw std::runtime_error(
139  fmt::format("Failed to parse json file: {}\n{}", json_path, e.what()));
140  }
141 }
142 
143 template <typename TMessageT>
144 void fromJsonFile(cpp::fs::path const& json_path, TMessageT& out_message) {
145  fromJsonFile<typename TMessageT::TableType>(json_path)->UnPackTo(
146  &out_message);
147 }
148 
149 template <typename TMessageT>
151  cpp::fs::path const& json_path,
152  TMessageT const& message,
154  std::ofstream out_json(json_path);
155  out_json << toJson(message, format);
156 }
157 
158 template <typename TMessage>
160  cpp::fs::path const& json_path,
161  TMessage const* message,
163  std::ofstream out_json(json_path);
164  out_json << toJson(message, format);
165 }
166 
167 } // namespace sol3::core
std::string loadJsonFile(cpp::fs::path const &json_path)
Definition: any_message_input.h:15
flatbuffers::span< uint8_t const > bufferSpanFromJson(flatbuffers::Parser &parser, std::string const &json_str)
TMessage const * fromJson(std::string const &json_str)
Definition: fb_json.h:119
flatbuffers::Parser & reflectionParser(JsonFormat format=JsonFormat::SINGLE_LINE)
Definition: fb_json.h:39
void toJsonFile(cpp::fs::path const &json_path, TMessageT const &message, JsonFormat format=JsonFormat::SINGLE_LINE)
Definition: fb_json.h:150
TMessage const * fromJsonFile(cpp::fs::path const &json_path)
Definition: fb_json.h:134
void toJson(AnyMessageView const &view, std::string &out_json, JsonFormat format=JsonFormat::SINGLE_LINE)
flatbuffers::Parser deserializeReflectionParser()
Definition: fb_json.h:25
JsonFormat
Definition: fb_json.h:14