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_INDEXEDDICTIONARY_H 00020 #define EDOC_INDEXEDDICTIONARY_H 00021 00022 #include "EDoc/stdint.h" 00023 #include "EDoc/Dictionary.h" 00024 #include "EDoc/utils.h" 00025 #include "EDoc/exceptions.h" 00026 #include "EDoc/StringIdentifiedObject.h" 00027 #include <vector> 00028 00029 // @@@Brendon Not sure why i need to include these here to compile on GCC 4 00030 // Works fine without them on GCC 3 00031 #include "EDoc/Function.h" 00032 #include "EDoc/FunctionType.h" 00033 #include "EDoc/Type.h" 00034 00035 namespace EDoc 00036 { 00037 class Type; 00038 class Function; 00039 class Dictionary; 00040 class File; 00041 00042 //=========================================================================== 00043 /** \brief Stores a map of StringIdentifiedObject's that are indexed by an 00044 * integer value. 00045 * 00046 * This is designed to be used for the process of loading EDoc++ data items 00047 * from a file. In the EDoc++ data format all items are identified by a 00048 * integer instead of a string to reduce the size of the resulting data file. 00049 */ 00050 class IndexedObject 00051 { 00052 public: 00053 00054 //------------------------------------------------------------------------ 00055 /** \brief Create an instance to manage loading for the given dictionary. 00056 */ 00057 IndexedObject(Dictionary& dict_in) : 00058 dict(dict_in) 00059 { 00060 } 00061 00062 //------------------------------------------------------------------------ 00063 /** \brief Destructor. 00064 */ 00065 virtual ~IndexedObject() {} 00066 00067 //------------------------------------------------------------------------ 00068 /** \brief Obtain the instance for the given index or return NULL if one 00069 * does not exist. 00070 */ 00071 StringIdentifiedObject* CGet(uint32_t index) 00072 { 00073 if (index < items.size()) 00074 { 00075 return items[index]; 00076 } 00077 else 00078 { 00079 return NULL; 00080 } 00081 } 00082 00083 //------------------------------------------------------------------------ 00084 /** \brief Adds an existing StringIdentifiedObject instance to this map. 00085 * 00086 * Should not be called ore than once for a single index. 00087 */ 00088 void CAdd(uint32_t index, StringIdentifiedObject* item) 00089 { 00090 // Make the vector larger if it is too small. 00091 if (index >= items.size()) 00092 { 00093 items.resize(index + 1, NULL); 00094 } 00095 00096 if (items[index] != NULL) 00097 { 00098 EDOC_THROW_EXCEPTION(FileIOException, "Multiple records with same index." 00099 "The index: " << index << ", was previously taken.", 00100 ""); 00101 } 00102 items[index] = item; 00103 item->index = index; 00104 } 00105 00106 //------------------------------------------------------------------------ 00107 /** \brief Obtain the instance for the given index or create one if one 00108 * does not exist. 00109 */ 00110 StringIdentifiedObject* CAlwaysGet(uint32_t index) 00111 { 00112 StringIdentifiedObject* item = CGet(index); 00113 if (!item) 00114 { 00115 item = New(dict, index); 00116 CAdd(index, item); 00117 } 00118 00119 return item; 00120 } 00121 00122 //------------------------------------------------------------------------ 00123 /** \brief Implemented in child to create instance of specific 00124 * derivation from StringIdentifiedObject. 00125 */ 00126 virtual StringIdentifiedObject* New(Dictionary& dict, uint32_t index) = 0; 00127 00128 //------------------------------------------------------------------------ 00129 /** \brief Reference to the dictionary object that all instances belong. 00130 */ 00131 Dictionary& dict; 00132 00133 //------------------------------------------------------------------------ 00134 /** \brief List of items that currently exist. 00135 */ 00136 // @@@Brendon Probably create a map for this. 00137 std::vector<StringIdentifiedObject*> items; 00138 }; 00139 00140 //=========================================================================== 00141 /** \brief Specific varient of IndexedObject for a particular 00142 * StringIdentifiedObject derivation type like, File, Function etc. 00143 */ 00144 template<typename T> 00145 class SpecificIndexedObject : public IndexedObject 00146 { 00147 public: 00148 00149 //------------------------------------------------------------------------ 00150 /** \brief Create an instance for a specific dictionary. 00151 */ 00152 SpecificIndexedObject(Dictionary& dict_in) : 00153 IndexedObject(dict_in) 00154 { 00155 } 00156 00157 //------------------------------------------------------------------------ 00158 /** \brief Create a new instance of the type with the given index as an 00159 * identifier. 00160 */ 00161 virtual StringIdentifiedObject* New(Dictionary& dict, uint32_t index) 00162 { 00163 T* item = NULL; 00164 AllocNew(item, dict, index); 00165 return static_cast<StringIdentifiedObject*>(item); 00166 } 00167 00168 //------------------------------------------------------------------------ 00169 /** \brief Type specific implementation of IndexedObject::CGet() 00170 */ 00171 T* Get(uint32_t index) 00172 { 00173 return dynamic_cast<T*>(CGet(index)); 00174 } 00175 00176 //------------------------------------------------------------------------ 00177 /** \brief Type specific implementation of IndexedObject::AlwaysGet() 00178 */ 00179 T* AlwaysGet(uint32_t index) 00180 { 00181 return dynamic_cast<T*>(CAlwaysGet(index)); 00182 } 00183 00184 //------------------------------------------------------------------------ 00185 00186 }; 00187 //=========================================================================== 00188 00189 00190 00191 //=========================================================================== 00192 /** \brief Manages all File, Type, FunctionType, and Function instances as 00193 * they are being loaded from a EDoc++ data file. 00194 * 00195 * This stores all items indexed by an integer value. 00196 */ 00197 class IndexedDictionary 00198 { 00199 friend class Dictionary; 00200 public: 00201 00202 //------------------------------------------------------------------------ 00203 /** \brief Create an instance for loading data for the given dictionary. 00204 */ 00205 IndexedDictionary(Dictionary& dict_in) : 00206 files(dict_in), 00207 types(dict_in), 00208 function_types(dict_in), 00209 functions(dict_in), 00210 dict(&dict_in) 00211 {} 00212 00213 //------------------------------------------------------------------------ 00214 /** \brief Returns a vector with all managed types. 00215 * 00216 * This is a helper to simplify the code a little. 00217 */ 00218 std::vector<IndexedObject*> GetManagedObjects() 00219 { 00220 // NOTE: The order is important here. 00221 std::vector<IndexedObject*> ret; 00222 ret.push_back(&files); 00223 ret.push_back(&types); 00224 ret.push_back(&function_types); 00225 ret.push_back(&functions); 00226 00227 return ret; 00228 } 00229 00230 //------------------------------------------------------------------------ 00231 /** \brief Map of all File instances. 00232 */ 00233 SpecificIndexedObject<File> files; 00234 00235 //------------------------------------------------------------------------ 00236 /** \brief Map of all Type instances. 00237 */ 00238 SpecificIndexedObject<Type> types; 00239 00240 //------------------------------------------------------------------------ 00241 /** \brief Map of all FunctionType instances. 00242 */ 00243 SpecificIndexedObject<FunctionType> function_types; 00244 00245 //------------------------------------------------------------------------ 00246 /** \brief Map of all Function instances. 00247 */ 00248 SpecificIndexedObject<Function> functions; 00249 00250 //------------------------------------------------------------------------ 00251 /** \brief A reference to the dictionary all these instances belong to. 00252 */ 00253 Dictionary* dict; 00254 00255 //------------------------------------------------------------------------ 00256 }; 00257 } 00258 00259 #endif // EDOC_INDEXEDDICTIONARY_H