CppCMS
|
00001 00002 // 00003 // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com> 00004 // 00005 // See accompanying file COPYING.TXT file for licensing details. 00006 // 00008 #ifndef CPPCMS_SERIALIZATION_CLASSES_H 00009 #define CPPCMS_SERIALIZATION_CLASSES_H 00010 00011 #include <cppcms/defs.h> 00012 #include <booster/copy_ptr.h> 00013 #include <string> 00014 #include <booster/backtrace.h> 00015 00016 #include <booster/traits/enable_if.h> 00017 #include <booster/traits/is_base_of.h> 00018 00019 namespace cppcms { 00020 00021 #ifdef CPPCMS_DOXYGEN_DOCS 00022 00023 00024 00025 00026 template<typename Object> 00027 struct archive_traits 00028 { 00032 static void save(Object const &d,archive &a); 00036 static void load(Object &d,archive &a); 00037 }; 00038 00039 #else 00040 00041 template<typename Object,typename Enable = void> 00042 struct archive_traits; 00043 #endif 00044 00045 00049 class archive_error : public booster::runtime_error { 00050 public: 00051 archive_error(std::string const &e) : booster::runtime_error("cppcms::archive_error: " + e) 00052 { 00053 } 00054 }; 00055 00056 00061 class CPPCMS_API archive { 00062 public: 00063 00067 void reserve(size_t size); 00068 00072 void write_chunk(void const *begin,size_t len); 00073 00077 void read_chunk(void *begin,size_t len); 00078 00082 size_t next_chunk_size(); 00083 00087 bool eof(); 00088 00089 00093 std::string read_chunk_as_string(); 00094 00098 typedef enum { 00099 save_to_archive, 00100 load_from_archive 00101 } mode_type; 00102 00106 void mode(mode_type m); 00107 00111 mode_type mode(); 00112 00116 void reset(); 00117 00121 std::string str(); 00122 00126 void str(std::string const &str); 00127 00131 archive(); 00132 00136 ~archive(); 00137 00141 archive(archive const &); 00142 00146 archive const &operator=(archive const &); 00147 00148 private: 00149 std::string buffer_; 00150 size_t ptr_; 00151 mode_type mode_; 00152 00153 struct _data; 00154 booster::copy_ptr<_data> d; 00155 00156 }; 00157 00162 template<typename Archivable> 00163 archive & operator &(archive &a,Archivable &object) 00164 { 00165 if(a.mode() == archive::save_to_archive) 00166 archive_traits<Archivable>::save(object,a); 00167 else 00168 archive_traits<Archivable>::load(object,a); 00169 return a; 00170 } 00171 00175 template<typename Archivable> 00176 archive & operator <<(archive &a,Archivable const &object) 00177 { 00178 archive_traits<Archivable>::save(object,a); 00179 return a; 00180 } 00181 00185 template<typename Archivable> 00186 archive & operator >>(archive &a,Archivable &object) 00187 { 00188 archive_traits<Archivable>::load(object,a); 00189 return a; 00190 } 00191 00192 00193 00194 00198 class serializable_base { 00199 public: 00203 virtual void load(archive &serialized_object) = 0; 00207 virtual void save(archive &serialized_object) const = 0; 00208 00209 virtual ~serializable_base() 00210 { 00211 } 00212 }; 00213 00217 class serializable : public serializable_base { 00218 public: 00219 00240 00241 virtual void serialize(archive &a) = 0; 00245 virtual void load(archive &a) 00246 { 00247 serialize(a); 00248 } 00252 virtual void save(archive &a) const 00253 { 00254 const_cast<serializable *>(this)->serialize(a); 00255 } 00256 }; 00257 00258 00259 #ifdef CPPCMS_DOXYGEN_DOCS 00260 00294 00295 template<typename Object> 00296 struct serialization_traits { 00300 static void load(std::string const &serialized_object,Object &real_object); 00301 00305 static void save(Object const &real_object,std::string &serialized_object); 00306 }; 00307 00308 #else 00309 00310 template<typename Object,typename Enable = void> 00311 struct serialization_traits; 00312 00317 template<typename D> 00318 struct serialization_traits<D,typename booster::enable_if<booster::is_base_of<serializable_base,D> >::type> { 00322 static void load(std::string const &serialized_object,serializable_base &real_object) 00323 { 00324 archive a; 00325 a.str(serialized_object); 00326 real_object.load(a); 00327 } 00331 static void save(serializable_base const &real_object,std::string &serialized_object) 00332 { 00333 archive a; 00334 real_object.save(a); 00335 serialized_object = a.str(); 00336 } 00337 }; 00338 00339 00340 #endif 00341 00342 00343 } 00344 #endif