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