00001 /******************************************************************************* 00002 00003 Copyright (C) 2007 by Brendon Costa 00004 00005 This library is free software; you can redistribute it and/or modify 00006 it under the terms of the "LGPL Like" License defined in the file COPYING 00007 that should have been distributed along with this source. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 You should have received a copy of the "LGPL Like" License 00014 along with this library; see the file COPYING. if not, it can be 00015 obtained from the EDoc++ website: 00016 http://edoc.sourceforge.net/license.html 00017 00018 *******************************************************************************/ 00019 #ifndef EDOC_STRINGIDENTIFIEDOBJECT_H 00020 #define EDOC_STRINGIDENTIFIEDOBJECT_H 00021 00022 #include "EDoc/DictionarySpecific.h" 00023 #include "EDoc/stdint.h" 00024 #include <string> 00025 #include <ostream> 00026 #include <sstream> 00027 00028 #include <map> 00029 00030 namespace EDoc 00031 { 00032 class PersistenceIFace; 00033 class IndexedDictionary; 00034 class IndexedObject; 00035 class Dictionary; 00036 class PStack; 00037 00038 //=========================================================================== 00039 /** \brief Represents a fundamental DictionarySpecific data type that has a 00040 * unique string identifier. 00041 * 00042 * All fundamental dictionary types derive from this abstract class. This 00043 * includes the classes: 00044 * - File 00045 * - Type 00046 * - FunctionType 00047 * - Function 00048 * . 00049 * 00050 * This class exposes common functionality that makes managing these objects 00051 * a little simpler. In particular all such types are identified by a unique 00052 * string, however when saved in .edc files they are identified by unique 00053 * integer indexes. This class provides mechanisms to help in the process of 00054 * loading objects that are indexed with integers and fitting them into 00055 * objects indexed by strings. 00056 * 00057 * 00058 * These objects all have common properties such as: 00059 * - They all have eithre a string identifier OR an integer identifier. 00060 * Only the string OR the integer can be used for indexing the object 00061 * at any one point in time. 00062 * - They can exist in a non-populated state waiting to be populated 00063 * - They can all be written/read to/from a file 00064 * - It can be easy to introduce a bug in pointer assignment between 00065 * dictionaries, so they all support special internal validation and 00066 * pointer replacement methods. 00067 * . 00068 * 00069 * \see See Also Dictionary and DictionarySpecific 00070 */ 00071 class StringIdentifiedObject : public DictionarySpecific 00072 { 00073 friend class IndexedDictionary; 00074 friend class IndexedObject; 00075 friend class Dictionary; 00076 public: 00077 00078 //------------------------------------------------------------------------ 00079 /** \brief Constructor called from a derived class initialising the object 00080 * with an initial string identifier. 00081 */ 00082 StringIdentifiedObject(Dictionary& dict_in, std::string key_name_in, 00083 bool populated_in=false); 00084 00085 //------------------------------------------------------------------------ 00086 /** \brief Constructor called from a derived class initialising the object 00087 * with an initial integer identifier. 00088 */ 00089 StringIdentifiedObject(Dictionary& dict_in, int32_t index_in, 00090 bool populated_in=false); 00091 00092 //------------------------------------------------------------------------ 00093 /** \brief Destructor. 00094 */ 00095 virtual ~StringIdentifiedObject() {} 00096 00097 //------------------------------------------------------------------------ 00098 /** \brief See CodeBlock::Read() 00099 * 00100 * After reading objects 00101 * derived from StringIdentifiedObject will have their key name set and 00102 * will be considered "populated" 00103 */ 00104 virtual void Read(PersistenceIFace& file, IndexedDictionary& idict) = 0; 00105 00106 //------------------------------------------------------------------------ 00107 /** \brief See CodeBlock::Write() 00108 */ 00109 virtual void Write(PersistenceIFace& file) const = 0; 00110 00111 //------------------------------------------------------------------------ 00112 /** \brief Merges two StringIdentifiedObjects. 00113 * 00114 * \warning NOTE: The two objects MUST be of the same type. You can NOT 00115 * merge a File with a Function. 00116 */ 00117 virtual void Merge(const StringIdentifiedObject& right) = 0; 00118 00119 //------------------------------------------------------------------------ 00120 /** \brief Returns an integer identifying the type of the derived class. 00121 * 00122 * Currently the following integers are defined i npersistence_data.h: 00123 * - 1 VALUE_RECORD_TYPE_TYPE for Type objects. 00124 * - 2 VALUE_RECORD_TYPE_FUNCTION for Function objects. 00125 * - 3 VALUE_RECORD_TYPE_FILE for File objects. 00126 * - 4 VALUE_RECORD_TYPE_FUNCTION_TYPE for FunctionType objects. 00127 * . 00128 */ 00129 virtual uint8_t GetRecordType() const = 0; 00130 00131 //------------------------------------------------------------------------ 00132 /** \brief Returns the string key that identifies this object. 00133 * 00134 * Will assert if the object has not yet been populated OR it currently 00135 * uses an integer identifier not a string identifier. 00136 */ 00137 const std::string& GetKeyName() const; 00138 00139 //------------------------------------------------------------------------ 00140 /** \brief Returns the integer key that identifies this object. 00141 */ 00142 inline ssize_t GetIndex() const 00143 { 00144 return index; 00145 } 00146 00147 //------------------------------------------------------------------------ 00148 /** \brief Returns true if this object has been completely populated from 00149 * a file source or manually or false if the object is incomplete. 00150 */ 00151 inline bool IsPopulated() const 00152 { 00153 return populated; 00154 } 00155 00156 00157 //------------------------------------------------------------------------ 00158 00159 protected: 00160 00161 //------------------------------------------------------------------------ 00162 /** \brief Used by derived class to set the string key once it is able to 00163 * determine it. 00164 * 00165 * Usually an instance is created with an integer index and then data is 00166 * loaded into the object and once it has loaded it is able to determine 00167 * what its string index should be. Then it will call this function which 00168 * sets the integer index to -1 and sets the string key to the given 00169 * value. 00170 */ 00171 void SetKeyName(std::string key_name_in); 00172 00173 //------------------------------------------------------------------------ 00174 /** \brief True if this object has been completely populated. 00175 */ 00176 bool populated; 00177 00178 //------------------------------------------------------------------------ 00179 /** \brief Set to the integer index used to identify this object or -1 if 00180 * the key_name is used to identify this object. 00181 */ 00182 mutable int32_t index; 00183 00184 //------------------------------------------------------------------------ 00185 /** \brief Set to the string key used to identify this object. 00186 */ 00187 std::string key_name; 00188 00189 00190 00191 00192 //------------------------------------------------------------------------ 00193 // Public Temporary Data values. 00194 //------------------------------------------------------------------------ 00195 00196 //------------------------------------------------------------------------ 00197 /** \brief USED ONLY FROM Dictionary::Write() 00198 * 00199 * While writing an object to file it is possible to use both the objects 00200 * integer and string keys. This is the only time that is allowable and 00201 * this flag is used to determine that. 00202 */ 00203 // @@@Brendon This is a horrible hack. 00204 mutable bool writing; 00205 00206 //------------------------------------------------------------------------ 00207 }; 00208 //=========================================================================== 00209 00210 // For SWIG 00211 typedef StringIdentifiedObject* StringIdentifiedObjectPtr; 00212 typedef std::map<std::string, StringIdentifiedObject* > StrIDObjPMap; 00213 } 00214 00215 #endif // EDOC_STRINGIDENTIFIEDOBJECT_H