Вообщем, критикуйте....
/* * mserializer.h * iAtlasCtl * * Created by __OwnerName__ on 01.02.05. * Copyright 2005 __MyCompanyName__. All rights reserved. * */ #ifndef __MSERIALIZER_H__ #define __MSERIALIZER_H__ #include <common/mstring.h> #include <common/marray.h> #include <common/mhash.h> #include <common/mexception.h> #include <string.h> #include <errno.h> #define BEGIN_SERIALIZER(name) \ struct DefaultSerializer: public BaseSerializer<name> { \ DefaultSerializer():BaseSerializer<name>(#name) { #define END_SERIALIZER }}; #define PROPERTY(Class,Var) Simple(#Var,(&Class::Var)); #define BASE_PROPERTY(Type,Class,Var) Simple(#Var,reinterpret_cast<Type Class::*>(&Class::Var)); #define COLLECTION(Class,Var) Array(#Var,&Class::Var); #define BASE_COLLECTION(Type,Class,Var) Array(#Var,reinterpret_cast<Type Class::*>(&Class::Var)); template <typename StructType> struct FieldAttrubute { MString Name; FieldAttrubute() {} FieldAttrubute(const char *name):Name(name) {} virtual int Read(StructType &data,const MString &s, int start=0) const {return 0;} virtual void Write(StructType &data,MString &s) const {} }; template<typename StructType, typename FieldType> struct FieldBaseAttribute: public FieldAttrubute<StructType> { FieldType StructType::* Ptr; FieldBaseAttribute() {} FieldBaseAttribute(const char *n,FieldType StructType::* p):FieldAttrubute<StructType>(n),Ptr(p) {} virtual void Write(StructType &data,MString &s) const { Serialize(data.*Ptr,s); } virtual int Read(StructType &data,const MString &s, int start=0) const { return Unserialize(data.*Ptr,s,start); } }; template<typename StructType, typename FieldType> struct ArrayAttribute: public FieldAttrubute<StructType> { FieldType StructType::* Ptr; ArrayAttribute() {} ArrayAttribute(const char *n,FieldType StructType::* p):FieldAttrubute<StructType>(n),Ptr(p) {} virtual void Write(StructType &data,MString &s) const { (data.*Ptr).Serialize(s); } virtual int Read(StructType &data,const MString &s, int start=0) const { return (data.*Ptr).Unserialize(s,start); } }; template<typename DataObject> struct BaseSerializer { MArray<FieldAttrubute<DataObject>*,FieldAttrubute<DataObject> *> attr; MString objectname; BaseSerializer(const char* name):objectname(name) {} BaseSerializer(){} ~BaseSerializer() { for(int i=0;i<attr.GetSize();i++) delete attr[i]; } template<typename T> void Simple(const char *name,T DataObject::* ptr) { attr.Add(new FieldBaseAttribute<DataObject,T>(name,ptr)); } template<typename T> void Array(const char *name,T DataObject::* ptr) { attr.Add(new ArrayAttribute<DataObject,T>(name,ptr)); } }; template<typename T> int Unserialize( T &data , const MString &s, int start = 0) { static typename T::DefaultSerializer layout; MString &objectname = layout.BaseSerializer<T>::objectname; MArray<FieldAttrubute<T>*,FieldAttrubute<T> *> &attr = layout.BaseSerializer<T>::attr; int sz; //check type if(s[start] != 'O') throw MException(__FILE__,__LINE__,"Trying to unserialize non-object"); start += 2; MString classname; sz = strtol(&s[start],NULL,0); if(!sz && errno == EINVAL) throw MException(__FILE__,__LINE__,"Invalid classname size representation at position %d [%s]",start,s.CStr()); start = s.Find(':',start); classname = s.Substr(start+2,start+2+sz); if(strncasecmp(classname.CStr(),objectname.CStr(),classname.GetSize()) != 0) throw MException(__FILE__,__LINE__,"Trying to unserialize object [%s] from object [%s]",objectname.CStr(),classname.CStr()); start=s.Find(':',start+2+sz)+1; sz = strtol(&s[start],NULL,0); start = s.Find('{',start)+1; while(sz-- && s[start] != '}') { int i; MString varname; start = Unserialize(varname,s,start); for(i=0;(i < attr.GetSize()) && (strncasecmp(varname.CStr(),attr[i]->Name.CStr(),varname.GetSize()) != 0);i++); if(i == attr.GetSize()) throw MException(__FILE__,__LINE__,"Property [%s] for object not supported",varname.CStr(),classname.CStr()); if(s[start] == 'N') start += 2; else start = attr[i]->Read(data,s,start); } return start+1; } template<typename T> void Serialize(T &data,MString &s) { static typename T::DefaultSerializer layout; MString &objectname = layout.BaseSerializer<T>::objectname; MArray<FieldAttrubute<T>*,FieldAttrubute<T> *> &attr = layout.BaseSerializer<T>::attr; objectname.ToLower(); s += MString("O:%d:\"%s\":%d:{", objectname.GetSize(),objectname.CStr(),attr.GetSize()); for(int i=0;i<attr.GetSize();i++) { MString &varname = attr[i]->Name; s += MString("s:%d:\"%s\";",varname.GetSize(),varname.CStr()); attr[i]->Write(data,s); } s += "}"; } template<> void Serialize(int &value,MString &s); template<> void Serialize(bool &value,MString &s); template<> void Serialize(double &value,MString &s); template<> void Serialize(MString &value,MString &s); template<> int Unserialize<int>(int &value,const MString &s, int start); template<> int Unserialize(bool &value,const MString &s, int start); template<> int Unserialize(double &value,const MString &s, int start); template<> int Unserialize(MString &value,const MString &s, int start); #endif
Я знаю, что это не совершенство, надеюсь на разумную критику...
Сообщение отредактировал DarkSerj: 06 Июль 2005 - 01:00