LCOV - code coverage report
Current view: directory - frmts/pds - nasakeywordhandler.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 136 120 88.2 %
Date: 2010-01-09 Functions: 8 8 100.0 %

       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                 : 
      36                 : #include "cpl_string.h" 
      37                 : #include "nasakeywordhandler.h"
      38                 : 
      39                 : /************************************************************************/
      40                 : /* ==================================================================== */
      41                 : /*                          NASAKeywordHandler                          */
      42                 : /* ==================================================================== */
      43                 : /************************************************************************/
      44                 : 
      45                 : /************************************************************************/
      46                 : /*                         NASAKeywordHandler()                         */
      47                 : /************************************************************************/
      48                 : 
      49              11 : NASAKeywordHandler::NASAKeywordHandler()
      50                 : 
      51                 : {
      52              11 :     papszKeywordList = NULL;
      53              11 : }
      54                 : 
      55                 : /************************************************************************/
      56                 : /*                        ~NASAKeywordHandler()                         */
      57                 : /************************************************************************/
      58                 : 
      59              11 : NASAKeywordHandler::~NASAKeywordHandler()
      60                 : 
      61                 : {
      62              11 :     CSLDestroy( papszKeywordList );
      63              11 :     papszKeywordList = NULL;
      64              11 : }
      65                 : 
      66                 : /************************************************************************/
      67                 : /*                               Ingest()                               */
      68                 : /************************************************************************/
      69                 : 
      70              11 : int NASAKeywordHandler::Ingest( FILE *fp, int nOffset )
      71                 : 
      72                 : {
      73                 : /* -------------------------------------------------------------------- */
      74                 : /*      Read in buffer till we find END all on it's own line.           */
      75                 : /* -------------------------------------------------------------------- */
      76              11 :     if( VSIFSeekL( fp, nOffset, SEEK_SET ) != 0 )
      77               0 :         return FALSE;
      78                 : 
      79              91 :     for( ; TRUE; ) 
      80                 :     {
      81                 :         const char *pszCheck;
      82                 :         char szChunk[513];
      83                 : 
      84             102 :         int nBytesRead = VSIFReadL( szChunk, 1, 512, fp );
      85                 : 
      86             102 :         szChunk[nBytesRead] = '\0';
      87             102 :         osHeaderText += szChunk;
      88                 : 
      89             102 :         if( nBytesRead < 512 )
      90               4 :             break;
      91                 : 
      92              98 :         if( osHeaderText.size() > 520 )
      93              87 :             pszCheck = osHeaderText.c_str() + (osHeaderText.size() - 520);
      94                 :         else
      95              11 :             pszCheck = szChunk;
      96                 : 
      97              98 :         if( strstr(pszCheck,"\r\nEND\r\n") != NULL 
      98                 :             || strstr(pszCheck,"\nEND\n") != NULL 
      99                 :             || strstr(pszCheck,"\r\nEnd\r\n") != NULL 
     100                 :             || strstr(pszCheck,"\nEnd\n") != NULL )
     101               7 :             break;
     102                 :     }
     103                 : 
     104              11 :     pszHeaderNext = osHeaderText.c_str();
     105                 : 
     106                 : /* -------------------------------------------------------------------- */
     107                 : /*      Process name/value pairs, keeping track of a "path stack".      */
     108                 : /* -------------------------------------------------------------------- */
     109              11 :     return ReadGroup( "" );
     110                 : }
     111                 : 
     112                 : /************************************************************************/
     113                 : /*                             ReadGroup()                              */
     114                 : /************************************************************************/
     115                 : 
     116              70 : int NASAKeywordHandler::ReadGroup( const char *pszPathPrefix )
     117                 : 
     118                 : {
     119              70 :     CPLString osName, osValue;
     120                 : 
     121             917 :     for( ; TRUE; )
     122                 :     {
     123             987 :         if( !ReadPair( osName, osValue ) )
     124               0 :             return FALSE;
     125                 : 
     126             987 :         if( EQUAL(osName,"OBJECT") || EQUAL(osName,"GROUP") )
     127                 :         {
     128              59 :             if( !ReadGroup( (CPLString(pszPathPrefix) + osValue + ".").c_str() ) )
     129               0 :                 return FALSE;
     130                 :         }
     131             928 :         else if( EQUALN(osName,"END",3) )
     132                 :         {
     133              70 :             return TRUE;
     134                 :         }
     135                 :         else
     136                 :         {
     137             858 :             osName = pszPathPrefix + osName;
     138                 :             papszKeywordList = CSLSetNameValue( papszKeywordList, 
     139             858 :                                                 osName, osValue );
     140                 :         }
     141               0 :     }
     142                 : }
     143                 : 
     144                 : /************************************************************************/
     145                 : /*                              ReadPair()                              */
     146                 : /*                                                                      */
     147                 : /*      Read a name/value pair from the input stream.  Strip off        */
     148                 : /*      white space, ignore comments, split on '='.                     */
     149                 : /*      Returns TRUE on success.                                        */
     150                 : /************************************************************************/
     151                 : 
     152             987 : int NASAKeywordHandler::ReadPair( CPLString &osName, CPLString &osValue )
     153                 : 
     154                 : {
     155             987 :     osName = "";
     156            1974 :     osValue = "";
     157                 : 
     158             987 :     if( !ReadWord( osName ) )
     159               0 :         return FALSE;
     160                 : 
     161             987 :     SkipWhite();
     162                 : 
     163             987 :     if( EQUAL(osName,"END") )
     164              11 :         return TRUE;
     165                 : 
     166             976 :     if( *pszHeaderNext != '=' )
     167                 :     {
     168                 :         // ISIS3 does not have anything after the end group/object keyword. 
     169              21 :         if( EQUAL(osName,"End_Group") || EQUAL(osName,"End_Object") )
     170              21 :             return TRUE;
     171                 :         else
     172               0 :             return FALSE;
     173                 :     }
     174                 :     
     175             955 :     pszHeaderNext++;
     176                 :     
     177             955 :     SkipWhite();
     178                 :     
     179             955 :     osValue = "";
     180                 : 
     181                 :     // Handle value lists like:     Name   = (Red, Red)
     182             955 :     if( *pszHeaderNext == '(' )
     183                 :     {
     184              51 :         CPLString osWord;
     185                 : 
     186              51 :         while( ReadWord( osWord ) )
     187                 :         {
     188             232 :             SkipWhite();
     189                 : 
     190             232 :             osValue += osWord;
     191             232 :             if( osWord[strlen(osWord)-1] == ')' )
     192              51 :                 break;
     193              51 :         }
     194                 :     }
     195                 : 
     196                 :     // Handle value lists like:     Name   = {Red, Red}
     197             904 :     else if( *pszHeaderNext == '{' )
     198                 :     {
     199               2 :         CPLString osWord;
     200                 : 
     201               2 :         while( ReadWord( osWord ) )
     202                 :         {
     203              14 :             SkipWhite();
     204                 : 
     205              14 :             osValue += osWord;
     206              14 :             if( osWord[strlen(osWord)-1] == '}' )
     207               2 :                 break;
     208               2 :         }
     209                 :     }
     210                 : 
     211                 :     else // Handle more normal "single word" values. 
     212                 :     {
     213             902 :         if( !ReadWord( osValue ) )
     214               0 :             return FALSE;
     215                 : 
     216                 :     }
     217                 :         
     218             955 :     SkipWhite();
     219                 : 
     220                 :     // No units keyword?   
     221             955 :     if( *pszHeaderNext != '<' )
     222             849 :         return TRUE;
     223                 : 
     224                 :     // Append units keyword.  For lines that like like this:
     225                 :     //  MAP_RESOLUTION               = 4.0 <PIXEL/DEGREE>
     226                 :     
     227             106 :     CPLString osWord;
     228                 :     
     229             106 :     osValue += " ";
     230                 :     
     231             212 :     while( ReadWord( osWord ) )
     232                 :     {
     233             106 :         SkipWhite();
     234                 :         
     235             106 :         osValue += osWord;
     236             106 :         if( osWord[strlen(osWord)-1] == '>' )
     237             106 :             break;
     238                 :     }
     239                 :     
     240             106 :     return TRUE;
     241                 : }
     242                 : 
     243                 : /************************************************************************/
     244                 : /*                              ReadWord()                              */
     245                 : /*  Returns TRUE on success                                             */
     246                 : /************************************************************************/
     247                 : 
     248            2241 : int NASAKeywordHandler::ReadWord( CPLString &osWord )
     249                 : 
     250                 : {
     251            2241 :     osWord = "";
     252                 : 
     253            2241 :     SkipWhite();
     254                 : 
     255            4482 :     if( !(*pszHeaderNext != '\0' 
     256                 :            && *pszHeaderNext != '=' 
     257                 :            && !isspace((unsigned char)*pszHeaderNext)) )
     258               0 :         return FALSE;
     259                 : 
     260                 :     /* Extract a text string delimited by '\"' */
     261                 :     /* Convert newlines (CR or LF) within quotes. While text strings
     262                 :        support them as per ODL, the keyword list doesn't want them */
     263            2241 :     if( *pszHeaderNext == '"' )
     264                 :     {
     265             210 :         osWord += *(pszHeaderNext++);
     266            3851 :         while( *pszHeaderNext != '"' )
     267                 :         {
     268            3431 :             if( *pszHeaderNext == '\0' )
     269               0 :                 return FALSE;
     270            3431 :             if( *pszHeaderNext == '\n' )
     271                 :             {
     272              14 :                 osWord += "\\n";
     273              14 :                 pszHeaderNext++;
     274              14 :                 continue;
     275                 :             }
     276            3417 :             if( *pszHeaderNext == '\r' )
     277                 :             {
     278              12 :                 osWord += "\\r";
     279              12 :                 pszHeaderNext++;
     280              12 :                 continue;
     281                 :             }
     282            3405 :             osWord += *(pszHeaderNext++);
     283                 :         }
     284             210 :         osWord += *(pszHeaderNext++);
     285             210 :         return TRUE;
     286                 :     }
     287                 :     /* Extract a symbol string */
     288                 :     /* These are expected to not have
     289                 :        '\'' (delimiters),
     290                 :        format effectors (should fit on a single line) or
     291                 :        control characters.  */
     292            2031 :     if( *pszHeaderNext == '\'' )
     293                 :     {
     294               0 :         osWord += *(pszHeaderNext++);
     295               0 :         while( *pszHeaderNext != '\'' )
     296                 :         {
     297               0 :             if( *pszHeaderNext == '\0' )
     298               0 :                 return FALSE;
     299                 : 
     300               0 :             osWord += *(pszHeaderNext++);
     301                 :         }
     302               0 :         osWord += *(pszHeaderNext++);
     303               0 :         return TRUE;
     304                 :     }
     305                 : 
     306           26846 :     while( *pszHeaderNext != '\0' 
     307                 :            && *pszHeaderNext != '=' 
     308                 :            && !isspace((unsigned char)*pszHeaderNext) )
     309                 :     {
     310           22784 :         osWord += *pszHeaderNext;
     311           22784 :         pszHeaderNext++;
     312                 :     }
     313                 :     
     314            2031 :     return TRUE;
     315                 : }
     316                 : 
     317                 : /************************************************************************/
     318                 : /*                             SkipWhite()                              */
     319                 : /*  Skip white spaces and C style comments                              */
     320                 : /************************************************************************/
     321                 : 
     322           21471 : void NASAKeywordHandler::SkipWhite()
     323                 : 
     324                 : {
     325           15981 :     for( ; TRUE; )
     326                 :     {
     327                 :         // Skip C style comments 
     328           21471 :         if( *pszHeaderNext == '/' && pszHeaderNext[1] == '*' )
     329                 :         {
     330             121 :             pszHeaderNext += 2;
     331                 :             
     332            6480 :             while( *pszHeaderNext != '\0' 
     333                 :                    && (*pszHeaderNext != '*' 
     334             228 :                        || pszHeaderNext[1] != '/' ) )
     335                 :             {
     336            6010 :                 pszHeaderNext++;
     337                 :             }
     338                 : 
     339             121 :             pszHeaderNext += 2;
     340             121 :             continue;
     341                 :         }
     342                 : 
     343                 :         // Skip # style comments 
     344           37210 :          if( (*pszHeaderNext == 10 || *pszHeaderNext == 13 ||
     345                 :        *pszHeaderNext == ' ' || *pszHeaderNext == '\t' )
     346           15860 :               && pszHeaderNext[1] == '#' )
     347                 :         {
     348               4 :             pszHeaderNext += 2;
     349                 : 
     350                 :             // consume till end of line.
     351             216 :             while( *pszHeaderNext != '\0' 
     352                 :                    && *pszHeaderNext != 10
     353                 :                    && *pszHeaderNext != 13 )
     354                 :             {
     355             208 :                 pszHeaderNext++;
     356                 :             }
     357               4 :             continue;
     358                 :         }
     359                 : 
     360                 :         // Skip white space (newline, space, tab, etc )
     361           21346 :         if( isspace( (unsigned char)*pszHeaderNext ) )
     362                 :         {
     363           15856 :             pszHeaderNext++; 
     364           15856 :             continue;
     365                 :         }
     366                 :         
     367                 :         // not white space, return. 
     368                 :         return;
     369                 :     }
     370                 : }
     371                 : 
     372                 : /************************************************************************/
     373                 : /*                             GetKeyword()                             */
     374                 : /************************************************************************/
     375                 : 
     376             371 : const char *NASAKeywordHandler::GetKeyword( const char *pszPath,
     377                 :                                             const char *pszDefault )
     378                 : 
     379                 : {
     380                 :     const char *pszResult;
     381                 : 
     382             371 :     pszResult = CSLFetchNameValue( papszKeywordList, pszPath );
     383             371 :     if( pszResult == NULL )
     384             116 :         return pszDefault;
     385                 :     else
     386             255 :         return pszResult;
     387                 : }
     388                 : 

Generated by: LCOV version 1.7