LCOV - code coverage report
Current view: directory - frmts/hfa - hfafield.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 532 300 56.4 %
Date: 2010-01-09 Functions: 10 8 80.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: hfafield.cpp 17490 2009-08-01 10:45:06Z rouault $
       3                 :  *
       4                 :  * Project:  Erdas Imagine (.img) Translator
       5                 :  * Purpose:  Implementation of the HFAField class for managing information
       6                 :  *           about one field in a HFA dictionary type.  Managed by HFAType.
       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: hfafield.cpp 17490 2009-08-01 10:45:06Z rouault $");
      34                 : 
      35                 : #define MAX_ENTRY_REPORT   16
      36                 :                            
      37                 : /************************************************************************/
      38                 : /* ==================================================================== */
      39                 : /*                    HFAField        */
      40                 : /* ==================================================================== */
      41                 : /************************************************************************/
      42                 : 
      43                 : /************************************************************************/
      44                 : /*                              HFAField()                              */
      45                 : /************************************************************************/
      46                 : 
      47           52249 : HFAField::HFAField()
      48                 : 
      49                 : {
      50           52249 :     nBytes = 0;
      51                 : 
      52           52249 :     nItemCount = 0;
      53           52249 :     chPointer = '\0';
      54           52249 :     chItemType = '\0';
      55                 : 
      56           52249 :     pszItemObjectType = NULL;
      57           52249 :     poItemObjectType = NULL;
      58                 : 
      59           52249 :     papszEnumNames = NULL;
      60                 : 
      61           52249 :     pszFieldName = NULL;
      62           52249 : }
      63                 : 
      64                 : /************************************************************************/
      65                 : /*                             ~HFAField()                              */
      66                 : /************************************************************************/
      67                 : 
      68           52249 : HFAField::~HFAField()
      69                 : 
      70                 : {
      71           52249 :     CPLFree( pszItemObjectType );
      72           52249 :     CSLDestroy( papszEnumNames );
      73           52249 :     CPLFree( pszFieldName );
      74           52249 : }
      75                 : 
      76                 : /************************************************************************/
      77                 : /*                             Initialize()                             */
      78                 : /************************************************************************/
      79                 : 
      80           52249 : const char *HFAField::Initialize( const char * pszInput )
      81                 : 
      82                 : {
      83                 :     int   i;
      84                 :     
      85                 : /* -------------------------------------------------------------------- */
      86                 : /*      Read the number.                                                */
      87                 : /* -------------------------------------------------------------------- */
      88           52249 :     nItemCount = atoi(pszInput);
      89                 : 
      90          157875 :     while( *pszInput != '\0' && *pszInput != ':' )
      91           53377 :         pszInput++;
      92                 : 
      93           52249 :     if( *pszInput == '\0' )
      94               0 :         return NULL;
      95                 :     
      96           52249 :     pszInput++;
      97                 : 
      98                 : /* -------------------------------------------------------------------- */
      99                 : /*      Is this a pointer?                                              */
     100                 : /* -------------------------------------------------------------------- */
     101           52249 :     if( *pszInput == 'p' || *pszInput == '*' )
     102           11979 :         chPointer = *(pszInput++);
     103                 : 
     104                 : /* -------------------------------------------------------------------- */
     105                 : /*      Get the general type                                            */
     106                 : /* -------------------------------------------------------------------- */
     107           52249 :     if( *pszInput == '\0' )
     108               0 :         return NULL;
     109                 : 
     110           52249 :     chItemType = *(pszInput++);
     111                 : 
     112           52249 :     if ( strchr( "124cCesStlLfdmMbox", chItemType) == NULL )
     113                 :     {
     114                 :         CPLError(CE_Failure, CPLE_AppDefined,
     115               0 :                  "Unrecognized item type : %c", chItemType);
     116               0 :         return NULL;
     117                 :     }
     118                 : 
     119                 : /* -------------------------------------------------------------------- */
     120                 : /*      If this is an object, we extract the type of the object.        */
     121                 : /* -------------------------------------------------------------------- */
     122           52249 :     if( chItemType == 'o' )
     123                 :     {
     124            6285 :         for( i = 0; pszInput[i] != '\0' && pszInput[i] != ','; i++ ) {}
     125                 : 
     126            6285 :         pszItemObjectType = (char *) CPLMalloc(i+1);
     127            6285 :         strncpy( pszItemObjectType, pszInput, i );
     128            6285 :         pszItemObjectType[i] = '\0';
     129                 : 
     130            6285 :         pszInput += i+1;
     131                 :     }
     132                 : 
     133                 : /* -------------------------------------------------------------------- */
     134                 : /*      If this is an inline object, we need to skip past the           */
     135                 : /*      definition, and then extract the object class name.             */
     136                 : /*                                                                      */
     137                 : /*      We ignore the actual definition, so if the object type isn't    */
     138                 : /*      already defined, things will not work properly.  See the        */
     139                 : /*      file lceugr250_00_pct.aux for an example of inline defs.        */
     140                 : /* -------------------------------------------------------------------- */
     141           52249 :     if( chItemType == 'x' && *pszInput == '{' )
     142                 :     {
     143            1442 :         int nBraceDepth = 1;
     144            1442 :         pszInput++;
     145                 : 
     146                 :         // Skip past the definition.
     147           48418 :         while( nBraceDepth > 0 && *pszInput != '\0' )
     148                 :         {
     149           45534 :             if( *pszInput == '{' )
     150             720 :                 nBraceDepth++;
     151           44814 :             else if( *pszInput == '}' )
     152            2162 :                 nBraceDepth--;
     153                 :             
     154           45534 :             pszInput++;
     155                 :         }
     156                 : 
     157            1442 :         chItemType = 'o';
     158                 : 
     159                 :         // find the comma terminating the type name.
     160            1442 :         for( i = 0; pszInput[i] != '\0' && pszInput[i] != ','; i++ ) {}
     161                 : 
     162            1442 :         pszItemObjectType = (char *) CPLMalloc(i+1);
     163            1442 :         strncpy( pszItemObjectType, pszInput, i );
     164            1442 :         pszItemObjectType[i] = '\0';
     165                 : 
     166            1442 :         pszInput += i+1;
     167                 :     }
     168                 : 
     169                 : /* -------------------------------------------------------------------- */
     170                 : /*      If this is an enumeration we have to extract all the            */
     171                 : /*      enumeration values.                                             */
     172                 : /* -------------------------------------------------------------------- */
     173           52249 :     if( chItemType == 'e' )
     174                 :     {
     175            7030 :         int nEnumCount = atoi(pszInput);
     176                 :         int iEnum;
     177                 : 
     178            7030 :         pszInput = strchr(pszInput,':');
     179            7030 :         if( pszInput == NULL )
     180               0 :             return NULL;
     181                 : 
     182            7030 :         pszInput++;
     183                 : 
     184            7030 :         papszEnumNames = (char **) CPLCalloc(sizeof(char *), nEnumCount+1);
     185                 :         
     186           39193 :         for( iEnum = 0; iEnum < nEnumCount; iEnum++ )
     187                 :         {
     188                 :             char  *pszToken;
     189                 :             
     190           32163 :             for( i = 0; pszInput[i] != '\0' && pszInput[i] != ','; i++ ) {}
     191                 : 
     192           32163 :             if( pszInput[i] != ',' )
     193               0 :                 return NULL;
     194                 : 
     195           32163 :             pszToken = (char *) CPLMalloc(i+1);
     196           32163 :             strncpy( pszToken, pszInput, i );
     197           32163 :             pszToken[i] = '\0';
     198                 : 
     199           32163 :             papszEnumNames[iEnum] = pszToken;
     200                 : 
     201           32163 :             pszInput += i+1;
     202                 :         }
     203                 :     }
     204                 : 
     205                 : /* -------------------------------------------------------------------- */
     206                 : /*      Extract the field name.                                         */
     207                 : /* -------------------------------------------------------------------- */
     208           52249 :     for( i = 0; pszInput[i] != '\0' && pszInput[i] != ','; i++ ) {}
     209                 : 
     210           52249 :     pszFieldName = (char *) CPLMalloc(i+1);
     211           52249 :     strncpy( pszFieldName, pszInput, i );
     212           52249 :     pszFieldName[i] = '\0';
     213                 : 
     214           52249 :     pszInput += i+1;
     215                 :     
     216           52249 :     return( pszInput );
     217                 : }
     218                 : 
     219                 : /************************************************************************/
     220                 : /*                            CompleteDefn()                            */
     221                 : /*                                                                      */
     222                 : /*      Establish size, and pointers to component types.                */
     223                 : /************************************************************************/
     224                 : 
     225           52249 : void HFAField::CompleteDefn( HFADictionary * poDict )
     226                 : 
     227                 : {
     228                 : /* -------------------------------------------------------------------- */
     229                 : /*      Get a reference to the type object if we have a type name       */
     230                 : /*      for this field (not a built in).                                */
     231                 : /* -------------------------------------------------------------------- */
     232           52249 :     if( pszItemObjectType != NULL )
     233            7727 :         poItemObjectType = poDict->FindType( pszItemObjectType );
     234                 : 
     235                 : /* -------------------------------------------------------------------- */
     236                 : /*      Figure out the size.                                            */
     237                 : /* -------------------------------------------------------------------- */
     238           52249 :     if( chPointer == 'p' )
     239                 :     {
     240            8296 :         nBytes = -1; /* we can't know the instance size */
     241                 :     }
     242           43953 :     else if( poItemObjectType != NULL )
     243                 :     {
     244            5882 :         poItemObjectType->CompleteDefn( poDict );
     245            5882 :         if( poItemObjectType->nBytes == -1 )
     246            4784 :             nBytes = -1;
     247                 :         else
     248            1098 :             nBytes = poItemObjectType->nBytes * nItemCount;
     249                 : 
     250            5882 :         if( chPointer == '*' && nBytes != -1 )
     251            1098 :             nBytes += 8; /* count, and offset */
     252                 :     }
     253                 :     else
     254                 :     {
     255           38071 :         nBytes = poDict->GetItemSize( chItemType ) * nItemCount;
     256                 :     }
     257           52249 : }
     258                 : 
     259                 : /************************************************************************/
     260                 : /*                                Dump()                                */
     261                 : /************************************************************************/
     262                 : 
     263               0 : void HFAField::Dump( FILE * fp )
     264                 : 
     265                 : {
     266                 :     const char  *pszTypeName;
     267                 :     
     268               0 :     switch( chItemType )
     269                 :     {
     270                 :       case '1':
     271               0 :         pszTypeName = "U1";
     272               0 :         break;
     273                 :         
     274                 :       case '2':
     275               0 :         pszTypeName = "U2";
     276               0 :         break;
     277                 :         
     278                 :       case '4':
     279               0 :         pszTypeName = "U4";
     280               0 :         break;
     281                 :         
     282                 :       case 'c':
     283               0 :         pszTypeName = "UCHAR";
     284               0 :         break;
     285                 :         
     286                 :       case 'C':
     287               0 :         pszTypeName = "CHAR";
     288               0 :         break;
     289                 : 
     290                 :       case 'e':
     291               0 :         pszTypeName = "ENUM";
     292               0 :         break;
     293                 :         
     294                 :       case 's':
     295               0 :         pszTypeName = "USHORT";
     296               0 :         break;
     297                 :         
     298                 :       case 'S':
     299               0 :         pszTypeName = "SHORT";
     300               0 :         break;
     301                 :         
     302                 :       case 't':
     303               0 :         pszTypeName = "TIME";
     304               0 :         break;
     305                 :         
     306                 :       case 'l':
     307               0 :         pszTypeName = "ULONG";
     308               0 :         break;
     309                 :         
     310                 :       case 'L':
     311               0 :         pszTypeName = "LONG";
     312               0 :         break;
     313                 :         
     314                 :       case 'f':
     315               0 :         pszTypeName = "FLOAT";
     316               0 :         break;
     317                 :         
     318                 :       case 'd':
     319               0 :         pszTypeName = "DOUBLE";
     320               0 :         break;
     321                 :         
     322                 :       case 'm':
     323               0 :         pszTypeName = "COMPLEX";
     324               0 :         break;
     325                 :         
     326                 :       case 'M':
     327               0 :         pszTypeName = "DCOMPLEX";
     328               0 :         break;
     329                 :         
     330                 :       case 'b':
     331               0 :         pszTypeName = "BASEDATA";
     332               0 :         break;
     333                 :         
     334                 :       case 'o':
     335               0 :         pszTypeName = pszItemObjectType;
     336               0 :         break;
     337                 : 
     338                 :       case 'x':
     339               0 :         pszTypeName = "InlineType";
     340               0 :         break;
     341                 : 
     342                 :       default:
     343                 :         CPLAssert( FALSE );
     344               0 :         pszTypeName = "Unknown";
     345                 :     }
     346                 :     
     347                 :     VSIFPrintf( fp, "    %-19s %c %s[%d];\n",
     348                 :                 pszTypeName,
     349                 :                 chPointer ? chPointer : ' ',
     350               0 :                 pszFieldName, nItemCount );
     351                 : 
     352               0 :     if( papszEnumNames != NULL )
     353                 :     {
     354                 :         int i;
     355                 :         
     356               0 :         for( i = 0; papszEnumNames[i] != NULL; i++ )
     357                 :         {
     358                 :             VSIFPrintf( fp, "        %s=%d\n",
     359               0 :                         papszEnumNames[i], i );
     360                 :         }
     361                 :     }
     362               0 : }
     363                 : 
     364                 : /************************************************************************/
     365                 : /*                            SetInstValue()                            */
     366                 : /************************************************************************/
     367                 : 
     368                 : CPLErr
     369            5578 : HFAField::SetInstValue( const char * pszField, int nIndexValue,
     370                 :                         GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
     371                 :                         char chReqType, void *pValue )
     372                 : 
     373                 : {
     374                 : /* -------------------------------------------------------------------- */
     375                 : /*  If this field contains a pointer, then we will adjust the */
     376                 : /*  data offset relative to it.             */
     377                 : /* -------------------------------------------------------------------- */
     378            5578 :     if( chPointer != '\0' )
     379                 :     {
     380                 :         GUInt32   nCount;
     381                 :         GUInt32   nOffset;
     382                 : 
     383                 :          /* set the count for fixed sized arrays */
     384            2167 :         if( nBytes > -1 )
     385             336 :             nCount = nItemCount;
     386                 : 
     387                 :         // The count returned for BASEDATA's are the contents, 
     388                 :         // but here we really want to mark it as one BASEDATA instance
     389                 :         // (see #2144)
     390            2167 :         if( chItemType == 'b' ) 
     391              28 :             nCount = 1;
     392                 : 
     393                 :         /* Set the size from string length */
     394            2630 :         else if( chReqType == 's' && (chItemType == 'c' || chItemType == 'C'))
     395                 :         {
     396             491 :             if( pValue == NULL )
     397              67 :                 nCount = 0;
     398                 :             else
     399             424 :                 nCount = strlen((char *) pValue) + 1;
     400                 :         }
     401                 : 
     402                 :         /* set size based on index ... assumes in-order setting of array */
     403                 :         else
     404            1648 :             nCount = nIndexValue+1;
     405                 : 
     406            2167 :         if( (int) nCount + 8 > nDataSize )
     407                 :         {
     408                 :             CPLError( CE_Failure, CPLE_AppDefined,
     409                 :                       "Attempt to extend field %s in node past end of data,\n"
     410                 :                       "not currently supported.",
     411               0 :                       pszField );
     412               0 :             return CE_Failure;
     413                 :         }
     414                 : 
     415                 :         // we will update the object count iff we are writing beyond the end
     416            2167 :         memcpy( &nOffset, pabyData, 4 );
     417                 :         HFAStandard( 4, &nOffset );
     418            2167 :         if( nOffset < nCount )
     419                 :         {
     420            1601 :             nOffset = nCount;
     421                 :             HFAStandard( 4, &nOffset );
     422            1601 :             memcpy( pabyData, &nOffset, 4 );
     423                 :         }
     424                 : 
     425            2167 :         if( pValue == NULL )
     426              67 :             nOffset = 0;
     427                 :         else
     428            2100 :             nOffset = nDataOffset + 8;
     429                 :         HFAStandard( 4, &nOffset );
     430            2167 :         memcpy( pabyData+4, &nOffset, 4 );
     431                 : 
     432            2167 :         pabyData += 8;
     433                 : 
     434            2167 :         nDataOffset += 8;
     435            2167 :         nDataSize -= 8;
     436                 :     }
     437                 : 
     438                 : /* -------------------------------------------------------------------- */
     439                 : /*      pointers to char or uchar arrays requested as strings are       */
     440                 : /*      handled as a special case.                                      */
     441                 : /* -------------------------------------------------------------------- */
     442            5578 :     if( (chItemType == 'c' || chItemType == 'C') && chReqType == 's' )
     443                 :     {
     444                 :         int nBytesToCopy;
     445                 :         
     446             491 :         if( nBytes == -1 )
     447                 :         {
     448             491 :             if( pValue == NULL )
     449              67 :                 nBytesToCopy = 0;
     450                 :             else
     451             424 :                 nBytesToCopy = strlen((char *) pValue) + 1;
     452                 :         }
     453                 :         else
     454               0 :             nBytesToCopy = nBytes;
     455                 : 
     456             491 :         if( nBytesToCopy > nDataSize )
     457                 :         {
     458                 :             CPLError( CE_Failure, CPLE_AppDefined,
     459                 :                       "Attempt to extend field %s in node past end of data,\n"
     460                 :                       "not currently supported.",
     461               0 :                       pszField );
     462               0 :             return CE_Failure;
     463                 :         }
     464                 : 
     465             491 :         memset( pabyData, 0, nBytesToCopy );
     466                 : 
     467             491 :         if( pValue != NULL )
     468             424 :             strncpy( (char *) pabyData, (char *) pValue, nBytesToCopy );
     469                 : 
     470             491 :         return CE_None;
     471                 :     }
     472                 : 
     473                 : /* -------------------------------------------------------------------- */
     474                 : /*      Translate the passed type into different representations.       */
     475                 : /* -------------------------------------------------------------------- */
     476                 :     int   nIntValue;
     477                 :     double      dfDoubleValue;
     478                 : 
     479            5087 :     if( chReqType == 's' )
     480                 :     {
     481            1006 :         nIntValue = atoi((char *) pValue);
     482            1006 :         dfDoubleValue = atof((char *) pValue);
     483                 :     }
     484            4081 :     else if( chReqType == 'd' )
     485                 :     {
     486            2086 :         dfDoubleValue = *((double *) pValue);
     487            2086 :         nIntValue = (int) dfDoubleValue;
     488                 :     }
     489            1995 :     else if( chReqType == 'i' )
     490                 :     {
     491            1995 :         dfDoubleValue = *((int *) pValue);
     492            1995 :         nIntValue = *((int *) pValue);
     493                 :     }
     494               0 :     else if( chReqType == 'p' )
     495                 :     {
     496                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     497               0 :             "HFAField::SetInstValue() not supported yet for pointer values." );
     498                 :         
     499               0 :         return CE_Failure;
     500                 :     }
     501                 :     else
     502                 :     {
     503                 :         CPLAssert( FALSE );
     504               0 :         return CE_Failure;
     505                 :     }
     506                 : 
     507                 : /* -------------------------------------------------------------------- */
     508                 : /*      Handle by type.                                                 */
     509                 : /* -------------------------------------------------------------------- */
     510            5087 :     switch( chItemType )
     511                 :     {
     512                 :       case 'c':
     513                 :       case 'C':
     514               0 :         if( nIndexValue + 1 > nDataSize )
     515                 :         {
     516                 :             CPLError( CE_Failure, CPLE_AppDefined,
     517                 :                       "Attempt to extend field %s in node past end of data,\n"
     518                 :                       "not currently supported.",
     519               0 :                       pszField );
     520               0 :               return CE_Failure;
     521                 :         }
     522                 : 
     523               0 :         if( chReqType == 's' )
     524               0 :             pabyData[nIndexValue] = ((char *) pValue)[0];
     525                 :         else
     526               0 :             pabyData[nIndexValue] = (char) nIntValue;
     527               0 :         break;
     528                 : 
     529                 :       case 'e':
     530                 :       case 's':
     531                 :       {
     532             840 :           if( chItemType == 'e' && chReqType == 's' )
     533                 :           {
     534             600 :               nIntValue = CSLFindString( papszEnumNames, (char *) pValue );
     535             600 :               if( nIntValue == -1 )
     536                 :               {
     537                 :                   CPLError( CE_Failure, CPLE_AppDefined, 
     538                 :                             "Attempt to set enumerated field with unknown"
     539                 :                             " value `%s'.", 
     540               0 :                             (char *) pValue );
     541               0 :                   return CE_Failure;
     542                 :               }
     543                 :           }
     544                 : 
     545             840 :           unsigned short nNumber = (unsigned short) nIntValue;
     546                 : 
     547             840 :           if( nIndexValue*2 + 2 > nDataSize )
     548                 :           {
     549                 :               CPLError( CE_Failure, CPLE_AppDefined,
     550                 :                         "Attempt to extend field %s in node past end of data,\n"
     551                 :                         "not currently supported.",
     552               0 :                         pszField );
     553               0 :               return CE_Failure;
     554                 :           }
     555                 : 
     556                 :           HFAStandard( 2, &nNumber );
     557             840 :           memcpy( pabyData + nIndexValue*2, &nNumber, 2 );
     558                 :       }
     559             840 :       break;
     560                 : 
     561                 :       case 'S':
     562                 :       {
     563                 :           short nNumber;
     564                 : 
     565               0 :           if( nIndexValue*2 + 2 > nDataSize )
     566                 :           {
     567                 :               CPLError( CE_Failure, CPLE_AppDefined,
     568                 :                         "Attempt to extend field %s in node past end of data,\n"
     569                 :                         "not currently supported.",
     570               0 :                         pszField );
     571               0 :               return CE_Failure;
     572                 :           }
     573                 : 
     574               0 :           nNumber = (short) nIntValue;
     575                 :           HFAStandard( 2, &nNumber );
     576               0 :           memcpy( pabyData + nIndexValue*2, &nNumber, 2 );
     577                 :       }
     578               0 :       break;
     579                 :         
     580                 :       case 't':
     581                 :       case 'l':
     582                 :       {
     583            1324 :           GUInt32 nNumber = nIntValue;
     584                 : 
     585            1324 :           if( nIndexValue*4 + 4 > nDataSize )
     586                 :           {
     587                 :               CPLError( CE_Failure, CPLE_AppDefined,
     588                 :                         "Attempt to extend field %s in node past end of data,\n"
     589                 :                         "not currently supported.",
     590               0 :                         pszField );
     591               0 :               return CE_Failure;
     592                 :           }
     593                 : 
     594                 :           HFAStandard( 4, &nNumber );
     595            1324 :           memcpy( pabyData + nIndexValue*4, &nNumber, 4 );
     596                 :       }
     597            1324 :       break;
     598                 :       
     599                 :       case 'L':
     600                 :       {
     601             385 :           GInt32  nNumber = nIntValue;
     602                 :           
     603             385 :           if( nIndexValue*4 + 4 > nDataSize )
     604                 :           {
     605                 :               CPLError( CE_Failure, CPLE_AppDefined,
     606                 :                         "Attempt to extend field %s in node past end of data,\n"
     607                 :                         "not currently supported.",
     608               0 :                         pszField );
     609               0 :               return CE_Failure;
     610                 :           }
     611                 : 
     612                 :           HFAStandard( 4, &nNumber );
     613             385 :           memcpy( pabyData + nIndexValue*4, &nNumber, 4 );
     614                 :       }
     615             385 :       break;
     616                 :       
     617                 :       case 'f':
     618                 :       {
     619               0 :           float   fNumber = (float) dfDoubleValue;
     620                 :           
     621               0 :           if( nIndexValue*4 + 4 > nDataSize )
     622                 :           {
     623                 :               CPLError( CE_Failure, CPLE_AppDefined,
     624                 :                         "Attempt to extend field %s in node past end of data,\n"
     625                 :                         "not currently supported.",
     626               0 :                         pszField );
     627               0 :               return CE_Failure;
     628                 :           }
     629                 : 
     630                 :           HFAStandard( 4, &fNumber );
     631               0 :           memcpy( pabyData + nIndexValue*4, &fNumber, 4 );
     632                 :       }
     633               0 :       break;
     634                 :         
     635                 :       case 'd':
     636                 :       {
     637            1564 :           double  dfNumber = dfDoubleValue;
     638                 :           
     639            1564 :           if( nIndexValue*8 + 8 > nDataSize )
     640                 :           {
     641                 :               CPLError( CE_Failure, CPLE_AppDefined,
     642                 :                         "Attempt to extend field %s in node past end of data,\n"
     643                 :                         "not currently supported.",
     644               0 :                         pszField );
     645               0 :               return CE_Failure;
     646                 :           }
     647                 : 
     648                 :           HFAStandard( 8, &dfNumber );
     649            1564 :           memcpy( pabyData + nIndexValue*8, &dfNumber, 8 );
     650                 :       }
     651            1564 :       break;
     652                 : 
     653                 :     case 'b': 
     654                 :     { 
     655              28 :         GInt32 nRows = 1; 
     656              28 :         GInt32 nColumns = 1; 
     657                 :         GInt16 nBaseItemType;
     658                 : 
     659                 :         // Extract existing rows, columns, and datatype.
     660              28 :         memcpy( &nRows, pabyData, 4 );
     661                 :         HFAStandard( 4, &nRows );
     662              28 :         memcpy( &nColumns, pabyData+4, 4 );
     663                 :         HFAStandard( 4, &nColumns );
     664              28 :         memcpy( &nBaseItemType, pabyData+8, 2 );
     665                 :         HFAStandard( 2, &nBaseItemType );
     666                 : 
     667                 :         // Are we using special index values to update the rows, columnrs
     668                 :         // or type?
     669                 :         
     670              28 :         if( nIndexValue == -3 )
     671               6 :             nBaseItemType = nIntValue;
     672              22 :         else if( nIndexValue == -2 )
     673               6 :             nColumns = nIntValue;
     674              16 :         else if( nIndexValue == -1 )
     675               6 :             nRows = nIntValue;
     676                 : 
     677              28 :         if( nIndexValue < -3 || nIndexValue >= nRows * nColumns ) 
     678               0 :             return CE_Failure; 
     679                 : 
     680                 :         // Write back the rows, columns and basedatatype.
     681                 :         HFAStandard( 4, &nRows ); 
     682              28 :         memcpy( pabyData, &nRows, 4 ); 
     683                 :         HFAStandard( 4, &nColumns ); 
     684              28 :         memcpy( pabyData+4, &nColumns, 4 ); 
     685                 :         HFAStandard( 2, &nBaseItemType ); 
     686              28 :         memcpy ( pabyData + 8, &nBaseItemType, 2 ); 
     687                 :         HFAStandard( 2, &nBaseItemType ); // swap back for our use.
     688                 : 
     689                 :         // We ignore the 2 byte objecttype value.  
     690                 : 
     691              28 :         nDataSize -= 12; 
     692                 : 
     693              28 :         if( nIndexValue >= 0 )
     694                 :         { 
     695              10 :             if( (nIndexValue+1) * (HFAGetDataTypeBits(nBaseItemType)/8)
     696                 :                 > nDataSize ) 
     697                 :             { 
     698                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     699                 :                           "Attempt to extend field %s in node past end of data,\n" 
     700                 :                           "not currently supported.", 
     701               0 :                           pszField ); 
     702               0 :                 return CE_Failure; 
     703                 :             } 
     704                 : 
     705              10 :             if( nBaseItemType == EPT_f64 )
     706                 :             {
     707              10 :                 double dfNumber = dfDoubleValue; 
     708                 : 
     709                 :                 HFAStandard( 8, &dfNumber ); 
     710              10 :                 memcpy( pabyData + 12 + nIndexValue * 8, &dfNumber, 8 ); 
     711                 :             }
     712                 :             else
     713                 :             {
     714                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     715                 :                           "Setting basedata field %s with type %s not currently supported.", 
     716               0 :                           pszField, HFAGetDataTypeName( nBaseItemType ) ); 
     717               0 :                 return CE_Failure; 
     718                 :             }
     719                 :         } 
     720                 :     } 
     721              28 :     break;               
     722                 : 
     723                 :       case 'o':
     724             946 :         if( poItemObjectType != NULL )
     725                 :         {
     726             946 :             int   nExtraOffset = 0;
     727                 :             int   iIndexCounter;
     728                 : 
     729             946 :             if( poItemObjectType->nBytes > 0 )
     730                 :             {
     731             466 :                 nExtraOffset = poItemObjectType->nBytes * nIndexValue;
     732                 :             }
     733                 :             else
     734                 :             {
     735             485 :                 for( iIndexCounter = 0;
     736                 :                      iIndexCounter < nIndexValue && nExtraOffset < nDataSize;
     737                 :                      iIndexCounter++ )
     738                 :                 {
     739                 :                     int nInc = poItemObjectType->GetInstBytes(pabyData + nExtraOffset,
     740               5 :                                                               nDataSize - nExtraOffset);
     741               5 :                     if (nInc < 0 || nExtraOffset > INT_MAX - nInc)
     742                 :                     {
     743               0 :                         CPLError(CE_Failure, CPLE_AppDefined, "Invalid return value");
     744               0 :                         return CE_Failure;
     745                 :                     }
     746                 : 
     747               5 :                     nExtraOffset += nInc;
     748                 :                 }
     749                 :             }
     750                 : 
     751             946 :             if( pszField != NULL && strlen(pszField) > 0 )
     752                 :             {
     753                 :                 return( poItemObjectType->
     754                 :                             SetInstValue( pszField, pabyData + nExtraOffset,
     755                 :                                           nDataOffset + nExtraOffset,
     756                 :                                           nDataSize - nExtraOffset,
     757             946 :                                           chReqType, pValue ) );
     758                 :             }
     759                 :             else
     760                 :             {
     761                 :                 CPLAssert( FALSE );
     762               0 :                 return CE_Failure;
     763                 :             }
     764                 :         }
     765               0 :         break;
     766                 : 
     767                 :       default:
     768                 :         CPLAssert( FALSE );
     769               0 :         return CE_Failure;
     770                 :         break;
     771                 :     }
     772                 : 
     773            4141 :     return CE_None;
     774                 : }
     775                 : 
     776                 : /************************************************************************/
     777                 : /*                          ExtractInstValue()                          */
     778                 : /*                                                                      */
     779                 : /*      Extract the value of an instance of a field.                    */
     780                 : /*                                                                      */
     781                 : /*      pszField should be NULL if this field is not a                  */
     782                 : /*      substructure.                                                   */
     783                 : /************************************************************************/
     784                 : 
     785                 : int
     786           12767 : HFAField::ExtractInstValue( const char * pszField, int nIndexValue,
     787                 :                            GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
     788                 :                            char chReqType, void *pReqReturn )
     789                 : 
     790                 : {
     791           12767 :     char    *pszStringRet = NULL;
     792           12767 :     int     nIntRet = 0;
     793           12767 :     double    dfDoubleRet = 0.0;
     794           12767 :     int     nInstItemCount = GetInstCount( pabyData, nDataSize );
     795           12767 :     GByte   *pabyRawData = NULL;
     796                 : 
     797                 : /* -------------------------------------------------------------------- */
     798                 : /*      Check the index value is valid.                                 */
     799                 : /*                                                                      */
     800                 : /*      Eventually this will have to account for variable fields.       */
     801                 : /* -------------------------------------------------------------------- */
     802           12767 :     if( nIndexValue < 0 || nIndexValue >= nInstItemCount )
     803                 :     {
     804             148 :         if( chItemType == 'b' && nIndexValue >= -3 && nIndexValue < 0 )
     805                 :             /* ok - special index values */;
     806                 :         else
     807             148 :             return FALSE;
     808                 :     }
     809                 : 
     810                 : /* -------------------------------------------------------------------- */
     811                 : /*  If this field contains a pointer, then we will adjust the */
     812                 : /*  data offset relative to it.             */
     813                 : /* -------------------------------------------------------------------- */
     814           12619 :     if( chPointer != '\0' )
     815                 :     {
     816                 :         GUInt32   nOffset;
     817                 : 
     818            3325 :         if (nDataSize < 8)
     819                 :         {
     820               0 :             CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
     821               0 :             return FALSE;
     822                 :         }
     823                 : 
     824            3325 :         memcpy( &nOffset, pabyData+4, 4 );
     825                 :         HFAStandard( 4, &nOffset );
     826                 : 
     827            3325 :         if( nOffset != (GUInt32) (nDataOffset + 8) )
     828                 :         {
     829                 : #ifdef notdef            
     830                 :             CPLError( CE_Warning, CPLE_AppDefined,
     831                 :                       "%s.%s points at %d, not %d as expected\n",
     832                 :                       pszFieldName, pszField ? pszField : "",
     833                 :                       nOffset, nDataOffset+8 );
     834                 : #endif            
     835                 :         }
     836                 :         
     837            3325 :         pabyData += 8;
     838                 : 
     839            3325 :         nDataOffset += 8;
     840            3325 :         nDataSize -= 8;
     841                 :     }
     842                 : 
     843                 : /* -------------------------------------------------------------------- */
     844                 : /*      pointers to char or uchar arrays requested as strings are       */
     845                 : /*      handled as a special case.                                      */
     846                 : /* -------------------------------------------------------------------- */
     847           12619 :     if( (chItemType == 'c' || chItemType == 'C') && chReqType == 's' )
     848                 :     {
     849             494 :         *((GByte **)pReqReturn) = pabyData;
     850             494 :         return( pabyData != NULL );
     851                 :     }
     852                 : 
     853                 : /* -------------------------------------------------------------------- */
     854                 : /*      Handle by type.                                                 */
     855                 : /* -------------------------------------------------------------------- */
     856           12125 :     switch( chItemType )
     857                 :     {
     858                 :       case 'c':
     859                 :       case 'C':
     860               0 :         if (nIndexValue >= nDataSize)
     861                 :         {
     862               0 :             CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
     863               0 :             return FALSE;
     864                 :         }
     865               0 :         nIntRet = pabyData[nIndexValue];
     866               0 :         dfDoubleRet = nIntRet;
     867               0 :         break;
     868                 : 
     869                 :       case 'e':
     870                 :       case 's':
     871                 :       {
     872                 :           unsigned short nNumber;
     873            2188 :           if (nIndexValue*2 + 2 > nDataSize)
     874                 :           {
     875               0 :               CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
     876               0 :               return FALSE;
     877                 :           }
     878            2188 :           memcpy( &nNumber, pabyData + nIndexValue*2, 2 );
     879                 :           HFAStandard( 2, &nNumber );
     880            2188 :           nIntRet = nNumber;
     881            2188 :           dfDoubleRet = nIntRet;
     882                 : 
     883            2188 :           if( chItemType == 'e'
     884                 :               && nIntRet >= 0 && nIntRet < CSLCount(papszEnumNames) )
     885                 :           {
     886            2187 :               pszStringRet = papszEnumNames[nIntRet];
     887                 :           }
     888                 :       }
     889            2188 :       break;
     890                 : 
     891                 :       case 'S':
     892                 :       {
     893                 :           short nNumber;
     894               0 :           if (nIndexValue*2 + 2 > nDataSize)
     895                 :           {
     896               0 :               CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
     897               0 :               return FALSE;
     898                 :           }
     899               0 :           memcpy( &nNumber, pabyData + nIndexValue*2, 2 );
     900                 :           HFAStandard( 2, &nNumber );
     901               0 :           nIntRet = nNumber;
     902               0 :           dfDoubleRet = nIntRet;
     903                 :       }
     904               0 :       break;
     905                 :         
     906                 :       case 't':
     907                 :       case 'l':
     908                 :       {
     909                 :           GUInt32 nNumber;
     910            5189 :           if (nIndexValue*4 + 4 > nDataSize)
     911                 :           {
     912               0 :               CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
     913               0 :               return FALSE;
     914                 :           }
     915            5189 :           memcpy( &nNumber, pabyData + nIndexValue*4, 4 );
     916                 :           HFAStandard( 4, &nNumber );
     917            5189 :           nIntRet = nNumber;
     918            5189 :           dfDoubleRet = nIntRet;
     919                 :       }
     920            5189 :       break;
     921                 :       
     922                 :       case 'L':
     923                 :       {
     924                 :           GInt32  nNumber;
     925             636 :           if (nIndexValue*4 + 4 > nDataSize)
     926                 :           {
     927               0 :               CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
     928               0 :               return FALSE;
     929                 :           }
     930             636 :           memcpy( &nNumber, pabyData + nIndexValue*4, 4 );
     931                 :           HFAStandard( 4, &nNumber );
     932             636 :           nIntRet = nNumber;
     933             636 :           dfDoubleRet = nIntRet;
     934                 :       }
     935             636 :       break;
     936                 :       
     937                 :       case 'f':
     938                 :       {
     939                 :           float   fNumber;
     940               0 :           if (nIndexValue*4 + 4 > nDataSize)
     941                 :           {
     942               0 :               CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
     943               0 :               return FALSE;
     944                 :           }
     945               0 :           memcpy( &fNumber, pabyData + nIndexValue*4, 4 );
     946                 :           HFAStandard( 4, &fNumber );
     947               0 :           dfDoubleRet = fNumber;
     948               0 :           nIntRet = (int) fNumber;
     949                 :       }
     950               0 :       break;
     951                 :         
     952                 :       case 'd':
     953                 :       {
     954                 :           double  dfNumber;
     955            1596 :           if (nIndexValue*8 + 8 > nDataSize)
     956                 :           {
     957               0 :               CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
     958               0 :               return FALSE;
     959                 :           }
     960            1596 :           memcpy( &dfNumber, pabyData + nIndexValue*8, 8 );
     961                 :           HFAStandard( 8, &dfNumber );
     962            1596 :           dfDoubleRet = dfNumber;
     963            1596 :           nIntRet = (int) dfNumber;
     964                 :       }
     965            1596 :       break;
     966                 : 
     967                 :       case 'b':
     968                 :       {
     969                 :           GInt32 nRows, nColumns;
     970                 :           GInt16 nBaseItemType;
     971                 : 
     972             105 :           if( nDataSize < 12 )
     973               0 :               return FALSE;
     974                 :         
     975             105 :           memcpy( &nRows, pabyData, 4 );
     976                 :           HFAStandard( 4, &nRows );
     977             105 :           memcpy( &nColumns, pabyData+4, 4 );
     978                 :           HFAStandard( 4, &nColumns );
     979             105 :           memcpy( &nBaseItemType, pabyData+8, 2 );
     980                 :           HFAStandard( 2, &nBaseItemType );
     981                 :           // We ignore the 2 byte objecttype value. 
     982                 : 
     983             105 :           if( nIndexValue < -3 || nIndexValue >= nRows * nColumns )
     984               0 :               return FALSE;
     985                 : 
     986             105 :           pabyData += 12;
     987             105 :           nDataSize -= 12;
     988                 : 
     989             105 :           if( nIndexValue == -3 ) 
     990                 :           {
     991               0 :               dfDoubleRet = nIntRet = nBaseItemType;
     992                 :           }
     993             105 :           else if( nIndexValue == -2 )
     994                 :           {
     995               0 :               dfDoubleRet = nIntRet = nColumns;
     996                 :           }
     997             105 :           else if( nIndexValue == -1 )
     998                 :           {
     999               0 :               dfDoubleRet = nIntRet = nRows;
    1000                 :           }
    1001             105 :           else if( nBaseItemType == EPT_u8 )
    1002                 :           {
    1003               6 :               if (nIndexValue >= nDataSize)
    1004                 :               {
    1005               0 :                   CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
    1006               0 :                   return FALSE;
    1007                 :               }
    1008               6 :               dfDoubleRet = pabyData[nIndexValue];
    1009               6 :               nIntRet = pabyData[nIndexValue];
    1010                 :           }
    1011              99 :           else if( nBaseItemType == EPT_s16 )
    1012                 :           {
    1013                 :               GInt16  nValue;
    1014               0 :               if (nIndexValue*2 + 2 > nDataSize)
    1015                 :               {
    1016               0 :                   CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
    1017               0 :                   return FALSE;
    1018                 :               }
    1019               0 :               memcpy( &nValue, pabyData + 2*nIndexValue, 2 );
    1020                 :               HFAStandard( 2, &nValue );
    1021                 : 
    1022               0 :               dfDoubleRet = nValue;
    1023               0 :               nIntRet = nValue;
    1024                 :           }
    1025              99 :           else if( nBaseItemType == EPT_u16 )
    1026                 :           {
    1027                 :               GUInt16  nValue;
    1028               0 :               if (nIndexValue*2 + 2 > nDataSize)
    1029                 :               {
    1030               0 :                   CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
    1031               0 :                   return FALSE;
    1032                 :               }
    1033               0 :               memcpy( &nValue, pabyData + 2*nIndexValue, 2 );
    1034                 :               HFAStandard( 2, &nValue );
    1035                 : 
    1036               0 :               dfDoubleRet = nValue;
    1037               0 :               nIntRet = nValue;
    1038                 :           }
    1039              99 :           else if( nBaseItemType == EPT_s32 )
    1040                 :           {
    1041                 :               GInt32  nValue;
    1042               0 :               if (nIndexValue*4 + 4 > nDataSize)
    1043                 :               {
    1044               0 :                   CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
    1045               0 :                   return FALSE;
    1046                 :               }
    1047               0 :               memcpy( &nValue, pabyData + 4*nIndexValue, 4 );
    1048                 :               HFAStandard( 4, &nValue );
    1049                 : 
    1050               0 :               dfDoubleRet = nValue;
    1051               0 :               nIntRet = nValue;
    1052                 :           }
    1053              99 :           else if( nBaseItemType == EPT_u32 )
    1054                 :           {
    1055                 :               GUInt32  nValue;
    1056               0 :               if (nIndexValue*4 + 4 > nDataSize)
    1057                 :               {
    1058               0 :                   CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
    1059               0 :                   return FALSE;
    1060                 :               }
    1061               0 :               memcpy( &nValue, pabyData + 4*nIndexValue, 4 );
    1062                 :               HFAStandard( 4, &nValue );
    1063                 : 
    1064               0 :               dfDoubleRet = nValue;
    1065               0 :               nIntRet = nValue;
    1066                 :           }
    1067              99 :           else if( nBaseItemType == EPT_f32 )
    1068                 :           {
    1069                 :               float fValue;
    1070               0 :               if (nIndexValue*4 + 4 > nDataSize)
    1071                 :               {
    1072               0 :                   CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
    1073               0 :                   return FALSE;
    1074                 :               }
    1075               0 :               memcpy( &fValue, pabyData + 4*nIndexValue, 4 );
    1076                 :               HFAStandard( 4, &fValue );
    1077                 : 
    1078               0 :               dfDoubleRet = fValue;
    1079               0 :               nIntRet = (int) fValue;
    1080                 :           }
    1081              99 :           else if( nBaseItemType == EPT_f64 )
    1082                 :           {
    1083                 :               double dfValue;
    1084              99 :               if (nIndexValue*8 + 8 > nDataSize)
    1085                 :               {
    1086               0 :                   CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
    1087               0 :                   return FALSE;
    1088                 :               }
    1089              99 :               memcpy( &dfValue, pabyData+8*nIndexValue, 8 );
    1090                 :               HFAStandard( 8, &dfValue );
    1091                 : 
    1092              99 :               dfDoubleRet = dfValue;
    1093              99 :               nIntRet = (int) dfValue;
    1094                 :           }
    1095                 :           else
    1096                 :           {
    1097               0 :               CPLError(CE_Failure, CPLE_AppDefined, "Unknown base item type : %d", nBaseItemType);
    1098               0 :               return FALSE;
    1099                 :           }
    1100                 :       }
    1101             105 :       break;
    1102                 : 
    1103                 :       case 'o':
    1104            2411 :         if( poItemObjectType != NULL )
    1105                 :         {
    1106            2411 :             int   nExtraOffset = 0;
    1107                 :             int   iIndexCounter;
    1108                 : 
    1109            2411 :             if( poItemObjectType->nBytes > 0 )
    1110                 :             {
    1111            1828 :                 nExtraOffset = poItemObjectType->nBytes * nIndexValue;
    1112                 :             }
    1113                 :             else
    1114                 :             {
    1115             587 :                 for( iIndexCounter = 0;
    1116                 :                      iIndexCounter < nIndexValue && nExtraOffset < nDataSize;
    1117                 :                      iIndexCounter++ )
    1118                 :                 {
    1119                 :                     int nInc = poItemObjectType->GetInstBytes(pabyData + nExtraOffset,
    1120               4 :                                                               nDataSize - nExtraOffset);
    1121               4 :                     if (nInc < 0 || nExtraOffset > INT_MAX - nInc)
    1122                 :                     {
    1123               0 :                         CPLError(CE_Failure, CPLE_AppDefined, "Invalid return value");
    1124               0 :                         return CE_Failure;
    1125                 :                     }
    1126                 : 
    1127               4 :                     nExtraOffset += nInc;
    1128                 :                 }
    1129                 :             }
    1130                 : 
    1131            2411 :             pabyRawData = pabyData + nExtraOffset;
    1132                 : 
    1133            2411 :             if( pszField != NULL && strlen(pszField) > 0 )
    1134                 :             {
    1135                 :                 return( poItemObjectType->
    1136                 :                         ExtractInstValue( pszField, pabyRawData,
    1137                 :                                           nDataOffset + nExtraOffset,
    1138                 :                                           nDataSize - nExtraOffset,
    1139            2411 :                                           chReqType, pReqReturn ) );
    1140                 :             }
    1141                 :         }
    1142               0 :         break;
    1143                 : 
    1144                 :       default:
    1145               0 :         return FALSE;
    1146                 :         break;
    1147                 :     }
    1148                 : 
    1149                 : /* -------------------------------------------------------------------- */
    1150                 : /*      Return the appropriate representation.                          */
    1151                 : /* -------------------------------------------------------------------- */
    1152            9714 :     if( chReqType == 's' )
    1153                 :     {
    1154             560 :         if( pszStringRet == NULL )
    1155                 :         {
    1156               0 :             sprintf( szNumberString, "%.14g", dfDoubleRet );
    1157               0 :             pszStringRet = szNumberString;
    1158                 :         }
    1159                 :         
    1160             560 :         *((char **) pReqReturn) = pszStringRet;
    1161             560 :         return( TRUE );
    1162                 :     }
    1163            9154 :     else if( chReqType == 'd' )
    1164                 :     {
    1165            1701 :         *((double *)pReqReturn) = dfDoubleRet;
    1166            1701 :         return( TRUE );
    1167                 :     }
    1168            7453 :     else if( chReqType == 'i' )
    1169                 :     {
    1170            7453 :         *((int *) pReqReturn) = nIntRet;
    1171            7453 :         return( TRUE );
    1172                 :     }
    1173               0 :     else if( chReqType == 'p' )
    1174                 :     {
    1175               0 :         *((GByte **) pReqReturn) = pabyRawData;
    1176               0 :         return( TRUE );
    1177                 :     }
    1178                 :     else
    1179                 :     {
    1180                 :         CPLAssert( FALSE );
    1181               0 :         return FALSE;
    1182                 :     }
    1183                 : }
    1184                 : 
    1185                 : /************************************************************************/
    1186                 : /*                            GetInstBytes()                            */
    1187                 : /*                                                                      */
    1188                 : /*      Get the number of bytes in a particular instance of a           */
    1189                 : /*      field.  This will normally be the fixed internal nBytes         */
    1190                 : /*      value, but for pointer objects will include the variable        */
    1191                 : /*      portion.                                                        */
    1192                 : /************************************************************************/
    1193                 : 
    1194           43109 : int HFAField::GetInstBytes( GByte *pabyData, int nDataSize )
    1195                 : 
    1196                 : {
    1197                 :     int   nCount;
    1198           43109 :     int   nInstBytes = 0;
    1199                 :     
    1200           43109 :     if( nBytes > -1 )
    1201           34632 :         return nBytes;
    1202                 : 
    1203            8477 :     if( chPointer != '\0' )
    1204                 :     {
    1205            7608 :         if (nDataSize < 4)
    1206                 :         {
    1207               0 :             CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
    1208               0 :             return -1;
    1209                 :         }
    1210                 : 
    1211            7608 :         memcpy( &nCount, pabyData, 4 );
    1212                 :         HFAStandard( 4, &nCount );
    1213                 : 
    1214            7608 :         pabyData += 8;
    1215            7608 :         nInstBytes += 8;
    1216                 :     }
    1217                 :     else
    1218             869 :         nCount = 1;
    1219                 : 
    1220            8764 :     if( chItemType == 'b' && nCount != 0 ) // BASEDATA
    1221                 :     {
    1222             287 :         if (nDataSize < 4+4+2)
    1223                 :         {
    1224               0 :             CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
    1225               0 :             return -1;
    1226                 :         }
    1227                 : 
    1228                 :         GInt32 nRows, nColumns;
    1229                 :         GInt16 nBaseItemType;
    1230                 :         
    1231             287 :         memcpy( &nRows, pabyData, 4 );
    1232                 :         HFAStandard( 4, &nRows );
    1233             287 :         memcpy( &nColumns, pabyData+4, 4 );
    1234                 :         HFAStandard( 4, &nColumns );
    1235             287 :         memcpy( &nBaseItemType, pabyData+8, 2 );
    1236                 :         HFAStandard( 2, &nBaseItemType );
    1237                 : 
    1238             287 :         nInstBytes += 12;
    1239                 : 
    1240                 :         nInstBytes += 
    1241             287 :             ((HFAGetDataTypeBits(nBaseItemType) + 7) / 8) * nRows * nColumns;
    1242                 :     }
    1243            8190 :     else if( poItemObjectType == NULL )
    1244                 :     {
    1245            6910 :         nInstBytes += nCount * HFADictionary::GetItemSize(chItemType);
    1246                 :     }
    1247                 :     else
    1248                 :     {
    1249                 :         int   i;
    1250                 : 
    1251            2173 :         for( i = 0; i < nCount &&
    1252                 :                     nInstBytes < nDataSize &&
    1253                 :                     nInstBytes >= 0; i++ )
    1254                 :         {
    1255                 :             int nThisBytes;
    1256                 : 
    1257                 :             nThisBytes =
    1258                 :                 poItemObjectType->GetInstBytes( pabyData,
    1259             893 :                                                 nDataSize - nInstBytes );
    1260             893 :             if (nThisBytes < 0 || nInstBytes > INT_MAX - nThisBytes)
    1261                 :             {
    1262               0 :                 CPLError(CE_Failure, CPLE_AppDefined, "Invalid return value");
    1263               0 :                 return -1;
    1264                 :             }
    1265                 : 
    1266             893 :             nInstBytes += nThisBytes;
    1267             893 :             pabyData += nThisBytes;
    1268                 :         }
    1269                 :     }
    1270                 : 
    1271            8477 :     return( nInstBytes );
    1272                 : }
    1273                 : 
    1274                 : /************************************************************************/
    1275                 : /*                            GetInstCount()                            */
    1276                 : /*                                                                      */
    1277                 : /*      Get the count for a particular instance of a field.  This       */
    1278                 : /*      will normally be the built in value, but for variable fields    */
    1279                 : /*      this is extracted from the data itself.                         */
    1280                 : /************************************************************************/
    1281                 : 
    1282           13144 : int HFAField::GetInstCount( GByte * pabyData, int nDataSize )
    1283                 : 
    1284                 : {
    1285           13144 :     if( chPointer == '\0' )
    1286            9569 :         return nItemCount;
    1287            3575 :     else if( chItemType == 'b' )
    1288                 :     {
    1289                 :         GInt32 nRows, nColumns;
    1290                 : 
    1291             136 :         if( nDataSize < 20 )
    1292               0 :             return 0;
    1293                 : 
    1294             136 :         memcpy( &nRows, pabyData+8, 4 );
    1295                 :         HFAStandard( 4, &nRows );
    1296             136 :         memcpy( &nColumns, pabyData+12, 4 );
    1297                 :         HFAStandard( 4, &nColumns );
    1298                 : 
    1299             136 :         return nRows * nColumns;
    1300                 :     }
    1301                 :     else
    1302                 :     {
    1303                 :         GInt32 nCount;
    1304                 : 
    1305            3439 :         if( nDataSize < 4 )
    1306               0 :             return 0;
    1307                 : 
    1308            3439 :         memcpy( &nCount, pabyData, 4 );
    1309                 :         HFAStandard( 4, &nCount );
    1310            3439 :         return nCount;
    1311                 :     }
    1312                 : }
    1313                 : 
    1314                 : /************************************************************************/
    1315                 : /*                           DumpInstValue()                            */
    1316                 : /************************************************************************/
    1317                 : 
    1318               0 : void HFAField::DumpInstValue( FILE *fpOut, 
    1319                 :                            GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
    1320                 :                            const char *pszPrefix )
    1321                 : 
    1322                 : {
    1323                 :     int   iEntry, nEntries;
    1324                 :     void  *pReturn;
    1325                 :     char  szLongFieldName[256];
    1326                 : 
    1327               0 :     nEntries = GetInstCount( pabyData, nDataSize );
    1328                 : 
    1329                 : /* -------------------------------------------------------------------- */
    1330                 : /*      Special case for arrays of chars or uchars which are printed    */
    1331                 : /*      as a string.                                                    */
    1332                 : /* -------------------------------------------------------------------- */
    1333               0 :     if( (chItemType == 'c' || chItemType == 'C') && nEntries > 0 )
    1334                 :     {
    1335               0 :         if( ExtractInstValue( NULL, 0,
    1336                 :                               pabyData, nDataOffset, nDataSize,
    1337                 :                               's', &pReturn ) )
    1338                 :             VSIFPrintf( fpOut, "%s%s = `%s'\n",
    1339                 :                         pszPrefix, pszFieldName,
    1340               0 :                         (char *) pReturn );
    1341                 :         else
    1342                 :             VSIFPrintf( fpOut, "%s%s = (access failed)\n",
    1343               0 :                         pszPrefix, pszFieldName );
    1344                 : 
    1345               0 :         return;
    1346                 :     }
    1347                 :             
    1348                 : /* -------------------------------------------------------------------- */
    1349                 : /*      For BASEDATA objects, we want to first dump their dimension     */
    1350                 : /*      and type.                                                       */
    1351                 : /* -------------------------------------------------------------------- */
    1352               0 :     if( chItemType == 'b' )
    1353                 :     {
    1354                 :         int nDataType, nRows, nColumns;
    1355                 :         int bSuccess = ExtractInstValue( NULL, -3, pabyData, nDataOffset, 
    1356               0 :                           nDataSize, 'i', &nDataType );
    1357               0 :         if (bSuccess)
    1358                 :         {
    1359                 :             ExtractInstValue( NULL, -2, pabyData, nDataOffset, 
    1360               0 :                             nDataSize, 'i', &nColumns );
    1361                 :             ExtractInstValue( NULL, -1, pabyData, nDataOffset, 
    1362               0 :                             nDataSize, 'i', &nRows );
    1363                 :             VSIFPrintf( fpOut, "%sBASEDATA(%s): %dx%d of %s\n", 
    1364                 :                         pszPrefix, pszFieldName,
    1365               0 :                         nColumns, nRows, HFAGetDataTypeName( nDataType ) );
    1366                 :         }
    1367                 :         else
    1368                 :         {
    1369                 :             VSIFPrintf( fpOut, "%sBASEDATA(%s): empty\n", 
    1370               0 :                         pszPrefix, pszFieldName );
    1371                 :         }
    1372                 :     }
    1373                 :         
    1374                 : /* -------------------------------------------------------------------- */
    1375                 : /*      Dump each entry in the field array.                             */
    1376                 : /* -------------------------------------------------------------------- */
    1377               0 :     for( iEntry = 0; iEntry < MIN(MAX_ENTRY_REPORT,nEntries); iEntry++ )
    1378                 :     {
    1379               0 :         if( nEntries == 1 )
    1380               0 :             VSIFPrintf( fpOut, "%s%s = ", pszPrefix, pszFieldName );
    1381                 :         else
    1382                 :             VSIFPrintf( fpOut, "%s%s[%d] = ",
    1383               0 :                         pszPrefix, pszFieldName, iEntry );
    1384                 :         
    1385               0 :         switch( chItemType )
    1386                 :         {
    1387                 :           case 'f':
    1388                 :           case 'd':
    1389                 :           {
    1390                 :               double  dfValue;
    1391               0 :               if( ExtractInstValue( NULL, iEntry,
    1392                 :                                     pabyData, nDataOffset, nDataSize,
    1393                 :                                     'd', &dfValue ) )
    1394               0 :                   VSIFPrintf( fpOut, "%f\n", dfValue );
    1395                 :               else
    1396               0 :                   VSIFPrintf( fpOut, "(access failed)\n" );
    1397                 :           }
    1398               0 :           break;
    1399                 : 
    1400                 :           case 'b':
    1401                 :           {
    1402                 :               double dfValue;
    1403                 : 
    1404               0 :               if( ExtractInstValue( NULL, iEntry, 
    1405                 :                                     pabyData, nDataOffset, nDataSize, 
    1406                 :                                     'd', &dfValue ) )
    1407               0 :                   VSIFPrintf( fpOut, "%s%.15g\n", pszPrefix, dfValue );
    1408                 :               else
    1409               0 :                   VSIFPrintf( fpOut, "%s(access failed)\n", pszPrefix );
    1410                 :           }
    1411               0 :           break;
    1412                 : 
    1413                 :           case 'e':
    1414               0 :             if( ExtractInstValue( NULL, iEntry,
    1415                 :                                   pabyData, nDataOffset, nDataSize,
    1416                 :                                   's', &pReturn ) )
    1417               0 :                 VSIFPrintf( fpOut, "%s\n", (char *) pReturn );
    1418                 :             else
    1419               0 :                 VSIFPrintf( fpOut, "(access failed)\n" );
    1420               0 :             break;
    1421                 : 
    1422                 :           case 'o':
    1423               0 :             if( !ExtractInstValue( NULL, iEntry,
    1424                 :                                    pabyData, nDataOffset, nDataSize,
    1425                 :                                    'p', &pReturn ) )
    1426                 :             {
    1427               0 :                 VSIFPrintf( fpOut, "(access failed)\n" );
    1428                 :             }
    1429                 :             else
    1430                 :             {
    1431                 :                 int   nByteOffset;
    1432                 : 
    1433               0 :                 VSIFPrintf( fpOut, "\n" );
    1434                 :                 
    1435               0 :                 nByteOffset = ((GByte *) pReturn) - pabyData;
    1436                 :             
    1437               0 :                 sprintf( szLongFieldName, "%s    ", pszPrefix );
    1438                 :             
    1439                 :                 poItemObjectType->DumpInstValue( fpOut,
    1440                 :                                                  pabyData + nByteOffset,
    1441                 :                                                  nDataOffset + nByteOffset,
    1442                 :                                                  nDataSize - nByteOffset,
    1443               0 :                                                  szLongFieldName );
    1444                 :             }
    1445               0 :             break;
    1446                 : 
    1447                 :           default:
    1448                 :           {
    1449                 :               GInt32 nIntValue;
    1450                 : 
    1451               0 :               if( ExtractInstValue( NULL, iEntry,
    1452                 :                                     pabyData, nDataOffset, nDataSize,
    1453                 :                                     'i', &nIntValue ) )
    1454               0 :                   VSIFPrintf( fpOut, "%d\n", nIntValue );
    1455                 :               else
    1456               0 :                   VSIFPrintf( fpOut, "(access failed)\n" );
    1457                 :           }
    1458                 :           break;
    1459                 :         }
    1460                 :     }
    1461                 : 
    1462               0 :     if( nEntries > MAX_ENTRY_REPORT )
    1463               0 :         printf( "%s ... remaining instances omitted ...\n", pszPrefix );
    1464                 : 
    1465               0 :     if( nEntries == 0 )
    1466               0 :         VSIFPrintf( fpOut, "%s%s = (no values)\n", pszPrefix, pszFieldName );
    1467                 : 
    1468                 : }

Generated by: LCOV version 1.7