Tulip  4.6.0
Better Visualization Through Research
library/tulip-core/include/tulip/DataSet.h
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
 All Classes Files Functions Variables Enumerations Enumerator Properties