gKitGL
TextFile.h
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 &not_found;
00408     }    
00409 };
00410 
00411 }       // namespace
00412 
00413 #endif
 All Classes Namespaces Functions Variables Typedefs Enumerator Friends