00001
00002
00003
00004
00005
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