ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

345 lines
7.3 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // See accompanying file COPYING.TXT file for licensing details.
  6. //
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #ifndef CPPCMS_SERIALIZATION_CLASSES_H
  9. #define CPPCMS_SERIALIZATION_CLASSES_H
  10. #include <cppcms/defs.h>
  11. #include <booster/copy_ptr.h>
  12. #include <string>
  13. #include <booster/backtrace.h>
  14. #include <booster/traits/enable_if.h>
  15. #include <booster/traits/is_base_of.h>
  16. namespace cppcms {
  17. #ifdef CPPCMS_DOXYGEN_DOCS
  18. ///
  19. /// \brief Special traits class that describes how to serialize various
  20. /// objects that are not defived from serializable_base.
  21. ///
  22. template<typename Object>
  23. struct archive_traits
  24. {
  25. ///
  26. /// Save object to archive function
  27. ///
  28. static void save(Object const &d,archive &a);
  29. ///
  30. /// Load object from archive function
  31. ///
  32. static void load(Object &d,archive &a);
  33. };
  34. #else
  35. template<typename Object,typename Enable = void>
  36. struct archive_traits;
  37. #endif
  38. ///
  39. /// \brief Error thrown in case of serialization error
  40. ///
  41. class archive_error : public booster::runtime_error {
  42. public:
  43. archive_error(std::string const &e) : booster::runtime_error("cppcms::archive_error: " + e)
  44. {
  45. }
  46. };
  47. ///
  48. /// \brief Class that represents a binary archive that can be stored in persistent storage or
  49. /// transfered.
  50. ///
  51. class CPPCMS_API archive {
  52. public:
  53. ///
  54. /// Reserve some memory before we write actual data
  55. ///
  56. void reserve(size_t size);
  57. ///
  58. /// Write a chunk of size len to archive
  59. ///
  60. void write_chunk(void const *begin,size_t len);
  61. ///
  62. /// Read a chunk of size len from archive
  63. ///
  64. void read_chunk(void *begin,size_t len);
  65. ///
  66. /// Get the size of the next chunk that can be read
  67. ///
  68. size_t next_chunk_size();
  69. ///
  70. /// Get if we got to the end of archive while reading
  71. ///
  72. bool eof();
  73. ///
  74. /// Read next chunk as std::string
  75. ///
  76. std::string read_chunk_as_string();
  77. ///
  78. /// Operations mode on archive
  79. ///
  80. typedef enum {
  81. save_to_archive,
  82. load_from_archive
  83. } mode_type;
  84. ///
  85. /// Set IO mode, resets pointer
  86. ///
  87. void mode(mode_type m);
  88. ///
  89. /// Get IO mode
  90. ///
  91. mode_type mode();
  92. ///
  93. /// Reset IO pointer
  94. ///
  95. void reset();
  96. ///
  97. /// Get serialized object memory
  98. ///
  99. std::string str();
  100. ///
  101. /// Set serialized object memory, sets mode to load_from_archive
  102. ///
  103. void str(std::string const &str);
  104. ///
  105. /// Create new archive, by default in save_to_archive mode
  106. ///
  107. archive();
  108. ///
  109. /// Destructor
  110. ///
  111. ~archive();
  112. ///
  113. /// Copy archive (avoid it)
  114. ///
  115. archive(archive const &);
  116. ///
  117. /// Assign archive (avoid it)
  118. ///
  119. archive const &operator=(archive const &);
  120. private:
  121. std::string buffer_;
  122. size_t ptr_;
  123. mode_type mode_;
  124. struct _data;
  125. booster::copy_ptr<_data> d;
  126. };
  127. ///
  128. /// Operator that performs load or store \a object operations
  129. /// on archive \a
  130. ///
  131. template<typename Archivable>
  132. archive & operator &(archive &a,Archivable &object)
  133. {
  134. if(a.mode() == archive::save_to_archive)
  135. archive_traits<Archivable>::save(object,a);
  136. else
  137. archive_traits<Archivable>::load(object,a);
  138. return a;
  139. }
  140. ///
  141. /// Operator that saves an object to the archive
  142. ///
  143. template<typename Archivable>
  144. archive & operator <<(archive &a,Archivable const &object)
  145. {
  146. archive_traits<Archivable>::save(object,a);
  147. return a;
  148. }
  149. ///
  150. /// Operator that loads an object from the archive
  151. ///
  152. template<typename Archivable>
  153. archive & operator >>(archive &a,Archivable &object)
  154. {
  155. archive_traits<Archivable>::load(object,a);
  156. return a;
  157. }
  158. ///
  159. /// \brief Base abstract class for object that can be serialized into std::string
  160. ///
  161. class serializable_base {
  162. public:
  163. ///
  164. /// Load object from archive
  165. ///
  166. virtual void load(archive &serialized_object) = 0;
  167. ///
  168. /// Save object to archive
  169. ///
  170. virtual void save(archive &serialized_object) const = 0;
  171. virtual ~serializable_base()
  172. {
  173. }
  174. };
  175. ///
  176. /// \brief Abstract class for serialization object
  177. ///
  178. class serializable : public serializable_base {
  179. public:
  180. ///
  181. /// Abstract function that should be implemented for correct serialization
  182. /// of an object, it allows implementing only one function for load and save instead of two.
  183. ///
  184. /// For example:
  185. ///
  186. /// \code
  187. ///
  188. /// struct persone : public serializable {
  189. /// double age;
  190. /// std::string name;
  191. /// std::vector<std::string> kids_names;
  192. ///
  193. /// void serialize(archive &a)
  194. /// {
  195. /// a & age & name & kids_names;
  196. /// }
  197. /// };
  198. /// \endcode
  199. ///
  200. virtual void serialize(archive &a) = 0;
  201. ///
  202. /// Calls serialize member functions
  203. ///
  204. virtual void load(archive &a)
  205. {
  206. serialize(a);
  207. }
  208. ///
  209. /// Const-casts and calls serialize member function
  210. ///
  211. virtual void save(archive &a) const
  212. {
  213. const_cast<serializable *>(this)->serialize(a);
  214. }
  215. };
  216. #ifdef CPPCMS_DOXYGEN_DOCS
  217. ///
  218. /// \brief This is the traits class for serialization traits.
  219. ///
  220. /// It allows user to use
  221. /// arbitrary serialization libraries or use its own serialization rules,
  222. /// for example you can use boost::serialization.
  223. ///
  224. /// For this purpose user should specialize the serialization_traits struct for his type.
  225. ///
  226. /// For example: We want to allow a serialization of a point class:
  227. ///
  228. /// \code
  229. ///
  230. //// namespace cppcms {
  231. /// template<>
  232. /// struct serialization_traits<point> {
  233. ///
  234. /// void load(std::string const &serialized_object,point &real_object)
  235. /// {
  236. /// std::stringstream ss(serialized_object);
  237. /// ss >> real_object.x >> real_object.y;
  238. /// }
  239. /// void save(point const &real_object,std::string &serialized_object)
  240. /// {
  241. /// std::stringstream ss;
  242. /// ss << real_object.x << ' ' << real_object.y;
  243. /// serialized_object = ss.str();
  244. /// }
  245. /// };
  246. /// } // cppcms
  247. ///
  248. /// \endcode
  249. ///
  250. template<typename Object>
  251. struct serialization_traits {
  252. ///
  253. /// Load \a real_object from the \a serialized_object representation (std::string)
  254. ///
  255. static void load(std::string const &serialized_object,Object &real_object);
  256. ///
  257. /// Save \a real_object to the \a serialized_object representation (std::string)
  258. ///
  259. static void save(Object const &real_object,std::string &serialized_object);
  260. };
  261. #else
  262. template<typename Object,typename Enable = void>
  263. struct serialization_traits;
  264. ///
  265. /// \brief Traits for serializable objects - converts object to and from string
  266. /// using archive class
  267. ///
  268. template<typename D>
  269. struct serialization_traits<D,typename booster::enable_if<booster::is_base_of<serializable_base,D> >::type> {
  270. ///
  271. /// Convert string to object
  272. ///
  273. static void load(std::string const &serialized_object,serializable_base &real_object)
  274. {
  275. archive a;
  276. a.str(serialized_object);
  277. real_object.load(a);
  278. }
  279. ///
  280. /// Convert object to string
  281. ///
  282. static void save(serializable_base const &real_object,std::string &serialized_object)
  283. {
  284. archive a;
  285. real_object.save(a);
  286. serialized_object = a.str();
  287. }
  288. };
  289. #endif
  290. } /// cppcms
  291. #endif