Tulip
4.6.0
Better Visualization Through Research
|
00001 /* 00002 * 00003 * This file is part of Tulip (www.tulip-software.org) 00004 * 00005 * Authors: David Auber and the Tulip development Team 00006 * from LaBRI, University of Bordeaux 00007 * 00008 * Tulip is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License 00010 * as published by the Free Software Foundation, either version 3 00011 * of the License, or (at your option) any later version. 00012 * 00013 * Tulip is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00016 * See the GNU General Public License for more details. 00017 * 00018 */ 00019 00020 #ifndef _TULIPREFLECT 00021 #define _TULIPREFLECT 00022 00023 #include <tulip/tulipconf.h> 00024 #include <tulip/tuliphash.h> 00025 #include <tulip/StlIterator.h> 00026 00027 #include <string> 00028 #include <typeinfo> 00029 #include <list> 00030 00031 namespace tlp { 00032 00033 class Graph; 00034 00035 ///@cond DOXYGEN_HIDDEN 00036 // basic interface to embed a data of any type 00037 struct TLP_SCOPE DataMem { 00038 DataMem() {} 00039 virtual ~DataMem() {} 00040 }; 00041 00042 // basic template to embed a value of a known type 00043 template<typename TYPE> struct TypedValueContainer: public DataMem { 00044 TYPE value; 00045 TypedValueContainer() {} 00046 TypedValueContainer(const TYPE& val) : value(val) {} 00047 ~TypedValueContainer() { 00048 } 00049 }; 00050 ///@endcond 00051 00052 /** 00053 * @ingroup Structures 00054 * @brief Describes a value of any type 00055 */ 00056 struct DataType :public DataMem { 00057 DataType() {} 00058 DataType(void *value):value(value) {} 00059 00060 /** 00061 * @return A deep copy of the stored value. 00062 */ 00063 virtual DataType *clone() const = 0; 00064 00065 /** 00066 * @return The C++ typename of the stored element 00067 */ 00068 virtual std::string getTypeName() const = 0; 00069 00070 /** 00071 * @brief The actual pointer to the element's data 00072 */ 00073 void *value; 00074 }; 00075 00076 ///@cond DOXYGEN_HIDDEN 00077 // template class to embed value of known type 00078 template<typename T> 00079 struct TypedData :public DataType { 00080 TypedData(void *value) :DataType(value) {} 00081 ~TypedData() { 00082 delete (T*) value; 00083 } 00084 DataType* clone() const { 00085 return new TypedData<T>(new T(*(T*)value)); 00086 } 00087 00088 std::string getTypeName() const { 00089 return std::string(typeid(T).name()); 00090 } 00091 }; 00092 00093 // forward declaration of DataSet 00094 class DataSet; 00095 00096 // Basic class for serialization of DataType embedded value 00097 struct DataTypeSerializer { 00098 // the readable type name the serializer is designed for 00099 std::string outputTypeName; 00100 DataTypeSerializer(const std::string& otn):outputTypeName(otn) {} 00101 virtual ~DataTypeSerializer() {} 00102 // return a copy of this 00103 virtual DataTypeSerializer* clone() const = 0; 00104 // write the DataType embedded value into the output stream 00105 virtual void writeData(std::ostream& os, const DataType *data)=0; 00106 // build a DataType embedding value read from input stream 00107 virtual DataType* readData(std::istream &is)=0; 00108 // set a value into a DataSet 00109 virtual bool setData(DataSet& ds, const std::string& prop, const std::string& value)=0; 00110 }; 00111 00112 // a template class designs to simplify the developer's work 00113 // when writing a serializer class 00114 template<typename T> 00115 struct TypedDataSerializer :public DataTypeSerializer { 00116 TypedDataSerializer(const std::string& otn):DataTypeSerializer(otn) {} 00117 // declare new serialization virtual functions 00118 virtual void write(std::ostream& os, const T& value)=0; 00119 // return true if the read of value succeed, false if not 00120 virtual bool read(std::istream& is, T& value)=0; 00121 // define virtually inherited functions using the previous ones 00122 void writeData(std::ostream& os, const DataType* data) { 00123 write(os, *((T*) data->value)); 00124 } 00125 DataType* readData(std::istream& is) { 00126 T value; 00127 bool ok = read(is, value); 00128 00129 if (ok) 00130 return new TypedData<T>(new T(value)); 00131 00132 return NULL; 00133 } 00134 // set a value into a DataSet 00135 virtual bool setData(DataSet& ds, const std::string& prop, const std::string& value)=0; 00136 }; 00137 00138 // This class is there to ensure the destruction of DataTypeSerializer objects 00139 // when program ends 00140 class DataTypeSerializerContainer { 00141 00142 public : 00143 00144 ~DataTypeSerializerContainer() { 00145 TLP_HASH_MAP<std::string, DataTypeSerializer*>::iterator it = tnTodts.begin(); 00146 00147 for (; it != tnTodts.end() ; ++it) { 00148 delete it->second; 00149 } 00150 } 00151 00152 TLP_HASH_MAP<std::string, DataTypeSerializer*> tnTodts; 00153 TLP_HASH_MAP<std::string, DataTypeSerializer*> otnTodts; 00154 00155 }; 00156 ///@endcond 00157 00158 /** 00159 * @ingroup Structures 00160 * @brief A container that can store data from any type. 00161 * 00162 * The DataSet aggregate data of various types into a single structure and map each value to a key (std::string) describing its name. 00163 * 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. 00164 **/ 00165 class TLP_SCOPE DataSet { 00166 //Internal list of key-value pairs. 00167 std::list< std::pair<std::string, DataType*> > data; 00168 /* management of data serialization 00169 two hashmap to retrieve data serializer from their 00170 type names and output type names 00171 tnTodsts => typename to data type serializer 00172 otnTodts => output type name to data type serializer */ 00173 static DataTypeSerializerContainer serializerContainer; 00174 static void registerDataTypeSerializer(const std::string& typeName, 00175 DataTypeSerializer* dts); 00176 public: 00177 DataSet() {} 00178 DataSet(const DataSet &set); 00179 ~DataSet(); 00180 00181 /** 00182 * @brief Performs a deep copy of a DataSet into another 00183 */ 00184 DataSet& operator=(const DataSet &set); 00185 00186 /** 00187 * @brief Returns the stored value associated with the given key. 00188 * The stored value is a copy of the original value that was set. 00189 * If there is no value associated with the given key, the input value is left untouched. 00190 * 00191 * @param key The key with which the data we want to retrieve is associated. 00192 * @param value A variable wich will be overwritten with the value to retrieve. 00193 * @return bool Whether there is a value associated with given key or not. 00194 **/ 00195 template<typename T> bool get(const std::string &key, T& value) const; 00196 00197 /** 00198 * @brief Returns the stored value, and deletes the stored copy. 00199 * If no value is found, nothing is deleted. 00200 * 00201 * @param key The key with which the data we want to retrieve is associated. 00202 * @param value A variable wich will be overwritten with the value to retrieve. 00203 * @return bool Whether there is a value associated with given key or not. 00204 **/ 00205 template<typename T> bool getAndFree(const std::string &key, T& value); 00206 00207 /** 00208 * @brief Stores a copy of the given param, associated with the key. 00209 * The value must have a well-formed copy constructor. 00210 * 00211 * @param key The key which can be used to retrieve the data. 00212 * @param value The data to store. 00213 * @return void 00214 **/ 00215 template<typename T> void set(const std::string &key, const T& value); 00216 00217 /** 00218 * @brief Registers a serializer for a known type 00219 * 00220 * Serializers are used to write/read from std::ostream objects when saving DataSet instances. 00221 */ 00222 template<typename T> static void registerDataTypeSerializer(const DataTypeSerializer &serializer) { 00223 registerDataTypeSerializer(std::string(typeid(T).name()), serializer.clone()); 00224 } 00225 00226 /** 00227 * @brief write an embedded value 00228 */ 00229 void writeData(std::ostream& os, const std::string& prop,const DataType* dt) const; 00230 00231 /** 00232 * @brief Serializes a DataSet into a stream 00233 */ 00234 static void write(std::ostream& os, const DataSet& ds); 00235 00236 /** 00237 * @brief Read a value and stores it into the specified type 00238 */ 00239 bool readData(std::istream& is, const std::string& prop, const std::string& outputTypeName); 00240 00241 /** 00242 * @brief Reads a stream and stores its contents into a DataSet 00243 */ 00244 static bool read(std::istream& is, DataSet& ds); 00245 00246 /** 00247 * @param str the name of the member to look for 00248 * @return true if str exists into the DataSet. 00249 */ 00250 bool exist(const std::string &str) const; 00251 00252 /** 00253 * @brief Removes an element from the DataSet 00254 * @param str the name of the element to remove 00255 */ 00256 void remove(const std::string &str); 00257 00258 /** 00259 * @param str The name of the element to retrieve 00260 * @return A untyped value for a given element name. NULL if the element does not exist 00261 */ 00262 DataType* getData(const std::string &str) const; 00263 00264 /** 00265 * @brief Set from an untyped value 00266 */ 00267 void setData(const std::string &str, const DataType* value); 00268 00269 /** 00270 * @return An iterator over stored values as a std::pair name => untyped value 00271 */ 00272 tlp::Iterator< std::pair<std::string, DataType*> > *getValues() const; 00273 00274 /** 00275 * @brief Returns the number of registered values 00276 */ 00277 unsigned int size() const; 00278 00279 /** 00280 * @brief Indicates whether the set is empty of not 00281 */ 00282 bool empty() const; 00283 00284 /** 00285 * @return the data type serializer associated to the given typename. NULL if no serializer is found 00286 */ 00287 static DataTypeSerializer *typenameToSerializer(const std::string &name); 00288 00289 /** 00290 * @return A std::string representation of a DataSet 00291 */ 00292 std::string toString() const; 00293 }; 00294 00295 } 00296 00297 #include "cxx/DataSet.cxx" 00298 00299 #endif