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