LCOV - code coverage report
Current view: directory - port - cplkeywordparser.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 133 96 72.2 %
Date: 2012-04-28 Functions: 10 8 80.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: cplkeywordparser.cpp 20996 2010-10-28 18:38:15Z rouault $
       3                 :  *
       4                 :  * Project:  Common Portability Library
       5                 :  * Purpose:  Implementation of CPLKeywordParser - a class for parsing
       6                 :  *           the keyword format used for files like QuickBird .RPB files.
       7                 :  *           This is a slight variation on the NASAKeywordParser used for
       8                 :  *           the PDS/ISIS2/ISIS3 formats. 
       9                 :  * Author:   Frank Warmerdam <warmerdam@pobox.com
      10                 :  *
      11                 :  ******************************************************************************
      12                 :  * Copyright (c) 2008, Frank Warmerdam <warmerdam@pobox.com>
      13                 :  * 
      14                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      15                 :  * copy of this software and associated documentation files (the "Software"),
      16                 :  * to deal in the Software without restriction, including without limitation
      17                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      18                 :  * and/or sell copies of the Software, and to permit persons to whom the
      19                 :  * Software is furnished to do so, subject to the following conditions:
      20                 :  *
      21                 :  * The above copyright notice and this permission notice shall be included
      22                 :  * in all copies or substantial portions of the Software.
      23                 :  *
      24                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      25                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      26                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      27                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      28                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      29                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      30                 :  * DEALINGS IN THE SOFTWARE.
      31                 :  ****************************************************************************/
      32                 : 
      33                 : #include "cpl_string.h" 
      34                 : #include "cplkeywordparser.h"
      35                 : 
      36                 : CPL_CVSID("$Id");
      37                 : 
      38                 : /************************************************************************/
      39                 : /* ==================================================================== */
      40                 : /*                          CPLKeywordParser                           */
      41                 : /* ==================================================================== */
      42                 : /************************************************************************/
      43                 : 
      44                 : /************************************************************************/
      45                 : /*                         CPLKeywordParser()                          */
      46                 : /************************************************************************/
      47                 : 
      48              40 : CPLKeywordParser::CPLKeywordParser()
      49                 : 
      50                 : {
      51              40 :     papszKeywordList = NULL;
      52              40 : }
      53                 : 
      54                 : /************************************************************************/
      55                 : /*                        ~CPLKeywordParser()                          */
      56                 : /************************************************************************/
      57                 : 
      58              40 : CPLKeywordParser::~CPLKeywordParser()
      59                 : 
      60                 : {
      61              40 :     CSLDestroy( papszKeywordList );
      62              40 :     papszKeywordList = NULL;
      63              40 : }
      64                 : 
      65                 : /************************************************************************/
      66                 : /*                               Ingest()                               */
      67                 : /************************************************************************/
      68                 : 
      69             152 : int CPLKeywordParser::Ingest( VSILFILE *fp )
      70                 : 
      71                 : {
      72                 : /* -------------------------------------------------------------------- */
      73                 : /*      Read in buffer till we find END all on it's own line.           */
      74                 : /* -------------------------------------------------------------------- */
      75             112 :     for( ; TRUE; ) 
      76                 :     {
      77                 :         const char *pszCheck;
      78                 :         char szChunk[513];
      79                 : 
      80             152 :         int nBytesRead = VSIFReadL( szChunk, 1, 512, fp );
      81                 : 
      82             152 :         szChunk[nBytesRead] = '\0';
      83             152 :         osHeaderText += szChunk;
      84                 : 
      85             152 :         if( nBytesRead < 512 )
      86              40 :             break;
      87                 : 
      88             112 :         if( osHeaderText.size() > 520 )
      89              80 :             pszCheck = osHeaderText.c_str() + (osHeaderText.size() - 520);
      90                 :         else
      91              32 :             pszCheck = szChunk;
      92                 : 
      93             112 :         if( strstr(pszCheck,"\r\nEND;\r\n") != NULL 
      94                 :             || strstr(pszCheck,"\nEND;\n") != NULL )
      95               0 :             break;
      96                 :     }
      97                 : 
      98              40 :     pszHeaderNext = osHeaderText.c_str();
      99                 : 
     100                 : /* -------------------------------------------------------------------- */
     101                 : /*      Process name/value pairs, keeping track of a "path stack".      */
     102                 : /* -------------------------------------------------------------------- */
     103              40 :     return ReadGroup( "" );
     104                 : }
     105                 : 
     106                 : /************************************************************************/
     107                 : /*                             ReadGroup()                              */
     108                 : /************************************************************************/
     109                 : 
     110             104 : int CPLKeywordParser::ReadGroup( const char *pszPathPrefix )
     111                 : 
     112                 : {
     113             104 :     CPLString osName, osValue;
     114                 : 
     115            1796 :     for( ; TRUE; )
     116                 :     {
     117            1900 :         if( !ReadPair( osName, osValue ) )
     118               0 :             return FALSE;
     119                 : 
     120            1900 :         if( EQUAL(osName,"BEGIN_GROUP") )
     121                 :         {
     122              64 :             if( !ReadGroup( (CPLString(pszPathPrefix) + osValue + ".").c_str() ) )
     123               0 :                 return FALSE;
     124                 :         }
     125            1836 :         else if( EQUALN(osName,"END",3) )
     126                 :         {
     127             104 :             return TRUE;
     128                 :         }
     129                 :         else
     130                 :         {
     131            1732 :             osName = pszPathPrefix + osName;
     132                 :             papszKeywordList = CSLSetNameValue( papszKeywordList, 
     133            1732 :                                                 osName, osValue );
     134                 :         }
     135               0 :     }
     136                 : }
     137                 : 
     138                 : /************************************************************************/
     139                 : /*                              ReadPair()                              */
     140                 : /*                                                                      */
     141                 : /*      Read a name/value pair from the input stream.  Strip off        */
     142                 : /*      white space, ignore comments, split on '='.                     */
     143                 : /************************************************************************/
     144                 : 
     145            1900 : int CPLKeywordParser::ReadPair( CPLString &osName, CPLString &osValue )
     146                 : 
     147                 : {
     148            1900 :     osName = "";
     149            3800 :     osValue = "";
     150                 : 
     151            1900 :     if( !ReadWord( osName ) )
     152               0 :         return FALSE;
     153                 : 
     154            1900 :     SkipWhite();
     155                 : 
     156            1900 :     if( EQUAL(osName,"END") )
     157              40 :         return TRUE;
     158                 : 
     159            1860 :     if( *pszHeaderNext != '=' )
     160                 :     {
     161                 :         // ISIS3 does not have anything after the end group/object keyword. 
     162               0 :         if( EQUAL(osName,"End_Group") || EQUAL(osName,"End_Object") )
     163               0 :             return TRUE;
     164                 :         else
     165               0 :             return FALSE;
     166                 :     }
     167                 :     
     168            1860 :     pszHeaderNext++;
     169                 :     
     170            1860 :     SkipWhite();
     171                 :     
     172            1860 :     osValue = "";
     173                 : 
     174                 :     // Handle value lists like:     Name   = (Red, Red)
     175                 :     // or list of lists like : TLCList = ( (0,  0.000000), (8299,  4.811014) );
     176            1860 :     if( *pszHeaderNext == '(' )
     177                 :     {
     178              96 :         CPLString osWord;
     179              96 :         int nDepth = 0;
     180              96 :         const char* pszLastPos = pszHeaderNext;
     181                 : 
     182            1792 :         while( ReadWord( osWord ) && pszLastPos != pszHeaderNext)
     183                 :         {
     184            1696 :             SkipWhite();
     185            1696 :             pszLastPos = pszHeaderNext;
     186                 : 
     187            1696 :             osValue += osWord;
     188            1696 :             const char* pszIter = osWord.c_str();
     189            1696 :             int bInQuote = FALSE;
     190           24480 :             while(*pszIter != '\0')
     191                 :             {
     192           21184 :                 if (*pszIter == '"')
     193               0 :                     bInQuote = !bInQuote;
     194           21184 :                 else if (!bInQuote)
     195                 :                 {
     196           21184 :                     if (*pszIter == '(')
     197              96 :                         nDepth ++;
     198           21088 :                     else if (*pszIter == ')')
     199                 :                     {
     200              96 :                         nDepth --;
     201              96 :                         if (nDepth == 0)
     202              96 :                             break;
     203                 :                     }
     204                 :                 }
     205           21088 :                 pszIter ++;
     206                 :             }
     207            1696 :             if (*pszIter == ')' && nDepth == 0)
     208              96 :                 break;
     209              96 :         }
     210                 :     }
     211                 : 
     212                 :     else // Handle more normal "single word" values. 
     213                 :     {
     214            1764 :         if( !ReadWord( osValue ) )
     215               0 :             return FALSE;
     216                 : 
     217                 :     }
     218                 :         
     219            1860 :     SkipWhite();
     220                 : 
     221                 :     // No units keyword?   
     222            1860 :     if( *pszHeaderNext != '<' )
     223            1860 :         return TRUE;
     224                 : 
     225                 :     // Append units keyword.  For lines that like like this:
     226                 :     //  MAP_RESOLUTION               = 4.0 <PIXEL/DEGREE>
     227                 :     
     228               0 :     CPLString osWord;
     229                 :     
     230               0 :     osValue += " ";
     231                 :     
     232               0 :     while( ReadWord( osWord ) )
     233                 :     {
     234               0 :         SkipWhite();
     235                 :         
     236               0 :         osValue += osWord;
     237               0 :         if( osWord[strlen(osWord)-1] == '>' )
     238               0 :             break;
     239                 :     }
     240                 :     
     241               0 :     return TRUE;
     242                 : }
     243                 : 
     244                 : /************************************************************************/
     245                 : /*                              ReadWord()                              */
     246                 : /************************************************************************/
     247                 : 
     248            5360 : int CPLKeywordParser::ReadWord( CPLString &osWord )
     249                 : 
     250                 : {
     251            5360 :     osWord = "";
     252                 : 
     253            5360 :     SkipWhite();
     254                 : 
     255            5360 :     if( pszHeaderNext == '\0' )
     256               0 :         return FALSE;
     257                 : 
     258           61644 :     while( *pszHeaderNext != '\0' 
     259                 :            && *pszHeaderNext != '=' 
     260                 :            && *pszHeaderNext != ';'
     261                 :            && !isspace((unsigned char)*pszHeaderNext) )
     262                 :     {
     263           50924 :         if( *pszHeaderNext == '"' )
     264                 :         {
     265             404 :             osWord += *(pszHeaderNext++);
     266            3032 :             while( *pszHeaderNext != '"' )
     267                 :             {
     268            2224 :                 if( *pszHeaderNext == '\0' )
     269               0 :                     return FALSE;
     270                 : 
     271            2224 :                 osWord += *(pszHeaderNext++);
     272                 :             }
     273             404 :             osWord += *(pszHeaderNext++);
     274                 :         }
     275           50520 :         else if( *pszHeaderNext == '\'' )
     276                 :         {
     277               0 :             osWord += *(pszHeaderNext++);
     278               0 :             while( *pszHeaderNext != '\'' )
     279                 :             {
     280               0 :                 if( *pszHeaderNext == '\0' )
     281               0 :                     return FALSE;
     282                 : 
     283               0 :                 osWord += *(pszHeaderNext++);
     284                 :             }
     285               0 :             osWord += *(pszHeaderNext++);
     286                 :         }
     287                 :         else
     288                 :         {
     289           50520 :             osWord += *pszHeaderNext;
     290           50520 :             pszHeaderNext++;
     291                 :         }
     292                 :     }
     293                 : 
     294            5360 :     if( *pszHeaderNext == ';' )
     295            1736 :         pszHeaderNext++;
     296                 :     
     297            5360 :     return TRUE;
     298                 : }
     299                 : 
     300                 : /************************************************************************/
     301                 : /*                             SkipWhite()                              */
     302                 : /************************************************************************/
     303                 : 
     304           26404 : void CPLKeywordParser::SkipWhite()
     305                 : 
     306                 : {
     307           13728 :     for( ; TRUE; )
     308                 :     {
     309                 :         // Skip white space (newline, space, tab, etc )
     310           26404 :         if( isspace( (unsigned char)*pszHeaderNext ) )
     311                 :         {
     312           13728 :             pszHeaderNext++; 
     313           13728 :             continue;
     314                 :         }
     315                 :         
     316                 :         // Skip C style comments 
     317           12676 :         if( *pszHeaderNext == '/' && pszHeaderNext[1] == '*' )
     318                 :         {
     319               0 :             pszHeaderNext += 2;
     320                 :             
     321               0 :             while( *pszHeaderNext != '\0' 
     322                 :                    && (*pszHeaderNext != '*' 
     323               0 :                        || pszHeaderNext[1] != '/' ) )
     324                 :             {
     325               0 :                 pszHeaderNext++;
     326                 :             }
     327                 : 
     328               0 :             pszHeaderNext += 2;
     329               0 :             continue;
     330                 :         }
     331                 : 
     332                 :         // Skip # style comments 
     333           12676 :         if( *pszHeaderNext == '#'  )
     334                 :         {
     335               0 :             pszHeaderNext += 1;
     336                 : 
     337                 :             // consume till end of line.
     338               0 :             while( *pszHeaderNext != '\0' 
     339                 :                    && *pszHeaderNext != 10
     340                 :                    && *pszHeaderNext != 13 )
     341                 :             {
     342               0 :                 pszHeaderNext++;
     343                 :             }
     344               0 :             continue;
     345                 :         }
     346                 : 
     347                 :         // not white space, return. 
     348                 :         return;
     349                 :     }
     350                 : }
     351                 : 
     352                 : /************************************************************************/
     353                 : /*                             GetKeyword()                             */
     354                 : /************************************************************************/
     355                 : 
     356             224 : const char *CPLKeywordParser::GetKeyword( const char *pszPath,
     357                 :                                             const char *pszDefault )
     358                 : 
     359                 : {
     360                 :     const char *pszResult;
     361                 : 
     362             224 :     pszResult = CSLFetchNameValue( papszKeywordList, pszPath );
     363             224 :     if( pszResult == NULL )
     364               0 :         return pszDefault;
     365                 :     else
     366             224 :         return pszResult;
     367                 : }
     368                 : 

Generated by: LCOV version 1.7