LCOV - code coverage report
Current view: directory - frmts/pds - nasakeywordhandler.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 144 129 89.6 %
Date: 2012-12-26 Functions: 11 8 72.7 %

       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             190 : NASAKeywordHandler::NASAKeywordHandler()
      66                 : 
      67                 : {
      68             190 :     papszKeywordList = NULL;
      69             190 : }
      70                 : 
      71                 : /************************************************************************/
      72                 : /*                        ~NASAKeywordHandler()                         */
      73                 : /************************************************************************/
      74                 : 
      75             190 : NASAKeywordHandler::~NASAKeywordHandler()
      76                 : 
      77                 : {
      78             190 :     CSLDestroy( papszKeywordList );
      79             190 :     papszKeywordList = NULL;
      80             190 : }
      81                 : 
      82                 : /************************************************************************/
      83                 : /*                               Ingest()                               */
      84                 : /************************************************************************/
      85                 : 
      86              62 : int NASAKeywordHandler::Ingest( VSILFILE *fp, int nOffset )
      87                 : 
      88                 : {
      89                 : /* -------------------------------------------------------------------- */
      90                 : /*      Read in buffer till we find END all on it's own line.           */
      91                 : /* -------------------------------------------------------------------- */
      92              62 :     if( VSIFSeekL( fp, nOffset, SEEK_SET ) != 0 )
      93               0 :         return FALSE;
      94                 : 
      95             178 :     for( ; TRUE; ) 
      96                 :     {
      97                 :         const char *pszCheck;
      98                 :         char szChunk[513];
      99                 : 
     100             240 :         int nBytesRead = VSIFReadL( szChunk, 1, 512, fp );
     101                 : 
     102             240 :         szChunk[nBytesRead] = '\0';
     103             240 :         osHeaderText += szChunk;
     104                 : 
     105             240 :         if( nBytesRead < 512 )
     106               7 :             break;
     107                 : 
     108             233 :         if( osHeaderText.size() > 520 )
     109             171 :             pszCheck = osHeaderText.c_str() + (osHeaderText.size() - 520);
     110                 :         else
     111              62 :             pszCheck = szChunk;
     112                 : 
     113             233 :         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              55 :             break;
     118                 :     }
     119                 : 
     120              62 :     pszHeaderNext = osHeaderText.c_str();
     121                 : 
     122                 : /* -------------------------------------------------------------------- */
     123                 : /*      Process name/value pairs, keeping track of a "path stack".      */
     124                 : /* -------------------------------------------------------------------- */
     125              62 :     return ReadGroup( "" );
     126                 : }
     127                 : 
     128                 : /************************************************************************/
     129                 : /*                             ReadGroup()                              */
     130                 : /************************************************************************/
     131                 : 
     132             186 : int NASAKeywordHandler::ReadGroup( const char *pszPathPrefix )
     133                 : 
     134                 : {
     135             186 :     CPLString osName, osValue;
     136                 : 
     137            2169 :     for( ; TRUE; )
     138                 :     {
     139            2355 :         if( !ReadPair( osName, osValue ) )
     140               0 :             return FALSE;
     141                 : 
     142            2355 :         if( EQUAL(osName,"OBJECT") || EQUAL(osName,"GROUP") )
     143                 :         {
     144             124 :             if( !ReadGroup( (CPLString(pszPathPrefix) + osValue + ".").c_str() ) )
     145               0 :                 return FALSE;
     146                 :         }
     147            2231 :         else if( EQUAL(osName,"END") 
     148                 :                  || EQUAL(osName,"END_GROUP" )
     149                 :                  || EQUAL(osName,"END_OBJECT" ) )
     150                 :         {
     151             186 :             return TRUE;
     152                 :         }
     153                 :         else
     154                 :         {
     155            2045 :             osName = pszPathPrefix + osName;
     156                 :             papszKeywordList = CSLSetNameValue( papszKeywordList, 
     157            2045 :                                                 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            2355 : int NASAKeywordHandler::ReadPair( CPLString &osName, CPLString &osValue )
     171                 : 
     172                 : {
     173            2355 :     osName = "";
     174            4710 :     osValue = "";
     175                 : 
     176            2355 :     if( !ReadWord( osName ) )
     177               0 :         return FALSE;
     178                 : 
     179            2355 :     SkipWhite();
     180                 : 
     181            2355 :     if( EQUAL(osName,"END") )
     182              62 :         return TRUE;
     183                 : 
     184            2293 :     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            2270 :     pszHeaderNext++;
     194                 :     
     195            2270 :     SkipWhite();
     196                 :     
     197            2270 :     osValue = "";
     198                 : 
     199                 :     // Handle value lists like:     Name   = (Red, Red)
     200            2270 :     if( *pszHeaderNext == '(' )
     201                 :     {
     202             192 :         CPLString osWord;
     203                 : 
     204             192 :         while( ReadWord( osWord ) )
     205                 :         {
     206             511 :             SkipWhite();
     207                 : 
     208             511 :             osValue += osWord;
     209             511 :             if( osWord[strlen(osWord)-1] == ')' )
     210             192 :                 break;
     211             192 :         }
     212                 :     }
     213                 : 
     214                 :     // Handle value lists like:     Name   = {Red, Red}
     215            2078 :     else if( *pszHeaderNext == '{' )
     216                 :     {
     217               4 :         CPLString osWord;
     218                 : 
     219               4 :         while( ReadWord( osWord ) )
     220                 :         {
     221              23 :             SkipWhite();
     222                 : 
     223              23 :             osValue += osWord;
     224              23 :             if( osWord[strlen(osWord)-1] == '}' )
     225               4 :                 break;
     226               4 :         }
     227                 :     }
     228                 : 
     229                 :     else // Handle more normal "single word" values. 
     230                 :     {
     231            2074 :         if( !ReadWord( osValue ) )
     232               0 :             return FALSE;
     233                 : 
     234                 :     }
     235                 :         
     236            2270 :     SkipWhite();
     237                 : 
     238                 :     // No units keyword?   
     239            2270 :     if( *pszHeaderNext != '<' )
     240            2130 :         return TRUE;
     241                 : 
     242                 :     // Append units keyword.  For lines that like like this:
     243                 :     //  MAP_RESOLUTION               = 4.0 <PIXEL/DEGREE>
     244                 :     
     245             140 :     CPLString osWord;
     246                 :     
     247             140 :     osValue += " ";
     248                 :     
     249             280 :     while( ReadWord( osWord ) )
     250                 :     {
     251             140 :         SkipWhite();
     252                 :         
     253             140 :         osValue += osWord;
     254             140 :         if( osWord[strlen(osWord)-1] == '>' )
     255             140 :             break;
     256                 :     }
     257                 :     
     258             140 :     return TRUE;
     259                 : }
     260                 : 
     261                 : /************************************************************************/
     262                 : /*                              ReadWord()                              */
     263                 : /*  Returns TRUE on success                                             */
     264                 : /************************************************************************/
     265                 : 
     266            5103 : int NASAKeywordHandler::ReadWord( CPLString &osWord )
     267                 : 
     268                 : {
     269            5103 :     osWord = "";
     270                 : 
     271            5103 :     SkipWhite();
     272                 : 
     273           10206 :     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            5103 :     if( *pszHeaderNext == '"' )
     282                 :     {
     283             458 :         osWord += *(pszHeaderNext++);
     284            8193 :         while( *pszHeaderNext != '"' )
     285                 :         {
     286            7277 :             if( *pszHeaderNext == '\0' )
     287               0 :                 return FALSE;
     288            7277 :             if( *pszHeaderNext == '\n' )
     289                 :             {
     290              36 :                 osWord += "\\n";
     291              36 :                 pszHeaderNext++;
     292              36 :                 continue;
     293                 :             }
     294            7241 :             if( *pszHeaderNext == '\r' )
     295                 :             {
     296              34 :                 osWord += "\\r";
     297              34 :                 pszHeaderNext++;
     298              34 :                 continue;
     299                 :             }
     300            7207 :             osWord += *(pszHeaderNext++);
     301                 :         }
     302             458 :         osWord += *(pszHeaderNext++);
     303             458 :         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            4645 :     if( *pszHeaderNext == '\'' )
     313                 :     {
     314               4 :         osWord += *(pszHeaderNext++);
     315              20 :         while( *pszHeaderNext != '\'' )
     316                 :         {
     317              12 :             if( *pszHeaderNext == '\0' )
     318               0 :                 return FALSE;
     319                 : 
     320              12 :             osWord += *(pszHeaderNext++);
     321                 :         }
     322               4 :         osWord += *(pszHeaderNext++);
     323               4 :         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           54775 :     while( *pszHeaderNext != '\0' 
     334                 :            && *pszHeaderNext != '=' 
     335                 :            && !isspace((unsigned char)*pszHeaderNext) )
     336                 :     {
     337           45493 :         osWord += *pszHeaderNext;
     338           45493 :         pszHeaderNext++;
     339                 : 
     340           45621 :         if( *pszHeaderNext == '-' 
     341             128 :             && (pszHeaderNext[1] == 10 || pszHeaderNext[1] == 13) )
     342                 :         {
     343               0 :             pszHeaderNext += 2;
     344               0 :             SkipWhite();
     345                 :         }
     346                 :     }
     347                 :     
     348            4641 :     return TRUE;
     349                 : }
     350                 : 
     351                 : /************************************************************************/
     352                 : /*                             SkipWhite()                              */
     353                 : /*  Skip white spaces and C style comments                              */
     354                 : /************************************************************************/
     355                 : 
     356           61549 : void NASAKeywordHandler::SkipWhite()
     357                 : 
     358                 : {
     359           48877 :     for( ; TRUE; )
     360                 :     {
     361                 :         // Skip C style comments 
     362           61549 :         if( *pszHeaderNext == '/' && pszHeaderNext[1] == '*' )
     363                 :         {
     364             380 :             pszHeaderNext += 2;
     365                 :             
     366           14533 :             while( *pszHeaderNext != '\0' 
     367                 :                    && (*pszHeaderNext != '*' 
     368             493 :                        || pszHeaderNext[1] != '/' ) )
     369                 :             {
     370           13280 :                 pszHeaderNext++;
     371                 :             }
     372                 : 
     373             380 :             pszHeaderNext += 2;
     374                 : 
     375                 :             // consume till end of line.
     376                 :             // reduce sensibility to a label error
     377             760 :             while( *pszHeaderNext != '\0'
     378                 :                 && *pszHeaderNext != 10
     379                 :                 && *pszHeaderNext != 13 )
     380                 :             {
     381               0 :               pszHeaderNext++;
     382                 :             }
     383             380 :             continue;
     384                 :         }
     385                 : 
     386                 :         // Skip # style comments 
     387          109666 :          if( (*pszHeaderNext == 10 || *pszHeaderNext == 13 ||
     388                 :        *pszHeaderNext == ' ' || *pszHeaderNext == '\t' )
     389           48497 :               && pszHeaderNext[1] == '#' )
     390                 :         {
     391               4 :             pszHeaderNext += 2;
     392                 : 
     393                 :             // consume till end of line.
     394             216 :             while( *pszHeaderNext != '\0' 
     395                 :                    && *pszHeaderNext != 10
     396                 :                    && *pszHeaderNext != 13 )
     397                 :             {
     398             208 :                 pszHeaderNext++;
     399                 :             }
     400               4 :             continue;
     401                 :         }
     402                 : 
     403                 :         // Skip white space (newline, space, tab, etc )
     404           61165 :         if( isspace( (unsigned char)*pszHeaderNext ) )
     405                 :         {
     406           48493 :             pszHeaderNext++; 
     407           48493 :             continue;
     408                 :         }
     409                 :         
     410                 :         // not white space, return. 
     411                 :         return;
     412                 :     }
     413                 : }
     414                 : 
     415                 : /************************************************************************/
     416                 : /*                             GetKeyword()                             */
     417                 : /************************************************************************/
     418                 : 
     419            1839 : const char *NASAKeywordHandler::GetKeyword( const char *pszPath,
     420                 :                                             const char *pszDefault )
     421                 : 
     422                 : {
     423                 :     const char *pszResult;
     424                 : 
     425            1839 :     pszResult = CSLFetchNameValue( papszKeywordList, pszPath );
     426            1839 :     if( pszResult == NULL )
     427             775 :         return pszDefault;
     428                 :     else
     429            1064 :         return pszResult;
     430                 : }
     431                 : 
     432                 : /************************************************************************/
     433                 : /*                             GetKeywordList()                         */
     434                 : /************************************************************************/
     435                 :  
     436               0 : char **NASAKeywordHandler::GetKeywordList()
     437                 : {
     438               0 :     return papszKeywordList;
     439                 : }
     440                 : 

Generated by: LCOV version 1.7