CppCMS
cppcms/serialization_classes.h
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