DataIO_Polymorphic.h
上传用户:kx_jwh
上传日期:2021-09-03
资源大小:76k
文件大小:9k
源码类别:

STL

开发平台:

Visual C++

  1. /* vim: set tabstop=4 : */
  2. #ifndef __febird_io_DataIO_Polymorphic_h__
  3. #define __febird_io_DataIO_Polymorphic_h__
  4. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  5. # pragma once
  6. #endif
  7. #include <typeinfo>
  8. #include <stdexcept>
  9. #include <boost/tuple/tuple.hpp>
  10. #include <boost/type_traits.hpp>
  11. #include <boost/static_assert.hpp>
  12. #include "../stdtypes.h"
  13. #include <febird/io/StreamBuffer.h>
  14. // 目前还未完成
  15. namespace febird {
  16. class DataIO_Mash_Base
  17. {
  18. public:
  19. virtual ~DataIO_Mash_Base() {}
  20. virtual std::string name() const = 0;
  21. virtual void* create() const = 0;
  22. virtual void load(PortableDataInput<InputBuffer>& input, void* obj) const = 0;
  23. virtual void save(PortableDataOutput<OutputBuffer>& input, void* obj) const = 0;
  24. static std::map<std::string, const DataIO_Mash_Base*> S_dynamic_mash_map;
  25. };
  26. template<class Class>
  27. class DataIO_Mash_Impl : public DataIO_Mash_Base
  28. {
  29. const static DataIO_Mash_Impl<Class> S_my_mash;
  30. DataIO_Mash_Impl()
  31. {
  32. S_dynamic_mash_map.insert(std::make_pair(typeid(*this).name(), this));
  33. }
  34. friend class Class;
  35. public:
  36. virtual std::string name() const
  37. {
  38. return typeid(Class).name();
  39. }
  40. virtual void* create() const
  41. {
  42. return new Class;
  43. }
  44. virtual void load(PortableDataInput<InputBuffer>& input, void* obj) const
  45. {
  46. input >> *(Class*)(obj);
  47. }
  48. virtual void save(PortableDataOutput<OutputBuffer>& output, void* obj) const
  49. {
  50. output << *(const Class*)(obj);
  51. }
  52. };
  53. template<class Class>
  54. const static DataIO_Mash_Impl<Class> DataIO_Mash_Impl<Class>::S_my_mash;
  55. #define DATA_IO_LOAD_SAVE_D(Class, Members)
  56. DATA_IO_LOAD_SAVE(Class, Members)
  57. static const DataIO_Mash_Impl<Class> S_dynamic_load_save_singleton;
  58. #define DATA_IO_LOAD_SAVE_DV(Class, Version, Members)
  59. DATA_IO_LOAD_SAVE_V(Class, Version, Members)
  60. static const DataIO_Mash_Impl<Class> S_dynamic_load_save_singleton;
  61. //////////////////////////////////////////////////////////////////////////
  62. /*
  63. namespace serialization { namespace polymorphic {
  64. // typedef typename serialization::polymorphic::Factory<DataInput>::local_factory_t local_factory_t;
  65. // local_factory_t m_factory;
  66. template<class Object>
  67. void load_polym(Object& x, uint32_t classID)
  68. {
  69. factory_t::iterator found = m_factory.find(classID);
  70. if (m_factory.end() == found)
  71. {
  72. std::ostringstream oss;
  73. oss << "class=" << typeid(x).name() << ", classID=" << classID;
  74. throw NotFoundFactoryException(oss.str());
  75. }
  76. (*found).second->load(*this, (void*)(x), classID);
  77. }
  78. struct IPolymorphicObject
  79. {
  80. virtual void* create() const = 0;
  81. virtual const std::type_info& getType() const = 0;
  82. virtual const char* className() const = 0;
  83. };
  84. //! proxy for load polymorphic object
  85. template<class Object>
  86. struct PolymorphicObject : public IPolymorphicObject
  87. {
  88. Object& object;
  89. explicit PolymorphicObject(Object& object) : object(object) {}
  90. };
  91. //! only used for make short symbol for convenient
  92. struct DataIO_PolymorphicSerialization
  93. {
  94. template<class Object>
  95. PolymorphicObject<Object> operator()(Object& object)
  96. {
  97. return PolymorphicObject<Object>(object);
  98. }
  99. };
  100. //! 声明一个类可多态序列化时,只能把序列化方法绑定到一个 DataIO
  101. //! 因而必须使用 IDataInput/IDataOutput
  102. using namespace boost::multi_index;
  103. template<class Interface>
  104. struct Factory
  105. {
  106. struct CmpTypeInfo
  107. {
  108. bool operator()(const std::type_info& left, const std::type_info& right)
  109. {
  110. return left.before(right);
  111. }
  112. };
  113. typedef multi_index_container<
  114. const Interface*, 
  115. indexed_by<
  116. ordered_unique<member<Interface, std::string, &Interface::className> >,
  117. ordered_unique<const_mem_fun<Interface, const std::type_info&, &Interface::getType>, CmpTypeInfo>
  118. >
  119. > factory_t;
  120. typedef auto_id_container<multi_index_container<
  121. const Interface*, 
  122. indexed_by<
  123. ordered_unique<member<Interface, uint32_t, &Interface::classID> >,
  124. ordered_unique<const_mem_fun<Interface, const std::type_info&, &Interface::getType>, CmpTypeInfo>
  125. >
  126. > > local_factory_t;
  127. static factory_t& getFactory()
  128. {
  129. static factory_t factory;
  130. return factory;
  131. }
  132. };
  133. template<class Input>
  134. struct InputInterface
  135. {
  136. virtual void* create() const = 0;
  137. virtual void  load(Input& input, IPolymorphicObject& x) const = 0;
  138. virtual const std::type_info& getType() const = 0;
  139. std::string className;
  140. InputInterface(const char* className) : className(className) {}
  141. };
  142. template<class Output>
  143. struct OutputInterface
  144. {
  145. virtual void  save(Output& output, IPolymorphicObject& x) const = 0;
  146. virtual const std::type_info& getType() const = 0;
  147. std::string className;
  148. OutputInterface(const char* className) : className(className) {}
  149. };
  150. template<class Input, class Object>
  151. struct InputImplement : public InputInterface<Input>
  152. {
  153. BOOST_STATIC_ASSERT(boost::is_pointer<Object>::value);
  154. void load(Input& input, IPolymorphicObject& x) const
  155. {
  156. PolymorphicObject<Object>* y = dynamic_cast<PolymorphicObject<Object>*>(&x);
  157. assert(y);
  158. input >> y->object;
  159. }
  160. void* create() const
  161. {
  162. return new PolymorphicObject(new Object);
  163. }
  164. virtual const std::type_info& getType() const { return typeid(Object); }
  165. private:
  166. InputImplement(const char* className)
  167. : InputInterface<Input>(className)
  168. {
  169. Factory<InputInterface<Input> >::getFactory().insert(this);
  170. }
  171. static InputImplement s_single_instance;
  172. };
  173. template<class Output, class Object>
  174. struct OutputImplement : public OutputInterface<Output>
  175. {
  176. BOOST_STATIC_ASSERT(boost::is_pointer<Object>::value);
  177. void save(Output& output, IPolymorphicObject& x) const
  178. {
  179. PolymorphicObject<Object>* y = dynamic_cast<PolymorphicObject<Object>*>(&x);
  180. assert(y);
  181. output << y->object;
  182. }
  183. virtual const std::type_info& getType() const { return typeid(Object); }
  184. private:
  185. OutputImplement(const char* className)
  186. : OutputInterface<Output>(className)
  187. {
  188. Factory<OutputInterface<Output> >::getFactory().insert(this);
  189. }
  190. static OutputImplement s_single_instance;
  191. };
  192. template<class DataIO, class Object>
  193. void DataIO_loadObject(DataIO& input, PolymorphicObject<Object*> x)
  194. {
  195. typedef  Factory<InputInterface<DataIO> > factory_t;
  196. typename factory_t::factory_t& factory = factory_t::getFactory();
  197. assert(0 == x.object); //< ptr must be null before load
  198. var_uint32_t classID;
  199. input >> classID;
  200. InputInterface<DataIO>* creator = 0;
  201. if (0 == classID) {
  202. std::string className;
  203. input >> className;
  204. classID.t = input.m_factory.alloc_id(className);
  205. typename factory_t::factory_t::iterator found = factory.find(className);
  206. if (factory.end() == found)
  207. {
  208. std::ostringstream oss;
  209. oss << "not found loader, class.typeid=" << typeid(*x.object).name() << "n"
  210. << "className=" << className;
  211. throw NotFoundFactoryException(oss.str());
  212. }
  213. input.m_factory[classID.t] = creator = &*found;
  214. } else {
  215. typename factory_t::local_factory_t::iterator found = input.m_factory.find(classID.t);
  216. if (input.m_factory.end() == found)
  217. {
  218. std::ostringstream oss;
  219. oss << "not found loader, class.typeid=" << typeid(*x.object).name() << "n"
  220. << "classID=" << classID.t;
  221. throw NotFoundFactoryException(oss.str());
  222. }
  223. creator = &*found;
  224. }
  225. IPolymorphicObject* obj = creator->create();
  226. x.object = reinterpret_cast<Object*>(obj);
  227. creator->load(input, x);
  228. }
  229. template<class DataIO, class Object>
  230. void DataIO_saveObject(DataIO& output, PolymorphicObject<const Object*> x)
  231. {
  232. typedef  Factory<OutputInterface<DataIO> > factory_t;
  233. typename factory_t::factory_t factory = factory_t::getFactory();
  234. var_uint32_t classID = output.getClassID(typeid(x.getRef()));
  235. if (0 == classID) {
  236. typename factory_t::iterator found = factory.find(typeid(x.getRef()));
  237. if (factory.end() == found) {
  238. std::ostringstream oss;
  239. oss << "not found loader, class.typeid=" << typeid(x.getRef()).name();
  240. throw NotFoundFactoryException(oss.str());
  241. }
  242. output << classID;
  243. output << (*found).className;
  244. classID = output.newClassID(className);
  245. }
  246. OutputInterface<Output>* saver = output.getSaver(classID);
  247. saver.save(output, x);
  248. }
  249. //////////////////////////////////////////////////////////////////////////
  250. #define DATA_IO_POLYM_LOAD_EX(Input,Class)
  251. febird::serialization::polymorphic::InputImplement<Input, Class> 
  252. InputImplement<Input, Class>::s_single_instance(BOOST_STRINGIZE(Class));
  253. #define DATA_IO_POLYM_LOAD(Class) DATA_IO_POLYM_LOAD_EX(IDataInput,Class)
  254. #define DATA_IO_POLYM_SAVE_EX(Input,Class)
  255. febird::serialization::polymorphic::InputImplement<Input, Class> 
  256. InputImplement<Input, Class>::s_single_instance(BOOST_STRINGIZE(Class));
  257. #define DATA_IO_POLYM_SAVE(Class) DATA_IO_POLYM_SAVE_EX(IDataOutput,Class)
  258. #define DATA_IO_POLYM_SERIALIZE_EX(Input,Output,Class)
  259. DATA_IO_POLYM_LOAD_EX(Input,Class)
  260. DATA_IO_POLYM_SAVE_EX(Output,Class)
  261. #define DATA_IO_POLYM_SERIALIZE(Class) DATA_IO_POLYM_SERIALIZE_EX(IDataInput, IDataOutput, Class)
  262. } } // serialization::polymorphic
  263. */
  264. } // namespace febird
  265. #endif // __febird_io_DataIO_Polymorphic_h__