DataInput.h
上传用户:kx_jwh
上传日期:2021-09-03
资源大小:76k
文件大小:29k
源码类别:

STL

开发平台:

Visual C++

  1. /* vim: set tabstop=4 : */
  2. #ifndef __febird_io_DataInput_h__
  3. #define __febird_io_DataInput_h__
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. #include <string.h>
  8. #include <typeinfo>
  9. #include <stdexcept>
  10. #include <string>
  11. #include <sstream>
  12. #include <deque>
  13. #include <list>
  14. #include <map>
  15. #include <set>
  16. #include <vector>
  17. #include <boost/version.hpp>
  18. #if BOOST_VERSION < 103301
  19. # include <boost/limits.hpp>
  20. # include <boost/detail/limits.hpp>
  21. #else
  22. # include <boost/detail/endian.hpp>
  23. #endif
  24. #include <boost/cstdint.hpp>
  25. #include <boost/type_traits.hpp>
  26. #include <boost/ref.hpp>
  27. #if !defined(BOOST_BIG_ENDIAN) && !defined(BOOST_LITTLE_ENDIAN)
  28. #error must define byte endian
  29. #endif
  30. #include "../pass_by_value.h"
  31. #include "byte_swap.h"
  32. #include "DataIO_Basic.h"
  33. #include "DataIO_Version.h"
  34. #include "DataIO_Tuple.h"
  35. #include "DataIO_Exception.h"
  36. #include "var_int.h"
  37. #if !defined(BOOST_BIG_ENDIAN) && !defined(BOOST_LITTLE_ENDIAN)
  38. # error must define byte endian
  39. #endif
  40. namespace febird {
  41. template<class Input, class Class>
  42. void DataIO_loadObject(Input& input, Class& x)
  43. {
  44. #ifdef DATA_IO_ALLOW_DEFAULT_SERIALIZE
  45. input.ensureRead(&x, sizeof(Class));
  46. #else
  47. x.MustDefineCustomLoad(input);
  48. #endif
  49. }
  50. //////////////////////////////////////////////////////////////////////////////////////////////////////
  51. template<class DataIO, class T, class Alloc>
  52. void DataIO_load_vector_raw(DataIO& dio, std::vector<T, Alloc>& x, boost::mpl::false_ bswap)
  53. {
  54. dio.ensureRead(&*x.begin(), sizeof(T) * x.size());
  55. }
  56. template<class DataIO, class T, class Alloc>
  57. void DataIO_load_vector_raw(DataIO& dio, std::vector<T, Alloc>& x, boost::mpl::true_ bswap)
  58. {
  59. dio.ensureRead(&*x.begin(), sizeof(T) * x.size());
  60. byte_swap(&*x.begin(), x.size());
  61. }
  62. template<class DataIO, class T, class Alloc, class Bswap>
  63. void DataIO_load_vector_aux(DataIO& dio, std::vector<T, Alloc>& x,
  64. Bswap bswap, ::boost::mpl::true_ real_dumpable)
  65. {
  66. DataIO_load_vector_raw(dio, x, bswap);
  67. }
  68. template<class DataIO, class T, class Alloc, class Bswap>
  69. void DataIO_load_vector_aux(DataIO& dio, std::vector<T, Alloc>& x,
  70. Bswap bswap, ::boost::mpl::false_ real_dumpable)
  71. {
  72. size_t i = x.size();
  73. T* first = &*x.begin();
  74. try {
  75. for (; i; --i, ++first)
  76. dio >> *first;
  77. }
  78. catch (...)
  79. {
  80. x.resize(x.size() - i);
  81. throw;
  82. }
  83. }
  84. template<class DataIO, class T, class Alloc, int Size, bool Dumpable, class Bswap>
  85. void DataIO_load_vector_opt(DataIO& dio, std::vector<T, Alloc>& x, Bswap bswap,
  86.  DataIO_is_realdump<DataIO, T, Size, Dumpable> tag)
  87. {
  88. // sizeof(T) == Size implies T has no paddings
  89. BOOST_STATIC_ASSERT(sizeof(T) >= Size);
  90. typedef ::boost::mpl::bool_<sizeof(T)==Size && Dumpable> is_realdump_t;
  91. DATA_IO_OPT_TRAITS_VERIFY(DataIO, T, is_realdump_t);
  92. var_uint32_t size0; dio >> size0;
  93. x.resize(size0.t);
  94. if (size0.t)
  95. DataIO_load_vector_aux(dio, x, bswap, is_realdump_t());
  96. }
  97. template<class DataIO, class T1, class T2, class Alloc, class Bswap>
  98. void DataIO_load_vector(DataIO& dio, std::vector<std::pair<T1,T2>, Alloc>& x, Bswap bs)
  99. {
  100. DataIO_is_realdump<
  101. DataIO,
  102. std::pair<T1,T2>,
  103. sizeof(T1)+sizeof(T2),
  104. DataIO_is_dump<DataIO, std::pair<T1,T2> >::value
  105. > tag(NULL);
  106. DataIO_load_vector_opt(dio, x, bs, tag);
  107. }
  108. template<class DataIO, class T, class Alloc, class Bswap>
  109. void DataIO_load_vector(DataIO& dio, std::vector<T, Alloc>& x, Bswap bs)
  110. {
  111. DataIO_is_realdump<
  112. DataIO,
  113. T,
  114. sizeof(T),
  115. DataIO_is_dump<DataIO, T>::value
  116. > tag(NULL);
  117. DataIO_load_vector_opt(dio, x, bs, tag);
  118. }
  119. //////////////////////////////////////////////////////////////////////////////////////////////////////
  120. template<class DataIO, class T>
  121. void DataIO_load_array_raw(DataIO& dio, T* a, size_t n, boost::mpl::false_ bswap)
  122. {
  123. dio.ensureRead(a, sizeof(T) * n);
  124. }
  125. template<class DataIO, class T>
  126. void DataIO_load_array_raw(DataIO& dio, T* a, size_t n, boost::mpl::true_ bswap)
  127. {
  128. dio.ensureRead(a, sizeof(T) * n);
  129. byte_swap(a, n);
  130. }
  131. template<class DataIO, class T, class Bswap>
  132. void DataIO_load_array_aux(DataIO& dio, T* a, size_t n, Bswap bswap,
  133.    ::boost::mpl::true_ real_dumpable)
  134. {
  135. DataIO_load_array_raw(dio, a, n, bswap);
  136. }
  137. template<class DataIO, class T, class Bswap>
  138. void DataIO_load_array_aux(DataIO& dio, T* a, size_t n, Bswap bswap,
  139.    ::boost::mpl::false_ real_dumpable)
  140. {
  141. for (size_t i = n; i; --i, ++a)
  142. dio >> *a;
  143. }
  144. template<class DataIO, class T, int Size, bool Dumpable, class Bswap>
  145. void DataIO_load_array_opt(DataIO& dio, T* a, size_t n, Bswap bswap,
  146.  DataIO_is_realdump<DataIO, T, Size, Dumpable> tag)
  147. {
  148. // sizeof(T) == Size implies T has no paddings
  149. BOOST_STATIC_ASSERT(sizeof(T) >= Size);
  150. typedef ::boost::mpl::bool_<sizeof(T)==Size && Dumpable> is_realdump_t;
  151. DATA_IO_OPT_TRAITS_VERIFY(DataIO, T, is_realdump_t);
  152. DataIO_load_array_aux(dio, a, n, bswap, is_realdump_t());
  153. }
  154. template<class DataIO, class T1, class T2, class Bswap>
  155. void DataIO_load_array(DataIO& dio, std::pair<T1,T2>* a, size_t n, Bswap bs)
  156. {
  157. DataIO_is_realdump<
  158. DataIO,
  159. std::pair<T1,T2>,
  160. sizeof(T1)+sizeof(T2),
  161. DataIO_is_dump<DataIO, std::pair<T1,T2> >::value
  162. > tag(NULL);
  163. DataIO_load_array_opt(dio, a, n, bs, tag);
  164. }
  165. template<class DataIO, class T, class Bswap>
  166. void DataIO_load_array(DataIO& dio, T* a, size_t n, Bswap bs)
  167. {
  168. DataIO_is_realdump<
  169. DataIO,
  170. T,
  171. sizeof(T),
  172. DataIO_is_dump<DataIO, T>::value
  173. > tag(NULL);
  174. DataIO_load_array_opt(dio, a, n, bs, tag);
  175. }
  176. //////////////////////////////////////////////////////////////////////////
  177. template<class DataIO, class T>
  178. void DataIO_load_elem_raw(DataIO& dio, T& x, boost::mpl::false_ bswap)
  179. {
  180. dio.ensureRead(&x, sizeof(T));
  181. }
  182. template<class DataIO, class T>
  183. void DataIO_load_elem_raw(DataIO& dio, T& x, boost::mpl::true_ bswap)
  184. {
  185. dio.ensureRead(&x, sizeof(T));
  186. byte_swap_in(x, bswap);
  187. }
  188. template<class DataIO, class T, class Bswap>
  189. void DataIO_load_elem_aux(DataIO& dio, T& x, Bswap bswap, boost::mpl::true_ real_dumpable)
  190. {
  191. DataIO_load_elem_raw(dio, x, bswap);
  192. }
  193. template<class DataIO, class T, class Bswap>
  194. void DataIO_load_elem_aux(DataIO& dio, T& x, Bswap bswap, boost::mpl::false_ real_dumpable)
  195. {
  196. DataIO_loadObject(dio, x);
  197. }
  198. template<class DataIO, class T, int Size, bool Dumpable, class Bswap>
  199. void DataIO_load_elem_opt(DataIO& dio, T& x, Bswap bswap,
  200.   DataIO_is_realdump<DataIO, T, Size, Dumpable> tag)
  201. {
  202. BOOST_STATIC_ASSERT(sizeof(T) >= Size);
  203. typedef ::boost::mpl::bool_<sizeof(T)==Size && Dumpable> is_realdump_t;
  204. DATA_IO_OPT_TRAITS_VERIFY(DataIO, T, is_realdump_t);
  205. DataIO_load_elem_aux(dio, x, bswap, is_realdump_t());
  206. }
  207. template<class DataIO, class T, class Bswap>
  208. void DataIO_load_elem(DataIO& dio, T& x, Bswap bs)
  209. {
  210. DataIO_is_realdump<
  211. DataIO,
  212. T,
  213. sizeof(T),
  214. DataIO_is_dump<DataIO, T>::value
  215. > tag(NULL);
  216. DataIO_load_elem_opt(dio, x, bs, tag);
  217. }
  218. //////////////////////////////////////////////////////////////////////////////////////////////////////
  219. //////////////////////////////////////////////////////////////////////////
  220. template<class BaseInput, class Final_Input>
  221. class DataInput : public BaseInput
  222. {
  223. public:
  224. typedef typename BaseInput::is_seekable  is_seekable;
  225. typedef typename BaseInput::stream_t     stream_t;
  226. typedef boost::mpl::true_  is_loading;
  227. typedef boost::mpl::false_ is_saving;
  228. using BaseInput::operator>>;
  229. //////////////////////////////////////////////////////////////////////////
  230. //! dual operator, for auto dispatch single serialize proc...
  231. //!
  232. //! for PrimitiveInputImpl, operator& is input,
  233. //! for DataOutput, operator& is output.
  234. template<class T> Final_Input& operator&(T& x) { return operator>>(x); }
  235. //-------------------------------------------------------------------------------------------------
  236. //! can not bound temp object to non-const reference,
  237. //! so use pass_by_value object in this case
  238. //! @{
  239. template<class T> Final_Input& operator& (pass_by_value<T> x) { return (*this) >> x.val; }
  240. template<class T> Final_Input& operator>>(pass_by_value<T> x) { return (*this) >> x.val; }
  241. //@}
  242. //-------------------------------------------------------------------------------------------------
  243. template<class T> Final_Input& operator& (boost::reference_wrapper<T> x) { return (*this) >> x.get(); }
  244. template<class T> Final_Input& operator>>(boost::reference_wrapper<T> x) { return (*this) >> x.get(); }
  245. template<int Dim> Final_Input& operator>>(char (&x)[Dim]) { return this->load(x, Dim); }
  246. template<int Dim> Final_Input& operator>>(unsigned char (&x)[Dim]) { return this->load(x, Dim); }
  247. template<int Dim> Final_Input& operator>>(  signed char (&x)[Dim]) { return this->load(x, Dim); }
  248. #ifdef DATA_IO_SUPPORT_SERIALIZE_PTR
  249. template<class T> Final_Input& operator>>(T*& x)
  250. {
  251. x = new T;
  252. *this >> *x;
  253. return static_cast<Final_Input&>(*this);
  254. }
  255. #else
  256. template<class T> Final_Input& operator>>(T*& x)
  257. {
  258. T::NotSupportSerializePointer();
  259. return static_cast<Final_Input&>(*this);
  260. }
  261. #endif
  262. //!@{
  263. //! standard container this->....
  264. //--------------------------------------------------------------------
  265. struct Container_insert
  266. {
  267. template<class Container, class Element>
  268. void operator()(Container& cont, const Element& e) const
  269. { cont.insert(e); }
  270. };
  271. struct Container_push_back
  272. {
  273. template<class Container, class Element>
  274. void operator()(Container& cont, const Element& e) const
  275. { cont.push_back(e); }
  276. };
  277. template<class ContainerType, class InsertOp>
  278. Final_Input& container_load(ContainerType& x, InsertOp insert)
  279. {
  280. x.clear();
  281. var_uint32_t size;
  282. *this >> size;
  283. for (uint32_t i = 0; i < size.t; ++i)
  284. {
  285. typename ContainerType::value_type e;
  286. *this >> e;
  287. insert(x, e);
  288. }
  289. return static_cast<Final_Input&>(*this);
  290. }
  291. //--------------------------------------------------------------------
  292. template<class First, class Second>
  293. Final_Input& operator>>(std::pair<First, Second>& x)
  294. {
  295. return *this >> x.first >> x.second;
  296. }
  297. template<class KeyT, class ValueT, class Compare, class Alloc>
  298. Final_Input& operator>>(std::map<KeyT, ValueT, Compare, Alloc>& x)
  299. {
  300. var_uint32_t size; *this >> size;
  301. x.clear();
  302. for (uint32_t i = 0; i < size.t; ++i)
  303. {
  304. std::pair<KeyT, ValueT> e;
  305. *this >> e;
  306. x.insert(e);
  307. }
  308. return static_cast<Final_Input&>(*this);
  309. }
  310. template<class KeyT, class ValueT, class Compare, class Alloc>
  311. Final_Input& operator>>(std::multimap<KeyT, ValueT, Compare, Alloc>& x)
  312. {
  313. var_uint32_t size; *this >> size;
  314. x.clear();
  315. for (uint32_t i = 0; i < size.t; ++i)
  316. {
  317. std::pair<KeyT, ValueT> e;
  318. *this >> e;
  319. x.insert(e);
  320. }
  321. return static_cast<Final_Input&>(*this);
  322. }
  323. template<class ValueT, class Compare, class Alloc>
  324. Final_Input& operator>>(std::set<ValueT, Compare, Alloc>& x)
  325. {
  326. return container_load(x, Container_insert());
  327. }
  328. template<class ValueT, class Compare, class Alloc>
  329. Final_Input& operator>>(std::multiset<ValueT, Compare, Alloc>& x)
  330. {
  331. return container_load(x, Container_insert());
  332. }
  333. template<class ValueT, class Alloc>
  334. Final_Input& operator>>(std::list<ValueT, Alloc>& x)
  335. {
  336. return container_load(x, Container_push_back());
  337. }
  338. template<class ValueT, class Alloc>
  339. Final_Input& operator>>(std::deque<ValueT, Alloc>& x)
  340. {
  341. return container_load(x, Container_push_back());
  342. }
  343. //!@}
  344. };
  345. //////////////////////////////////////////////////////////////////////////
  346. template<class BaseInput, class Final_Input>
  347. class VarIntVarInput : public BaseInput
  348. {
  349. protected:
  350. uint32_t load_var_uint32()
  351. {
  352. uint32_t v = 0;
  353. for (int shift = 0; shift < 35; shift += 7)
  354. {
  355. byte b; *this >> b;
  356. v |= uint32_t(b & 0x7F) << shift;
  357. if ((b & 0x80) == 0)
  358. return v;
  359. }
  360. assert(0); // should not get here
  361. return v; // avoid compile warning
  362. }
  363. uint64_t load_var_uint64()
  364. {
  365. uint64_t v = 0;
  366. byte b;
  367. for (int shift = 0; shift < 56; shift += 7)
  368. {
  369. *this >> b;
  370. v |= uint64_t(b & 0x7F) << shift;
  371. if ((b & 0x80) == 0)
  372. return v;
  373. }
  374. *this >> b;
  375. v |= uint64_t(b) << 56;
  376. return v;
  377. }
  378. public:
  379. using BaseInput::operator>>;
  380. Final_Input& operator>>(var_int16_t& x)
  381. {
  382. x.t = var_int16_u2s(load_var_uint32());
  383. return static_cast<Final_Input&>(*this);
  384. }
  385. Final_Input& operator>>(var_int32_t& x)
  386. {
  387. x.t = var_int32_u2s(load_var_uint32());
  388. return static_cast<Final_Input&>(*this);
  389. }
  390. Final_Input& operator>>(var_uint16_t& x) { x.t = load_var_uint32(); return static_cast<Final_Input&>(*this); }
  391. Final_Input& operator>>(var_uint32_t& x) { x.t = load_var_uint32(); return static_cast<Final_Input&>(*this); }
  392. #if !defined(BOOST_NO_INT64_T)
  393. Final_Input& operator>>(var_int64_t& x)
  394. {
  395. x.t = var_int64_u2s(load_var_uint64());
  396. return static_cast<Final_Input&>(*this);
  397. }
  398. Final_Input& operator>>(var_uint64_t& x) { x.t = load_var_uint64(); return static_cast<Final_Input&>(*this); }
  399. #endif
  400. Final_Input& operator>>(serialize_version_t& x) { x.t = load_var_uint32(); return static_cast<Final_Input&>(*this); }
  401. };
  402. template<class BaseInput, class Final_Input>
  403. class VarIntFixedInput : public BaseInput
  404. {
  405. public:
  406. using BaseInput::operator>>;
  407. Final_Input& operator>>(var_int16_t & x) { return *this >> x.t; }
  408. Final_Input& operator>>(var_uint16_t& x) { return *this >> x.t; }
  409. Final_Input& operator>>(var_int32_t & x) { return *this >> x.t; }
  410. Final_Input& operator>>(var_uint32_t& x) { return *this >> x.t; }
  411. #if !defined(BOOST_NO_INT64_T)
  412. Final_Input& operator>>(var_int64_t & x) { return *this >> x.t; }
  413. Final_Input& operator>>(var_uint64_t& x) { return *this >> x.t; }
  414. #endif
  415. Final_Input& operator>>(serialize_version_t& x) { return *this >> x.t; }
  416. };
  417. template<class BaseInput, class Final_Input>
  418. class BigEndianStringInput : public BaseInput
  419. {
  420. public:
  421. using BaseInput::operator>>;
  422. Final_Input& load(wchar_t* s, size_t n)
  423. {
  424. this->ensureRead(s, sizeof(wchar_t)*n);
  425. #ifdef BOOST_LITTLE_ENDIAN
  426. byte_swap(s, n);
  427. #endif
  428. return static_cast<Final_Input&>(*this);
  429. }
  430. #ifndef BOOST_NO_INTRINSIC_WCHAR_T
  431. Final_Input& operator>>(wchar_t& x)
  432. {
  433. this->ensureRead(&x, sizeof(x));
  434. #ifdef BOOST_LITTLE_ENDIAN
  435. x = byte_swap(x);
  436. #endif
  437. return static_cast<Final_Input&>(*this); 
  438. }
  439. #endif
  440. };
  441. template<class BaseInput, class Final_Input>
  442. class LittleEndianStringInput : public BaseInput
  443. {
  444. public:
  445. using BaseInput::operator>>;
  446. Final_Input& load(wchar_t* s, size_t n)
  447. {
  448. this->ensureRead(s, sizeof(wchar_t)*n);
  449. #ifdef BOOST_BIG_ENDIAN
  450. byte_swap(s, n);
  451. #endif
  452. return static_cast<Final_Input&>(*this); 
  453. }
  454. #ifndef BOOST_NO_INTRINSIC_WCHAR_T
  455. Final_Input& operator>>(wchar_t& x)
  456. {
  457. this->ensureRead(&x, sizeof(x));
  458. #ifdef BOOST_BIG_ENDIAN
  459. x = byte_swap(x);
  460. #endif
  461. return static_cast<Final_Input&>(*this); 
  462. }
  463. #endif
  464. };
  465. template<class BaseInput, class Final_Input>
  466. class CommonStringInput : public BaseInput
  467. {
  468. public:
  469. using BaseInput::load;
  470. using BaseInput::operator>>;
  471. Final_Input& load(char* s, size_t n) { this->ensureRead(s, n); return static_cast<Final_Input&>(*this); }
  472. Final_Input& load(unsigned char* s, size_t n) { this->ensureRead(s, n); return static_cast<Final_Input&>(*this); }
  473. Final_Input& load(  signed char* s, size_t n) { this->ensureRead(s, n); return static_cast<Final_Input&>(*this); }
  474. Final_Input& operator>>(char*& s) { return load_s0(s); }
  475. Final_Input& operator>>(wchar_t*& s) { return load_s0(s); }
  476. Final_Input& operator>>(std:: string& x) { return load_s1(x); }
  477. Final_Input& operator>>(std::wstring& x) { return load_s1(x); }
  478. private:
  479. template<class ChT> Final_Input& load_s0(ChT*& s)
  480. {
  481. assert(0 == s);
  482. var_uint32_t n;
  483. *this >> n;
  484. s = new ChT[n.t+1];
  485. this->load(s, n.t);
  486. s[n] = 0;
  487. return static_cast<Final_Input&>(*this);
  488. }
  489. //! string in file format: [length : ....content.... ]
  490. template<class CharType, class Traits, class Allocator>
  491. Final_Input& load_s1(std::basic_string<CharType, Traits, Allocator>& x)
  492. {
  493. var_uint32_t length;
  494. *this >> length;
  495. x.resize(length.t); // str will be allocated at least (length+1) chars..
  496. if (length.t)
  497. {
  498. // CharType* data = const_cast<CharType*>(str.data());
  499. CharType* data = &*x.begin(); // this will make a mutable string content
  500. this->load(data, length.t);
  501. // data[length.t] = 0; // in most string implementation, this is accessible
  502. // data[length.t] = 0; // in some string implementation, this is out of string bound
  503. }
  504. return static_cast<Final_Input&>(*this);
  505. }
  506. };
  507. template<class StreamT, class Final_Input>
  508. class PrimitiveInputImpl : public StreamT
  509. {
  510. //  this will cause compile error!!
  511. // DECLARE_NONE_COPYABLE_CLASS(PrimitiveInputImpl)
  512. public:
  513. typedef StreamT stream_t;
  514. StreamT* getStream() { return this; }
  515. Final_Input& operator>>(char& x) { x = (char)this->readByte(); return static_cast<Final_Input&>(*this); }
  516. Final_Input& operator>>(unsigned char& x) { x = (unsigned char)this->readByte(); return static_cast<Final_Input&>(*this); }
  517. Final_Input& operator>>(  signed char& x) { x = (  signed char)this->readByte(); return static_cast<Final_Input&>(*this); }
  518. };
  519. template<class StreamT, class Final_Input>
  520. class PrimitiveInputImpl<StreamT*, Final_Input>
  521. {
  522. protected:
  523. StreamT* stream;
  524. public:
  525. typedef StreamT stream_t;
  526. typedef typename stream_t::is_seekable is_seekable;
  527. void attach(stream_t* stream) { this->stream = stream; }
  528. StreamT* getStream() { return stream; }
  529. //! only delegate this method of StreamT
  530. size_t read(void* data, size_t length) { return stream->read(data, length); }
  531. void ensureRead(void* data, size_t length) { stream->ensureRead(data, length); }
  532. Final_Input& operator>>(char& x) { x = (char)stream->readByte(); return static_cast<Final_Input&>(*this); }
  533. Final_Input& operator>>(byte& x) { x = (byte)stream->readByte(); return static_cast<Final_Input&>(*this); }
  534. Final_Input& operator>>(signed char& x) { x = (signed char)stream->readByte(); return static_cast<Final_Input&>(*this); }
  535. };
  536. #define DATA_IO_GEN_DUMP_INPUT(Type)
  537. Final_Input& operator>>(Type& x)
  538. { this->ensureRead(&x, sizeof(Type));
  539. return static_cast<Final_Input&>(*this);
  540. }
  541. template<int Dim>
  542. Final_Input& operator>>(Type (&x)[Dim])
  543. { this->ensureRead(x, sizeof(Type)*Dim);
  544. return static_cast<Final_Input&>(*this); 
  545. }
  546. template<class Alloc>
  547. Final_Input& operator>>(std::vector<Type, Alloc>& x)
  548. { var_uint32_t n;
  549. static_cast<Final_Input&>(*this) >> n;
  550. x.resize(n.t);
  551.     if (n.t)
  552.   this->ensureRead(&*x.begin(), sizeof(Type)*x.size());
  553. return static_cast<Final_Input&>(*this); 
  554. }
  555. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  556. #define DATA_IO_GEN_BSWAP_INT_INPUT(Int)
  557. Final_Input& operator>>(Int& x) {
  558.   this->ensureRead(&x, sizeof(Int));
  559.   x = byte_swap(x);
  560.   return static_cast<Final_Input&>(*this); 
  561. }
  562. template<int Dim>
  563. Final_Input& operator>>(Int (&x)[Dim]) {
  564.   this->ensureRead(x, sizeof(Int)*Dim); 
  565.   byte_swap(x, Dim); 
  566.   return static_cast<Final_Input&>(*this); 
  567. }
  568. template<class Alloc>
  569. Final_Input& operator>>(std::vector<Int, Alloc>& x) {
  570.   var_uint32_t n;
  571.   static_cast<Final_Input&>(*this) >> n;
  572.   x.resize(n.t);
  573.   if (n.t) {
  574.     this->ensureRead(&*x.begin(), sizeof(Int)*x.size());
  575.     byte_swap(x.begin(), x.end());
  576.   }
  577.   return static_cast<Final_Input&>(*this); 
  578. }
  579. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  580. template<class BaseInput, class Final_Input>
  581. class BinFloatInput : public BaseInput
  582. {
  583. public:
  584. using BaseInput::operator>>;
  585. DATA_IO_GEN_DUMP_INPUT(float)
  586. DATA_IO_GEN_DUMP_INPUT(double)
  587. DATA_IO_GEN_DUMP_INPUT(long double)
  588. };
  589. template<class StreamT, class Final_Input>
  590. class PortableIntegerInput : public PrimitiveInputImpl<StreamT, Final_Input>
  591. {
  592. public:
  593. #ifdef BOOST_LITTLE_ENDIAN
  594. #define DATA_IO_GEN_PORTABLE_INT_INPUT  DATA_IO_GEN_BSWAP_INT_INPUT
  595. #elif defined(BOOST_BIG_ENDIAN)
  596. #define DATA_IO_GEN_PORTABLE_INT_INPUT  DATA_IO_GEN_DUMP_INPUT
  597. #else
  598. #error "must define BOOST_LITTLE_ENDIAN or BOOST_BIG_ENDIAN"
  599. #endif
  600. using PrimitiveInputImpl<StreamT, Final_Input>::operator>>;
  601. DATA_IO_GEN_PORTABLE_INT_INPUT(short)
  602. DATA_IO_GEN_PORTABLE_INT_INPUT(unsigned short)
  603. DATA_IO_GEN_PORTABLE_INT_INPUT(int)
  604. DATA_IO_GEN_PORTABLE_INT_INPUT(unsigned int)
  605. DATA_IO_GEN_PORTABLE_INT_INPUT(long)
  606. DATA_IO_GEN_PORTABLE_INT_INPUT(unsigned long)
  607. #if defined(BOOST_HAS_LONG_LONG)
  608. DATA_IO_GEN_PORTABLE_INT_INPUT(long long)
  609. DATA_IO_GEN_PORTABLE_INT_INPUT(unsigned long long)
  610. #elif defined(BOOST_HAS_MS_INT64)
  611. DATA_IO_GEN_PORTABLE_INT_INPUT(__int64)
  612. DATA_IO_GEN_PORTABLE_INT_INPUT(unsigned __int64)
  613. #endif
  614. template<class T> Final_Input& operator>>(T& x)
  615. {
  616. DataIO_load_elem(static_cast<Final_Input&>(*this), x, DATA_IO_BSWAP_FOR_BIG(T)());
  617. return static_cast<Final_Input&>(*this);
  618. }
  619. template<class T, int Dim>
  620. Final_Input& operator>>(T (&x)[Dim])
  621. DataIO_load_array(static_cast<Final_Input&>(*this), x, Dim, DATA_IO_BSWAP_FOR_BIG(T)());
  622. return static_cast<Final_Input&>(*this);
  623. }
  624. template<class T, class Alloc>
  625. Final_Input& operator>>(std::vector<T, Alloc>& x)
  626. {
  627. DataIO_load_vector(static_cast<Final_Input&>(*this), x, DATA_IO_BSWAP_FOR_BIG(T)());
  628. return static_cast<Final_Input&>(*this);
  629. }
  630. };
  631. template<class StreamT, class Final_Input>
  632. class LittleEndianIntegerInput : public PrimitiveInputImpl<StreamT, Final_Input>
  633. {
  634. public:
  635. #ifdef BOOST_LITTLE_ENDIAN
  636. #define DATA_IO_GEN_LITTLE_INT_INPUT  DATA_IO_GEN_DUMP_INPUT
  637. #elif defined(BOOST_BIG_ENDIAN)
  638. #define DATA_IO_GEN_LITTLE_INT_INPUT  DATA_IO_GEN_BSWAP_INT_INPUT
  639. #else
  640. #error "must define BOOST_LITTLE_ENDIAN or BOOST_BIG_ENDIAN"
  641. #endif
  642. typedef boost::mpl::false_ need_byte_swap;
  643. using PrimitiveInputImpl<StreamT, Final_Input>::operator>>;
  644. DATA_IO_GEN_LITTLE_INT_INPUT(short)
  645. DATA_IO_GEN_LITTLE_INT_INPUT(unsigned short)
  646. DATA_IO_GEN_LITTLE_INT_INPUT(int)
  647. DATA_IO_GEN_LITTLE_INT_INPUT(unsigned int)
  648. DATA_IO_GEN_LITTLE_INT_INPUT(long)
  649. DATA_IO_GEN_LITTLE_INT_INPUT(unsigned long)
  650. #if defined(BOOST_HAS_LONG_LONG)
  651. DATA_IO_GEN_LITTLE_INT_INPUT(long long)
  652. DATA_IO_GEN_LITTLE_INT_INPUT(unsigned long long)
  653. #elif defined(BOOST_HAS_MS_INT64)
  654. DATA_IO_GEN_LITTLE_INT_INPUT(__int64)
  655. DATA_IO_GEN_LITTLE_INT_INPUT(unsigned __int64)
  656. #endif
  657. template<class T> Final_Input& operator>>(T& x)
  658. {
  659. DataIO_load_elem(static_cast<Final_Input&>(*this), x, DATA_IO_BSWAP_FOR_LITTLE(T)());
  660. return static_cast<Final_Input&>(*this);
  661. }
  662. template<class T, int Dim>
  663. Final_Input& operator>>(T (&x)[Dim])
  664. DataIO_load_array(static_cast<Final_Input&>(*this), x, Dim, DATA_IO_BSWAP_FOR_LITTLE(T)());
  665. return static_cast<Final_Input&>(*this);
  666. }
  667. template<class T, class Alloc>
  668. Final_Input& operator>>(std::vector<T, Alloc>& x)
  669. {
  670. DataIO_load_vector(static_cast<Final_Input&>(*this), x, DATA_IO_BSWAP_FOR_LITTLE(T)());
  671. return static_cast<Final_Input&>(*this);
  672. }
  673. };
  674. #ifdef BOOST_BIG_ENDIAN
  675. #  define LittleEndianStringInput BigEndianStringInput
  676. #else
  677. #  define LittleEndianStringInput LittleEndianStringInput
  678. #endif
  679. #define PortableStringInput BigEndianStringInput
  680. template<class StreamT>
  681. class LittleEndianDataInput : public DATA_IO_BASE_IO(LittleEndianDataInput, LittleEndian, VarIntVar, Input, StreamT)
  682. {
  683. public:
  684. LittleEndianDataInput() {}
  685. };
  686. template<class StreamT>
  687. class LittleEndianDataInput<StreamT*> : public DATA_IO_BASE_IO(LittleEndianDataInput, LittleEndian, VarIntVar, Input, StreamT*)
  688. {
  689. public:
  690. explicit LittleEndianDataInput(StreamT* stream = 0) { this->attach(stream); }
  691. };
  692. template<class StreamT>
  693. class PortableDataInput : public DATA_IO_BASE_IO(PortableDataInput, Portable, VarIntVar, Input, StreamT)
  694. {
  695. public:
  696. PortableDataInput() {}
  697. };
  698. template<class StreamT>
  699. class PortableDataInput<StreamT*> : public DATA_IO_BASE_IO(PortableDataInput, Portable, VarIntVar, Input, StreamT*)
  700. {
  701. public:
  702. explicit PortableDataInput(StreamT* stream = 0) { this->attach(stream); }
  703. };
  704. //////////////////////////////////////////////////////////////////////////
  705. template<class StreamT>
  706. class LittleEndianNoVarIntInput : public DATA_IO_BASE_IO(LittleEndianNoVarIntInput, LittleEndian, VarIntFixed, Input, StreamT)
  707. {
  708. public:
  709. LittleEndianNoVarIntInput() {}
  710. };
  711. template<class StreamT>
  712. class LittleEndianNoVarIntInput<StreamT*> : public DATA_IO_BASE_IO(LittleEndianNoVarIntInput, LittleEndian, VarIntFixed, Input, StreamT*)
  713. {
  714. public:
  715. explicit LittleEndianNoVarIntInput(StreamT* stream) { this->stream = stream; }
  716. };
  717. template<class StreamT>
  718. class PortableNoVarIntInput : public DATA_IO_BASE_IO(PortableNoVarIntInput, Portable, VarIntFixed, Input, StreamT)
  719. {
  720. public:
  721. PortableNoVarIntInput() {}
  722. };
  723. template<class StreamT>
  724. class PortableNoVarIntInput<StreamT*> : public DATA_IO_BASE_IO(PortableNoVarIntInput, Portable, VarIntFixed, Input, StreamT*)
  725. {
  726. public:
  727. explicit PortableNoVarIntInput(StreamT* stream = 0) { this->stream = stream; }
  728. };
  729. //////////////////////////////////////////////////////////////////////////
  730. //! call Class::load(Input, version)
  731. template<class Input>
  732. unsigned int DataIO_load_check_version(Input& in, unsigned int curr_version, const char* className)
  733. {
  734. serialize_version_t loaded_version;
  735. in >> loaded_version;
  736. if (loaded_version.t > curr_version)
  737. {
  738. //  if (0 == className)
  739. //  className = typeid(Class).name();
  740. throw BadVersionException(loaded_version.t, curr_version, className);
  741. }
  742. return loaded_version.t;
  743. }
  744. #define DATA_IO_REG_LOAD(Class) 
  745.   template<class Input> friend void DataIO_loadObject(Input& in, Class& x) { x.load(in); }
  746. #define DATA_IO_REG_LOAD_V(Class, CurrentVersion)
  747. template<class Input>
  748. friend void DataIO_loadObject(Input& in, Class& x)
  749. {
  750. x.load(in, DataIO_load_check_version(
  751. in, CurrentVersion, BOOST_STRINGIZE(Class)));
  752. }
  753. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  754. #define DATA_IO_DISABLE_LOAD(Class) 
  755.   template<class DataIO>
  756.   friend void DataIO_loadObject(DataIO& dio, Class& x) { dio.DisableLoadClass(x); }
  757. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  758. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  759. #ifdef FEBIRD_DATA_IO_DISABLE_OPTIMIZE_DUMPABLE
  760. #define DATA_IO_OPTIMIZE_VECTOR_LOAD(Self, Class, Members)
  761. #define DATA_IO_OPTIMIZE_ELEMEN_LOAD(Self, Class, Members)
  762. #define DATA_IO_OPTIMIZE_ARRAY_LOAD(Self, Class, Members)
  763. #else
  764. #define DATA_IO_OPTIMIZE_VECTOR_LOAD(Derived, Class, Members)
  765. template<class DataIO, class Alloc, class Bswap>
  766. void load_vector(DataIO& aDataIO,
  767. std::vector<Class, Alloc>& _vector_,
  768. Bswap bswap)
  769. {
  770. DataIO_load_vector_opt(aDataIO,_vector_, Bswap(),
  771. DataIO_is_realdump<DataIO,Class,0,true>(this)Members);
  772. }
  773. template<class DataIO, class Alloc, class Bswap>
  774. friend void DataIO_load_vector(DataIO& dio,
  775. std::vector<Class, Alloc>& x,
  776. Bswap bswap)
  777. {
  778. ((Derived*)0)->load_vector(dio, x, bswap);
  779. }
  780. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  781. #define DATA_IO_OPTIMIZE_ARRAY_LOAD(Derived, Class, Members) 
  782. template<class DataIO, class Bswap>
  783. void load_array(DataIO& aDataIO,
  784. Class* _A_address, size_t _N_count, Bswap)
  785. {
  786.   DataIO_load_array_opt(aDataIO,
  787. _A_address, _N_count, Bswap(),
  788. DataIO_is_realdump<DataIO,Class,0,true>(this)Members);
  789. }
  790. template<class DataIO, class Bswap>
  791. friend void DataIO_load_array(DataIO& dio,
  792. Class* a, size_t n, Bswap bswap)
  793. {
  794. ((Derived*)0)->load_array(dio, a, n, bswap);
  795. }
  796. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  797. #define DATA_IO_OPTIMIZE_ELEMEN_LOAD(Self, Class, Members)
  798. template<class Bswap> void byte_swap_in(Bswap)
  799. { ByteSwapChain<Bswap>()Members; }
  800. template<class Bswap> friend
  801. void byte_swap_in(Class& x, Bswap)
  802. { Self(x).byte_swap_in(Bswap()); }
  803. template<class DataIO, class Bswap>
  804. void opt_load(DataIO& aDataIO, Bswap)
  805. {
  806.   DataIO_load_elem_opt(aDataIO, *this, Bswap(), 
  807. DataIO_is_realdump<DataIO,Class,0,true>(this)Members);
  808. }
  809. template<class DataIO, class Bswap>
  810. friend void DataIO_load_elem(DataIO& dio,
  811. Class& x, Bswap bswap)
  812. {
  813. Self(x).opt_load(dio, bswap);
  814. }
  815. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  816. #endif // FEBIRD_DATA_IO_DISABLE_OPTIMIZE_DUMPABLE
  817. #ifdef BOOST_LITTLE_ENDIAN
  818. #define NativeDataInput LittleEndianDataInput
  819. #define NativeNoVarIntInput LittleEndianNoVarIntInput
  820. #elif defined(BOOST_BIG_ENDIAN)
  821. #define NativeDataInput PortableDataInput
  822. #define NativeNoVarIntInput PortableNoVarIntInput
  823. #else
  824. #error "must define BOOST_LITTLE_ENDIAN or BOOST_BIG_ENDIAN"
  825. #endif
  826. }
  827. #endif // __febird_io_DataInput_h__