00001
00021 #include "ver.h"
00022
00026
00027 #define VER_BUFFER_SIZE 1048576 // 1M - size of the data chunk stored in memory
00028 #define VER_OFFSET_SIZE 65536 // 64K - load new data when less than this is left
00029 #define VER_WORD_SIZE 65536 // 64K - the largest token that can be returned
00030
00031 #define VER_MINIMUM(a,b) (((a) < (b))? (a) : (b))
00032
00033 struct Ver_Stream_t_
00034 {
00035
00036 char * pFileName;
00037 FILE * pFile;
00038 int nFileSize;
00039 int nFileRead;
00040 int nLineCounter;
00041
00042 char * pBuffer;
00043 int nBufferSize;
00044 char * pBufferCur;
00045 char * pBufferEnd;
00046 char * pBufferStop;
00047
00048 char pChars[VER_WORD_SIZE+5];
00049 int nChars;
00050
00051 int fStop;
00052 };
00053
00054 static void Ver_StreamReload( Ver_Stream_t * p );
00055
00059
00071 Ver_Stream_t * Ver_StreamAlloc( char * pFileName )
00072 {
00073 Ver_Stream_t * p;
00074 FILE * pFile;
00075 int nCharsToRead;
00076
00077 pFile = fopen( pFileName, "rb" );
00078 if ( pFile == NULL )
00079 {
00080 printf( "Ver_StreamAlloc(): Cannot open input file \"%s\".\n", pFileName );
00081 return NULL;
00082 }
00083
00084 p = ALLOC( Ver_Stream_t, 1 );
00085 memset( p, 0, sizeof(Ver_Stream_t) );
00086 p->pFileName = pFileName;
00087 p->pFile = pFile;
00088
00089 fseek( pFile, 0, SEEK_END );
00090 p->nFileSize = ftell( pFile );
00091 rewind( pFile );
00092
00093 p->pBuffer = ALLOC( char, VER_BUFFER_SIZE+1 );
00094 p->nBufferSize = VER_BUFFER_SIZE;
00095 p->pBufferCur = p->pBuffer;
00096
00097 nCharsToRead = VER_MINIMUM(p->nFileSize, VER_BUFFER_SIZE);
00098
00099 fread( p->pBuffer, nCharsToRead, 1, p->pFile );
00100 p->nFileRead = nCharsToRead;
00101
00102 p->pBufferEnd = p->pBuffer + nCharsToRead;
00103 p->pBufferStop = (p->nFileRead == p->nFileSize)? p->pBufferEnd : p->pBuffer + VER_BUFFER_SIZE - VER_OFFSET_SIZE;
00104
00105 p->nLineCounter = 1;
00106 return p;
00107 }
00108
00120 void Ver_StreamReload( Ver_Stream_t * p )
00121 {
00122 int nCharsUsed, nCharsToRead;
00123 assert( !p->fStop );
00124 assert( p->pBufferCur > p->pBufferStop );
00125 assert( p->pBufferCur < p->pBufferEnd );
00126
00127 nCharsUsed = p->pBufferEnd - p->pBufferCur;
00128
00129 memmove( p->pBuffer, p->pBufferCur, nCharsUsed );
00130 p->pBufferCur = p->pBuffer;
00131
00132 nCharsToRead = VER_MINIMUM( p->nBufferSize - nCharsUsed, p->nFileSize - p->nFileRead );
00133
00134 fread( p->pBuffer + nCharsUsed, nCharsToRead, 1, p->pFile );
00135 p->nFileRead += nCharsToRead;
00136
00137 p->pBufferEnd = p->pBuffer + nCharsUsed + nCharsToRead;
00138 p->pBufferStop = (p->nFileRead == p->nFileSize)? p->pBufferEnd : p->pBuffer + VER_BUFFER_SIZE - VER_OFFSET_SIZE;
00139 }
00140
00152 void Ver_StreamFree( Ver_Stream_t * p )
00153 {
00154 if ( p->pFile )
00155 fclose( p->pFile );
00156 FREE( p->pBuffer );
00157 free( p );
00158 }
00159
00171 char * Ver_StreamGetFileName( Ver_Stream_t * p )
00172 {
00173 return p->pFileName;
00174 }
00175
00187 int Ver_StreamGetFileSize( Ver_Stream_t * p )
00188 {
00189 return p->nFileSize;
00190 }
00191
00203 int Ver_StreamGetCurPosition( Ver_Stream_t * p )
00204 {
00205 return p->nFileRead - (p->pBufferEnd - p->pBufferCur);
00206 }
00207
00219 int Ver_StreamGetLineNumber( Ver_Stream_t * p )
00220 {
00221 return p->nLineCounter;
00222 }
00223
00224
00225
00237 int Ver_StreamIsOkey( Ver_Stream_t * p )
00238 {
00239 return !p->fStop;
00240 }
00241
00253 char Ver_StreamScanChar( Ver_Stream_t * p )
00254 {
00255 assert( !p->fStop );
00256 return *p->pBufferCur;
00257 }
00258
00270 char Ver_StreamPopChar( Ver_Stream_t * p )
00271 {
00272 assert( !p->fStop );
00273
00274 if ( p->pBufferCur > p->pBufferStop )
00275 Ver_StreamReload( p );
00276
00277 if ( p->pBufferCur == p->pBufferEnd )
00278 {
00279 p->fStop = 1;
00280 return -1;
00281 }
00282
00283 if ( *p->pBufferCur == '\n' )
00284 p->nLineCounter++;
00285 return *p->pBufferCur++;
00286 }
00287
00299 void Ver_StreamSkipChars( Ver_Stream_t * p, char * pCharsToSkip )
00300 {
00301 char * pChar, * pTemp;
00302 assert( !p->fStop );
00303 assert( pCharsToSkip != NULL );
00304
00305 if ( p->pBufferCur > p->pBufferStop )
00306 Ver_StreamReload( p );
00307
00308 for ( pChar = p->pBufferCur; pChar < p->pBufferEnd; pChar++ )
00309 {
00310
00311 for ( pTemp = pCharsToSkip; *pTemp; pTemp++ )
00312 if ( *pChar == *pTemp )
00313 break;
00314 if ( *pTemp == 0 )
00315 {
00316 p->pBufferCur = pChar;
00317 return;
00318 }
00319
00320 if ( *pChar == '\n' )
00321 p->nLineCounter++;
00322 }
00323
00324
00325 if ( p->pBufferStop == p->pBufferEnd )
00326 {
00327 p->fStop = 1;
00328 return;
00329 }
00330 printf( "Ver_StreamSkipSymbol() failed to parse the file \"%s\".\n", p->pFileName );
00331 }
00332
00344 void Ver_StreamSkipToChars( Ver_Stream_t * p, char * pCharsToStop )
00345 {
00346 char * pChar, * pTemp;
00347 assert( !p->fStop );
00348 assert( pCharsToStop != NULL );
00349
00350 if ( p->pBufferCur > p->pBufferStop )
00351 Ver_StreamReload( p );
00352
00353 for ( pChar = p->pBufferCur; pChar < p->pBufferEnd; pChar++ )
00354 {
00355
00356 for ( pTemp = pCharsToStop; *pTemp; pTemp++ )
00357 if ( *pChar == *pTemp )
00358 break;
00359 if ( *pTemp == 0 )
00360 {
00361
00362 if ( *pChar == '\n' )
00363 p->nLineCounter++;
00364 continue;
00365 }
00366
00367 p->pBufferCur = pChar;
00368 return;
00369 }
00370
00371
00372 if ( p->pBufferStop == p->pBufferEnd )
00373 {
00374 p->fStop = 1;
00375 return;
00376 }
00377 printf( "Ver_StreamSkipToSymbol() failed to parse the file \"%s\".\n", p->pFileName );
00378 }
00379
00392 char * Ver_StreamGetWord( Ver_Stream_t * p, char * pCharsToStop )
00393 {
00394 char * pChar, * pTemp;
00395 if ( p->fStop )
00396 return NULL;
00397 assert( pCharsToStop != NULL );
00398
00399 if ( p->pBufferCur > p->pBufferStop )
00400 Ver_StreamReload( p );
00401
00402 p->nChars = 0;
00403 for ( pChar = p->pBufferCur; pChar < p->pBufferEnd; pChar++ )
00404 {
00405
00406 for ( pTemp = pCharsToStop; *pTemp; pTemp++ )
00407 if ( *pChar == *pTemp )
00408 break;
00409 if ( *pTemp == 0 )
00410 {
00411 p->pChars[p->nChars++] = *pChar;
00412 if ( p->nChars == VER_WORD_SIZE )
00413 {
00414 printf( "Ver_StreamGetWord(): The buffer size is exceeded.\n" );
00415 return NULL;
00416 }
00417
00418 if ( *pChar == '\n' )
00419 p->nLineCounter++;
00420 continue;
00421 }
00422
00423 p->pBufferCur = pChar;
00424 p->pChars[p->nChars] = 0;
00425 return p->pChars;
00426 }
00427
00428
00429 if ( p->pBufferStop == p->pBufferEnd )
00430 {
00431 p->fStop = 1;
00432 p->pChars[p->nChars] = 0;
00433 return p->pChars;
00434 }
00435 printf( "Ver_StreamGetWord() failed to parse the file \"%s\".\n", p->pFileName );
00436 return NULL;
00437 }
00438
00442
00443