Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef SERIALIZE_H
00014 #define SERIALIZE_H
00015
00016 #include <sstream>
00017
00018 #include "anope.h"
00019 #include "base.h"
00020
00021 namespace Serialize
00022 {
00023 class Data
00024 {
00025 public:
00026 enum Type
00027 {
00028 DT_TEXT,
00029 DT_INT
00030 };
00031
00032 virtual ~Data() { }
00033
00034 virtual std::iostream& operator[](const Anope::string &key) = 0;
00035 virtual std::set<Anope::string> KeySet() const { throw CoreException("Not supported"); }
00036 virtual size_t Hash() const { throw CoreException("Not supported"); }
00037
00038 virtual void SetType(const Anope::string &key, Type t) { }
00039 virtual Type GetType(const Anope::string &key) const { return DT_TEXT; }
00040 };
00041
00042 extern void RegisterTypes();
00043 extern void CheckTypes();
00044
00045 class Type;
00046 template<typename T> class Checker;
00047 template<typename T> class Reference;
00048 }
00049
00054 class CoreExport Serializable : public virtual Base
00055 {
00056 private:
00057
00058
00059
00060
00061
00062 static std::list<Serializable *> *SerializableItems;
00063
00064 Serialize::Type *s_type;
00065 private:
00066
00067 std::list<Serializable *>::iterator s_iter;
00068
00069 size_t last_commit;
00070
00071 time_t last_commit_time;
00072
00073 protected:
00074 Serializable(const Anope::string &serialize_type);
00075 Serializable(const Serializable &);
00076
00077 Serializable &operator=(const Serializable &);
00078
00079 public:
00080 virtual ~Serializable();
00081
00082
00083 unsigned int id;
00084
00087 void QueueUpdate();
00088
00089 bool IsCached(Serialize::Data &);
00090 void UpdateCache(Serialize::Data &);
00091
00092 bool IsTSCached();
00093 void UpdateTS();
00094
00098 Serialize::Type* GetSerializableType() const { return this->s_type; }
00099
00100 virtual void Serialize(Serialize::Data &data) const = 0;
00101
00102 static const std::list<Serializable *> &GetItems();
00103 };
00104
00105
00106
00107
00108
00109 class CoreExport Serialize::Type
00110 {
00111 typedef Serializable* (*unserialize_func)(Serializable *obj, Serialize::Data &);
00112
00113 static std::vector<Anope::string> TypeOrder;
00114 static std::map<Anope::string, Serialize::Type *> Types;
00115
00116
00117 Anope::string name;
00118 unserialize_func unserialize;
00119
00120
00121
00122 Module *owner;
00123
00124
00125
00126
00127
00128 time_t timestamp;
00129
00130 public:
00131
00132 std::map<unsigned int, Serializable *> objects;
00133
00139 Type(const Anope::string &n, unserialize_func f, Module *owner = NULL);
00140 ~Type();
00141
00145 const Anope::string &GetName() { return this->name; }
00146
00153 Serializable *Unserialize(Serializable *obj, Serialize::Data &data);
00154
00157 void Check();
00158
00162 time_t GetTimestamp() const;
00163
00166 void UpdateTimestamp();
00167
00168 Module* GetOwner() const { return this->owner; }
00169
00170 static Serialize::Type *Find(const Anope::string &name);
00171
00172 static const std::vector<Anope::string> &GetTypeOrder();
00173
00174 static const std::map<Anope::string, Serialize::Type *>& GetTypes();
00175 };
00176
00183 template<typename T>
00184 class Serialize::Checker
00185 {
00186 Anope::string name;
00187 T obj;
00188 mutable Serialize::Type *type;
00189
00190 inline void Check() const
00191 {
00192 if (!type)
00193 type = Serialize::Type::Find(this->name);
00194 if (type)
00195 type->Check();
00196 }
00197
00198 public:
00199 Checker(const Anope::string &n) : name(n), type(NULL) { }
00200
00201 inline const T* operator->() const
00202 {
00203 this->Check();
00204 return &this->obj;
00205 }
00206 inline T* operator->()
00207 {
00208 this->Check();
00209 return &this->obj;
00210 }
00211
00212 inline const T& operator*() const
00213 {
00214 this->Check();
00215 return this->obj;
00216 }
00217 inline T& operator*()
00218 {
00219 this->Check();
00220 return this->obj;
00221 }
00222
00223 inline operator const T&() const
00224 {
00225 this->Check();
00226 return this->obj;
00227 }
00228 inline operator T&()
00229 {
00230 this->Check();
00231 return this->obj;
00232 }
00233 };
00234
00241 template<typename T>
00242 class Serialize::Reference : public ReferenceBase
00243 {
00244 protected:
00245 T *ref;
00246
00247 public:
00248 Reference() : ref(NULL)
00249 {
00250 }
00251
00252 Reference(T *obj) : ref(obj)
00253 {
00254 if (obj)
00255 obj->AddReference(this);
00256 }
00257
00258 Reference(const Reference<T> &other) : ReferenceBase(other), ref(other.ref)
00259 {
00260 if (ref && !invalid)
00261 this->ref->AddReference(this);
00262 }
00263
00264 ~Reference()
00265 {
00266 if (ref && !invalid)
00267 this->ref->DelReference(this);
00268 }
00269
00270 inline Reference<T>& operator=(const Reference<T> &other)
00271 {
00272 if (this != &other)
00273 {
00274 if (ref && !invalid)
00275 this->ref->DelReference(this);
00276
00277 this->ref = other.ref;
00278 this->invalid = other.invalid;
00279
00280 if (ref && !invalid)
00281 this->ref->AddReference(this);
00282 }
00283 return *this;
00284 }
00285
00286 inline operator bool() const
00287 {
00288 if (!this->invalid)
00289 return this->ref != NULL;
00290 return false;
00291 }
00292
00293 inline operator T*() const
00294 {
00295 if (!this->invalid)
00296 {
00297 if (this->ref)
00298
00299 this->ref->QueueUpdate();
00300 if (!this->invalid)
00301 return this->ref;
00302 }
00303 return NULL;
00304 }
00305
00306 inline T* operator*() const
00307 {
00308 if (!this->invalid)
00309 {
00310 if (this->ref)
00311
00312 this->ref->QueueUpdate();
00313 if (!this->invalid)
00314 return this->ref;
00315 }
00316 return NULL;
00317 }
00318
00319 inline T* operator->() const
00320 {
00321 if (!this->invalid)
00322 {
00323 if (this->ref)
00324
00325 this->ref->QueueUpdate();
00326 if (!this->invalid)
00327 return this->ref;
00328 }
00329 return NULL;
00330 }
00331 };
00332
00333 #endif // SERIALIZE_H