Back to index

nux  3.0.0
Parsing.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #include "NuxCore.h"
00024 #include "Parsing.h"
00025 
00026 #define CHAR_TAB        TEXT('\t')
00027 #define CHAR_CR         TEXT('\r')
00028 #define CHAR_FF         TEXT('\f')
00029 #define CHAR_NEW_LINE   TEXT('\n')
00030 #define CHAR_QUOTE      TEXT('\"')
00031 
00032 namespace nux
00033 {
00034 
00035   bool ParseCommand (const TCHAR **Stream, const TCHAR  *Match)
00036   {
00037     while ( (**Stream == TEXT (' ') ) || (**Stream == CHAR_TAB) )
00038       (*Stream) ++;
00039 
00040     if (TCharStringNICompare (*Stream, Match, StringLength (Match) ) == 0)
00041     {
00042       *Stream += StringLength (Match);
00043 
00044       if (!IsAlphanumericChar (**Stream) )
00045       {
00046         while ( (**Stream == TEXT (' ') ) || (**Stream == CHAR_TAB) )
00047           (*Stream) ++;
00048 
00049         return true; // Success.
00050       }
00051       else
00052       {
00053         *Stream -= StringLength (Match);
00054         return false; // Only found partial match.
00055       }
00056     }
00057     else return false; // No match.
00058   }
00059 
00060   bool Parse_tchar (const TCHAR *Stream, const TCHAR *Match, TCHAR *Value, int Size, int MaxLen)
00061   {
00062     const TCHAR *Found = Strfind (Stream, Match);
00063     const TCHAR *Start;
00064 
00065     if (Found)
00066     {
00067       Start = Found + StringLength (Match);
00068 
00069       if (*Start == '\x22') // Character '"'
00070       {
00071         // The value begins with the quotation mark character: ". We skip it.
00072         Strncpy (Value, Size, Start + 1, MaxLen);
00073         Value[MaxLen - 1] = 0;
00074         TCHAR *Temp = Strstr (Value, TEXT ("\x22") );
00075 
00076         if (Temp != NULL)
00077         {
00078           // We read in the termination quotation mark. Set it t0 0 to null terminate the Value buffer.
00079           *Temp = 0;
00080         }
00081       }
00082       else
00083       {
00084         // Non-quoted string without spaces.
00085         Strncpy (Value, Size, Start, MaxLen);
00086         Value[MaxLen - 1] = 0;
00087         TCHAR *Temp;
00088         Temp = Strstr (Value, TEXT (" ") );
00089 
00090         if (Temp) *Temp = 0;
00091 
00092         Temp = Strstr (Value, TEXT ("\r") );
00093 
00094         if (Temp) *Temp = 0;
00095 
00096         Temp = Strstr (Value, TEXT ("\n") );
00097 
00098         if (Temp) *Temp = 0;
00099 
00100         Temp = Strstr (Value, TEXT ("\t") );
00101 
00102         if (Temp) *Temp = 0;
00103 
00104         Temp = Strstr (Value, TEXT (",") );
00105 
00106         if (Temp) *Temp = 0;
00107       }
00108 
00109       return true;
00110     }
00111     else
00112       return false;
00113   }
00114 
00115   bool ParseParam (const TCHAR *Stream, const TCHAR *Param)
00116   {
00117     const TCHAR *Start = Stream;
00118 
00119     if (*Stream)
00120     {
00121       while ( (Start = Strfind (Start + 1, Param) ) != NULL)
00122       {
00123         if (Start > Stream && ( (Start[-1] == TEXT ('-') ) || (Start[-1] == TEXT ('/') ) ) )
00124         {
00125           const TCHAR *End = Start + StringLength (Param);
00126 
00127           if (End == NULL || *End == 0 || IsWhitespaceChar (*End) )
00128             return true;
00129         }
00130       }
00131     }
00132 
00133     return false;
00134   }
00135 
00136   bool Parse_string (const TCHAR *Stream, const TCHAR *Match, NString &Value)
00137   {
00138     TCHAR Temp[4096] = TEXT ("");
00139 
00140     if (Parse_tchar (Stream, Match, Temp, NUX_ARRAY_COUNT (Temp), NUX_ARRAY_COUNT (Temp) ) )
00141     {
00142       Value = Temp;
00143       return true;
00144     }
00145     else return false;
00146   }
00147 
00148   bool Parse_u64 (const TCHAR *Stream, const TCHAR *Match, QWORD &Value)
00149   {
00150     return Parse_s64 (Stream, Match, * (SQWORD *) &Value);
00151   }
00152 
00153   bool Parse_s64 (const TCHAR *Stream, const TCHAR *Match, SQWORD &Value)
00154   {
00155     TCHAR Temp[4096] = TEXT (""), *Ptr = Temp;
00156 
00157     if (Parse_tchar (Stream, Match, Temp, NUX_ARRAY_COUNT (Temp), NUX_ARRAY_COUNT (Temp) ) )
00158     {
00159       Value = 0;
00160       bool Negative = (*Ptr == TEXT ('-') );
00161       Ptr += Negative;
00162 
00163       while ( (*Ptr >= TEXT ('0') ) && (*Ptr <= TEXT ('9') ) )
00164         Value = Value * 10 + *Ptr++ - TEXT ('0');
00165 
00166       if (Negative)
00167         Value = -Value;
00168 
00169       return true;
00170     }
00171     else
00172       return false;
00173   }
00174 
00175   bool Parse_u32 (const TCHAR *Stream, const TCHAR *Match, DWORD &Value)
00176   {
00177     const TCHAR *Temp = Strfind (Stream, Match);
00178     TCHAR *End;
00179 
00180     if (Temp == NULL)
00181       return false;
00182 
00183     Value = Strtoi (Temp + StringLength (Match), &End, 10);
00184 
00185     return true;
00186   }
00187 
00188   bool Parse_u8 (const TCHAR *Stream, const TCHAR *Match, BYTE &Value)
00189   {
00190     const TCHAR *Temp = Strfind (Stream, Match);
00191 
00192     if (Temp == NULL)
00193       return false;
00194 
00195     Temp += StringLength (Match);
00196     Value = (BYTE) CharToInteger (Temp);
00197     return (Value != 0) || IsDigitChar (Temp[0]);
00198   }
00199 
00200   bool Parse_s8 (const TCHAR *Stream, const TCHAR *Match, SBYTE &Value)
00201   {
00202     const TCHAR *Temp = Strfind (Stream, Match);
00203 
00204     if (Temp == NULL)
00205       return false;
00206 
00207     Temp += StringLength (Match);
00208     Value = CharToInteger (Temp);
00209     return Value != 0 || IsDigitChar (Temp[0]);
00210   }
00211 
00212   bool Parse_u16 (const TCHAR *Stream, const TCHAR *Match, WORD &Value)
00213   {
00214     const TCHAR *Temp = Strfind (Stream, Match);
00215 
00216     if (Temp == NULL)
00217       return false;
00218 
00219     Temp += StringLength (Match);
00220     Value = (unsigned short) CharToInteger (Temp);
00221     return Value != 0 || IsDigitChar (Temp[0]);
00222   }
00223 
00224   bool Parse_s16 (const TCHAR *Stream, const TCHAR *Match, SWORD &Value)
00225   {
00226     const TCHAR *Temp = Strfind (Stream, Match);
00227 
00228     if (Temp == NULL)
00229       return false;
00230 
00231     Temp += StringLength (Match);
00232     Value = (short) CharToInteger (Temp);
00233     return Value != 0 || IsDigitChar (Temp[0]);
00234   }
00235 
00236   bool Parse_float (const TCHAR *Stream, const TCHAR *Match, float &Value)
00237   {
00238     const TCHAR *Temp = Strfind (Stream, Match);
00239 
00240     if (Temp == NULL)
00241       return false;
00242 
00243     Value = CharToDouble (Temp + StringLength (Match) );
00244     return true;
00245   }
00246 
00247   bool Parse_int (const TCHAR *Stream, const TCHAR *Match, int &Value)
00248   {
00249     const TCHAR *Temp = Strfind (Stream, Match);
00250 
00251     if (Temp == NULL)
00252       return false;
00253 
00254     Value = CharToInteger (Temp + StringLength (Match) );
00255     return true;
00256   }
00257 
00258   bool Parse_bool (const TCHAR *Stream, const TCHAR *Match, bool &OnOff)
00259   {
00260     TCHAR TempStr[16];
00261 
00262     if (Parse_tchar (Stream, Match, TempStr, NUX_ARRAY_COUNT (TempStr), NUX_ARRAY_COUNT (TempStr) - 1) )
00263     {
00264       OnOff = !Stricmp (TempStr, TEXT ("On") ) || !Stricmp (TempStr, TEXT ("True") ) || !Stricmp (TempStr, TEXT ("1") );
00265       return true;
00266     }
00267     else
00268       return false;
00269   }
00270 
00271   void ParseToNextLine (const TCHAR **Stream, TCHAR CommentChar)
00272   {
00273     // Skip over spaces, tabs, cr's, and linefeeds.
00274 
00275     while (1)
00276     {
00277       while ( (**Stream == TEXT (' ') ) || (**Stream == CHAR_TAB) || (**Stream == CHAR_CR) || (**Stream == CHAR_NEW_LINE)  || (**Stream == CHAR_FF) )
00278       {
00279         // Skip tabs, cr, new line, form feed
00280         ++*Stream;
00281       }
00282 
00283       if (**Stream == CommentChar)
00284       {
00285         // Start of a comment
00286         while ( (**Stream != 0) && (**Stream != CHAR_NEW_LINE) && (**Stream != CHAR_CR) )
00287         {
00288           // Advance to a new line
00289           ++*Stream;
00290         }
00291       }
00292       else
00293       {
00294         break;
00295       }
00296     }
00297   }
00298 
00299   bool ParseToken (const TCHAR *Str, TCHAR *TokenBuffer, int BufferSize)
00300   {
00301     int sz = 0;
00302 
00303     while ( (*Str == TEXT (' ') ) || (*Str == CHAR_TAB) )
00304     {
00305       // Skip spaces and tabs.
00306       Str++;
00307     }
00308 
00309     if (*Str == CHAR_QUOTE)
00310     {
00311       // Get quoted string.
00312       Str++;
00313 
00314       while (*Str && (*Str != CHAR_QUOTE) && (sz + 1 < BufferSize) )
00315       {
00316         TCHAR c = *Str++;
00317 
00318         if (sz + 1 < BufferSize)
00319           TokenBuffer[sz++] = c;
00320       }
00321 
00322       if (*Str == CHAR_QUOTE)
00323         Str++;
00324     }
00325     else
00326     {
00327       // Get unquoted string.
00328       for (; *Str && (*Str != TEXT (' ') ) && (*Str != CHAR_TAB); Str++)
00329       {
00330         if (sz + 1 < BufferSize)
00331           TokenBuffer[sz++] = *Str;
00332       }
00333     }
00334 
00335     TokenBuffer[sz] = 0;
00336     return sz != 0;
00337   }
00338 
00339   bool ParseToken (const TCHAR *Str, NString &TokenString)
00340   {
00341     TokenString.Clear();
00342 
00343     // Skip spaces and tabs.
00344     while (IsWhitespaceChar (*Str) )
00345       Str++;
00346 
00347     if (*Str == CHAR_QUOTE)
00348     {
00349       // Get quoted string.
00350       Str++;
00351 
00352       while (*Str && *Str != CHAR_QUOTE)
00353       {
00354         TCHAR c = *Str++;
00355         TokenString += c;
00356       }
00357 
00358       if (*Str == CHAR_QUOTE)
00359         Str++;
00360     }
00361     else
00362     {
00363       // Get unquoted string.
00364       for (; *Str && !IsWhitespaceChar (*Str); Str++)
00365       {
00366         TokenString += *Str;
00367       }
00368     }
00369 
00370     return TokenString.Length() > 0;
00371   }
00372 
00373   NString ParseToken (const TCHAR *Str, bool UseEscape)
00374   {
00375     TCHAR Buffer[1024];
00376 
00377     if (ParseToken (Str, Buffer, NUX_ARRAY_COUNT (Buffer) ) )
00378       return Buffer;
00379     else
00380       return TEXT ("");
00381   }
00382 
00383 //
00384 // Get a line of Stream (everything up to, but not including, CR/LF.
00385 // Returns 0 if ok, nonzero if at end of stream and returned 0-length string.
00386 //
00387   bool ParseLine (const TCHAR **Stream, TCHAR *LineBuffer, int BufferSize)
00388   {
00389     TCHAR *tmp = LineBuffer;
00390     *tmp = 0;
00391 
00392     while ( (**Stream != 0) && (**Stream != CHAR_NEW_LINE) && (**Stream != CHAR_CR) && (**Stream != CHAR_FF) && (--BufferSize > 0) )
00393     {
00394       * (tmp++) = * ( (*Stream) ++);
00395     }
00396 
00397     *tmp = 0;
00398     return LineBuffer[0] != 0;
00399   }
00400 
00401   bool ParseLine (const TCHAR **Stream, NString &LineString)
00402   {
00403     LineString.Clear();
00404 
00405     while ( (**Stream != 0) && (**Stream != CHAR_NEW_LINE) && (**Stream != CHAR_CR) && (**Stream != CHAR_FF) )
00406     {
00407       LineString += **Stream++;
00408     }
00409 
00410     return LineString.Size() > 0;
00411   }
00412 
00413 }