Gizmo3D

gzLex.h

Go to the documentation of this file.
00001 //******************************************************************************
00002 // File         : gzLex.h
00003 // Module       : gzBase
00004 // Description  : Class definition of Lex classes
00005 // Author       : Anders Modén      
00006 // Product      : GizmoBase 2.1.1
00007 //      
00008 // Copyright © 2003- Saab Training Systems AB, Sweden
00009 //          
00010 // NOTE:    GizmoBase is a platform abstraction utility layer for C++. It contains 
00011 //          design patterns and C++ solutions for the advanced programmer.
00012 //
00013 //
00014 // Revision History...                          
00015 //                                  
00016 // Who  Date    Description                     
00017 //                                  
00018 // AMO  000728  Created file    
00019 //
00020 //******************************************************************************
00021 
00022 #ifndef __GZ_LEX_H__
00023 #define __GZ_LEX_H__
00024 
00029 #include "gzSerialize.h"
00030 #include "gzDynamic.h"
00031 #include "gzPerformance.h"
00032 
00033 typedef enum {  GZ_LEX_EMPTY            =0,
00034                 GZ_LEX_TOKEN            =(1<<0),
00035                 GZ_LEX_IDENTIFIER       =(1<<1),
00036 
00037                 GZ_LEX_DOUBLE_STRING    =(1<<2),
00038                 GZ_LEX_SINGLE_STRING    =(1<<3),
00039                 GZ_LEX_STRING           = GZ_LEX_SINGLE_STRING + GZ_LEX_DOUBLE_STRING ,
00040 
00041                 GZ_LEX_INTEGER          =(1<<4),
00042                 GZ_LEX_REAL             =(1<<5),
00043                 GZ_LEX_LONGLONG         =(1<<6),
00044                 GZ_LEX_NUMBER           = GZ_LEX_INTEGER + GZ_LEX_REAL + GZ_LEX_LONGLONG ,
00045 
00046                 GZ_LEX_COMMENT          =(1<<7),
00047                 GZ_LEX_WHITESPACE       =(1<<8),
00048                 GZ_LEX_ERROR            =(1<<9),
00049                 GZ_LEX_SET              =(1<<10)
00050 
00051             } gzLexDataType;
00052 
00053 typedef enum {  GZ_LEX_ERROR_IN_INTEGER=1,
00054                 GZ_LEX_ERROR_IN_REAL,
00055                 GZ_LEX_ERROR_UNEXPECTED_END_OF_COMMENT,
00056                 GZ_LEX_ERROR_UNEXPECTED_END_OF_INTEGER,
00057                 GZ_LEX_ERROR_UNEXPECTED_END_OF_REAL,
00058                 GZ_LEX_ERROR_UNEXPECTED_END_OF_STRING,
00059                 GZ_LEX_ERROR_UNEXPECTED_END_OF_SET } gzLexErrorType;
00060 
00061 const gzUShort USE_COMMA_AND_DOT=9999; 
00062 
00063 class gzLexTokenData 
00064 {
00065 public:
00066 
00067     gzBool operator==(const gzLexTokenData &right) { return (type==right.type) && (data==right.data); }
00068     gzBool operator!=(const gzLexTokenData &right) { return (type!=right.type) || (data!=right.data); }
00069 
00070     gzLexDataType   type;
00071     gzDynamicType   data;
00072 };
00073 
00074 //******************************************************************************
00075 // Class    : gzSerializeLex
00076 //                                  
00077 // Purpose  : -
00078 //                                  
00079 // Notes    : -
00080 //                                  
00081 // Revision History...                          
00082 //                                  
00083 // Who  Date    Description                     
00084 //                                  
00085 // AMO  000728  Created 
00086 //                                  
00087 //******************************************************************************
00088 class  gzSerializeLex : public gzSerializeData
00089 {
00090 public:
00091 
00092     GZ_BASE_EXPORT gzSerializeLex(gzBool useUnicodeTag=FALSE,gzBool useUtf8Tag=FALSE);
00093 
00094     GZ_BASE_EXPORT virtual ~gzSerializeLex(){};
00095 
00096     GZ_BASE_EXPORT virtual gzVoid write(gzSerializeAdapter *adapter); 
00097 
00098     GZ_BASE_EXPORT virtual gzVoid read(gzSerializeAdapter *adapter);
00099 
00100     GZ_BASE_EXPORT virtual gzVoid pushBack(gzSerializeAdapter *adapter);
00101 
00102     GZ_BASE_EXPORT virtual gzULong  getDataSize(gzSerializeAdapter *adapter=NULL) const; 
00103 
00104     GZ_BASE_EXPORT  gzLexDataType getDataType();
00105 
00106     GZ_BASE_EXPORT  gzDynamicType getData();
00107 
00108     //Generic settings for scanner
00109 
00110     GZ_BASE_EXPORT gzVoid usePlainIdentifier(gzBool on=FALSE);
00111     GZ_BASE_EXPORT gzVoid useUnicode(gzBool on=FALSE,gzBool bigEndian=TRUE);
00112     GZ_BASE_EXPORT gzVoid useUtf8(gzBool on=FALSE);
00113     GZ_BASE_EXPORT gzVoid useHashComment(gzBool on=FALSE);
00114     GZ_BASE_EXPORT gzVoid useStrings(gzBool on=FALSE);
00115     GZ_BASE_EXPORT gzVoid useSet(gzBool on=FALSE);
00116     GZ_BASE_EXPORT gzVoid useEscape(gzBool on=TRUE);
00117     GZ_BASE_EXPORT gzVoid useTokensOnly(gzBool on=FALSE);
00118     GZ_BASE_EXPORT gzVoid useDecimalToken(gzUShort token='.');
00119     GZ_BASE_EXPORT gzVoid useHexMode(gzBool on=FALSE);
00120     GZ_BASE_EXPORT gzVoid setMaxScanTokens(gzULong tokens=0xFFFFFFFFUL);
00121 
00123     GZ_BASE_EXPORT  gzLexTokenData getTokenData();
00124 
00125     GZ_BASE_EXPORT  gzString    getScannedBuffer();
00126 
00127     GZ_BASE_EXPORT  gzVoid      qPush(gzUShort data);
00128 
00129     GZ_BASE_EXPORT  gzVoid      qPushBack(gzSerializeAdapter *adapter);
00130 
00131     GZ_BASE_EXPORT  gzVoid      pushBack(gzSerializeAdapter *adapter,gzWideChar token);
00132 
00133     GZ_BASE_EXPORT  gzULong     getEncoding(gzUShort data);
00134 
00135     GZ_BASE_EXPORT  gzWideChar  getLexToken(gzSerializeAdapter *adapter);
00136 
00137 private:
00138 
00139     typedef enum {  ENCODE_WHITESPACE       = (1<<0) , 
00140                     ENCODE_BINARY_DIGIT     = (1<<1) ,
00141                     ENCODE_OCTAL_DIGIT      = (1<<2) ,
00142                     ENCODE_HEX_DIGIT        = (1<<3) ,
00143                     ENCODE_LETTER           = (1<<4) ,
00144                     ENCODE_DIGIT            = (1<<5) ,
00145                     ENCODE_ID_START         = (1<<6) ,
00146                     ENCODE_ID_REST          = (1<<7) ,
00147                     ENCODE_HEX_DIGIT_SMALL  = (1<<8) ,
00148                     ENCODE_HEX_DIGIT_LARGE  = (1<<9) 
00149                  } Encoding;
00150 
00151     typedef enum { 
00152                     STATE_DEFAULT , 
00153                     STATE_IDENTIFIER,
00154                     STATE_INTEGER,
00155                     STATE_SIGNED_INTEGER_ADD,
00156                     STATE_SIGNED_INTEGER_SUB,
00157                     STATE_REAL,
00158                     STATE_REAL_EXP,
00159                     STATE_REAL_EXP_SIGN,
00160                     STATE_REAL_EXP_ADD,
00161                     STATE_REAL_EXP_SUB,
00162                     STATE_DOUBLE_STRING,
00163                     STATE_SINGLE_STRING,
00164                     STATE_SET,
00165                     STATE_ESQAPE_STRING,
00166                     STATE_ESQAPE_SINGLE_STRING,
00167                     STATE_ESQAPE_SET,
00168                     STATE_IN_DIV , 
00169                     STATE_COMMENT_CPP , 
00170                     STATE_COMMENT_C,
00171                     STATE_COMMENT_C_END,
00172                     STATE_WHITESPACE,
00173                     STATE_EXT_INTEGER,
00174                     STATE_HEX_INTEGER
00175                 } LexState;
00176 
00177 
00178     gzLexDataType       m_dataType;
00179     gzDynamicType       m_data;
00180     gzQueue<gzUByte>    m_queue;
00181 
00182     gzUShort            m_decimalToken;
00183 
00184     gzBool              m_useHashComment    :1;
00185     gzBool              m_useUnicodeTag     :1;
00186     gzBool              m_useUtf8Tag        :1;
00187     gzBool              m_useStrings        :1;
00188     gzBool              m_useSet            :1;
00189     gzBool              m_useEscape         :1;
00190     gzBool              m_useUnicode        :1;
00191     gzBool              m_bigEndian         :1;
00192     gzBool              m_firstRun          :1;
00193     gzBool              m_usePlainIdentifier:1;
00194     gzBool              m_useTokensOnly     :1;
00195     gzBool              m_useHexMode        :1;
00196     gzBool              m_useUtf8           :1;
00197     gzULong             m_maxScanTokens;
00198 };
00199 
00200 class gzStringTokenizer : public gzSerializeLex
00201 {
00202 public:
00203 
00204     GZ_BASE_EXPORT gzStringTokenizer(const char *string,gzLong len=-1);
00205 
00206     GZ_BASE_EXPORT gzStringTokenizer(const gzString &string);
00207 
00208     GZ_BASE_EXPORT gzStringTokenizer(const gzWideChar *string,gzLong len=-1);
00209 
00210     GZ_BASE_EXPORT ~gzStringTokenizer();
00211 
00212     GZ_BASE_EXPORT gzLexDataType getDataType(gzBool iterate=TRUE);
00213 
00214     GZ_BASE_EXPORT gzString getRemainingBuffer();
00215 
00216     GZ_BASE_EXPORT gzULong getRemainingTokens();
00217 
00218     GZ_BASE_EXPORT gzVoid pushBack( const gzString &back );
00219 
00220     GZ_BASE_EXPORT gzVoid pushBack();
00221 
00223     GZ_BASE_EXPORT  gzLexTokenData getTokenData(gzBool iterate=TRUE);
00224 
00225 private:
00226 
00227     gzArray<gzUByte>            m_data;
00228     gzSerializeAdapterMemory    m_adapter;
00229     gzBool                      m_unicode;
00230 };
00231 
00232 typedef gzArray<gzLexTokenData> gzLexTokenDataArray;
00233 typedef gzArray<gzDynamicType>  gzParseResultArray;
00234 
00236 gzLexTokenDataArray GZ_BASE_EXPORT getLexTokenDataArray(const char *string,gzBool skipWhiteSpace = TRUE);
00237 
00239 gzBool GZ_BASE_EXPORT checkLexToken(const gzLexTokenDataArray &array , const gzULong argPos , const gzLexDataType & type , const gzDynamicType &data);
00240 
00242 gzBool GZ_BASE_EXPORT checkLexToken(const gzLexTokenDataArray &array , const gzULong argPos , const gzLexDataType & type , gzDynamicType * data=NULL);
00243 
00245 
00265 gzParseResultArray GZ_BASE_EXPORT parse(const char *parseFormatString , const char *dataString ,  gzBool *success=NULL,gzUShort decimalToken='.');
00266 
00267 
00268 //******************************************************************************
00269 // Class    : gzArgumentParser
00270 //                                  
00271 // Purpose  : parse arguments from main or from a given string
00272 //                                  
00273 // Notes    : - 
00274 //                                  
00275 // Revision History...                          
00276 //                                  
00277 // Who  Date    Description                     
00278 //                                  
00279 // AMO  040601  Created 
00280 //                                  
00281 //******************************************************************************
00283 class gzArgumentParser
00284 {
00285 public:
00286 
00288     GZ_BASE_EXPORT  gzArgumentParser(int argc, char *argv[],const gzString &optionPrefix="-");
00289 
00291     GZ_BASE_EXPORT  gzArgumentParser(const gzString &argString,const gzString &optionPrefix="-");
00292 
00294     GZ_BASE_EXPORT  virtual ~gzArgumentParser();
00295 
00297     GZ_BASE_EXPORT  gzVoid setArgumentString(const gzString &argString,const gzString &optionPrefix="-");
00298 
00299     // Option based -option or --option
00300 
00302 
00305     GZ_BASE_EXPORT  gzULong     getOptionCount() const;
00306 
00308 
00311     GZ_BASE_EXPORT  gzBool      hasOption(const gzString &option,gzBool caseSensitive=FALSE,gzULong *argument=NULL,gzULong *maxArgument=NULL) const;
00312 
00313     GZ_BASE_EXPORT  gzBool      getOptionValue(const gzString &option,const gzBool &        defaultValue,gzULong argument=0,gzBool useDefault=TRUE,gzBool caseSensitive=FALSE) const;
00314     GZ_BASE_EXPORT  gzByte      getOptionValue(const gzString &option,const gzByte &        defaultValue,gzULong argument=0,gzBool useDefault=TRUE,gzBool caseSensitive=FALSE) const;
00315     GZ_BASE_EXPORT  gzUShort    getOptionValue(const gzString &option,const gzUShort &      defaultValue,gzULong argument=0,gzBool useDefault=TRUE,gzBool caseSensitive=FALSE) const;
00316     GZ_BASE_EXPORT  gzShort     getOptionValue(const gzString &option,const gzShort &       defaultValue,gzULong argument=0,gzBool useDefault=TRUE,gzBool caseSensitive=FALSE) const;
00317     GZ_BASE_EXPORT  gzUInt      getOptionValue(const gzString &option,const gzUInt &        defaultValue,gzULong argument=0,gzBool useDefault=TRUE,gzBool caseSensitive=FALSE) const;
00318     GZ_BASE_EXPORT  gzInt       getOptionValue(const gzString &option,const gzInt &         defaultValue,gzULong argument=0,gzBool useDefault=TRUE,gzBool caseSensitive=FALSE) const;
00319     GZ_BASE_EXPORT  gzULong     getOptionValue(const gzString &option,const gzULong &       defaultValue,gzULong argument=0,gzBool useDefault=TRUE,gzBool caseSensitive=FALSE) const;
00320     GZ_BASE_EXPORT  gzLong      getOptionValue(const gzString &option,const gzLong &        defaultValue,gzULong argument=0,gzBool useDefault=TRUE,gzBool caseSensitive=FALSE) const;
00321     GZ_BASE_EXPORT  gzLongLong  getOptionValue(const gzString &option,const gzLongLong &    defaultValue,gzULong argument=0,gzBool useDefault=TRUE,gzBool caseSensitive=FALSE) const;
00322     GZ_BASE_EXPORT  gzULongLong getOptionValue(const gzString &option,const gzULongLong &   defaultValue,gzULong argument=0,gzBool useDefault=TRUE,gzBool caseSensitive=FALSE) const;
00323     GZ_BASE_EXPORT  gzDouble    getOptionValue(const gzString &option,const gzDouble &      defaultValue,gzULong argument=0,gzBool useDefault=TRUE,gzBool caseSensitive=FALSE) const;
00324     GZ_BASE_EXPORT  gzString    getOptionValue(const gzString &option,const gzString &      defaultValue,gzULong argument=0,gzBool useDefault=TRUE,gzBool caseSensitive=FALSE) const;
00325 
00326     GZ_BASE_EXPORT  gzString    getOptionString(const gzString &option,gzBool caseSensitive=FALSE) const;
00327         
00328     // argument position based (options excluded)
00329 
00330     GZ_BASE_EXPORT  gzULong     getArgumentCount(gzBool notUsedForOption=TRUE) const;
00331 
00332     GZ_BASE_EXPORT  gzString    getArgument(gzULong argpos,gzBool notUsedForOption=TRUE) const;
00333 
00334     GZ_BASE_EXPORT  gzBool      getArgumentValue(gzULong argpos,const gzBool &      defaultValue) const;
00335     GZ_BASE_EXPORT  gzByte      getArgumentValue(gzULong argpos,const gzByte &      defaultValue) const;
00336     GZ_BASE_EXPORT  gzUShort    getArgumentValue(gzULong argpos,const gzUShort &    defaultValue) const;
00337     GZ_BASE_EXPORT  gzShort     getArgumentValue(gzULong argpos,const gzShort &     defaultValue) const;
00338     GZ_BASE_EXPORT  gzUInt      getArgumentValue(gzULong argpos,const gzUInt &      defaultValue) const;
00339     GZ_BASE_EXPORT  gzInt       getArgumentValue(gzULong argpos,const gzInt &       defaultValue) const;
00340     GZ_BASE_EXPORT  gzULong     getArgumentValue(gzULong argpos,const gzULong &     defaultValue) const;
00341     GZ_BASE_EXPORT  gzLong      getArgumentValue(gzULong argpos,const gzLong &      defaultValue) const;
00342     GZ_BASE_EXPORT  gzLongLong  getArgumentValue(gzULong argpos,const gzLongLong &  defaultValue) const;
00343     GZ_BASE_EXPORT  gzULongLong getArgumentValue(gzULong argpos,const gzULongLong & defaultValue) const;
00344     GZ_BASE_EXPORT  gzDouble    getArgumentValue(gzULong argpos,const gzDouble &    defaultValue) const;
00345     GZ_BASE_EXPORT  gzString    getArgumentValue(gzULong argpos,const gzString &    defaultValue) const;
00346 
00347     // Error management
00348 
00349     GZ_BASE_EXPORT  gzVoid      exitOnError(gzBool on=TRUE);
00350     GZ_BASE_EXPORT  gzBool      hasError() const;
00351     GZ_BASE_EXPORT  gzString    getError() const;
00352     GZ_BASE_EXPORT  gzVoid      setSyntaxString(const gzString &syntax);
00353     GZ_BASE_EXPORT  gzVoid      checkArgumentCount(gzULong required);
00354     
00355 private:
00356 
00357     gzVoid  terminateCheck() const;
00358 
00359     class gzArgOption : public gzReference
00360     {
00361     public:
00362         gzString        option;
00363         gzULong         argument;
00364 
00365         gzReference *   clone() const { return new gzArgOption(*this); }
00366 
00367     };
00368 
00369     class gzArgArgument : public gzReference
00370     {
00371     public:
00372         gzString        argument;
00373         gzBool          usedForOption;
00374 
00375         gzReference *   clone() const { return new gzArgArgument(*this); };
00376     };
00377 
00378     gzRefList<gzArgOption>      m_optionList;
00379 
00380     gzRefList<gzArgArgument>    m_argList;
00381 
00382     gzString                    m_error;
00383 
00384     gzString                    m_syntax;
00385 
00386     gzBool                      m_exitOnError;
00387 
00388 };
00389 
00390 // ----------------------- Parser Stuff --------------------------------
00391 
00393 enum gzBasicParseException
00394 {
00395     GZ_EXCEPTION_OUT_OF_DATA,
00396     GZ_EXCEPTION_DATA_IS_DISCARDED,
00397     GZ_EXCEPTION_USER_EXIT,
00398     GZ_EXCEPTION_GENERIC_ERROR,
00399 };
00400 
00402 enum gzParseResult
00403 {
00404     GZ_PARSE_ERROR      = 0,    // Error occured
00405     GZ_PARSE_OK         = 1,    // Ok
00406     GZ_PARSE_NO_MATCH   = 2,    // Tested tokens did not match. Tokens are pushed back
00407 };
00408 
00410 const gzString  GZ_RULE_DELIMITER       =   gzUniqueString("::=");
00411 const gzString  GZ_PUSH_TOKEN           =   gzUniqueString("$");
00412 const gzString  GZ_MISSING_IDENTIFIER   =   gzUniqueString("Missing Identifier");
00413 
00414 struct gzTokenPos
00415 {
00416     gzULong tokenPos;
00417     gzULong itemID;
00418 };
00419 
00420 //******************************************************************************
00421 // Class    : gzParserFunction
00422 //                                  
00423 // Purpose  : Generic utility to register you parser callback functions
00424 //                                  
00425 // Notes    : - 
00426 //                                  
00427 // Revision History...                          
00428 //                                  
00429 // Who  Date    Description                     
00430 //                                  
00431 // AMO  040601  Created 
00432 //                                  
00433 //******************************************************************************
00434 template <class T , class BaseParser> class gzParserFunction : public BaseParser
00435 {
00436 public:
00437 
00438     gzParserFunction():m_itemID(0)
00439     {
00440         m_propertyEnableTrace=FALSE;
00441         m_propertyEnablePerfMon=FALSE;
00442     }
00443 
00444     virtual ~gzParserFunction()
00445     {
00446     }
00447 
00448     typedef gzParseResult (T::* ThisPtr)();
00449 
00450     class gzFuncInfo : public gzReference
00451     {
00452     public:
00453 
00454         gzFuncInfo(ThisPtr func):m_func(func){}
00455 
00456         virtual ~gzFuncInfo(){}
00457 
00458         ThisPtr getFunction() { return m_func; }
00459 
00460     private:
00461 
00462         ThisPtr m_func;
00463     };
00464 
00465     class gzRuleInfo : public gzReference
00466     {
00467     public:
00468 
00469         gzRuleInfo(const gzString &rule):m_rule(rule){}
00470 
00471         virtual ~gzRuleInfo(){}
00472 
00473         const gzString & getRule() { return m_rule; }
00474 
00475     private:
00476 
00477         gzString m_rule;
00478     };
00479 
00480     gzParseResult parseMultiple(ThisPtr func,gzULong min=0,gzULong max=0xFFFFFFFFUL)    // Mul(func) ::= [min,max](func)
00481     {
00482         gzULong tokenPos=BaseParser::getTokenPos();
00483         gzULong count=0;
00484 
00485         while( (count<max) && BaseParser::hasData())
00486         {
00487             gzParseResult result=(((T*)this)->*func)();
00488 
00489             if(!result) // Error
00490                 return result;
00491 
00492             if(result!=GZ_PARSE_OK)
00493                 break;
00494 
00495             ++count;
00496         }
00497 
00498         if(count>=min)
00499             return GZ_PARSE_OK;
00500 
00501         BaseParser::pushBackTokens(BaseParser::getTokenPos()-tokenPos);
00502 
00503         return GZ_PARSE_NO_MATCH;
00504     }
00505 
00506     gzParseResult parseTokens(const gzString &string)
00507     {
00508         gzUShort len=string.getWideStringLength();
00509 
00510         if(BaseParser::checkTokens(string.getWideString(len),len))
00511             return GZ_PARSE_OK;
00512 
00513         return GZ_PARSE_NO_MATCH;
00514     }
00515 
00516     gzParseResult parseSet(const gzString &string)
00517     {
00518         if(!string)
00519             return GZ_PARSE_OK;
00520 
00521         gzULong len=string.getWideStringLength();
00522 
00523         m_buffer.setSize(len);
00524 
00525         gzWideChar *buffer=m_buffer.getAddress();
00526 
00527         string.getWideString(buffer,FALSE);
00528 
00529         gzBool inverse=(*buffer=='^');
00530 
00531         gzBool match=FALSE;
00532         
00533         gzULong valueStart,valueEnd,i;
00534 
00535         if(BaseParser::hasData() && len)
00536         {
00537             gzUShort token=BaseParser::getNextToken(FALSE);
00538 
00539             i=inverse?1:0;
00540             
00541             while(i<len)
00542             {
00543                 valueStart=valueEnd=buffer[i];
00544                 
00545                 if(( (i+2) < len ) && (valueStart=='#')  && ( buffer[i+1]=='x' ))
00546                 {
00547                     i+=2;
00548                     
00549                     valueStart=0;
00550                     
00551                     while( (i<len) && (((buffer[i]>='0') && (buffer[i]<='9')) || ((buffer[i]>='a') && (buffer[i]<='f')) || ((buffer[i]>='A') && (buffer[i]<='F'))))
00552                     {
00553                         if(buffer[i]<='9')
00554                             valueStart=(valueStart<<4)+(buffer[i]-'0');
00555                         else if(buffer[i]>='a')
00556                             valueStart=(valueStart<<4)+(buffer[i]-'a')+10;
00557                         else 
00558                             valueStart=(valueStart<<4)+(buffer[i]-'A')+10;
00559                         
00560                         i++;
00561                     }
00562 
00563                     valueEnd=valueStart;
00564                     
00565                     i--;
00566                 }
00567                                 
00568                 if( ( (i+2) < len ) && ( buffer[i+1]=='-' ))
00569                 {
00570                     i+=2;
00571                     valueEnd=buffer[i];
00572                     
00573                     if(( (i+2) < len ) && (valueEnd=='#')  && ( buffer[i+1]=='x' ))
00574                     {
00575                         i+=2;
00576                     
00577                         valueEnd=0;
00578                     
00579                         while( (i<len) && (((buffer[i]>='0') && (buffer[i]<='9')) || ((buffer[i]>='a') && (buffer[i]<='f')) || ((buffer[i]>='A') && (buffer[i]<='F'))))
00580                         {
00581                             if(buffer[i]<='9')
00582                                 valueEnd=(valueEnd<<4)+(buffer[i]-'0');
00583                             else if(buffer[i]>='a')
00584                                 valueEnd=(valueEnd<<4)+(buffer[i]-'a')+10;
00585                             else 
00586                                 valueEnd=(valueEnd<<4)+(buffer[i]-'A')+10;
00587                         
00588                             i++;
00589                         }
00590                         
00591                         i--;
00592                     }
00593                 }
00594                 
00595                 if((token>=valueStart) && (token<=valueEnd))
00596                 {
00597                     match=TRUE;
00598                     break;
00599                 }
00600                 
00601                 i++;
00602             }
00603 
00604             if(match==inverse)
00605                 BaseParser::pushBackTokens(1);
00606         }
00607         else
00608             match=inverse;
00609 
00610         if(match!=inverse)
00611             return GZ_PARSE_OK;
00612         else
00613             return GZ_PARSE_NO_MATCH;
00614     }
00615 
00616     gzVoid registerFunction(const gzString &name,ThisPtr func)
00617     {
00618         gzString compressedName=getCompressedIdentifier(name);
00619 
00620         m_registeredFunctions.remove(compressedName);
00621         m_registeredFunctions.enter(compressedName,new gzFuncInfo(func));
00622     }
00623 
00624     gzBool registerRule(const gzString &rule)
00625     {
00626         gzString url;
00627 
00628         url.format("mem:%d,%d",rule.getString(),rule.length());
00629 
00630         return registerRulesFromURL(url);
00631     }
00632 
00633     gzBool registerCompressedRule(const gzString &rule)
00634     {
00635         gzString ruleName=rule.leftOf(GZ_RULE_DELIMITER).stripWhiteSpace();
00636         gzString ruleExpression=rule.rightOf(GZ_RULE_DELIMITER,FALSE).stripWhiteSpace();
00637 
00638         if(!ruleName || !ruleExpression)
00639         {
00640             GZMESSAGE(GZ_MESSAGE_WARNING,"Malformed rule in parser -> '%s'",rule);
00641             return FALSE;
00642         }
00643 
00644         m_registeredRules.remove(ruleName);
00645         m_registeredRules.enter(ruleName,new gzRuleInfo(ruleExpression));
00646 
00647         return TRUE;    
00648     }
00649 
00650     gzString getRule(const gzString &rule)
00651     {
00652         gzString theRule=rule.stripWhiteSpace();
00653 
00654         gzRuleInfo *info=m_registeredRules.find(getCompressedIdentifier(theRule));
00655 
00656         if(info)
00657         {
00658             gzStringTokenizer lexer(info->getRule());
00659             gzString retval;
00660 
00661             lexer.useStrings(TRUE);
00662             lexer.useSet(TRUE);
00663             lexer.useEscape(FALSE);
00664 
00665             while(lexer.getDataType()!=GZ_LEX_EMPTY)
00666             {
00667                 switch(lexer.getDataType(FALSE))
00668                 {
00669                     case GZ_LEX_DOUBLE_STRING :
00670                         {
00671                             retval+="\"";
00672                             retval+=getUnCompressedIdentifier(lexer.getData().getString());
00673                             retval+="\"";
00674 
00675                             continue;
00676                         }
00677 
00678                     case GZ_LEX_SINGLE_STRING :
00679                         {
00680                             retval+="'";
00681                             retval+=lexer.getData().getString();
00682                             retval+="'";
00683 
00684                             continue;
00685                         }
00686 
00687                     case GZ_LEX_SET :
00688                         {
00689                             retval+="[";
00690                             retval+=lexer.getData().getString();
00691                             retval+="]";
00692 
00693                             continue;
00694                         }
00695 
00696 
00697                     case GZ_LEX_WHITESPACE :
00698                         {
00699                             retval+=" ";
00700                             continue;
00701                         }
00702 
00703                     case GZ_LEX_IDENTIFIER :
00704                         {
00705                             retval+=getUnCompressedIdentifier(lexer.getData().getString());
00706                             continue;
00707                         }
00708                 }
00709 
00710                 retval=retval+lexer.getScannedBuffer();
00711             }
00712 
00713             return retval;
00714         }
00715 
00716         return GZ_EMPTY_STRING;
00717     }
00718 
00719     gzVoid removeCompressedIdentifier(const gzString &name)
00720     {
00721         gzRefData<gzString> *data=m_identifierLookupB.find(name);
00722 
00723         m_identifierLookupA.remove(*data);
00724         m_identifierLookupB.remove(name);
00725     }
00726 
00727     gzString getCompressedIdentifier(const gzString &name,gzBool *created=NULL)
00728     {
00729         gzRefData<gzString> *data=m_identifierLookupA.find(name);
00730 
00731         if(!data)
00732         {
00733             data=new gzRefData<gzString>(gzString().identifier(m_identifierLookupA.entries()));
00734 
00735             m_identifierLookupA.enter(name,data);
00736 
00737             gzRefData<gzString> *dataB=new gzRefData<gzString>(name);
00738 
00739             m_identifierLookupB.enter(*data,dataB);
00740 
00741             if(created)
00742                 *created=TRUE;
00743         }
00744         else if(created)
00745         {
00746             *created=FALSE;
00747         }
00748 
00749         return *data;
00750     }
00751 
00752     gzString getUnCompressedIdentifier(const gzString &name)
00753     {
00754         gzRefData<gzString> *data=m_identifierLookupB.find(name);
00755 
00756         if(!data)
00757             return GZ_MISSING_IDENTIFIER;
00758         
00759         return *data;
00760     }
00761 
00762     gzBool registerRulesFromURL(const gzString &url)
00763     {
00764         gzRefPointer<gzSerializeAdapter> adapter=gzSerializeAdapter::getURLAdapter(url);
00765 
00766         if(!adapter)
00767             return FALSE;
00768 
00769         gzSerializeLex lexer(TRUE,TRUE);
00770         
00771         lexer.useStrings(TRUE);
00772         lexer.useSet(TRUE);
00773         lexer.useEscape(FALSE);
00774 
00775         lexer.read(adapter);
00776 
00777         gzString rule,compressed;
00778         
00779         gzBool result=TRUE;
00780 
00781         gzBool created;
00782 
00783         gzULong rulenum=1;
00784 
00785         while(lexer.getDataType()!=GZ_LEX_EMPTY)
00786         {
00787             switch(lexer.getDataType())
00788             {
00789                 case GZ_LEX_DOUBLE_STRING :
00790                 case GZ_LEX_SINGLE_STRING :
00791                     {
00792                         compressed=getCompressedIdentifier(lexer.getData().getString(),&created);
00793 
00794                         if(compressed.length()<lexer.getData().getString().length())
00795                         {
00796                             rule+="\"";
00797                             rule+=compressed;
00798                             rule+="\"";
00799                         }
00800                         else
00801                         {
00802                             rule+="'";
00803                             rule+=lexer.getData().getString().convertCtrlToText();
00804                             rule+="'";
00805 
00806                             if(created)
00807                                 removeCompressedIdentifier(compressed);
00808                         }
00809                         
00810 
00811                         lexer.read(adapter);
00812                         continue;
00813                     }
00814 
00815 
00816                 case GZ_LEX_SET :
00817                     {
00818                         rule+="[";
00819                         rule+=lexer.getData().getString();
00820                         rule+="]";
00821 
00822                         lexer.read(adapter);
00823                         continue;
00824                     }
00825 
00826 
00827                 case GZ_LEX_TOKEN :
00828                     {
00829                         if(lexer.getData().getNumber()==';')
00830                         {
00831                             if(!registerCompressedRule(rule))
00832                             {
00833                                 GZMESSAGE(GZ_MESSAGE_WARNING,"Malformed rule in parser url:%s rule nr:%d",url,rulenum);
00834                                 result=FALSE;
00835                             }
00836 
00837                             ++rulenum;
00838 
00839                             rule.clear();
00840                             lexer.read(adapter);
00841                             continue;
00842                         }
00843                     }
00844                     break;
00845 
00846                 case GZ_LEX_WHITESPACE :
00847                     {
00848                         rule+=" ";
00849                         lexer.read(adapter);
00850                         continue;
00851                     }
00852 
00853                 case GZ_LEX_COMMENT :
00854                     {
00855                         lexer.read(adapter);
00856                         continue;
00857                     }
00858 
00859                 case GZ_LEX_IDENTIFIER :
00860                     {
00861                         rule+=getCompressedIdentifier(lexer.getData().getString());
00862 
00863                         lexer.read(adapter);
00864                         continue;
00865                     }
00866             }
00867 
00868             rule=rule+lexer.getScannedBuffer();
00869             
00870             lexer.read(adapter);
00871         }
00872         
00873         if(rule.contains(GZ_RULE_DELIMITER))
00874         {
00875             if(!registerCompressedRule(rule))
00876             {
00877                 GZMESSAGE(GZ_MESSAGE_WARNING,"Malformed rule in parser url:%s rule nr:%d",url,rulenum);
00878                 result=FALSE;
00879             }
00880         }
00881 
00882         return result;
00883     }
00884 
00885     gzParseResult parseFunction(const gzString &name)
00886     {
00887         parseCompressedFunction(getCompressedIdentifier(name));
00888     }
00889 
00890     gzParseResult parseCompressedFunction(const gzString &name)
00891     {
00892         gzFuncInfo *funcInfo=m_registeredFunctions.find(name);
00893 
00894         if(!funcInfo)
00895             return BaseParser::parseFunction(getUnCompressedIdentifier(name));
00896 
00897         return (((T *)this)->*funcInfo->getFunction())();
00898     }
00899 
00900     gzParseResult parseRule(const gzString &rule)
00901     {
00902         return parseCompressedRule(getCompressedIdentifier(rule));
00903     }
00904 
00905     gzParseResult parseCompressedRule(const gzString &rule);
00906 
00907     gzULong addItem()
00908     {
00909         return m_itemID++;
00910     }
00911 
00912     gzVoid rejectItem(gzULong restore)
00913     {
00914         m_itemID=restore;
00915 
00916         while(m_tokenPos.entries() && m_tokenPos.top().itemID>restore)
00917             m_tokenPos.pop();
00918 
00919         onRejectItem(restore);
00920     }
00921 
00922     gzULong getItemID()
00923     {
00924         return m_itemID;
00925     }
00926 
00927     gzVoid pushTokenPos()
00928     {
00929         gzTokenPos pos={BaseParser::getTokenPos(),m_itemID};
00930         m_tokenPos.push(pos);
00931     }
00932 
00933     gzULong getPushedTokenPos()
00934     {
00935         if(m_tokenPos.entries())
009