110 typedef BufferT Buffer;
111 typedef DynamicParser<FastBinaryReader&> Parser;
114 BOND_STATIC_CONSTEXPR uint16_t magic = FAST_PROTOCOL;
115 BOND_STATIC_CONSTEXPR uint16_t version = v1;
128 : _input(that._input)
135 return _input == rhs._input;
140 typename boost::call_traits<Buffer>::const_reference
148 typename boost::call_traits<Buffer>::reference
157 uint16_t magic_value, version_value;
159 _input.Read(magic_value);
160 _input.Read(version_value);
162 return magic_value == FastBinaryReader::magic
163 && version_value <= FastBinaryReader::version;
168 template <
typename T>
169 typename boost::disable_if<is_string_type<T> >::type
177 template <
typename T>
178 typename boost::enable_if<is_string_type<T> >::type
183 ReadVariableUnsigned(_input, length);
185 constexpr uint8_t charSize =
static_cast<uint8_t
>(
sizeof(
typename detail::string_char_int_type<T>::type));
186 uint32_t numStringBytes = detail::checked_multiply(length, charSize);
187 if (!_input.CanRead(numStringBytes))
188 OutOfBoundStringSizeException();
190 detail::ReadStringData(_input, value, length);
195 void Read(blob& value, uint32_t size)
197 _input.Read(value, size);
202 bool CanReadArray(uint32_t num_elems)
206#pragma warning(disable:4127)
209 BOND_IF_CONSTEXPR(is_string_type<T>::value)
211 return _input.CanRead(num_elems);
217 uint64_t num_bytes =
static_cast<uint64_t
>(num_elems) *
sizeof(T);
218 return (num_bytes >> 32 == 0) && _input.CanRead(num_bytes & 0xffffffff);
226 void ReadStructBegin()
234 void ReadFieldBegin(BondDataType& type, uint16_t&
id)
238 if (type != BT_STOP && type != BT_STOP_BASE)
249 void ReadContainerBegin(uint32_t& size, BondDataType& type)
252 ReadVariableUnsigned(_input, size);
257 void ReadContainerBegin(uint32_t& size, std::pair<BondDataType, BondDataType>& type)
259 ReadType(type.first);
260 ReadType(type.second);
261 ReadVariableUnsigned(_input, size);
265 void ReadContainerEnd()
269 template <
typename T>
272 SkipType<get_type_id<T>::value>();
276 template <
typename T>
277 void Skip(
const bonded<T, FastBinaryReader&>&)
279 SkipType<BT_STRUCT>();
282 void Skip(BondDataType type)
288 void ReadType(BondDataType& type)
293 type =
static_cast<BondDataType
>(byte);
296 using BT = BondDataType;
299 typename boost::enable_if_c<(T == BT_BOOL || T == BT_UINT8 || T == BT_INT8)>::type
300 SkipType(uint32_t size = 1)
302 _input.Skip(detail::checked_multiply(size,
sizeof(uint8_t)));
306 typename boost::enable_if_c<(T == BT_UINT16 || T == BT_INT16)>::type
307 SkipType(uint32_t size = 1)
309 _input.Skip(detail::checked_multiply(size,
sizeof(uint16_t)));
313 typename boost::enable_if_c<(T == BT_UINT32 || T == BT_INT32)>::type
314 SkipType(uint32_t size = 1)
316 _input.Skip(detail::checked_multiply(size,
sizeof(uint32_t)));
320 typename boost::enable_if_c<(T == BT_UINT64 || T == BT_INT64)>::type
321 SkipType(uint32_t size = 1)
323 _input.Skip(detail::checked_multiply(size,
sizeof(uint64_t)));
327 typename boost::enable_if_c<(T == BT_FLOAT)>::type
328 SkipType(uint32_t size = 1)
330 _input.Skip(detail::checked_multiply(size,
sizeof(
float)));
334 typename boost::enable_if_c<(T == BT_DOUBLE)>::type
335 SkipType(uint32_t size = 1)
337 _input.Skip(detail::checked_multiply(size,
sizeof(
double)));
341 typename boost::enable_if_c<(T == BT_STRING)>::type
346 ReadVariableUnsigned(_input, size);
351 typename boost::enable_if_c<(T == BT_WSTRING)>::type
356 ReadVariableUnsigned(_input, size);
357 _input.Skip(detail::checked_multiply(size,
sizeof(uint16_t)));
361 typename boost::enable_if_c<(T == BT_STRUCT)>::type
364 bond::detail::RecursionGuard guard;
371 BondDataType field_type;
373 for (ReadFieldBegin(field_type,
id);
374 field_type != BT_STOP && field_type != BT_STOP_BASE;
375 ReadFieldEnd(), ReadFieldBegin(field_type,
id))
377 SkipType(field_type);
382 if (field_type == BT_STOP)
388 typename boost::enable_if_c<(T == BT_SET || T == BT_LIST)>::type
391 BondDataType element_type;
394 bond::detail::RecursionGuard guard;
396 ReadContainerBegin(size, element_type);
397 SkipType(element_type, size);
402 typename boost::enable_if_c<(T == BT_MAP)>::type
405 std::pair<BondDataType, BondDataType> element_type;
408 bond::detail::RecursionGuard guard;
410 ReadContainerBegin(size, element_type);
411 for (int64_t i = 0; i < size; ++i)
413 SkipType(element_type.first);
414 SkipType(element_type.second);
420 typename boost::enable_if_c<(T == BT_STRING || T == BT_WSTRING || T == BT_STRUCT
421 || T == BT_SET || T == BT_LIST || T == BT_MAP)>::type
422 SkipType(uint32_t size)
424 for (int64_t i = 0; i < size; ++i)
430 template <
typename... Args>
431 void SkipType(BondDataType type, Args&&... args)
438 SkipType<BT_BOOL>(std::forward<Args>(args)...);
443 SkipType<BT_UINT16>(std::forward<Args>(args)...);
448 SkipType<BT_UINT32>(std::forward<Args>(args)...);
453 SkipType<BT_UINT64>(std::forward<Args>(args)...);
457 SkipType<BT_FLOAT>(std::forward<Args>(args)...);
461 SkipType<BT_DOUBLE>(std::forward<Args>(args)...);
465 SkipType<BT_STRING>(std::forward<Args>(args)...);
469 SkipType<BT_WSTRING>(std::forward<Args>(args)...);
474 SkipType<BT_SET>(std::forward<Args>(args)...);
478 SkipType<BT_MAP>(std::forward<Args>(args)...);
482 SkipType<BT_STRUCT>(std::forward<Args>(args)...);
486 bond::UnknownDataTypeException();
507 typedef BufferT Buffer;
517 typename boost::call_traits<Buffer>::reference
525 _output.Write(Reader::magic);
526 _output.Write(Reader::version);
532 void WriteStructBegin(
const Metadata& ,
bool )
535 void WriteStructEnd(
bool base =
false)
537 WriteType(base ? BT_STOP_BASE : BT_STOP);
540 template <
typename T>
541 void WriteField(uint16_t
id,
const bond::Metadata& ,
const T& value)
543 WriteFieldBegin(get_type_id<T>::value,
id);
548 void WriteFieldBegin(BondDataType type, uint16_t
id,
const bond::Metadata& )
550 WriteFieldBegin(type,
id);
553 void WriteFieldBegin(BondDataType type, uint16_t
id)
562 void WriteContainerBegin(uint32_t size, BondDataType type)
565 WriteVariableUnsigned(_output, size);
569 void WriteContainerBegin(uint32_t size, std::pair<BondDataType, BondDataType> type)
571 WriteType(type.first);
572 WriteType(type.second);
573 WriteVariableUnsigned(_output, size);
576 void WriteContainerEnd()
581 typename boost::disable_if<is_string_type<T> >::type
582 Write(
const T& value)
584 _output.Write(value);
588 template <
typename T>
589 typename boost::enable_if<is_string_type<T> >::type
590 Write(
const T& value)
592 uint32_t length = string_length(value);
594 WriteVariableUnsigned(_output, length);
595 detail::WriteStringData(_output, value, length);
599 void Write(
const blob& value)
601 _output.Write(value);
605 void WriteType(BondDataType type)
607 _output.Write(
static_cast<uint8_t
>(type));