gKitGL
|
00001 00002 #ifndef _TEXTFILE_H 00003 #define _TEXTFILE_H 00004 00005 #include <cstdio> 00006 #include <cstring> 00007 #include <cassert> 00008 00009 #include <string> 00010 #include <vector> 00011 #include <map> 00012 00013 #include "IOResource.h" 00014 00015 00016 namespace gk { 00017 00018 //! representation d'un vec4, valeur associee a une cle, cf. TextKey et TextFile. 00019 struct Vec4Value 00020 { 00021 float x, y, z, w; 00022 00023 Vec4Value( const float _x= 0.f, const float _y= 0.f, const float _z= 0.f, const float _w= 0.f ) 00024 : 00025 x(_x), y(_y), z(_z), w(_w) 00026 {} 00027 00028 operator const float *( ) const 00029 { 00030 return &x; 00031 } 00032 }; 00033 00034 //! representation d'un vec3, valeur associee a une cle, cf. TextKey et TextFile. 00035 struct Vec3Value 00036 { 00037 float x, y, z; 00038 00039 Vec3Value( const float _x= 0.f, const float _y= 0.f, const float _z= 0.f ) 00040 : 00041 x(_x), y(_y), z(_z) 00042 {} 00043 00044 operator const float *( ) const 00045 { 00046 return &x; 00047 } 00048 }; 00049 00050 //! representation d'un vec2, valeur associee a une cle, cf. TextKey et TextFile. 00051 struct Vec2Value 00052 { 00053 float x, y; 00054 00055 Vec2Value( const float _x= 0.f, const float _y= 0.f) 00056 : 00057 x(_x), y(_y) 00058 {} 00059 00060 operator const float *( ) const 00061 { 00062 return &x; 00063 } 00064 }; 00065 00066 //! representation d'un float, valeur associee a une cle, cf. TextFile 00067 struct FloatValue 00068 { 00069 float x; 00070 00071 FloatValue( const float v= 0.f) 00072 : 00073 x(v) 00074 {} 00075 00076 operator float( ) 00077 { 00078 return x; 00079 } 00080 00081 operator const float *( ) const 00082 { 00083 return &x; 00084 } 00085 }; 00086 00087 //! representation d'un int, valeur associee a une cle, cf. TextFile. 00088 struct IntValue 00089 { 00090 int x; 00091 00092 IntValue( const int v= 0) 00093 : 00094 x(v) 00095 {} 00096 00097 operator int( ) 00098 { 00099 return x; 00100 } 00101 00102 operator const int *( ) const 00103 { 00104 return &x; 00105 } 00106 }; 00107 00108 //! representation d'une chaine de caracteres, valeur associee a une cle, cf. TextFile. 00109 struct StringValue 00110 { 00111 std::string string; 00112 00113 StringValue( ) 00114 : 00115 string() 00116 {} 00117 00118 StringValue( const std::string& value ) 00119 : 00120 string(value) 00121 {} 00122 00123 operator const std::string&( ) const 00124 { 00125 return string; 00126 } 00127 00128 const char *c_str( ) const 00129 { 00130 return string.c_str(); 00131 } 00132 }; 00133 00134 //! representation d'un nom de fichier, valeur associee a une cle, cf. TextFile. 00135 struct FileValue : public StringValue 00136 { 00137 FileValue( ) 00138 : 00139 StringValue() 00140 {} 00141 00142 FileValue( const std::string& value ) 00143 : 00144 StringValue(value) 00145 {} 00146 }; 00147 00148 //! representation d'un nom de variable, de section, etc. valeur associee a une cle, cf. TextFile. 00149 struct NameValue : public StringValue 00150 { 00151 NameValue( ) 00152 : 00153 StringValue() 00154 {} 00155 00156 NameValue( const std::string& value ) 00157 : 00158 StringValue(value) 00159 {} 00160 }; 00161 00162 //! representation d'une valeur (non interpretee, texte) associee a une cle, cf. TextKey et TextFile. 00163 class TextValue 00164 { 00165 std::string value; 00166 00167 public: 00168 //! utilisation interne. constructeur. 00169 TextValue( ); 00170 //! utilisation interne. constructeur. 00171 TextValue( const std::string& string ); 00172 //! utilisation interne. constructeur. 00173 TextValue& operator= ( const TextValue& b ); 00174 00175 //! comparaison. 00176 bool operator== ( const TextValue& b ) const; 00177 //! comparaison. 00178 bool operator!= ( const TextValue& b ) const; 00179 00180 //! destructeur. 00181 ~TextValue( ) {} 00182 00183 //! interprete la valeur texte comme un vec4. syntaxe: vec4( x, y, z, w ). 00184 Vec4Value asVec4( ) const; 00185 //! interprete la valeur texte comme un vec3. syntaxe: vec3( x, y, z ). 00186 Vec3Value asVec3( ) const; 00187 //! interprete la valeur texte comme un vec2. syntaxe: vec2( x, y ). 00188 Vec2Value asVec2( ) const; 00189 //! interprete la valeur texte comme un float. syntaxe: float( v ). 00190 FloatValue asFloat( ) const; 00191 //! interprete la valeur texte comme un int. syntaxe: int( v ). 00192 IntValue asInt( ) const; 00193 //! renvoie la chaine de caracteres sans interpretation. 00194 StringValue asString( ) const; 00195 //! interprete la valeur texte comme un nom de fichier. syntaxe: "nom/de/fichier". 00196 FileValue asFile( ) const; 00197 //! renvoie un nom (de section, par exemple). syntaxe: identifiant_sans_espace. 00198 NameValue asName( ) const; 00199 00200 //! affecte une nouvelle valeur. 00201 TextValue& operator= ( const Vec4Value& value ); 00202 TextValue& operator= ( const Vec3Value& value ); 00203 TextValue& operator= ( const Vec2Value& value ); 00204 TextValue& operator= ( const FloatValue& value ); 00205 TextValue& operator= ( const IntValue& value ); 00206 TextValue& operator= ( const StringValue& value ); 00207 TextValue& operator= ( const FileValue& value ); 00208 TextValue& operator= ( const NameValue& value ); 00209 00210 //! utilisation interne. renvoie la chaine de caracteres representant la valeur. 00211 const char *c_str( ) const; 00212 00213 //! renvoie une valeur non definie, permet de verifier le resultat d'une recherche de cle. 00214 static TextValue& notFound( ) 00215 { 00216 static TextValue not_found("not_found"); 00217 return not_found; 00218 } 00219 }; 00220 00221 //! representation d'une section d'un fichier texte / d'un fichier effet .gkfx. 00222 struct TextSection 00223 { 00224 std::string filename; 00225 int line; 00226 std::string text; 00227 00228 TextSection( const std::string& _filename, const int _line= 1 ) 00229 : 00230 filename(_filename), 00231 line(_line), 00232 text() 00233 {} 00234 00235 TextSection( const std::string& _text, const std::string& _filename, const int _line ) 00236 : 00237 filename(_filename), 00238 line(_line), 00239 text(_text) 00240 {} 00241 }; 00242 00243 00244 //! ensemble de definitions, #define what value 00245 class TextDefinitions 00246 { 00247 std::map<std::string, std::string> m_definitions; 00248 std::string m_text; 00249 00250 public: 00251 TextDefinitions( ) {} 00252 ~TextDefinitions( ) {} 00253 00254 //! ajoute une definition au source. "#define 'what' 'value'". 00255 int pushDefinition( const std::string& what, const std::string& value= "" ) 00256 { 00257 std::pair<std::map<std::string, std::string>::iterator, bool> found= 00258 m_definitions.insert( std::make_pair(what, value) ); 00259 if(found.second == false) 00260 return -1; 00261 00262 const std::string define( "#define " + what + " " + value + "\n"); 00263 m_text.append(define); 00264 return 0; 00265 } 00266 00267 int count( ) const 00268 { 00269 return m_definitions.size(); 00270 } 00271 00272 int clear( ) 00273 { 00274 m_definitions.clear(); 00275 m_text.clear(); 00276 return 0; 00277 } 00278 00279 const std::string& string( ) const 00280 { 00281 return m_text; 00282 } 00283 00284 void print( ) const 00285 { 00286 printf("%s\n", m_text.c_str()); 00287 } 00288 }; 00289 00290 00291 //! representation d'une section de fichier effet (.gkfx), d'un texte, d'un source de shader, etc. 00292 //! un TextFile est compose de plusieurs sections et peut etre interprete comme un ensemble de paires (cle, valeur) ou comme une seule valeur. 00293 class TextFile : public IOResource 00294 { 00295 std::vector<std::string> m_definitions; 00296 std::vector<TextSection> m_sections; 00297 std::string m_name; 00298 00299 std::map<std::string, int> m_pairs; // indexation des paires cle, valeur, pour la recherche. 00300 std::vector< std::pair<std::string, TextValue> > m_linear_pairs; // ensemble des paires cle, valeur. 00301 bool m_pairs_init; 00302 00303 //! affecte le contenu du fichier a la section. 00304 int read( TextSection& section, FILE *in ); 00305 00306 //! renvoie l'ensemble de cles. 00307 std::map<std::string, int>& pairs( ); 00308 00309 public: 00310 TextFile( const std::string& name ) 00311 : 00312 IOResource(), 00313 m_definitions(), 00314 m_sections(), 00315 m_name(name), 00316 m_pairs(), 00317 m_pairs_init(false) 00318 {} 00319 00320 ~TextFile( ) {} 00321 00322 //! lecture du fichier 'filename'. 00323 int read( const std::string& filename ); 00324 00325 //! inclure le contenu du fichier 'filename', a la suite du contenu deja charge. 00326 int include( const std::string& filename ); 00327 00328 //! insere le contenu de 'source', a la suite du contenu deja charge. 00329 int include( const std::string& source, const std::string& filename, const int line ); 00330 00331 //! insere le contenu de 'source', a la suite du contenu deja charge. 00332 int include( const TextFile *text ); 00333 00334 //! insere une definition dans l'entete du fichier, a la suite des autres definitions. 00335 int define( const std::string& what, const std::string& value ); 00336 00337 //! remplace l'ensemble de definitions. 00338 int setDefinitions( const std::vector<std::string>& definitions ); 00339 00340 //! renvoie les definitions. 00341 const std::vector<std::string> *definitions( ); 00342 00343 //! reinitialise le contenu du fichier. 00344 int clear( ); 00345 00346 //! renvoie le contenu du fichier sous forme de chaine de caracteres std::string. 00347 std::string string( ) const; 00348 00349 //! utilisation interne. renvoie la chaine de caracteres de la premiere section. 00350 const char *c_str( ) const; 00351 00352 //! renvoie une ligne du texte et son 'origine' : nom du fichier et numero de ligne 00353 int getLine( const int line, std::string &string, std::string& file_name, int &file_line ) const; 00354 00355 //! renvoie le nom du fichier. 00356 const std::string& name( ) const 00357 { 00358 return m_name; 00359 } 00360 00361 //! affiche le contenu du fichier. 00362 void print( ) const; 00363 00364 //! interprete la premiere section comme un vec4. cf. TextValue pour la syntaxe a utiliser. 00365 Vec4Value asVec4( ) const; 00366 //! interprete la premiere section comme un vec3. cf. TextValue pour la syntaxe a utiliser. 00367 Vec3Value asVec3( ) const; 00368 //! interprete la premiere section comme un vec2. cf. TextValue pour la syntaxe a utiliser. 00369 Vec2Value asVec2( ) const; 00370 //! interprete la premiere section comme un reel. cf. TextValue pour la syntaxe a utiliser. 00371 FloatValue asFloat( ) const; 00372 //! interprete la premiere section comme un entier. cf. TextValue pour la syntaxe a utiliser. 00373 IntValue asInt( ) const; 00374 //! interprete la premiere section comme un nom (de section, par exemple). cf. TextValue pour la syntaxe a utiliser. 00375 NameValue asName( ) const; 00376 //! interprete la premiere section comme une chaine de caracteres. 00377 StringValue asString( ) const; 00378 //! interprete la premiere section comme un nom de fichier. cf. TextValue pour la syntaxe a utiliser. 00379 FileValue asFile( ) const; 00380 00381 //! recherche une cle et renvoie sa valeur. cf. TextValue pour obtenir un resultat type. 00382 //! renvoie TextValue::notFound() en cas d'echec / si la cle n'existe pas. 00383 TextValue& find( const std::string& key ); 00384 00385 //! ajoute ou modifie la valeur d'une cle. 00386 TextValue& insert( const std::string& key ); 00387 00388 //! renvoie le nombre de paires (cle, valeurs). 00389 int pairCount( ) 00390 { 00391 pairs(); // initialise l'ensemble de paires, si necessaire. 00392 return (int) m_linear_pairs.size(); 00393 } 00394 00395 //! renvoie une paire (cle, valeur). 00396 const std::pair<std::string, TextValue>& pair( const int id ) 00397 { 00398 pairs(); // initialise l'ensemble de paires, si necessaire. 00399 assert(id >= 0 && id < (int) m_linear_pairs.size()); 00400 return m_linear_pairs[id]; 00401 } 00402 00403 //! renvoie une valeur non definie, permet de verifier le resultat d'une recherche de cle, cf find(). 00404 static TextFile *notFound( ) 00405 { 00406 static TextFile not_found("not_found"); 00407 return ¬_found; 00408 } 00409 }; 00410 00411 } // namespace 00412 00413 #endif