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

STL

开发平台:

Visual C++

  1. /* vim: set tabstop=4 : */
  2. #ifndef __febird_io_DataOutput_h__
  3. #define __febird_io_DataOutput_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/ref.hpp>
  26. #if !defined(BOOST_BIG_ENDIAN) && !defined(BOOST_LITTLE_ENDIAN)
  27. #error must define byte endian
  28. #endif
  29. #include "../pass_by_value.h"
  30. #include "byte_swap.h"
  31. #include "DataIO_Basic.h"
  32. #include "DataIO_Version.h"
  33. #include "DataIO_Tuple.h"
  34. #include "var_int.h"
  35. #include "IOException.h"
  36. #if !defined(BOOST_BIG_ENDIAN) && !defined(BOOST_LITTLE_ENDIAN)
  37. #error must define byte endian
  38. #endif
  39. namespace febird {
  40. template<class Output, class T>
  41. void DataIO_saveObject(Output& output, const T& x)
  42. {
  43. #ifdef DATA_IO_ALLOW_DEFAULT_SERIALIZE
  44. output.ensureWrite(&x, sizeof(x));
  45. #else
  46. x.MustDefineCustomSave(output);
  47. #endif
  48. }
  49. //////////////////////////////////////////////////////////////////////////////////////////////////////
  50. template<class DataIO, class T, class Alloc>
  51. void DataIO_save_vector_raw(DataIO& dio, const std::vector<T, Alloc>& x, boost::mpl::false_ bswap)
  52. {
  53. dio.ensureWrite(&*x.begin(), sizeof(T) * x.size());
  54. }
  55. template<class DataIO, class T, class Alloc>
  56. void DataIO_save_vector_raw(DataIO& dio, const std::vector<T, Alloc>& x, boost::mpl::true_ bswap)
  57. {
  58. for (typename std::vector<T, Alloc>::const_iterator i = x.begin(); i != x.end(); ++i)
  59. {
  60. T e(*i);
  61. byte_swap_in(e, bswap);
  62. dio.ensureWrite(&e, sizeof(T));
  63. }
  64. }
  65. template<class DataIO, class T, class Alloc, class Bswap>
  66. void DataIO_save_vector_aux(DataIO& dio, const std::vector<T, Alloc>& x,
  67. Bswap bswap, ::boost::mpl::true_ real_dumpable)
  68. {
  69. DataIO_save_vector_raw(dio, x, bswap);
  70. }
  71. template<class DataIO, class T, class Alloc, class Bswap>
  72. void DataIO_save_vector_aux(DataIO& dio, const std::vector<T, Alloc>& x,
  73. Bswap bswap, ::boost::mpl::false_ real_dumpable)
  74. {
  75. for (typename std::vector<T, Alloc>::const_iterator i = x.begin(); i != x.end(); ++i)
  76. {
  77. dio << *i;
  78. }
  79. }
  80. template<class DataIO, class T, class Alloc, int Size, bool Dumpable, class Bswap>
  81. void DataIO_save_vector_opt(DataIO& dio, const std::vector<T, Alloc>& x,
  82. Bswap bswap, DataIO_is_realdump<DataIO, T, Size, Dumpable> tag)
  83. {
  84. BOOST_STATIC_ASSERT(sizeof(T) >= Size);
  85. typedef ::boost::mpl::bool_<sizeof(T)==Size && Dumpable> is_realdump_t;
  86. DATA_IO_OPT_TRAITS_VERIFY(DataIO, T, is_realdump_t);
  87. dio << var_uint32_t(x.size());
  88. if (!x.empty())
  89. DataIO_save_vector_aux(dio, x, bswap, is_realdump_t());
  90. }
  91. template<class DataIO, class T1, class T2, class Alloc, class Bswap>
  92. void DataIO_save_vector(DataIO& dio, const std::vector<std::pair<T1,T2>, Alloc>& x, Bswap bswap)
  93. {
  94. DataIO_is_realdump<
  95. DataIO,
  96. std::pair<T1,T2>,
  97. sizeof(T1)+sizeof(T2),
  98. DataIO_is_dump<DataIO, std::pair<T1,T2> >::value
  99. > tag(NULL);
  100. DataIO_save_vector_opt(dio, x, bswap, tag);
  101. }
  102. template<class DataIO, class T, class Alloc, class Bswap>
  103. void DataIO_save_vector(DataIO& dio, const std::vector<T, Alloc>& x, Bswap bswap)
  104. {
  105. DataIO_is_realdump<
  106. DataIO,
  107. T,
  108. sizeof(T),
  109. DataIO_is_dump<DataIO, T>::value
  110. > tag(NULL);
  111. DataIO_save_vector_opt(dio, x, bswap, tag);
  112. }
  113. //////////////////////////////////////////////////////////////////////////////////////////////////////
  114. template<class DataIO, class T>
  115. void DataIO_save_array_raw(DataIO& dio, const T* a, size_t n, boost::mpl::false_ bswap)
  116. {
  117. dio.ensureWrite(a, sizeof(T) * n);
  118. }
  119. template<class DataIO, class T>
  120. void DataIO_save_array_raw(DataIO& dio, const T* a, size_t n, boost::mpl::true_ bswap)
  121. {
  122. for (size_t i = n; i; --i, ++a)
  123. {
  124. T e(*a);
  125. byte_swap_in(e, bswap);
  126. dio.ensureWrite(&e, sizeof(T));
  127. }
  128. }
  129. template<class DataIO, class T, class Bswap>
  130. void DataIO_save_array_aux(DataIO& dio, const T* a, size_t n, Bswap bswap,
  131.    ::boost::mpl::true_ real_dumpable)
  132. {
  133. DataIO_save_array_raw(dio, a, n, bswap);
  134. }
  135. template<class DataIO, class T, class Bswap>
  136. void DataIO_save_array_aux(DataIO& dio, const T* a, size_t n, Bswap bswap,
  137.    ::boost::mpl::false_ real_dumpable)
  138. {
  139. for (size_t i = n; i; --i, ++a)
  140. dio << *a;
  141. }
  142. template<class DataIO, class T, int Size, bool Dumpable, class Bswap>
  143. void DataIO_save_array_opt(DataIO& dio, const T* a, size_t n, Bswap bswap,
  144.  DataIO_is_realdump<DataIO, T, Size, Dumpable> tag)
  145. {
  146. // sizeof(T) == Size implies T has no paddings
  147. BOOST_STATIC_ASSERT(sizeof(T) >= Size);
  148. typedef ::boost::mpl::bool_<sizeof(T)==Size && Dumpable> is_realdump_t;
  149. DATA_IO_OPT_TRAITS_VERIFY(DataIO, T, is_realdump_t);
  150. DataIO_save_array_aux(dio, a, n, bswap, is_realdump_t());
  151. }
  152. template<class DataIO, class T1, class T2, class Bswap>
  153. void DataIO_save_array(DataIO& dio, const std::pair<T1,T2>* a, size_t n, Bswap bs)
  154. {
  155. DataIO_is_realdump<
  156. DataIO,
  157. std::pair<T1,T2>,
  158. sizeof(T1)+sizeof(T2),
  159. DataIO_is_dump<DataIO, std::pair<T1,T2> >::value
  160. > tag(NULL);
  161. DataIO_save_array_opt(dio, a, n, bs, tag);
  162. }
  163. template<class DataIO, class T, class Bswap>
  164. void DataIO_save_array(DataIO& dio, const T* a, size_t n, Bswap bs)
  165. {
  166. DataIO_is_realdump<
  167. DataIO,
  168. T,
  169. sizeof(T),
  170. DataIO_is_dump<DataIO, T>::value
  171. > tag(NULL);
  172. DataIO_save_array_opt(dio, a, n, bs, tag);
  173. }
  174. //////////////////////////////////////////////////////////////////////////////////////////////////////
  175. template<class DataIO, class T>
  176. void DataIO_save_elem_raw(DataIO& dio, const T& x, ::boost::mpl::false_ bswap)
  177. {
  178. dio.ensureWrite(&x, sizeof(T));
  179. }
  180. template<class DataIO, class T>
  181. void DataIO_save_elem_raw(DataIO& dio, const T& x, ::boost::mpl::true_ bswap)
  182. {
  183. T e(x);
  184. byte_swap_in(e, bswap);
  185. dio.ensureWrite(&e, sizeof(T));
  186. }
  187. template<class DataIO, class T, class Bswap>
  188. void DataIO_save_elem_aux(DataIO& dio, const T& x, Bswap bswap, boost::mpl::true_ real_dumpable)
  189. {
  190. DataIO_save_elem_raw(dio, x, bswap);
  191. }
  192. template<class DataIO, class T, class Bswap>
  193. void DataIO_save_elem_aux(DataIO& dio, const T& x, Bswap bswap, boost::mpl::false_ real_dumpable)
  194. {
  195. DataIO_saveObject(dio, x);
  196. }
  197. template<class DataIO, class T, int Size, bool Dumpable, class Bswap>
  198. void DataIO_save_elem_opt(DataIO& dio, const T& x, Bswap bswap,
  199.   DataIO_is_realdump<DataIO, T, Size, Dumpable> tag)
  200. {
  201. BOOST_STATIC_ASSERT(sizeof(T) >= Size);
  202. typedef ::boost::mpl::bool_<sizeof(T)==Size && Dumpable> is_realdump_t;
  203. DATA_IO_OPT_TRAITS_VERIFY(DataIO, T, is_realdump_t);
  204. DataIO_save_elem_aux(dio, x, bswap, is_realdump_t());
  205. }
  206. template<class DataIO, class T, class Bswap>
  207. void DataIO_save_elem(DataIO& dio, const T& x, Bswap bswap)
  208. {
  209. DataIO_is_realdump<
  210. DataIO,
  211. T,
  212. sizeof(T),
  213. DataIO_is_dump<DataIO, T>::value
  214. > tag(NULL);
  215. DataIO_save_elem_opt(dio, x, bswap, tag);
  216. }
  217. //////////////////////////////////////////////////////////////////////////////////////////////////////
  218. //! string in file format: [length : ....content.... ]
  219. template<class PrimitiveOutput, class CharType, class Traits, class Allocator>
  220. void PrimitiveOutput_saveString(PrimitiveOutput& output, const std::basic_string<CharType, Traits, Allocator>& str)
  221. {
  222. var_uint32_t length(str.size());
  223. output << (length);
  224. output.save(str.data(), length.t);
  225. }
  226. //! @brief Primitive Output save string
  227. //!
  228. //! string in file format: [length : ....content.... ]
  229. //! @param[in]  buffer       pointer buffer
  230. //! @param[in]  length       buffer length
  231. template<class PrimitiveOutput, class CharType>
  232. void PrimitiveOutput_saveString(PrimitiveOutput& output, const CharType* buffer, size_t length)
  233. {
  234. assert(0 != buffer);
  235. output.save(buffer, length);
  236. }
  237. //////////////////////////////////////////////////////////////////////////
  238. //////////////////////////////////////////////////////////////////////////
  239. template<class BaseOutput, class Final_Output>
  240. class DataOutput : public BaseOutput
  241. {
  242. public:
  243. typedef boost::mpl::false_ is_loading;
  244. typedef boost::mpl::true_  is_saving;
  245. using BaseOutput::operator<<;
  246. //////////////////////////////////////////////////////////////////////////
  247. //! dual operator, for auto dispatch single serialize proc...
  248. //!
  249. //! for PrimitiveOutputImpl, operator& is output,
  250. //! for DataOutput, operator& is output.
  251. template<class T> Final_Output& operator&(const T& x) { return operator<<(x); }
  252. template<class T> Final_Output& operator& (pass_by_value<T> x) { return operator<<(x.val); }
  253. template<class T> Final_Output& operator<<(pass_by_value<T> x) { return operator<<(x.val); }
  254. template<class T> Final_Output& operator& (boost::reference_wrapper<T> x) { return operator<<(x.get()); }
  255. template<class T> Final_Output& operator<<(boost::reference_wrapper<T> x) { return operator<<(x.get()); }
  256. template<int Dim> Final_Output& operator<<(const char (&x)[Dim]) { return this->save(x, Dim); }
  257. template<int Dim> Final_Output& operator<<(const byte (&x)[Dim]) { return this->save(x, Dim); }
  258. #ifdef DATA_IO_SUPPORT_SERIALIZE_PTR
  259. template<class T> Final_Output& operator<<(T*& x)
  260. {
  261. *this << *x;
  262. return static_cast<Final_Output&>(*this);
  263. }
  264. template<class T> Final_Output& operator<<(const T*& x)
  265. {
  266. *this << *x;
  267. return static_cast<Final_Output&>(*this);
  268. }
  269. #else
  270. template<class T> Final_Output& operator<<(T*& x)
  271. {
  272. T::NotSupportSerializePointer();
  273. return static_cast<Final_Output&>(*this);
  274. }
  275. template<class T> Final_Output& operator<<(const T*& x)
  276. {
  277. T::NotSupportSerializePointer();
  278. return static_cast<Final_Output&>(*this);
  279. }
  280. #endif
  281. template<class Container>
  282. Final_Output& container_save(const Container& x)
  283. {
  284. var_uint32_t size(x.size());
  285. *this << size;
  286. for (typename Container::const_iterator i = x.begin(); i != x.end(); ++i)
  287. {
  288. *this << *i;
  289. }
  290. return static_cast<Final_Output&>(*this);
  291. }
  292. //!@{
  293. //! standard container output.....
  294. template<class KeyT, class ValueT, class CompareT, class AllocT>
  295. Final_Output& operator<<(const std::map<KeyT, ValueT, CompareT, AllocT>& x)
  296. {
  297. return container_save(x);
  298. }
  299. template<class KeyT, class ValueT, class CompareT, class AllocT>
  300. Final_Output& operator<<(const std::multimap<KeyT, ValueT, CompareT, AllocT>& x)
  301. {
  302. return container_save(x);
  303. }
  304. template<class ValueT, class CompareT, class AllocT>
  305. Final_Output& operator<<(const std::set<ValueT, CompareT, AllocT>& x)
  306. {
  307. return container_save(x);
  308. }
  309. template<class ValueT, class CompareT, class AllocT>
  310. Final_Output& operator<<(const std::multiset<ValueT, CompareT, AllocT>& x)
  311. {
  312. return container_save(x);
  313. }
  314. template<class ValueT, class AllocT>
  315. Final_Output& operator<<(const std::list<ValueT, AllocT>& x)
  316. {
  317. return container_save(x);
  318. }
  319. template<class ValueT, class AllocT>
  320. Final_Output& operator<<(const std::deque<ValueT, AllocT>& x)
  321. {
  322. return container_save(x);
  323. }
  324. };
  325. //////////////////////////////////////////////////////////////////////////
  326. template<class BaseOutput, class Final_Output>
  327. class VarIntVarOutput : public BaseOutput
  328. {
  329. public:
  330. using BaseOutput::operator<<;
  331. Final_Output& operator<<(var_int16_t x)
  332. {
  333. byte buf[3];
  334. this->ensureWrite(buf, save_var_int16(buf, x.t) - buf);
  335. return static_cast<Final_Output&>(*this);
  336. }
  337. Final_Output& operator<<(var_int32_t x)
  338. {
  339. byte buf[5];
  340. this->ensureWrite(buf, save_var_int32(buf, x.t) - buf);
  341. return static_cast<Final_Output&>(*this);
  342. }
  343. Final_Output& operator<<(var_uint16_t x)
  344. {
  345. byte buf[3];
  346. this->ensureWrite(buf, save_var_uint16(buf, x.t) - buf);
  347. return static_cast<Final_Output&>(*this);
  348. }
  349. Final_Output& operator<<(var_uint32_t x)
  350. {
  351. byte buf[5];
  352. this->ensureWrite(buf, save_var_uint32(buf, x.t) - buf);
  353. return static_cast<Final_Output&>(*this);
  354. }
  355. #if !defined(BOOST_NO_INT64_T)
  356. Final_Output& operator<<(var_int64_t x)
  357. {
  358. byte buf[9];
  359. this->ensureWrite(buf, save_var_int64(buf, x.t) - buf);
  360. return static_cast<Final_Output&>(*this);
  361. }
  362. Final_Output& operator<<(var_uint64_t x)
  363. {
  364. byte buf[9];
  365. this->ensureWrite(buf, save_var_uint64(buf, x.t) - buf);
  366. return static_cast<Final_Output&>(*this);
  367. }
  368. #endif
  369. Final_Output& operator<<(serialize_version_t x)
  370. {
  371. byte buf[5];
  372. this->ensureWrite(buf, save_var_uint32(buf, x.t) - buf);
  373. return static_cast<Final_Output&>(*this);
  374. }
  375. };
  376. template<class BaseOutput, class Final_Output>
  377. class VarIntFixedOutput : public BaseOutput
  378. {
  379. public:
  380. using BaseOutput::operator<<;
  381. Final_Output& operator<<(var_int16_t  x) { return this->operator<<(x.t); }
  382. Final_Output& operator<<(var_uint16_t x) { return this->operator<<(x.t); }
  383. Final_Output& operator<<(var_int32_t  x) { return this->operator<<(x.t); }
  384. Final_Output& operator<<(var_uint32_t x) { return this->operator<<(x.t); }
  385. #if !defined(BOOST_NO_INT64_T)
  386. Final_Output& operator<<(var_int64_t  x) { return this->operator<<(x.t); }
  387. Final_Output& operator<<(var_uint64_t x) { return this->operator<<(x.t); }
  388. #endif
  389. Final_Output& operator<<(serialize_version_t x) { return this->operator<<(x.t); }
  390. };
  391. template<class BaseOutput, class Final_Output>
  392. class BigEndianStringOutput : public BaseOutput
  393. {
  394. public:
  395. using BaseOutput::operator<<;
  396. Final_Output& save(const wchar_t* s, size_t n)
  397. {
  398. #ifdef BOOST_BIG_ENDIAN
  399. this->ensureWrite(s, sizeof(wchar_t)*n);
  400. #else
  401. std::vector<wchar_t> tempv(s, s + n);
  402. byte_swap(&*tempv.begin(), n);
  403. this->ensureWrite(&*tempv.begin(), sizeof(wchar_t)*n);
  404. #endif
  405. return static_cast<Final_Output&>(*this);
  406. }
  407. #ifndef BOOST_NO_INTRINSIC_WCHAR_T
  408. Final_Output& operator<<(wchar_t x)
  409. {
  410. #ifdef BOOST_LITTLE_ENDIAN
  411. x = byte_swap(x);
  412. #endif
  413. this->ensureWrite(&x, sizeof(x));
  414. return static_cast<Final_Output&>(*this);
  415. }
  416. #endif
  417. };
  418. template<class BaseOutput, class Final_Output>
  419. class LittleEndianStringOutput : public BaseOutput
  420. {
  421. public:
  422. using BaseOutput::operator<<;
  423. Final_Output& save(const wchar_t* s, size_t n)
  424. {
  425. #ifdef BOOST_LITTLE_ENDIAN
  426. this->ensureWrite(s, sizeof(wchar_t)*n);
  427. #else
  428. std::vector<wchar_t> tempv(s, s + n);
  429. byte_swap(&*tempv.begin(), n);
  430. this->ensureWrite(&*tempv.begin(), sizeof(wchar_t)*n);
  431. #endif
  432. return static_cast<Final_Output&>(*this);
  433. }
  434. #ifndef BOOST_NO_INTRINSIC_WCHAR_T
  435. Final_Output& operator<<(wchar_t x)
  436. {
  437. #ifdef BOOST_BIG_ENDIAN
  438. x = byte_swap(x);
  439. #endif
  440. this->ensureWrite(&x, sizeof(x));
  441. return static_cast<Final_Output&>(*this);
  442. }
  443. #endif
  444. };
  445. template<class BaseOutput, class Final_Output>
  446. class CommonStringOutput : public BaseOutput
  447. {
  448. public:
  449. using BaseOutput::save;
  450. using BaseOutput::operator<<;
  451. Final_Output& save(const char* s, size_t n) { this->ensureWrite(s, n); return static_cast<Final_Output&>(*this); }
  452. Final_Output& save(const unsigned char* s, size_t n) { this->ensureWrite(s, n); return static_cast<Final_Output&>(*this); }
  453. Final_Output& save(const   signed char* s, size_t n) { this->ensureWrite(s, n); return static_cast<Final_Output&>(*this); }
  454. Final_Output& operator<<(const char* s)
  455. {
  456. var_uint32_t n(strlen(s));
  457. static_cast<Final_Output&>(*this) << n;
  458. this->ensureWrite(s, n.t);
  459. return static_cast<Final_Output&>(*this);
  460. }
  461. Final_Output& operator<<(const wchar_t* s)
  462. {
  463. var_uint32_t n(wcslen(s));
  464. static_cast<Final_Output&>(*this) << n;
  465. this->save(s, n.t);
  466. return static_cast<Final_Output&>(*this);
  467. }
  468. #if 0
  469. template<class CharType, class Traits, class Allocator>
  470. Final_Output& operator<<(const std::basic_string<CharType, Traits, Allocator>& x)
  471. {
  472. var_uint32_t length(x.size());
  473. *this << (length);
  474. this->save(x.data(), length.t);
  475. return static_cast<Final_Output&>(*this);
  476. }
  477. #else
  478. Final_Output& operator<<(const std::string& x)
  479. {
  480. var_uint32_t length(x.size());
  481. *this << (length);
  482. this->save(x.data(), length.t);
  483. return static_cast<Final_Output&>(*this);
  484. }
  485. Final_Output& operator<<(const std::wstring& x)
  486. {
  487. var_uint32_t length(x.size());
  488. *this << (length);
  489. this->save(x.data(), length.t);
  490. return static_cast<Final_Output&>(*this);
  491. }
  492. #endif
  493. };
  494. template<class StreamT, class Final_Output>
  495. class PrimitiveOutputImpl : public StreamT
  496. {
  497. //  this will cause compile error!!
  498. // DECLARE_NONE_COPYABLE_CLASS(PrimitiveOutputImpl)
  499. public:
  500. typedef StreamT stream_t;
  501. StreamT* getStream() { return this; }
  502. Final_Output& operator<<(char x) { this->writeByte((byte)x); return static_cast<Final_Output&>(*this); }
  503. Final_Output& operator<<(unsigned char x) { this->writeByte((byte)x); return static_cast<Final_Output&>(*this); }
  504. Final_Output& operator<<(  signed char x) { this->writeByte((byte)x); return static_cast<Final_Output&>(*this); }
  505. };
  506. template<class StreamT, class Final_Output>
  507. class PrimitiveOutputImpl<StreamT*, Final_Output>
  508. {
  509. protected:
  510. StreamT* stream;
  511. public:
  512. typedef StreamT stream_t;
  513. typedef typename StreamT::is_seekable is_seekable;
  514. void attach(StreamT* stream) { this->stream = stream; }
  515. StreamT* getStream() const { return stream; }
  516. void flush() { stream->flush(); }
  517. //! delegate these 2 method of StreamT
  518. size_t write(const void* data, size_t length) { return stream->write(data, length); }
  519. void ensureWrite(const void* data, size_t length) { stream->ensureWrite(data, length); }
  520. Final_Output& operator<<(char x) { stream->writeByte((byte)x); return static_cast<Final_Output&>(*this); }
  521. Final_Output& operator<<(byte x) { stream->writeByte((byte)x); return static_cast<Final_Output&>(*this); }
  522. Final_Output& operator<<(signed char x) { stream->writeByte((byte)x); return static_cast<Final_Output&>(*this); }
  523. };
  524. #define DATA_IO_GEN_DUMP_OUTPUT(Type)
  525. Final_Output& operator<<(Type x) {
  526. this->ensureWrite(&x, sizeof(Type));
  527. return static_cast<Final_Output&>(*this); 
  528. }
  529. template<int Dim>
  530. Final_Output& operator<<(const Type (&x)[Dim]) {
  531. this->ensureWrite(x, sizeof(Type)*Dim);
  532. return static_cast<Final_Output&>(*this); 
  533. }
  534. template<class Alloc>
  535. Final_Output& operator<<(const std::vector<Type, Alloc>& x) {
  536. static_cast<Final_Output&>(*this) << var_uint32_t(x.size());
  537. if (!x.empty()) 
  538.   this->ensureWrite(&*x.begin(), sizeof(Type) * x.size());
  539. return static_cast<Final_Output&>(*this); 
  540. }
  541. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  542. #define DATA_IO_GEN_BSWAP_INT_OUTPUT(Int)
  543. Final_Output& operator<<(Int x) {
  544. x = byte_swap(x);
  545. this->ensureWrite(&x, sizeof(Int));
  546. return static_cast<Final_Output&>(*this); 
  547. }
  548. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  549. template<class BaseOutput, class Final_Output>
  550. class BinFloatOutput : public BaseOutput
  551. {
  552. public:
  553. using BaseOutput::operator<<;
  554. DATA_IO_GEN_DUMP_OUTPUT(float)
  555. DATA_IO_GEN_DUMP_OUTPUT(double)
  556. DATA_IO_GEN_DUMP_OUTPUT(long double)
  557. };
  558. template<class StreamT, class Final_Output>
  559. class PortableIntegerOutput : public PrimitiveOutputImpl<StreamT, Final_Output>
  560. {
  561. public:
  562. using PrimitiveOutputImpl<StreamT, Final_Output>::operator<<;
  563. #ifdef BOOST_LITTLE_ENDIAN
  564. #define DATA_IO_GEN_PORTABLE_INT_OUTPUT  DATA_IO_GEN_BSWAP_INT_OUTPUT
  565. #elif defined(BOOST_BIG_ENDIAN)
  566. #define DATA_IO_GEN_PORTABLE_INT_OUTPUT  DATA_IO_GEN_DUMP_OUTPUT
  567. #else
  568. #error "must define BOOST_LITTLE_ENDIAN or BOOST_BIG_ENDIAN"
  569. #endif
  570. DATA_IO_GEN_PORTABLE_INT_OUTPUT(short)
  571. DATA_IO_GEN_PORTABLE_INT_OUTPUT(unsigned short)
  572. DATA_IO_GEN_PORTABLE_INT_OUTPUT(int)
  573. DATA_IO_GEN_PORTABLE_INT_OUTPUT(unsigned int)
  574. DATA_IO_GEN_PORTABLE_INT_OUTPUT(long)
  575. DATA_IO_GEN_PORTABLE_INT_OUTPUT(unsigned long)
  576. #if defined(BOOST_HAS_LONG_LONG)
  577. DATA_IO_GEN_PORTABLE_INT_OUTPUT(long long)
  578. DATA_IO_GEN_PORTABLE_INT_OUTPUT(unsigned long long)
  579. #elif defined(BOOST_HAS_MS_INT64)
  580. DATA_IO_GEN_PORTABLE_INT_OUTPUT(__int64)
  581. DATA_IO_GEN_PORTABLE_INT_OUTPUT(unsigned __int64)
  582. #endif
  583. template<class T> Final_Output& operator<<(const T& x)
  584. {
  585. DataIO_save_elem(static_cast<Final_Output&>(*this), x, DATA_IO_BSWAP_FOR_BIG(T)());
  586. return static_cast<Final_Output&>(*this);
  587. }
  588. template<class T, int Dim>
  589. Final_Output& operator<<(const T (&x)[Dim])
  590. {
  591. DataIO_save_array(static_cast<Final_Output&>(*this), x, Dim, DATA_IO_BSWAP_FOR_BIG(T)());
  592. return static_cast<Final_Output&>(*this);
  593. }
  594. template<class T, class Alloc>
  595. Final_Output& operator<<(const std::vector<T, Alloc>& x)
  596. {
  597. DataIO_save_vector(static_cast<Final_Output&>(*this), x, DATA_IO_BSWAP_FOR_BIG(T)());
  598. return static_cast<Final_Output&>(*this);
  599. }
  600. };
  601. template<class StreamT, class Final_Output>
  602. class LittleEndianIntegerOutput : public PrimitiveOutputImpl<StreamT, Final_Output>
  603. {
  604. public:
  605. using PrimitiveOutputImpl<StreamT, Final_Output>::operator<<;
  606. #ifdef BOOST_LITTLE_ENDIAN
  607. #define DATA_IO_GEN_LITTLE_INT_OUTPUT  DATA_IO_GEN_DUMP_OUTPUT
  608. #elif defined(BOOST_BIG_ENDIAN)
  609. #define DATA_IO_GEN_LITTLE_INT_OUTPUT  DATA_IO_GEN_BSWAP_INT_OUTPUT
  610. #else
  611. #error "must define BOOST_LITTLE_ENDIAN or BOOST_BIG_ENDIAN"
  612. #endif
  613. DATA_IO_GEN_LITTLE_INT_OUTPUT(short)
  614. DATA_IO_GEN_LITTLE_INT_OUTPUT(unsigned short)
  615. DATA_IO_GEN_LITTLE_INT_OUTPUT(int)
  616. DATA_IO_GEN_LITTLE_INT_OUTPUT(unsigned int)
  617. DATA_IO_GEN_LITTLE_INT_OUTPUT(long)
  618. DATA_IO_GEN_LITTLE_INT_OUTPUT(unsigned long)
  619. #if defined(BOOST_HAS_LONG_LONG)
  620. DATA_IO_GEN_LITTLE_INT_OUTPUT(long long)
  621. DATA_IO_GEN_LITTLE_INT_OUTPUT(unsigned long long)
  622. #elif defined(BOOST_HAS_MS_INT64)
  623. DATA_IO_GEN_LITTLE_INT_OUTPUT(__int64)
  624. DATA_IO_GEN_LITTLE_INT_OUTPUT(unsigned __int64)
  625. #endif
  626. template<class T> Final_Output& operator<<(const T& x)
  627. {
  628. DataIO_save_elem(static_cast<Final_Output&>(*this), x, DATA_IO_BSWAP_FOR_LITTLE(T)());
  629. return static_cast<Final_Output&>(*this);
  630. }
  631. template<class T, int Dim>
  632. Final_Output& operator<<(const T (&x)[Dim])
  633. {
  634. DataIO_save_array(static_cast<Final_Output&>(*this), x, Dim, DATA_IO_BSWAP_FOR_LITTLE(T)());
  635. return static_cast<Final_Output&>(*this);
  636. }
  637. template<class T, class Alloc>
  638. Final_Output& operator<<(const std::vector<T, Alloc>& x)
  639. {
  640. DataIO_save_vector(static_cast<Final_Output&>(*this), x, DATA_IO_BSWAP_FOR_LITTLE(T)());
  641. return static_cast<Final_Output&>(*this);
  642. }
  643. };
  644. #define PortableStringOutput BigEndianStringOutput
  645. template<class StreamT>
  646. class LittleEndianDataOutput : public DATA_IO_BASE_IO(LittleEndianDataOutput, LittleEndian, VarIntVar, Output, StreamT)
  647. {
  648. public:
  649. LittleEndianDataOutput() {}
  650. };
  651. template<class StreamT>
  652. class LittleEndianDataOutput<StreamT*> : public DATA_IO_BASE_IO(LittleEndianDataOutput, LittleEndian, VarIntVar, Output, StreamT*)
  653. {
  654. public:
  655. explicit LittleEndianDataOutput(StreamT* stream) { this->stream = stream; }
  656. };
  657. template<class StreamT>
  658. class PortableDataOutput : public DATA_IO_BASE_IO(PortableDataOutput, Portable, VarIntVar, Output, StreamT)
  659. {
  660. public:
  661. PortableDataOutput() {}
  662. };
  663. template<class StreamT>
  664. class PortableDataOutput<StreamT*> : public DATA_IO_BASE_IO(PortableDataOutput, Portable, VarIntVar, Output, StreamT*)
  665. {
  666. public:
  667. explicit PortableDataOutput(StreamT* stream = 0) { this->stream = stream; }
  668. };
  669. //////////////////////////////////////////////////////////////////////////
  670. template<class StreamT>
  671. class LittleEndianNoVarIntOutput : public DATA_IO_BASE_IO(LittleEndianNoVarIntOutput, LittleEndian, VarIntFixed, Output, StreamT)
  672. {
  673. public:
  674. LittleEndianNoVarIntOutput() {}
  675. };
  676. template<class StreamT>
  677. class LittleEndianNoVarIntOutput<StreamT*> : public DATA_IO_BASE_IO(LittleEndianNoVarIntOutput, LittleEndian, VarIntFixed, Output, StreamT*)
  678. {
  679. public:
  680. explicit LittleEndianNoVarIntOutput(StreamT* stream) { this->stream = stream; }
  681. };
  682. template<class StreamT>
  683. class PortableNoVarIntOutput : public DATA_IO_BASE_IO(PortableNoVarIntOutput, Portable, VarIntFixed, Output, StreamT)
  684. {
  685. public:
  686. PortableNoVarIntOutput() {}
  687. };
  688. template<class StreamT>
  689. class PortableNoVarIntOutput<StreamT*> : public DATA_IO_BASE_IO(PortableNoVarIntOutput, Portable, VarIntFixed, Output, StreamT*)
  690. {
  691. public:
  692. explicit PortableNoVarIntOutput(StreamT* stream = 0) { this->stream = stream; }
  693. };
  694. //////////////////////////////////////////////////////////////////////////
  695. template<class StreamClass>
  696. LittleEndianDataOutput<StreamClass*> LittleEndianDataOutputer(StreamClass* stream)
  697. {
  698. return LittleEndianDataOutput<StreamClass*>(stream);
  699. }
  700. template<class StreamClass>
  701. PortableDataOutput<StreamClass*> PortableDataOutputer(StreamClass* stream)
  702. {
  703. return PortableDataOutput<StreamClass*>(stream);
  704. }
  705. //////////////////////////////////////////////////////////////////////////
  706. template<class Output, class FirstT, class SecondT>
  707. void DataIO_saveObject(Output& output, const std::pair<FirstT, SecondT>& x)
  708. {
  709. output << x.first << x.second;
  710. }
  711. #define DATA_IO_REG_SAVE(Class) 
  712.   template<class Output> friend void DataIO_saveObject(Output& output, const Class& x) { x.save(output); }
  713. #define DATA_IO_REG_SAVE_V(Class, CurrentVersion)
  714. template<class Output>
  715. friend void DataIO_saveObject(Output& out, const Class& x)
  716. {
  717. out << febird::serialize_version_t(CurrentVersion);
  718. x.save(out, CurrentVersion);
  719. }
  720. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  721. #define DATA_IO_DISABLE_SAVE(Class) 
  722.   template<class DataIO>
  723.   friend void DataIO_saveObject(DataIO& dio, const Class& x) { dio.DisableSaveClass(x); }
  724. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  725. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  726. #ifdef FEBIRD_DATA_IO_DISABLE_OPTIMIZE_DUMPABLE
  727. #define DATA_IO_OPTIMIZE_VECTOR_SAVE(Self, Class, Members)
  728. #define DATA_IO_OPTIMIZE_ELEMEN_SAVE(Self, Class, Members)
  729. #define DATA_IO_OPTIMIZE_ARRAY_SAVE(Self, Class, Members)
  730. #else
  731. //! 宏中的成员函数使用较长的参数名,目的是避免和 Members 中的某个成员同名
  732. //!
  733. #define DATA_IO_OPTIMIZE_VECTOR_SAVE(Derived, Class, Members)
  734. template<class DataIO, class Alloc, class Bswap>
  735. void save_vector(DataIO& aDataIO,
  736. const std::vector<Class, Alloc>& _vector_,
  737. Bswap)
  738. {
  739. DataIO_save_vector_opt(
  740. aDataIO, _vector_, Bswap(),
  741. DataIO_is_realdump<DataIO,Class,0,true>(this)Members);
  742. }
  743. template<class DataIO, class Alloc, class Bswap>
  744. friend void DataIO_save_vector(DataIO& dio,
  745. const std::vector<Class, Alloc>& x,
  746. Bswap bswap)
  747. {
  748. ((Derived*)0)->save_vector(dio, x, bswap);
  749. }
  750. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  751. #define DATA_IO_OPTIMIZE_ARRAY_SAVE(Derived, Class, Members) 
  752. template<class DataIO, class Bswap>
  753. void save_array(DataIO& aDataIO
  754. , const Class* _A_address, size_t _N_count
  755. , Bswap)
  756. {
  757. DataIO_save_array_opt(
  758. aDataIO, _A_address, _N_count, Bswap(),
  759. DataIO_is_realdump<DataIO,Class,0,true>(this)Members);
  760. }
  761. template<class DataIO, class Bswap>
  762. friend void DataIO_save_array(DataIO& dio
  763. , const Class* a, size_t n, Bswap bswap)
  764. {
  765. ((Derived*)0)->save_array(dio, a, n, bswap);
  766. }
  767. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  768. #define DATA_IO_OPTIMIZE_ELEMEN_SAVE(Self, Class, Members)
  769. template<class DataIO, class Bswap>
  770. void opt_save(DataIO& aDataIO, Bswap) const
  771. {
  772. DataIO_save_elem_opt(aDataIO, *this, Bswap(),
  773. DataIO_is_realdump<DataIO,Class,0,true>(this)Members);
  774. }
  775. template<class DataIO, class Bswap> friend
  776. void DataIO_save_elem(DataIO& dio,
  777. const Class& x, Bswap bswap)
  778. {
  779. Self(x).opt_save(dio, bswap);
  780. }
  781. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  782. #endif // FEBIRD_DATA_IO_DISABLE_OPTIMIZE_DUMPABLE
  783. #ifdef BOOST_LITTLE_ENDIAN
  784. #define NativeDataOutput LittleEndianDataOutput
  785. #define NativeNoVarIntOutput LittleEndianNoVarIntOutput
  786. #elif defined(BOOST_BIG_ENDIAN)
  787. #define NativeDataOutput PortableDataOutput
  788. #define NativeNoVarIntOutput PortableNoVarIntOutput
  789. #else
  790. #error "must define BOOST_LITTLE_ENDIAN or BOOST_BIG_ENDIAN"
  791. #endif
  792. } // namespace febird
  793. #endif // __febird_io_DataOutput_h__