6#include <bond/core/config.h>
8#include "detail/inheritance.h"
9#include "detail/omit_default.h"
10#include "detail/parser_utils.h"
11#include "detail/typeid_value.h"
13#include "reflection.h"
15#include "transforms.h"
18#include <bond/protocol/simple_binary_impl.h>
19#include <bond/protocol/simple_json_reader_impl.h>
30 template <
typename Transform>
32 ReadFields(
const boost::mpl::l_iter<boost::mpl::l_end>&,
const Transform&)
37 template <
typename Fields>
38 void SkipFields(
const Fields&)
43 template <
typename Transform>
44 struct UnknownFieldBinder
45 : detail::nonassignable
47 UnknownFieldBinder(Transform& transform)
48 : transform(transform)
52 bool Field(uint16_t
id,
const Metadata& ,
const T& value)
const
54 return transform.UnknownField(
id, value);
60 template <
typename Transform>
61 UnknownFieldBinder<Transform> BindUnknownField(Transform& transform)
63 return UnknownFieldBinder<Transform>(transform);
76template <
typename Input>
78 :
protected detail::ParserInheritance<Input, StaticParser<Input> >,
79 public detail::ParserCommon
82 StaticParser(Input input,
bool base =
false)
83 : detail::ParserInheritance<Input, StaticParser<Input> >(input, base)
87 template <
typename Schema,
typename Transform>
89 Apply(
const Transform& transform,
const Schema& schema)
91 detail::StructBegin(_input, _base);
92 bool result = this->Read(schema, transform);
93 detail::StructEnd(_input, _base);
97 friend class detail::ParserInheritance<Input, StaticParser<Input> >;
101 using detail::ParserInheritance<Input, StaticParser<Input> >::_input;
102 using detail::ParserInheritance<Input, StaticParser<Input> >::_base;
103 using detail::ParserCommon::ReadFields;
106 template <
typename Fields>
107 void SkipFields(
const Fields& fields)
110 ReadFields(fields, Null());
114 template <
typename Fields,
typename Transform,
typename I = Input,
115 typename boost::enable_if<detail::implements_field_omitting<I> >::type* =
nullptr>
117 ReadFields(
const Fields&,
const Transform& transform)
119 typedef typename boost::mpl::deref<Fields>::type Head;
121 if (detail::ReadFieldOmitted(_input))
122 detail::OmittedField(Head(), transform);
124 if (
bool done = detail::NonBasicTypeField(Head(), transform, _input))
127 return ReadFields(
typename boost::mpl::next<Fields>::type(), transform);
130 template <
typename Fields,
typename Transform,
typename I = Input,
131 typename boost::disable_if<detail::implements_field_omitting<I> >::type* =
nullptr>
133 ReadFields(
const Fields&,
const Transform& transform)
135 typedef typename boost::mpl::deref<Fields>::type Head;
137 if (
bool done = detail::NonBasicTypeField(Head(), transform, _input))
140 return ReadFields(
typename boost::mpl::next<Fields>::type(), transform);
145 template <
typename Transform>
147 ReadFields(
const RuntimeSchema& schema,
const Transform& transform)
151 for (const_enumerator<std::vector<FieldDef> > enumerator(schema.GetStruct().fields); enumerator.more() && !done;)
153 const FieldDef& field = enumerator.next();
154 const auto type = field.type.id;
156 if (detail::ReadFieldOmitted(_input))
158 transform.OmittedField(field.id, field.metadata, type);
162 if (type == bond::BT_STRUCT || type == bond::BT_LIST || type == bond::BT_SET || type == bond::BT_MAP)
164 done = detail::NonBasicTypeField(field, schema, transform, _input);
168 done = detail::BasicTypeField(field.id, field.metadata, type, transform, _input);
187template <
typename Input>
189 :
protected detail::ParserInheritance<Input, DynamicParser<Input> >,
190 public detail::ParserCommon
193 DynamicParser(Input input,
bool base)
194 : detail::ParserInheritance<Input, DynamicParser<Input> >(input, base)
198 template <
typename Schema,
typename Transform>
200 Apply(
const Transform& transform,
const Schema& schema)
202 detail::StructBegin(_input, _base);
203 bool result = this->Read(schema, transform);
204 detail::StructEnd(_input, _base);
208 friend class detail::ParserInheritance<Input, DynamicParser<Input> >;
212 using detail::ParserInheritance<Input, DynamicParser<Input> >::_input;
213 using detail::ParserInheritance<Input, DynamicParser<Input> >::_base;
217 template <
typename Fields,
typename Transform>
219 ReadFields(
const Fields& fields,
const Transform& transform)
224 _input.ReadFieldBegin(type,
id);
226 ReadFields(fields,
id, type, transform);
244 ReadUnknownFields(type,
id, transform);
249 done = (type == bond::BT_STOP);
252 _input.ReadFieldEnd();
259 template <
typename Fields,
typename Transform>
261 ReadFields(
const Fields&, uint16_t&
id, BondDataType& type,
const Transform& transform)
263 typedef typename boost::mpl::deref<Fields>::type Head;
267 const bool moveSchemaField = Head::id <= id;
268 if (Head::id ==
id && get_type_id<typename Head::field_type>::value == type)
271 detail::NonBasicTypeField(Head(), transform, _input);
273 else if (Head::id >=
id && type != bond::BT_STOP && type != bond::BT_STOP_BASE)
276 UnknownFieldOrTypeMismatch<is_basic_type<typename Head::field_type>::value>(
285 detail::OmittedField(Head(), transform);
286 goto NextSchemaField;
289 ReadSubsequentField(type,
id);
293 NextSchemaField:
return ReadFields(
typename boost::mpl::next<Fields>::type(),
id, type, transform);
299 template <
typename Transform>
301 ReadFields(
const boost::mpl::l_iter<boost::mpl::l_end>&, uint16_t&
id, BondDataType& type,
const Transform& transform)
303 for (; type != bond::BT_STOP && type != bond::BT_STOP_BASE; ReadSubsequentField(type,
id))
305 UnknownField(
id, type, transform);
313 template <
bool IsBasicType,
typename Transform>
315 typename boost::enable_if_c<IsBasicType, bool>::type
316 UnknownFieldOrTypeMismatch(uint16_t expected_id,
const Metadata& metadata, uint16_t
id, BondDataType type,
const Transform& transform)
318 if (
id == expected_id &&
319 type != bond::BT_LIST &&
320 type != bond::BT_SET &&
321 type != bond::BT_MAP &&
322 type != bond::BT_STRUCT)
324 return detail::BasicTypeField(expected_id, metadata, type, transform, _input);
328 return UnknownField(
id, type, transform);
332 template <
bool IsBasicType,
typename Transform>
334 typename boost::disable_if_c<IsBasicType, bool>::type
335 UnknownFieldOrTypeMismatch(uint16_t ,
const Metadata& , uint16_t
id, BondDataType type,
const Transform& transform)
337 return UnknownField(
id, type, transform);
342 template <
typename Transform>
344 ReadFields(
const RuntimeSchema& schema, uint16_t&
id, BondDataType& type,
const Transform& transform)
346 const auto& fields = schema.GetStruct().fields;
348 for (
auto it = fields.begin(), end = fields.end(); ; ReadSubsequentField(type,
id))
350 while (it != end && (it->id <
id || type == bond::BT_STOP || type == bond::BT_STOP_BASE))
352 const FieldDef& field = *it++;
353 transform.OmittedField(field.id, field.metadata, field.type.id);
356 if (type == bond::BT_STOP || type == bond::BT_STOP_BASE)
361 if (it != end && it->id ==
id)
363 const FieldDef& field = *it++;
365 if (type == bond::BT_STRUCT || type == bond::BT_LIST || type == bond::BT_SET || type == bond::BT_MAP)
367 if (field.type.id == type)
369 detail::NonBasicTypeField(field, schema, transform, _input);
375 detail::BasicTypeField(
id, field.metadata, type, transform, _input);
380 UnknownField(
id, type, transform);
385 template <
typename Transform>
386 void ReadUnknownFields(BondDataType& type, uint16_t&
id,
const Transform& transform)
388 for (; type != bond::BT_STOP; ReadSubsequentField(type,
id))
390 if (type == bond::BT_STOP_BASE)
391 transform.UnknownEnd();
393 UnknownField(
id, type, transform);
398 template <
typename T,
typename Protocols,
typename Val
idator>
399 bool UnknownField(uint16_t, BondDataType type,
const To<T, Protocols, Validator>&)
406 template <
typename Transform>
407 bool UnknownField(uint16_t
id, BondDataType type,
const Transform& transform)
409 if (type == bond::BT_STRUCT)
411 return transform.UnknownField(
id, bonded<void, Input>(_input, GetRuntimeSchema<Unknown>()));
413 else if (type == bond::BT_LIST || type == bond::BT_SET || type == bond::BT_MAP)
414 return transform.UnknownField(
id, value<void, Input>(_input, type));
416 return detail::BasicTypeField(
id, schema<Unknown>::type::metadata, type, BindUnknownField(transform), _input);
420 void ReadSubsequentField(BondDataType& type, uint16_t&
id)
422 _input.ReadFieldEnd();
423 _input.ReadFieldBegin(type,
id);
433template <
typename Input>
435 :
protected detail::ParserInheritance<Input, DOMParser<Input> >
437 typedef typename std::remove_reference<Input>::type Reader;
440 DOMParser(Input input,
bool base =
false)
441 : detail::ParserInheritance<Input, DOMParser<Input> >(input, base)
445 template <
typename Schema,
typename Transform>
446 bool Apply(
const Transform& transform,
const Schema& schema)
448 if (!_base) _input.Parse();
449 return this->Read(schema, transform);
452 friend class detail::ParserInheritance<Input, DOMParser<Input> >;
456 using detail::ParserInheritance<Input, DOMParser<Input> >::_input;
457 using detail::ParserInheritance<Input, DOMParser<Input> >::_base;
460 template <
typename Fields>
461 void SkipFields(
const Fields&)
465 template <
typename Fields,
typename Transform>
466 bool ReadFields(
const Fields&,
const Transform& transform)
468 typedef typename boost::mpl::deref<Fields>::type Head;
470 if (
const typename Reader::Field* field = _input.FindField(
473 get_type_id<typename Head::field_type>::value,
474 std::is_enum<typename Head::field_type>::value))
476 Reader input(_input, *field);
477 detail::NonBasicTypeField(Head(), transform, input);
480 return ReadFields(
typename boost::mpl::next<Fields>::type(), transform);
483 template <
typename Transform>
484 bool ReadFields(
const boost::mpl::l_iter<boost::mpl::l_end>&,
const Transform&)
491 template <
typename Transform>
492 bool ReadFields(
const RuntimeSchema& schema,
const Transform& transform)
496 for (const_enumerator<std::vector<FieldDef> > enumerator(schema.GetStruct().fields); enumerator.more() && !done;)
498 const FieldDef& fieldDef = enumerator.next();
499 const auto type = fieldDef.type.id;
501 if (
const typename Reader::Field* field = _input.FindField(fieldDef.id, fieldDef.metadata, type))
503 Reader input(_input, *field);
505 if (type == bond::BT_STRUCT || type == bond::BT_LIST || type == bond::BT_SET || type == bond::BT_MAP)
507 done = detail::NonBasicTypeField(fieldDef, schema, transform, input);
511 done = detail::BasicTypeField(fieldDef.id, fieldDef.metadata, type, transform, input);
525#if BOND_LIB_TYPE != BOND_LIB_TYPE_HEADER
526#include "detail/parser_extern.h"
529#error BOND_LIB_TYPE is undefined
namespace bond
Definition: apply.h:17