LTP GCOV extension - code coverage report
Current view: directory - frmts/pds - nasakeywordhandler.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 137
Code covered: 86.9 % Executed lines: 119

       1                 : /******************************************************************************
       2                 :  * $Id: pdsdataset.cpp 12658 2007-11-07 23:14:33Z warmerdam $
       3                 :  *
       4                 :  * Project:  PDS Driver; Planetary Data System Format
       5                 :  * Purpose:  Implementation of NASAKeywordHandler - a class to read 
       6                 :  *           keyword data from PDS, ISIS2 and ISIS3 data products.
       7                 :  * Author:   Frank Warmerdam <warmerdam@pobox.com
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 2006, Frank Warmerdam <warmerdam@pobox.com>
      11                 :  * 
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************
      30                 :  * Object Description Language (ODL) is used to encode data labels for PDS
      31                 :  * and other NASA data systems. Refer to Chapter 12 of "PDS Standards
      32                 :  * Reference" at http://pds.jpl.nasa.gov/tools/standards-reference.shtml for
      33                 :  * further details about ODL.
      34                 :  * 
      35                 :  * This is also known as PVL (Parameter Value Language) which is written
      36                 :  * about at http://www.orrery.us/node/44 where it notes:
      37                 :  * 
      38                 :  * The PVL syntax that the PDS uses is specified by the Consultative Committee 
      39                 :  * for Space Data Systems in their Blue Book publication: "Parameter Value 
      40                 :  * Language Specification (CCSD0006 and CCSD0008)", June 2000 
      41                 :  * [CCSDS 641.0-B-2], and Green Book publication: "Parameter Value Language - 
      42                 :  * A Tutorial", June 2000 [CCSDS 641.0-G-2]. PVL has also been accepted by the
      43                 :  * International Standards Organization (ISO), as a Final Draft International 
      44                 :  * Standard (ISO 14961:2002) keyword value type language for naming and 
      45                 :  * expressing data values.
      46                 :  * --
      47                 :  * also of interest, on PDS ODL:
      48                 :  *  http://pds.jpl.nasa.gov/documents/sr/Chapter12.pdf
      49                 :  *  
      50                 :  ****************************************************************************/
      51                 : 
      52                 : #include "cpl_string.h" 
      53                 : #include "nasakeywordhandler.h"
      54                 : 
      55                 : /************************************************************************/
      56                 : /* ==================================================================== */
      57                 : /*                          NASAKeywordHandler                          */
      58                 : /* ==================================================================== */
      59                 : /************************************************************************/
      60                 : 
      61                 : /************************************************************************/
      62                 : /*                         NASAKeywordHandler()                         */
      63                 : /************************************************************************/
      64                 : 
      65              22 : NASAKeywordHandler::NASAKeywordHandler()
      66                 : 
      67                 : {
      68              22 :     papszKeywordList = NULL;
      69              22 : }
      70                 : 
      71                 : /************************************************************************/
      72                 : /*                        ~NASAKeywordHandler()                         */
      73                 : /************************************************************************/
      74                 : 
      75              22 : NASAKeywordHandler::~NASAKeywordHandler()
      76                 : 
      77                 : {
      78              22 :     CSLDestroy( papszKeywordList );
      79              22 :     papszKeywordList = NULL;
      80              22 : }
      81                 : 
      82                 : /************************************************************************/
      83                 : /*                               Ingest()                               */
      84                 : /************************************************************************/
      85                 : 
      86              13 : int NASAKeywordHandler::Ingest( FILE *fp, int nOffset )
      87                 : 
      88                 : {
      89                 : /* -------------------------------------------------------------------- */
      90                 : /*      Read in buffer till we find END all on it's own line.           */
      91                 : /* -------------------------------------------------------------------- */
      92              13 :     if( VSIFSeekL( fp, nOffset, SEEK_SET ) != 0 )
      93               0 :         return FALSE;
      94                 : 
      95             101 :     for( ; TRUE; ) 
      96                 :     {
      97                 :         const char *pszCheck;
      98                 :         char szChunk[513];
      99                 : 
     100             114 :         int nBytesRead = VSIFReadL( szChunk, 1, 512, fp );
     101                 : 
     102             114 :         szChunk[nBytesRead] = '\0';
     103             114 :         osHeaderText += szChunk;
     104                 : 
     105             114 :         if( nBytesRead < 512 )
     106               6 :             break;
     107                 : 
     108             108 :         if( osHeaderText.size() > 520 )
     109              95 :             pszCheck = osHeaderText.c_str() + (osHeaderText.size() - 520);
     110                 :         else
     111              13 :             pszCheck = szChunk;
     112                 : 
     113             108 :         if( strstr(pszCheck,"\r\nEND\r\n") != NULL 
     114                 :             || strstr(pszCheck,"\nEND\n") != NULL 
     115                 :             || strstr(pszCheck,"\r\nEnd\r\n") != NULL 
     116                 :             || strstr(pszCheck,"\nEnd\n") != NULL )
     117               7 :             break;
     118                 :     }
     119                 : 
     120              13 :     pszHeaderNext = osHeaderText.c_str();
     121                 : 
     122                 : /* -------------------------------------------------------------------- */
     123                 : /*      Process name/value pairs, keeping track of a "path stack".      */
     124                 : /* -------------------------------------------------------------------- */
     125              13 :     return ReadGroup( "" );
     126                 : }
     127                 : 
     128                 : /************************************************************************/
     129                 : /*                             ReadGroup()                              */
     130                 : /************************************************************************/
     131                 : 
     132              75 : int NASAKeywordHandler::ReadGroup( const char *pszPathPrefix )
     133                 : 
     134                 : {
     135              75 :     CPLString osName, osValue;
     136                 : 
     137            1007 :     for( ; TRUE; )
     138                 :     {
     139            1082 :         if( !ReadPair( osName, osValue ) )
     140               0 :             return FALSE;
     141                 : 
     142            1082 :         if( EQUAL(osName,"OBJECT") || EQUAL(osName,"GROUP") )
     143                 :         {
     144              62 :             if( !ReadGroup( (CPLString(pszPathPrefix) + osValue + ".").c_str() ) )
     145               0 :                 return FALSE;
     146                 :         }
     147            1020 :         else if( EQUAL(osName,"END") 
     148                 :                  || EQUAL(osName,"END_GROUP" )
     149                 :                  || EQUAL(osName,"END_OBJECT" ) )
     150                 :         {
     151              75 :             return TRUE;
     152                 :         }
     153                 :         else
     154                 :         {
     155             945 :             osName = pszPathPrefix + osName;
     156                 :             papszKeywordList = CSLSetNameValue( papszKeywordList, 
     157             945 :                                                 osName, osValue );
     158                 :         }
     159               0 :     }
     160                 : }
     161                 : 
     162                 : /************************************************************************/
     163                 : /*                              ReadPair()                              */
     164                 : /*                                                                      */
     165                 : /*      Read a name/value pair from the input stream.  Strip off        */
     166                 : /*      white space, ignore comments, split on '='.                     */
     167                 : /*      Returns TRUE on success.                                        */
     168                 : /************************************************************************/
     169                 : 
     170            1082 : int NASAKeywordHandler::ReadPair( CPLString &osName, CPLString &osValue )
     171                 : 
     172                 : {
     173            1082 :     osName = "";
     174            2164 :     osValue = "";
     175                 : 
     176            1082 :     if( !ReadWord( osName ) )
     177               0 :         return FALSE;
     178                 : 
     179            1082 :     SkipWhite();
     180                 : 
     181            1082 :     if( EQUAL(osName,"END") )
     182              13 :         return TRUE;
     183                 : 
     184            1069 :     if( *pszHeaderNext != '=' )
     185                 :     {
     186                 :         // ISIS3 does not have anything after the end group/object keyword. 
     187              23 :         if( EQUAL(osName,"End_Group") || EQUAL(osName,"End_Object") )
     188              23 :             return TRUE;
     189                 :         else
     190               0 :             return FALSE;
     191                 :     }
     192                 :     
     193            1046 :     pszHeaderNext++;
     194                 :     
     195            1046 :     SkipWhite();
     196                 :     
     197            1046 :     osValue = "";
     198                 : 
     199                 :     // Handle value lists like:     Name   = (Red, Red)
     200            1046 :     if( *pszHeaderNext == '(' )
     201                 :     {
     202              54 :         CPLString osWord;
     203                 : 
     204             292 :         while( ReadWord( osWord ) )
     205                 :         {
     206             238 :             SkipWhite();
     207                 : 
     208             238 :             osValue += osWord;
     209             238 :             if( osWord[strlen(osWord)-1] == ')' )
     210              54 :                 break;
     211              54 :         }
     212                 :     }
     213                 : 
     214                 :     // Handle value lists like:     Name   = {Red, Red}
     215             992 :     else if( *pszHeaderNext == '{' )
     216                 :     {
     217               2 :         CPLString osWord;
     218                 : 
     219              16 :         while( ReadWord( osWord ) )
     220                 :         {
     221              14 :             SkipWhite();
     222                 : 
     223              14 :             osValue += osWord;
     224              14 :             if( osWord[strlen(osWord)-1] == '}' )
     225               2 :                 break;
     226               2 :         }
     227                 :     }
     228                 : 
     229                 :     else // Handle more normal "single word" values. 
     230                 :     {
     231             990 :         if( !ReadWord( osValue ) )
     232               0 :             return FALSE;
     233                 : 
     234                 :     }
     235                 :         
     236            1046 :     SkipWhite();
     237                 : 
     238                 :     // No units keyword?   
     239            1046 :     if( *pszHeaderNext != '<' )
     240             926 :         return TRUE;
     241                 : 
     242                 :     // Append units keyword.  For lines that like like this:
     243                 :     //  MAP_RESOLUTION               = 4.0 <PIXEL/DEGREE>
     244                 :     
     245             120 :     CPLString osWord;
     246                 :     
     247             120 :     osValue += " ";
     248                 :     
     249             240 :     while( ReadWord( osWord ) )
     250                 :     {
     251             120 :         SkipWhite();
     252                 :         
     253             120 :         osValue += osWord;
     254             120 :         if( osWord[strlen(osWord)-1] == '>' )
     255             120 :             break;
     256                 :     }
     257                 :     
     258             120 :     return TRUE;
     259                 : }
     260                 : 
     261                 : /************************************************************************/
     262                 : /*                              ReadWord()                              */
     263                 : /*  Returns TRUE on success                                             */
     264                 : /************************************************************************/
     265                 : 
     266            2444 : int NASAKeywordHandler::ReadWord( CPLString &osWord )
     267                 : 
     268                 : {
     269            2444 :     osWord = "";
     270                 : 
     271            2444 :     SkipWhite();
     272                 : 
     273            4888 :     if( !(*pszHeaderNext != '\0' 
     274                 :            && *pszHeaderNext != '=' 
     275                 :            && !isspace((unsigned char)*pszHeaderNext)) )
     276               0 :         return FALSE;
     277                 : 
     278                 :     /* Extract a text string delimited by '\"' */
     279                 :     /* Convert newlines (CR or LF) within quotes. While text strings
     280                 :        support them as per ODL, the keyword list doesn't want them */
     281            2444 :     if( *pszHeaderNext == '"' )
     282                 :     {
     283             240 :         osWord += *(pszHeaderNext++);
     284            4803 :         while( *pszHeaderNext != '"' )
     285                 :         {
     286            4323 :             if( *pszHeaderNext == '\0' )
     287               0 :                 return FALSE;
     288            4323 :             if( *pszHeaderNext == '\n' )
     289                 :             {
     290              18 :                 osWord += "\\n";
     291              18 :                 pszHeaderNext++;
     292              18 :                 continue;
     293                 :             }
     294            4305 :             if( *pszHeaderNext == '\r' )
     295                 :             {
     296              16 :                 osWord += "\\r";
     297              16 :                 pszHeaderNext++;
     298              16 :                 continue;
     299                 :             }
     300            4289 :             osWord += *(pszHeaderNext++);
     301                 :         }
     302             240 :         osWord += *(pszHeaderNext++);
     303             240 :         return TRUE;
     304                 :     }
     305                 : 
     306                 :     /* Extract a symbol string */
     307                 :     /* These are expected to not have
     308                 :        '\'' (delimiters),
     309                 :        format effectors (should fit on a single line) or
     310                 :        control characters.  
     311                 :     */
     312            2204 :     if( *pszHeaderNext == '\'' )
     313                 :     {
     314               0 :         osWord += *(pszHeaderNext++);
     315               0 :         while( *pszHeaderNext != '\'' )
     316                 :         {
     317               0 :             if( *pszHeaderNext == '\0' )
     318               0 :                 return FALSE;
     319                 : 
     320               0 :             osWord += *(pszHeaderNext++);
     321                 :         }
     322               0 :         osWord += *(pszHeaderNext++);
     323               0 :         return TRUE;
     324                 :     }
     325                 : 
     326                 :     /*
     327                 :      * Extract normal text.  Terminated by '=' or whitespace. 
     328                 :      *
     329                 :      * A special exception is that a line may terminate with a '-' 
     330                 :      * which is taken as a line extender, and we suck up white space to new
     331                 :      * text.
     332                 :      */
     333           29189 :     while( *pszHeaderNext != '\0' 
     334                 :            && *pszHeaderNext != '=' 
     335                 :            && !isspace((unsigned char)*pszHeaderNext) )
     336                 :     {
     337           24781 :         osWord += *pszHeaderNext;
     338           24781 :         pszHeaderNext++;
     339                 : 
     340           24781 :         if( *pszHeaderNext == '-' 
     341                 :             && (pszHeaderNext[1] == 10 || pszHeaderNext[1] == 13) )
     342                 :         {
     343               0 :             pszHeaderNext += 2;
     344               0 :             SkipWhite();
     345                 :         }
     346                 :     }
     347                 :     
     348            2204 :     return TRUE;
     349                 : }
     350                 : 
     351                 : /************************************************************************/
     352                 : /*                             SkipWhite()                              */
     353                 : /*  Skip white spaces and C style comments                              */
     354                 : /************************************************************************/
     355                 : 
     356           23384 : void NASAKeywordHandler::SkipWhite()
     357                 : 
     358                 : {
     359           17394 :     for( ; TRUE; )
     360                 :     {
     361                 :         // Skip C style comments 
     362           23384 :         if( *pszHeaderNext == '/' && pszHeaderNext[1] == '*' )
     363                 :         {
     364             136 :             pszHeaderNext += 2;
     365                 :             
     366            7287 :             while( *pszHeaderNext != '\0' 
     367                 :                    && (*pszHeaderNext != '*' 
     368                 :                        || pszHeaderNext[1] != '/' ) )
     369                 :             {
     370            7015 :                 pszHeaderNext++;
     371                 :             }
     372                 : 
     373             136 :             pszHeaderNext += 2;
     374             136 :             continue;
     375                 :         }
     376                 : 
     377                 :         // Skip # style comments 
     378           23248 :          if( (*pszHeaderNext == 10 || *pszHeaderNext == 13 ||
     379                 :        *pszHeaderNext == ' ' || *pszHeaderNext == '\t' )
     380                 :               && pszHeaderNext[1] == '#' )
     381                 :         {
     382               4 :             pszHeaderNext += 2;
     383                 : 
     384                 :             // consume till end of line.
     385             216 :             while( *pszHeaderNext != '\0' 
     386                 :                    && *pszHeaderNext != 10
     387                 :                    && *pszHeaderNext != 13 )
     388                 :             {
     389             208 :                 pszHeaderNext++;
     390                 :             }
     391               4 :             continue;
     392                 :         }
     393                 : 
     394                 :         // Skip white space (newline, space, tab, etc )
     395           23244 :         if( isspace( (unsigned char)*pszHeaderNext ) )
     396                 :         {
     397           17254 :             pszHeaderNext++; 
     398           17254 :             continue;
     399                 :         }
     400                 :         
     401                 :         // not white space, return. 
     402                 :         return;
     403                 :     }
     404                 : }
     405                 : 
     406                 : /************************************************************************/
     407                 : /*                             GetKeyword()                             */
     408                 : /************************************************************************/
     409                 : 
     410                 : const char *NASAKeywordHandler::GetKeyword( const char *pszPath,
     411             461 :                                             const char *pszDefault )
     412                 : 
     413                 : {
     414                 :     const char *pszResult;
     415                 : 
     416             461 :     pszResult = CSLFetchNameValue( papszKeywordList, pszPath );
     417             461 :     if( pszResult == NULL )
     418             162 :         return pszDefault;
     419                 :     else
     420             299 :         return pszResult;
     421                 : }
     422                 : 

Generated by: LTP GCOV extension version 1.5