6#include <bond/core/config.h>
8#include "rapidjson_utils.h"
10#include <bond/core/bond_const_enum.h>
11#include <bond/core/bond_types.h>
12#include <bond/core/detail/sdl.h>
13#include <bond/core/exception.h>
15#define RAPIDJSON_NO_INT64DEFINE
16#define RAPIDJSON_ASSERT BOOST_ASSERT
17#define RAPIDJSON_PARSE_ERROR(err, offset) bond::RapidJsonException(rapidjson::GetParseError_En(err), offset)
19#include "rapidjson/rapidjson.h"
20#include "rapidjson/error/en.h"
25#if defined(_WINDEF_) || defined(_MINWINDEF_)
27 #pragma push_macro("min")
28 #pragma push_macro("max")
35#include "rapidjson/document.h"
38#if defined(_WINDEF_) || defined(_MINWINDEF_)
40 #pragma pop_macro("min")
41 #pragma pop_macro("max")
46#include "rapidjson/writer.h"
48#include <boost/noncopyable.hpp>
59template <
typename Buffer>
60class RapidJsonInputStream
65 explicit RapidJsonInputStream(
const Buffer& input)
70 _input.Read(_current);
73 const Buffer& GetBuffer()
const
87 _input.Read(_current);
113 char* PutBegin() { BOOST_ASSERT(
false);
return 0; }
114 void Put(
char) { BOOST_ASSERT(
false); }
115 size_t PutEnd(
char*) { BOOST_ASSERT(
false);
return 0; }
125template <
typename Buffer>
126class RapidJsonOutputStream
129 explicit RapidJsonOutputStream(Buffer& output)
137 char Peek() { BOOST_ASSERT(
false);
return 0; }
138 size_t Tell()
const { BOOST_ASSERT(
false);
return 0; }
139 char Take() { BOOST_ASSERT(
false);
return 0; }
140 size_t PutEnd(
char* begin) { BOOST_ASSERT(
false);
return 0; }
141 char* PutBegin() { BOOST_ASSERT(
false);
return 0; }
159struct RapidJsonInputStream<const rapidjson::UTF8<>::Ch*> : rapidjson::StringStream
161 explicit RapidJsonInputStream(
const char* buffer)
162 : rapidjson::StringStream(buffer)
165 RapidJsonInputStream(
const RapidJsonInputStream& that,
const char*)
166 : rapidjson::StringStream(that)
171class JsonTypeMatching : boost::noncopyable
174 JsonTypeMatching(BondDataType type, BondDataType schema,
bool is_enum)
175 : matchesObject(type == BT_STRUCT && type == schema),
176 matchesArray((type == BT_MAP || type == BT_LIST || type == BT_SET) && type == schema),
177 matchesNull(type == BT_LIST && type == schema),
178 matchesInt(type >= BT_INT8 && type <= BT_INT64),
179 matchesInt64(type == BT_INT64),
180 matchesUint(type >= BT_UINT8 && type <= BT_UINT64),
181 matchesUint64(type == BT_UINT64),
182 matchesNumber(type >= BT_FLOAT && type <= BT_DOUBLE),
183 matchesString(type == BT_STRING || type == BT_WSTRING || is_enum),
184 matchesBool(type == BT_BOOL)
188 bool TypeMatch(
const rapidjson::Value& value)
const
190 return ComplexTypeMatch(value) || BasicTypeMatch(value);
193 bool ComplexTypeMatch(
const rapidjson::Value& value)
const
195 return ((value.IsObject() && matchesObject)
196 || (value.IsArray() && matchesArray)
197 || (value.IsNull() && matchesNull));
200 bool BasicTypeMatch(
const rapidjson::Value& value)
const
202 return ((value.IsString() && matchesString)
203 || (value.IsUint() && matchesUint)
204 || (value.IsInt() && matchesInt)
205 || (value.IsUint64() && matchesUint64)
206 || (value.IsInt64() && matchesInt64)
207 || (value.IsNumber() && matchesNumber)
208 || (value.IsBool() && matchesBool));
212 const bool matchesObject;
213 const bool matchesArray;
214 const bool matchesNull;
215 const bool matchesInt;
216 const bool matchesInt64;
217 const bool matchesUint;
218 const bool matchesUint64;
219 const bool matchesNumber;
220 const bool matchesString;
221 const bool matchesBool;
226inline void Read(
const rapidjson::Value& value,
bool& var)
228 var = value.GetBool();
233typename boost::enable_if<std::is_enum<T> >::type
234Read(
const rapidjson::Value& value, T& var)
236 if (value.IsString())
237 ToEnum(var, value.GetString());
239 var =
static_cast<T
>(value.GetInt());
244typename boost::enable_if<std::is_floating_point<T> >::type
245Read(
const rapidjson::Value& value, T& var)
247 var =
static_cast<T
>(value.GetDouble());
252typename boost::enable_if<is_signed_int<T> >::type
253Read(
const rapidjson::Value& value, T& var)
255 var =
static_cast<T
>(value.GetInt64());
260typename boost::enable_if<std::is_unsigned<T> >::type
261Read(
const rapidjson::Value& value, T& var)
263 var =
static_cast<T
>(value.GetUint64());
268typename boost::enable_if<is_string<T> >::type
269Read(
const rapidjson::Value& value, T& var)
271 const uint32_t length = value.GetStringLength();
272 resize_string(var, length);
274 std::copy(make_checked_array_iterator(value.GetString(), length),
275 make_checked_array_iterator(value.GetString(), length, length),
276 make_checked_array_iterator(string_data(var), length));
282typename boost::enable_if<is_wstring<T> >::type
283Read(
const rapidjson::Value& value, T& var)
285 const std::basic_string<uint16_t> str = utf_to_utf(
287 value.GetString() + value.GetStringLength());
289 const size_t length = str.size();
290 resize_string(var,
static_cast<uint32_t
>(length));
295 make_checked_array_iterator(string_data(var), length));
301typename boost::enable_if<is_type_alias<T> >::type
302Read(
const rapidjson::Value& value, T& var)
304 typename aliased_type<T>::type x;
306 set_aliased_value(var, x);
310template <
typename Reader>
312MakeValue(Reader& reader,
const value<void, Reader&>& element)
314 return value<void, Reader&>(reader, element.GetRuntimeSchema());
317template <
typename Reader,
typename T>
319MakeValue(Reader& reader,
const value<T, Reader&>&)
321 return value<T, Reader&>(reader);
324inline const std::string& FieldName(
const Metadata& metadata)
326 std::map<std::string, std::string>::const_iterator it
327 = metadata.attributes.find(
"JsonName");
329 if (it != metadata.attributes.end())
332 return metadata.name;
namespace bond
Definition: apply.h:17