Main Page · Modules · All Classes · Class Hierarchy
MCDataContainer.hpp
1 /*
2  * This file is part of the AiBO+ project
3  *
4  * Copyright (C) 2005-2016 Csaba Kertész (csaba.kertesz@gmail.com)
5  *
6  * AiBO+ is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * AiBO+ is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
19  *
20  */
21 
22 #pragma once
23 
24 #include "3rdparty/archives/portable_iarchive.hpp"
25 #include "3rdparty/archives/portable_oarchive.hpp"
26 #include "MCBinaryData.hpp"
27 #include "MCDefs.hpp"
28 #include "MCTypes.hpp"
29 
30 #include <boost/archive/binary_iarchive.hpp>
31 #include <boost/archive/binary_oarchive.hpp>
32 #include <boost/serialization/access.hpp>
33 #include <boost/serialization/list.hpp>
34 #include <boost/serialization/map.hpp>
35 #include <boost/serialization/split_member.hpp>
36 #include <boost/serialization/vector.hpp>
37 #include <boost/scoped_ptr.hpp>
38 
39 #include <string>
40 #include <list>
41 
42 #include <stdlib.h>
43 #include <typeinfo>
44 
45 class MCBinaryData;
46 
56 {
58  virtual ~MCDataItemBase();
59 
60  virtual void LoadFromArchive(boost::archive::binary_iarchive& archive);
61  virtual void SaveToArchive(boost::archive::binary_oarchive& archive) const;
62  virtual void LoadFromArchive(eos::portable_iarchive& archive);
63  virtual void SaveToArchive(eos::portable_oarchive& archive) const;
64  virtual void DeleteData();
65 
66  std::string DataName;
67  std::string TypeName;
68  void* DataPtr;
69 };
70 
71 namespace MC
72 {
74 typedef std::list<MCDataItemBase*> DataItemBasePtrList;
75 }
76 
80 template <typename T>
81 class MCDataItem : public MCDataItemBase
82 {
83 public:
84  MCDataItem(const T& data, const std::string& data_name) : MCDataItemBase()
85  {
86  InitWithCloning(data, data_name);
87  }
88 
89  MCDataItem(T& data, const std::string& data_name, bool clone_data) : MCDataItemBase()
90  {
91  if (clone_data)
92  {
93  InitWithCloning(data, data_name);
94  return;
95  }
96  DataPtr = (void*)&data;
97  DataName = data_name;
98  // Get the type name
99  TypeName = MCGetClassName(&data);
100  }
101 
102 private:
103 
104  void InitWithCloning(const T& data, const std::string& data_name)
105  {
106  T* NewData = new T;
107 
108  *NewData = data;
109  DataPtr = (void*)NewData;
110  DataName = data_name;
111  // Get the type name
112  TypeName = MCGetClassName(&data);
113  }
114 
115 public:
116 
117  T& GetData()
118  {
119  return *reinterpret_cast<T*>(DataPtr);
120  }
121 
122  virtual void DeleteData() override
123  {
124  delete reinterpret_cast<T*>(DataPtr);
125  DataPtr = nullptr;
126  }
127 
128  virtual void LoadFromArchive(eos::portable_iarchive& archive) override
129  {
130  // cppcheck-suppress clarifyCondition
131  archive & *reinterpret_cast<T*>(DataPtr);
132  }
133 
134  virtual void SaveToArchive(eos::portable_oarchive& archive) const override
135  {
136  // cppcheck-suppress clarifyCondition
137  archive & *reinterpret_cast<T*>(DataPtr);
138  }
139 
140  virtual void LoadFromArchive(boost::archive::binary_iarchive& archive) override
141  {
142  // cppcheck-suppress clarifyCondition
143  archive & *reinterpret_cast<T*>(DataPtr);
144  }
145 
146  virtual void SaveToArchive(boost::archive::binary_oarchive& archive) const override
147  {
148  // cppcheck-suppress clarifyCondition
149  archive & *reinterpret_cast<T*>(DataPtr);
150  }
151 };
152 
157 {
159  friend class boost::serialization::access;
160 
161 public:
162 
174  MCDataContainer(const std::string& name, bool portable = false);
175 
177  virtual ~MCDataContainer();
178 
186  bool IsPortable() const;
187 
193  void Clear();
194 
202  std::string GetName() const;
203 
211  MCBinaryData* Encode() const;
212 
227  static MCDataContainer* Decode(const MCBinaryData& data, bool portable = false,
228  MCDataContainer* instance = nullptr);
229 
235  void Dump() const;
236 
244  MC::StringList GetDataNames() const;
245 
256  void AddData(MCDataItemBase& item);
257 
267  MCDataItemBase* GetData(const std::string& data_name);
268 
276  const MC::DataItemBasePtrList& GetAllData() const;
277 
285  void RemoveData(const std::string& data_name);
286 
297  virtual MCDataItemBase* GetInputArchiveDataType(const std::string& type_name,
298  const std::string& data_name);
299 
300 private:
301  template<class Archive>
302  void load(Archive& archive, const unsigned int version);
303  template<class Archive>
304  void save(Archive& archive, const unsigned int version) const;
305  BOOST_SERIALIZATION_SPLIT_MEMBER();
306 
308  std::string Name;
310  bool Portable;
312  MC::DataItemBasePtrList Items;
313 };
314 
328 template <typename T>
329 MCBinaryData* MCEncodeToBinaryData(const T& data, bool portable = true)
330 {
331  boost::scoped_ptr<MCDataContainer> DataContainer(new MCDataContainer("Dummy", portable));
332 
333  DataContainer->AddData(*new MCDataItem<T>(data, "Data"));
334  return DataContainer->Encode();
335 }
336 
349 template <typename T>
350 boost::shared_ptr<T> MCDecodeFromBinaryData(const MCBinaryData& data, bool portable = true)
351 {
352  boost::scoped_ptr<MCDataContainer> DataContainer(MCDataContainer::Decode(data, portable));
353 
354  if (DataContainer.get())
355  {
356  MCDataItemBase* DataItem = DataContainer->GetData("Data");
357 
358  // Type-safe check before cloning
359  if (DataItem && MCGetClassName<T>() == DataItem->TypeName)
360  {
361  return boost::shared_ptr<T>(new T(*reinterpret_cast<T*>(DataItem->DataPtr)));
362  }
363  }
364  return boost::shared_ptr<T>();
365 }
366 
380 template <typename T>
381 std::string MCEncodeToString(const T& data, bool portable = true)
382 {
383  boost::scoped_ptr<MCBinaryData> BinaryData(MCEncodeToBinaryData(data, portable));
384 
385  return BinaryData->ToBase64();
386 }
387 
400 template <typename T>
401 boost::shared_ptr<T> MCDecodeFromString(const std::string& data_str, bool portable = true)
402 {
403  boost::scoped_ptr<MCBinaryData> BinaryData(new MCBinaryData);
404 
405  BinaryData->FromBase64(data_str);
406  return MCDecodeFromBinaryData<T>(*BinaryData, portable);
407 }
408 
A helper class to fill the type info to the base structure.
Data container.
Binary data class.
MC::DataItemBasePtrList Items
Data items.
Data container item base structure to store basic type info.
std::string MCEncodeToString(const T &data, bool portable=true)
Encode a data into a string.
#define MC_DISABLE_COPY(class_name)
Helper macro to disable the copy constructor and assignment operator of a class (object copying) ...
Definition: MCDefs.hpp:604
boost::shared_ptr< T > MCDecodeFromBinaryData(const MCBinaryData &data, bool portable=true)
Decode a data from binary form.
std::string MCGetClassName(T *instance=nullptr, const std::string &name_suffix="")
Get a class name.
Definition: MCDefs.hpp:627
static MCDataContainer * Decode(const MCBinaryData &data, bool portable=false, MCDataContainer *instance=nullptr)
Load the data container from binary form.
MCBinaryData * MCEncodeToBinaryData(const T &data, bool portable=true)
Encode a data into binary form.
boost::shared_ptr< T > MCDecodeFromString(const std::string &data_str, bool portable=true)
Decode a data from a string.
std::string Name
Data container name.
bool Portable
Data container type (portable/non-portable)