LTP GCOV extension - code coverage report
Current view: directory - frmts/hfa - hfatype.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 160
Code covered: 74.4 % Executed lines: 119

       1                 : /******************************************************************************
       2                 :  * $Id: hfatype.cpp 18895 2010-02-23 19:30:01Z warmerdam $
       3                 :  *
       4                 :  * Project:  Erdas Imagine (.img) Translator
       5                 :  * Purpose:  Implementation of the HFAType class, for managing one type
       6                 :  *           defined in the HFA data dictionary.  Managed by HFADictionary.
       7                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       8                 :  *
       9                 :  ******************************************************************************
      10                 :  * Copyright (c) 1999, Intergraph Corporation
      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                 : 
      31                 : #include "hfa_p.h"
      32                 : 
      33                 : CPL_CVSID("$Id: hfatype.cpp 18895 2010-02-23 19:30:01Z warmerdam $");
      34                 : 
      35                 : /************************************************************************/
      36                 : /* ==================================================================== */
      37                 : /*                 HFAType          */
      38                 : /* ==================================================================== */
      39                 : /************************************************************************/
      40                 : 
      41                 : /************************************************************************/
      42                 : /*                              HFAType()                               */
      43                 : /************************************************************************/
      44                 : 
      45           15509 : HFAType::HFAType()
      46                 : 
      47                 : {
      48           15509 :     nBytes = 0;
      49           15509 :     nFields = 0;
      50           15509 :     papoFields = NULL;
      51           15509 :     pszTypeName = NULL;
      52           15509 : }
      53                 : 
      54                 : /************************************************************************/
      55                 : /*                              ~HFAType()                              */
      56                 : /************************************************************************/
      57                 : 
      58           15509 : HFAType::~HFAType()
      59                 : 
      60                 : {
      61                 :     int   i;
      62                 : 
      63           74245 :     for( i = 0; i < nFields; i++ )
      64                 :     {
      65           58736 :         delete papoFields[i];
      66                 :     }
      67                 : 
      68           15509 :     CPLFree( papoFields );
      69                 : 
      70           15509 :     CPLFree( pszTypeName );
      71           15509 : }
      72                 : 
      73                 : /************************************************************************/
      74                 : /*                             Initialize()                             */
      75                 : /************************************************************************/
      76                 : 
      77           15509 : const char *HFAType::Initialize( const char * pszInput )
      78                 : 
      79                 : {
      80                 :     int   i;
      81                 :     
      82                 :     
      83           15509 :     if( *pszInput != '{' )
      84                 :     {
      85               0 :         if( *pszInput != '\0' )
      86                 :             CPLDebug( "HFAType", "Initialize(%60.60s) - unexpected input.",
      87               0 :                       pszInput );
      88                 : 
      89               0 :         while( *pszInput != '{' && *pszInput != '\0' )
      90               0 :             pszInput++;
      91                 : 
      92               0 :         if( *pszInput == '\0' )
      93               0 :             return NULL;
      94                 :     }
      95                 : 
      96           15509 :     pszInput++;
      97                 : 
      98                 : /* -------------------------------------------------------------------- */
      99                 : /*      Read the field definitions.                                     */
     100                 : /* -------------------------------------------------------------------- */
     101           89754 :     while( pszInput != NULL && *pszInput != '}' )
     102                 :     {
     103           58736 :         HFAField  *poNewField = new HFAField();
     104                 : 
     105           58736 :         pszInput = poNewField->Initialize( pszInput );
     106           58736 :         if( pszInput != NULL )
     107                 :         {
     108                 :             papoFields = (HFAField **)
     109           58736 :                 CPLRealloc(papoFields, sizeof(void*) * (nFields+1) );
     110           58736 :             papoFields[nFields++] = poNewField;
     111                 :         }
     112                 :         else
     113               0 :             delete poNewField;
     114                 :     }
     115                 : 
     116           15509 :     if( pszInput == NULL )
     117               0 :         return NULL;
     118                 : 
     119                 : /* -------------------------------------------------------------------- */
     120                 : /*      Collect the name.                                               */
     121                 : /* -------------------------------------------------------------------- */
     122           15509 :     pszInput++; /* skip `}' */
     123                 : 
     124           15509 :     for( i = 0; pszInput[i] != '\0' && pszInput[i] != ','; i++ ) {}
     125           15509 :     if (pszInput[i] == '\0')
     126               3 :         return NULL;
     127                 : 
     128           15506 :     pszTypeName = (char *) CPLMalloc(i+1);
     129           15506 :     strncpy( pszTypeName, pszInput, i );
     130           15506 :     pszTypeName[i] = '\0';
     131                 :     
     132           15506 :     pszInput += i+1;
     133                 : 
     134           15506 :     return( pszInput );
     135                 : }
     136                 : 
     137                 : /************************************************************************/
     138                 : /*                            CompleteDefn()                            */
     139                 : /************************************************************************/
     140                 : 
     141           22126 : void HFAType::CompleteDefn( HFADictionary * poDict )
     142                 : 
     143                 : {
     144                 :     int   i;
     145                 : 
     146                 : /* -------------------------------------------------------------------- */
     147                 : /*      This may already be done, if an earlier object required this    */
     148                 : /*      object (as a field), and forced an early computation of the     */
     149                 : /*      size.                                                           */
     150                 : /* -------------------------------------------------------------------- */
     151           22126 :     if( nBytes != 0 )
     152            6617 :         return;
     153                 :     
     154                 : /* -------------------------------------------------------------------- */
     155                 : /*      Complete each of the fields, totaling up the sizes.  This       */
     156                 : /*      isn't really accurate for object with variable sized            */
     157                 : /*      subobjects.                                                     */
     158                 : /* -------------------------------------------------------------------- */
     159           74245 :     for( i = 0; i < nFields; i++ )
     160                 :     {
     161           58736 :         papoFields[i]->CompleteDefn( poDict );
     162           84194 :         if( papoFields[i]->nBytes < 0 || nBytes == -1 )
     163           25458 :             nBytes = -1;
     164                 :         else
     165           33278 :             nBytes += papoFields[i]->nBytes;
     166                 :     }
     167                 : }
     168                 : 
     169                 : /************************************************************************/
     170                 : /*                                Dump()                                */
     171                 : /************************************************************************/
     172                 : 
     173               0 : void HFAType::Dump( FILE * fp )
     174                 : 
     175                 : {
     176                 :     int   i;
     177                 :     
     178               0 :     VSIFPrintf( fp, "HFAType %s/%d bytes\n", pszTypeName, nBytes );
     179                 : 
     180               0 :     for( i = 0; i < nFields; i++ )
     181                 :     {
     182               0 :         papoFields[i]->Dump( fp );
     183                 :     }
     184                 : 
     185               0 :     VSIFPrintf( fp, "\n" );
     186               0 : }
     187                 : 
     188                 : /************************************************************************/
     189                 : /*                            SetInstValue()                            */
     190                 : /************************************************************************/
     191                 : 
     192                 : CPLErr 
     193                 : HFAType::SetInstValue( const char * pszFieldPath,
     194                 :                        GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
     195            8886 :                        char chReqType, void *pValue )
     196                 : 
     197                 : {
     198            8886 :     int   nArrayIndex = 0, nNameLen, iField, nByteOffset;
     199                 :     const char  *pszRemainder;
     200                 : 
     201                 : /* -------------------------------------------------------------------- */
     202                 : /*      Parse end of field name, possible index value and               */
     203                 : /*      establish where the remaining fields (if any) would start.      */
     204                 : /* -------------------------------------------------------------------- */
     205            8886 :     if( strchr(pszFieldPath,'[') != NULL )
     206                 :     {
     207            2217 :         const char  *pszEnd = strchr(pszFieldPath,'[');
     208                 :         
     209            2217 :         nArrayIndex = atoi(pszEnd+1);
     210            2217 :         nNameLen = pszEnd - pszFieldPath;
     211                 : 
     212            2217 :         pszRemainder = strchr(pszFieldPath,'.');
     213            2217 :         if( pszRemainder != NULL )
     214             139 :             pszRemainder++;
     215                 :     }
     216                 : 
     217            6669 :     else if( strchr(pszFieldPath,'.') != NULL )
     218                 :     {
     219            1571 :         const char  *pszEnd = strchr(pszFieldPath,'.');
     220                 :         
     221            1571 :         nNameLen = pszEnd - pszFieldPath;
     222                 : 
     223            1571 :         pszRemainder = pszEnd + 1;
     224                 :     }
     225                 : 
     226                 :     else
     227                 :     {
     228            5098 :         nNameLen = strlen(pszFieldPath);
     229            5098 :         pszRemainder = pszFieldPath/*NULL*/;
     230                 :     }
     231                 :     
     232                 : /* -------------------------------------------------------------------- */
     233                 : /*      Find this field within this type, if possible.                  */
     234                 : /* -------------------------------------------------------------------- */
     235            8886 :     nByteOffset = 0;
     236           29753 :     for( iField = 0; iField < nFields && nByteOffset < nDataSize; iField++ )
     237                 :     {
     238           29708 :         if( EQUALN(pszFieldPath,papoFields[iField]->pszFieldName,nNameLen)
     239                 :             && papoFields[iField]->pszFieldName[nNameLen] == '\0' )
     240                 :         {
     241            8841 :             break;
     242                 :         }
     243                 : 
     244                 :         int nInc = papoFields[iField]->GetInstBytes( pabyData+nByteOffset,
     245           20867 :                                               nDataSize - nByteOffset );
     246                 : 
     247           20867 :         if (nInc < 0 || nByteOffset > INT_MAX - nInc)
     248                 :         {
     249               0 :             CPLError(CE_Failure, CPLE_AppDefined, "Invalid return value");
     250               0 :             return CE_Failure;
     251                 :         }
     252                 : 
     253           20867 :         nByteOffset += nInc;
     254                 :     }
     255                 : 
     256            8886 :     if( iField == nFields || nByteOffset >= nDataSize )
     257              45 :         return CE_Failure;
     258                 : 
     259                 : /* -------------------------------------------------------------------- */
     260                 : /*      Extract this field value, and return.                           */
     261                 : /* -------------------------------------------------------------------- */
     262                 :     return( papoFields[iField]->SetInstValue( pszRemainder, nArrayIndex,
     263                 :                                               pabyData + nByteOffset,
     264                 :                                               nDataOffset + nByteOffset,
     265                 :                                               nDataSize - nByteOffset,
     266            8841 :                                               chReqType, pValue ) );
     267                 : }
     268                 : 
     269                 : /************************************************************************/
     270                 : /*                            GetInstCount()                            */
     271                 : /************************************************************************/
     272                 : 
     273                 : int
     274                 : HFAType::GetInstCount( const char * pszFieldPath,
     275             426 :                        GByte *pabyData, GUInt32 nDataOffset, int nDataSize )
     276                 : 
     277                 : {
     278             426 :     int   nArrayIndex = 0, nNameLen, iField, nByteOffset;
     279                 :     const char  *pszRemainder;
     280                 : 
     281                 : /* -------------------------------------------------------------------- */
     282                 : /*      Parse end of field name, possible index value and               */
     283                 : /*      establish where the remaining fields (if any) would start.      */
     284                 : /* -------------------------------------------------------------------- */
     285             426 :     if( strchr(pszFieldPath,'[') != NULL )
     286                 :     {
     287               0 :         const char  *pszEnd = strchr(pszFieldPath,'[');
     288                 :         
     289               0 :         nArrayIndex = atoi(pszEnd+1);
     290               0 :         nNameLen = pszEnd - pszFieldPath;
     291                 : 
     292               0 :         pszRemainder = strchr(pszFieldPath,'.');
     293               0 :         if( pszRemainder != NULL )
     294               0 :             pszRemainder++;
     295                 :     }
     296                 : 
     297             426 :     else if( strchr(pszFieldPath,'.') != NULL )
     298                 :     {
     299             105 :         const char  *pszEnd = strchr(pszFieldPath,'.');
     300                 :         
     301             105 :         nNameLen = pszEnd - pszFieldPath;
     302                 : 
     303             105 :         pszRemainder = pszEnd + 1;
     304                 :     }
     305                 : 
     306                 :     else
     307                 :     {
     308             321 :         nNameLen = strlen(pszFieldPath);
     309             321 :         pszRemainder = NULL;
     310                 :     }
     311                 :     
     312                 : /* -------------------------------------------------------------------- */
     313                 : /*      Find this field within this type, if possible.                  */
     314                 : /* -------------------------------------------------------------------- */
     315             426 :     nByteOffset = 0;
     316            1762 :     for( iField = 0; iField < nFields && nByteOffset < nDataSize; iField++ )
     317                 :     {
     318            1762 :         if( EQUALN(pszFieldPath,papoFields[iField]->pszFieldName,nNameLen)
     319                 :             && papoFields[iField]->pszFieldName[nNameLen] == '\0' )
     320                 :         {
     321             426 :             break;
     322                 :         }
     323                 : 
     324                 :         int nInc = papoFields[iField]->GetInstBytes( pabyData+nByteOffset,
     325            1336 :                                               nDataSize - nByteOffset );
     326                 : 
     327            1336 :         if (nInc < 0 || nByteOffset > INT_MAX - nInc)
     328                 :         {
     329               0 :             CPLError(CE_Failure, CPLE_AppDefined, "Invalid return value");
     330               0 :             return -1;
     331                 :         }
     332                 : 
     333            1336 :         nByteOffset += nInc;
     334                 :     }
     335                 : 
     336             426 :     if( iField == nFields || nByteOffset >= nDataSize )
     337               0 :         return -1;
     338                 : 
     339                 : /* -------------------------------------------------------------------- */
     340                 : /*      Extract this field value, and return.                           */
     341                 : /* -------------------------------------------------------------------- */
     342                 :     return( papoFields[iField]->GetInstCount( pabyData + nByteOffset,
     343             426 :                                               nDataSize - nByteOffset ) );
     344                 : }
     345                 : 
     346                 : /************************************************************************/
     347                 : /*                          ExtractInstValue()                          */
     348                 : /*                                                                      */
     349                 : /*      Extract the value of a field instance within this type.         */
     350                 : /*      Most of the work is done by the ExtractInstValue() for the      */
     351                 : /*      HFAField, but this methond does the field name parsing.         */
     352                 : /*                                                                      */
     353                 : /*      field names have the form:                                      */
     354                 : /*                                                                      */
     355                 : /*        fieldname{[index]}{.fieldname...}                             */
     356                 : /*                                                                      */
     357                 : /*      eg.                                                             */
     358                 : /*        abc                                   - field abc[0]          */
     359                 : /*        abc[3]                                - field abc[3]          */
     360                 : /*        abc[2].def                            - field def[0] of       */
     361                 : /*                                                the third abc struct. */
     362                 : /************************************************************************/
     363                 : 
     364                 : int
     365                 : HFAType::ExtractInstValue( const char * pszFieldPath,
     366                 :                            GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
     367           15012 :                            char chReqType, void *pReqReturn, int *pnRemainingDataSize )
     368                 : 
     369                 : {
     370           15012 :     int   nArrayIndex = 0, nNameLen, iField, nByteOffset;
     371                 :     const char  *pszRemainder;
     372                 : 
     373                 : /* -------------------------------------------------------------------- */
     374                 : /*      Parse end of field name, possible index value and               */
     375                 : /*      establish where the remaining fields (if any) would start.      */
     376                 : /* -------------------------------------------------------------------- */
     377           15012 :     const char *pszFirstArray = strchr(pszFieldPath,'[');
     378           15012 :     const char *pszFirstDot = strchr(pszFieldPath,'.');
     379                 : 
     380           17857 :     if( pszFirstArray != NULL
     381                 :         && (pszFirstDot == NULL
     382                 :             || pszFirstDot > pszFirstArray) )
     383                 :     {
     384            2845 :         const char  *pszEnd = pszFirstArray;
     385                 :         
     386            2845 :         nArrayIndex = atoi(pszEnd+1);
     387            2845 :         nNameLen = pszEnd - pszFieldPath;
     388                 : 
     389            2845 :         pszRemainder = strchr(pszFieldPath,'.');
     390            2845 :         if( pszRemainder != NULL )
     391            1413 :             pszRemainder++;
     392                 :     }
     393                 : 
     394           12167 :     else if( pszFirstDot != NULL )
     395                 :     {
     396            1452 :         const char  *pszEnd = pszFirstDot;
     397                 :         
     398            1452 :         nNameLen = pszEnd - pszFieldPath;
     399                 : 
     400            1452 :         pszRemainder = pszEnd + 1;
     401                 :     }
     402                 : 
     403                 :     else
     404                 :     {
     405           10715 :         nNameLen = strlen(pszFieldPath);
     406           10715 :         pszRemainder = NULL;
     407                 :     }
     408                 :     
     409                 : /* -------------------------------------------------------------------- */
     410                 : /*      Find this field within this type, if possible.                  */
     411                 : /* -------------------------------------------------------------------- */
     412           15012 :     nByteOffset = 0;
     413           48100 :     for( iField = 0; iField < nFields && nByteOffset < nDataSize; iField++ )
     414                 :     {
     415           48072 :         if( EQUALN(pszFieldPath,papoFields[iField]->pszFieldName,nNameLen)
     416                 :             && papoFields[iField]->pszFieldName[nNameLen] == '\0' )
     417                 :         {
     418           14984 :             break;
     419                 :         }
     420                 : 
     421                 :         int nInc = papoFields[iField]->GetInstBytes( pabyData+nByteOffset,
     422           33088 :                                               nDataSize - nByteOffset );
     423                 : 
     424           33088 :         if (nInc < 0 || nByteOffset > INT_MAX - nInc)
     425                 :         {
     426               0 :             CPLError(CE_Failure, CPLE_AppDefined, "Invalid return value");
     427               0 :             return FALSE;
     428                 :         }
     429                 : 
     430           33088 :         nByteOffset += nInc;
     431                 :     }
     432                 : 
     433           15012 :     if( iField == nFields || nByteOffset >= nDataSize )
     434              28 :         return FALSE;
     435                 : 
     436                 : /* -------------------------------------------------------------------- */
     437                 : /*      Extract this field value, and return.                           */
     438                 : /* -------------------------------------------------------------------- */
     439                 :     return( papoFields[iField]->
     440                 :             ExtractInstValue( pszRemainder, nArrayIndex,
     441                 :                               pabyData + nByteOffset,
     442                 :                               nDataOffset + nByteOffset,
     443                 :                               nDataSize - nByteOffset,
     444                 :                               chReqType, pReqReturn,
     445           14984 :                               pnRemainingDataSize) );
     446                 : }
     447                 : 
     448                 : 
     449                 : /************************************************************************/
     450                 : /*                           DumpInstValue()                            */
     451                 : /************************************************************************/
     452                 : 
     453                 : void HFAType::DumpInstValue( FILE * fpOut,
     454                 :                              GByte *pabyData, GUInt32 nDataOffset,
     455               0 :                              int nDataSize, const char * pszPrefix )
     456                 : 
     457                 : {
     458                 :     int   iField;
     459                 :     
     460               0 :     for ( iField = 0; iField < nFields && nDataSize > 0; iField++ )
     461                 :     {
     462               0 :         HFAField  *poField = papoFields[iField];
     463                 :         int   nInstBytes;
     464                 :         
     465                 :         poField->DumpInstValue( fpOut, pabyData, nDataOffset,
     466               0 :                                 nDataSize, pszPrefix );
     467                 : 
     468               0 :         nInstBytes = poField->GetInstBytes( pabyData, nDataSize );
     469               0 :         if (nInstBytes < 0 || nDataOffset > UINT_MAX - nInstBytes)
     470                 :         {
     471               0 :             CPLError(CE_Failure, CPLE_AppDefined, "Invalid return value");
     472               0 :             return;
     473                 :         }
     474                 : 
     475               0 :         pabyData += nInstBytes;
     476               0 :         nDataOffset += nInstBytes;
     477               0 :         nDataSize -= nInstBytes;
     478                 :     }    
     479                 : }
     480                 : 
     481                 : /************************************************************************/
     482                 : /*                            GetInstBytes()                            */
     483                 : /*                                                                      */
     484                 : /*      How many bytes in this particular instance of this type?        */
     485                 : /************************************************************************/
     486                 : 
     487            1184 : int HFAType::GetInstBytes( GByte *pabyData, int nDataSize )
     488                 : 
     489                 : {
     490            1184 :     if( nBytes >= 0 )
     491               0 :         return( nBytes );
     492                 :     else
     493                 :     {
     494            1184 :         int nTotal = 0;
     495                 :         int iField;
     496                 :     
     497            2831 :         for( iField = 0; iField < nFields && nTotal < nDataSize; iField++ )
     498                 :         {
     499            1647 :             HFAField  *poField = papoFields[iField];
     500                 : 
     501                 :             int nInstBytes = poField->GetInstBytes( pabyData,
     502            1647 :                                                     nDataSize - nTotal );
     503            1647 :             if (nInstBytes < 0 || nTotal > INT_MAX - nInstBytes)
     504                 :             {
     505               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "Invalid return value");
     506               0 :                 return -1;
     507                 :             }
     508                 : 
     509            1647 :             pabyData += nInstBytes;
     510            1647 :             nTotal += nInstBytes;
     511                 :         }
     512                 : 
     513            1184 :         return( nTotal );
     514                 :     }
     515                 : }

Generated by: LTP GCOV extension version 1.5