Tulip  4.8.0
Better Visualization Through Research
 All Classes Files Functions Variables Enumerations Enumerator Properties Groups Pages
DataSet.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 
20 #ifndef _TULIPREFLECT
21 #define _TULIPREFLECT
22 
23 #include <tulip/tulipconf.h>
24 #include <tulip/tuliphash.h>
25 #include <tulip/StlIterator.h>
26 
27 #include <string>
28 #include <sstream>
29 #include <typeinfo>
30 #include <list>
31 
32 namespace tlp {
33 
34 class Graph;
35 
36 ///@cond DOXYGEN_HIDDEN
37 // basic interface to embed a data of any type
38 struct TLP_SCOPE DataMem {
39  DataMem() {}
40  virtual ~DataMem() {}
41 };
42 
43 // basic template to embed a value of a known type
44 template<typename TYPE> struct TypedValueContainer: public DataMem {
45  TYPE value;
46  TypedValueContainer() {}
47  TypedValueContainer(const TYPE& val) : value(val) {}
48  ~TypedValueContainer() {
49  }
50 };
51 ///@endcond
52 
53 /**
54  * @ingroup Structures
55  * @brief Describes a value of any type
56  */
57 struct DataType :public DataMem {
58  DataType() {}
59  DataType(void *value):value(value) {}
60 
61  /**
62  * @return A deep copy of the stored value.
63  */
64  virtual DataType *clone() const = 0;
65 
66  /**
67  * @return The C++ typename of the stored element
68  */
69  virtual std::string getTypeName() const = 0;
70 
71  /**
72  * @brief The actual pointer to the element's data
73  */
74  void *value;
75 };
76 
77 ///@cond DOXYGEN_HIDDEN
78 // template class to embed value of known type
79 template<typename T>
80 struct TypedData :public DataType {
81  TypedData(void *value) :DataType(value) {}
82  ~TypedData() {
83  delete (T*) value;
84  }
85  DataType* clone() const {
86  return new TypedData<T>(new T(*(T*)value));
87  }
88 
89  std::string getTypeName() const {
90  return std::string(typeid(T).name());
91  }
92 };
93 
94 // forward declaration of DataSet
95 class DataSet;
96 
97 // Basic class for serialization of DataType embedded value
98 struct DataTypeSerializer {
99  // the readable type name the serializer is designed for
100  std::string outputTypeName;
101  DataTypeSerializer(const std::string& otn):outputTypeName(otn) {}
102  virtual ~DataTypeSerializer() {}
103  // return a copy of this
104  virtual DataTypeSerializer* clone() const = 0;
105  // write the DataType embedded value into the output stream
106  virtual void writeData(std::ostream& os, const DataType *data)=0;
107  // return the DataType embedded value as a std::string
108  virtual std::string toString(const DataType *data) {
109  std::stringstream ss;
110  writeData(ss,data);
111  return ss.str();
112  }
113  // build a DataType embedding value read from input stream
114  virtual DataType* readData(std::istream &is)=0;
115  // set a value into a DataSet
116  virtual bool setData(DataSet& ds, const std::string& prop, const std::string& value)=0;
117 };
118 
119 // a template class designs to simplify the developer's work
120 // when writing a serializer class
121 template<typename T>
122 struct TypedDataSerializer :public DataTypeSerializer {
123  TypedDataSerializer(const std::string& otn):DataTypeSerializer(otn) {}
124  // declare new serialization virtual functions
125  virtual void write(std::ostream& os, const T& value)=0;
126  // return true if the read of value succeed, false if not
127  virtual bool read(std::istream& is, T& value)=0;
128  // define virtually inherited functions using the previous ones
129  void writeData(std::ostream& os, const DataType* data) {
130  write(os, *((T*) data->value));
131  }
132  DataType* readData(std::istream& is) {
133  T value;
134  bool ok = read(is, value);
135 
136  if (ok)
137  return new TypedData<T>(new T(value));
138 
139  return NULL;
140  }
141  // set a value into a DataSet
142  virtual bool setData(DataSet& ds, const std::string& prop, const std::string& value)=0;
143 };
144 
145 // This class is there to ensure the destruction of DataTypeSerializer objects
146 // when program ends
147 class DataTypeSerializerContainer {
148 
149 public :
150 
151  ~DataTypeSerializerContainer() {
152  TLP_HASH_MAP<std::string, DataTypeSerializer*>::iterator it = tnTodts.begin();
153 
154  for (; it != tnTodts.end() ; ++it) {
155  delete it->second;
156  }
157  }
158 
159  TLP_HASH_MAP<std::string, DataTypeSerializer*> tnTodts;
160  TLP_HASH_MAP<std::string, DataTypeSerializer*> otnTodts;
161 
162 };
163 ///@endcond
164 
165 /**
166  * @ingroup Structures
167  * @brief A container that can store data from any type.
168  *
169  * The DataSet aggregate data of various types into a single structure and map each value to a key (std::string) describing its name.
170  * DataSet is mainly used in plugins. When creating a plugin, one can add input parameters (using tlp::WithParameter methods) and retrieve them from the dataSet member variable once they have been set by the user.
171  **/
172 class TLP_SCOPE DataSet {
173  //Internal list of key-value pairs.
174  std::list< std::pair<std::string, DataType*> > data;
175  /* management of data serialization
176  two hashmap to retrieve data serializer from their
177  type names and output type names
178  tnTodsts => typename to data type serializer
179  otnTodts => output type name to data type serializer */
180  static DataTypeSerializerContainer serializerContainer;
181  static void registerDataTypeSerializer(const std::string& typeName,
182  DataTypeSerializer* dts);
183 public:
184  DataSet() {}
185  DataSet(const DataSet &set);
186  ~DataSet();
187 
188  /**
189  * @brief Performs a deep copy of a DataSet into another
190  */
191  DataSet& operator=(const DataSet &set);
192 
193  /**
194  * @brief Returns the stored value associated with the given key.
195  * The stored value is a copy of the original value that was set.
196  * If there is no value associated with the given key, the input value is left untouched.
197  *
198  * @param key The key with which the data we want to retrieve is associated.
199  * @param value A variable wich will be overwritten with the value to retrieve.
200  * @return bool Whether there is a value associated with given key or not.
201  **/
202  template<typename T> bool get(const std::string &key, T& value) const;
203 
204  /**
205  * @brief Returns the stored value, and deletes the stored copy.
206  * If no value is found, nothing is deleted.
207  *
208  * @param key The key with which the data we want to retrieve is associated.
209  * @param value A variable wich will be overwritten with the value to retrieve.
210  * @return bool Whether there is a value associated with given key or not.
211  **/
212  template<typename T> bool getAndFree(const std::string &key, T& value);
213 
214  /**
215  * @brief Stores a copy of the given param, associated with the key.
216  * The value must have a well-formed copy constructor.
217  *
218  * @param key The key which can be used to retrieve the data.
219  * @param value The data to store.
220  * @return void
221  **/
222  template<typename T> void set(const std::string &key, const T& value);
223 
224  /**
225  * @brief Registers a serializer for a known type
226  *
227  * Serializers are used to write/read from std::ostream objects when saving DataSet instances.
228  */
229  template<typename T> static void registerDataTypeSerializer(const DataTypeSerializer &serializer) {
230  registerDataTypeSerializer(std::string(typeid(T).name()), serializer.clone());
231  }
232 
233  /**
234  * @brief write an embedded value
235  */
236  void writeData(std::ostream& os, const std::string& prop,const DataType* dt) const;
237 
238  /**
239  * @brief Serializes a DataSet into a stream
240  */
241  static void write(std::ostream& os, const DataSet& ds);
242 
243  /**
244  * @brief Read a value and stores it into the specified type
245  */
246  bool readData(std::istream& is, const std::string& prop, const std::string& outputTypeName);
247 
248  /**
249  * @brief Reads a stream and stores its contents into a DataSet
250  */
251  static bool read(std::istream& is, DataSet& ds);
252 
253  /**
254  * @param str the name of the member to look for
255  * @return true if str exists into the DataSet.
256  */
257  bool exist(const std::string &str) const;
258 
259  /**
260  * @brief Removes an element from the DataSet
261  * @param str the name of the element to remove
262  */
263  void remove(const std::string &str);
264 
265  /**
266  * @param str The name of the element to retrieve
267  * @return A untyped value for a given element name. NULL if the element does not exist
268  */
269  DataType* getData(const std::string &str) const;
270 
271  /**
272  * @brief Set from an untyped value
273  */
274  void setData(const std::string &str, const DataType* value);
275 
276  /**
277  * @return An iterator over stored values as a std::pair name => untyped value
278  */
279  tlp::Iterator< std::pair<std::string, DataType*> > *getValues() const;
280 
281  /**
282  * @brief Returns the number of registered values
283  */
284  unsigned int size() const;
285 
286  /**
287  * @brief Indicates whether the set is empty of not
288  */
289  bool empty() const;
290 
291  /**
292  * @return the data type serializer associated to the given typename. NULL if no serializer is found
293  */
294  static DataTypeSerializer *typenameToSerializer(const std::string &name);
295 
296  /**
297  * @return A std::string representation of a DataSet
298  */
299  std::string toString() const;
300 };
301 
302 }
303 
304 #include "cxx/DataSet.cxx"
305 
306 #endif
static void registerDataTypeSerializer(const DataTypeSerializer &serializer)
Registers a serializer for a known type.
Definition: DataSet.h:229
Describes a value of any type.
Definition: DataSet.h:57
A container that can store data from any type.
Definition: DataSet.h:172
virtual std::string getTypeName() const =0
void * value
The actual pointer to the element's data.
Definition: DataSet.h:74
virtual DataType * clone() const =0