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