Exemplo n.º 1
0
int
HFAField::ExtractInstValue( const char * pszField, int nIndexValue,
                           GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
                           char chReqType, void *pReqReturn, int *pnRemainingDataSize )

{
    char		*pszStringRet = NULL;
    int			nIntRet = 0;
    double		dfDoubleRet = 0.0;
    int			nInstItemCount = GetInstCount( pabyData, nDataSize );
    GByte		*pabyRawData = NULL;

    if (pnRemainingDataSize)
        *pnRemainingDataSize = -1;

/* -------------------------------------------------------------------- */
/*      Check the index value is valid.                                 */
/*                                                                      */
/*      Eventually this will have to account for variable fields.       */
/* -------------------------------------------------------------------- */
    if( nIndexValue < 0 || nIndexValue >= nInstItemCount )
    {
        if( chItemType == 'b' && nIndexValue >= -3 && nIndexValue < 0 )
            /* ok - special index values */;
        else
            return FALSE;
    }

/* -------------------------------------------------------------------- */
/*	If this field contains a pointer, then we will adjust the	*/
/*	data offset relative to it.    					*/
/* -------------------------------------------------------------------- */
    if( chPointer != '\0' )
    {
        GUInt32		nOffset;

        if (nDataSize < 8)
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
            return FALSE;
        }

        memcpy( &nOffset, pabyData+4, 4 );
        HFAStandard( 4, &nOffset );

        if( nOffset != (GUInt32) (nDataOffset + 8) )
        {
#ifdef notdef            
            CPLError( CE_Warning, CPLE_AppDefined,
                      "%s.%s points at %d, not %d as expected\n",
                      pszFieldName, pszField ? pszField : "",
                      nOffset, nDataOffset+8 );
#endif            
        }
        
        pabyData += 8;

        nDataOffset += 8;
        nDataSize -= 8;
    }

/* -------------------------------------------------------------------- */
/*      pointers to char or uchar arrays requested as strings are       */
/*      handled as a special case.                                      */
/* -------------------------------------------------------------------- */
    if( (chItemType == 'c' || chItemType == 'C') && chReqType == 's' )
    {
        *((GByte **)pReqReturn) = pabyData;
        if (pnRemainingDataSize)
            *pnRemainingDataSize = nDataSize;
        return( pabyData != NULL );
    }

/* -------------------------------------------------------------------- */
/*      Handle by type.                                                 */
/* -------------------------------------------------------------------- */
    switch( chItemType )
    {
      case 'c':
      case 'C':
        if (nIndexValue >= nDataSize)
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
            return FALSE;
        }
        nIntRet = pabyData[nIndexValue];
        dfDoubleRet = nIntRet;
        break;

      case 'e':
      case 's':
      {
          unsigned short nNumber;
          if (nIndexValue*2 + 2 > nDataSize)
          {
              CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
              return FALSE;
          }
          memcpy( &nNumber, pabyData + nIndexValue*2, 2 );
          HFAStandard( 2, &nNumber );
          nIntRet = nNumber;
          dfDoubleRet = nIntRet;

          if( chItemType == 'e'
              && nIntRet >= 0 && nIntRet < CSLCount(papszEnumNames) )
          {
              pszStringRet = papszEnumNames[nIntRet];
          }
      }
      break;

      case 'S':
      {
          short nNumber;
          if (nIndexValue*2 + 2 > nDataSize)
          {
              CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
              return FALSE;
          }
          memcpy( &nNumber, pabyData + nIndexValue*2, 2 );
          HFAStandard( 2, &nNumber );
          nIntRet = nNumber;
          dfDoubleRet = nIntRet;
      }
      break;
        
      case 't':
      case 'l':
      {
          GUInt32	nNumber;
          if (nIndexValue*4 + 4 > nDataSize)
          {
              CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
              return FALSE;
          }
          memcpy( &nNumber, pabyData + nIndexValue*4, 4 );
          HFAStandard( 4, &nNumber );
          nIntRet = nNumber;
          dfDoubleRet = nIntRet;
      }
      break;
      
      case 'L':
      {
          GInt32	nNumber;
          if (nIndexValue*4 + 4 > nDataSize)
          {
              CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
              return FALSE;
          }
          memcpy( &nNumber, pabyData + nIndexValue*4, 4 );
          HFAStandard( 4, &nNumber );
          nIntRet = nNumber;
          dfDoubleRet = nIntRet;
      }
      break;
      
      case 'f':
      {
          float		fNumber;
          if (nIndexValue*4 + 4 > nDataSize)
          {
              CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
              return FALSE;
          }
          memcpy( &fNumber, pabyData + nIndexValue*4, 4 );
          HFAStandard( 4, &fNumber );
          dfDoubleRet = fNumber;
          nIntRet = (int) fNumber;
      }
      break;
        
      case 'd':
      {
          double	dfNumber;
          if (nIndexValue*8 + 8 > nDataSize)
          {
              CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
              return FALSE;
          }
          memcpy( &dfNumber, pabyData + nIndexValue*8, 8 );
          HFAStandard( 8, &dfNumber );
          dfDoubleRet = dfNumber;
          nIntRet = (int) dfNumber;
      }
      break;

      case 'b':
      {
          GInt32 nRows, nColumns;
          GInt16 nBaseItemType;

          if( nDataSize < 12 )
              return FALSE;
        
          memcpy( &nRows, pabyData, 4 );
          HFAStandard( 4, &nRows );
          memcpy( &nColumns, pabyData+4, 4 );
          HFAStandard( 4, &nColumns );
          memcpy( &nBaseItemType, pabyData+8, 2 );
          HFAStandard( 2, &nBaseItemType );
          // We ignore the 2 byte objecttype value. 

          if( nIndexValue < -3 || nIndexValue >= nRows * nColumns )
              return FALSE;

          pabyData += 12;
          nDataSize -= 12;

          if( nIndexValue == -3 ) 
          {
              dfDoubleRet = nIntRet = nBaseItemType;
          }
          else if( nIndexValue == -2 )
          {
              dfDoubleRet = nIntRet = nColumns;
          }
          else if( nIndexValue == -1 )
          {
              dfDoubleRet = nIntRet = nRows;
          }
          else if( nBaseItemType == EPT_u8 )
          {
              if (nIndexValue >= nDataSize)
              {
                  CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
                  return FALSE;
              }
              dfDoubleRet = pabyData[nIndexValue];
              nIntRet = pabyData[nIndexValue];
          }
          else if( nBaseItemType == EPT_s8 )
          {
              if (nIndexValue >= nDataSize)
              {
                  CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
                  return FALSE;
              }
              dfDoubleRet = ((signed char *)pabyData)[nIndexValue];
              nIntRet = ((signed char *)pabyData)[nIndexValue];
          }
          else if( nBaseItemType == EPT_s16 )
          {
              GInt16  nValue;
              if (nIndexValue*2 + 2 > nDataSize)
              {
                  CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
                  return FALSE;
              }
              memcpy( &nValue, pabyData + 2*nIndexValue, 2 );
              HFAStandard( 2, &nValue );

              dfDoubleRet = nValue;
              nIntRet = nValue;
          }
          else if( nBaseItemType == EPT_u16 )
          {
              GUInt16  nValue;
              if (nIndexValue*2 + 2 > nDataSize)
              {
                  CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
                  return FALSE;
              }
              memcpy( &nValue, pabyData + 2*nIndexValue, 2 );
              HFAStandard( 2, &nValue );

              dfDoubleRet = nValue;
              nIntRet = nValue;
          }
          else if( nBaseItemType == EPT_s32 )
          {
              GInt32  nValue;
              if (nIndexValue*4 + 4 > nDataSize)
              {
                  CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
                  return FALSE;
              }
              memcpy( &nValue, pabyData + 4*nIndexValue, 4 );
              HFAStandard( 4, &nValue );

              dfDoubleRet = nValue;
              nIntRet = nValue;
          }
          else if( nBaseItemType == EPT_u32 )
          {
              GUInt32  nValue;
              if (nIndexValue*4 + 4 > nDataSize)
              {
                  CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
                  return FALSE;
              }
              memcpy( &nValue, pabyData + 4*nIndexValue, 4 );
              HFAStandard( 4, &nValue );

              dfDoubleRet = nValue;
              nIntRet = nValue;
          }
          else if( nBaseItemType == EPT_f32 )
          {
              float fValue;
              if (nIndexValue*4 + 4 > nDataSize)
              {
                  CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
                  return FALSE;
              }
              memcpy( &fValue, pabyData + 4*nIndexValue, 4 );
              HFAStandard( 4, &fValue );

              dfDoubleRet = fValue;
              nIntRet = (int) fValue;
          }
          else if( nBaseItemType == EPT_f64 )
          {
              double dfValue;
              if (nIndexValue*8 + 8 > nDataSize)
              {
                  CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
                  return FALSE;
              }
              memcpy( &dfValue, pabyData+8*nIndexValue, 8 );
              HFAStandard( 8, &dfValue );

              dfDoubleRet = dfValue;
              nIntRet = (int) dfValue;
          }
          else
          {
              CPLError(CE_Failure, CPLE_AppDefined, "Unknown base item type : %d", nBaseItemType);
              return FALSE;
          }
      }
      break;

      case 'o':
        if( poItemObjectType != NULL )
        {
            int		nExtraOffset = 0;
            int		iIndexCounter;

            if( poItemObjectType->nBytes > 0 )
            {
                if (nIndexValue != 0 && poItemObjectType->nBytes > INT_MAX / nIndexValue)
                    return CE_Failure;
                nExtraOffset = poItemObjectType->nBytes * nIndexValue;
            }
            else
            {
                for( iIndexCounter = 0;
                     iIndexCounter < nIndexValue && nExtraOffset < nDataSize;
                     iIndexCounter++ )
                {
                    int nInc = poItemObjectType->GetInstBytes(pabyData + nExtraOffset,
                                                              nDataSize - nExtraOffset);
                    if (nInc < 0 || nExtraOffset > INT_MAX - nInc)
                    {
                        CPLError(CE_Failure, CPLE_AppDefined, "Invalid return value");
                        return CE_Failure;
                    }

                    nExtraOffset += nInc;
                }
            }

            if (nExtraOffset >= nDataSize)
                return CE_Failure;

            pabyRawData = pabyData + nExtraOffset;

            if( pszField != NULL && strlen(pszField) > 0 )
            {
                return( poItemObjectType->
                        ExtractInstValue( pszField, pabyRawData,
                                          nDataOffset + nExtraOffset,
                                          nDataSize - nExtraOffset,
                                          chReqType, pReqReturn, pnRemainingDataSize ) );
            }
        }
        break;

      default:
        return FALSE;
        break;
    }

/* -------------------------------------------------------------------- */
/*      Return the appropriate representation.                          */
/* -------------------------------------------------------------------- */
    if( chReqType == 's' )
    {
        if( pszStringRet == NULL )
        {
            /* HFAEntry:: BuildEntryFromMIFObject() expects to have always */
            /* 8 bytes before the data. In normal situations, it should */
            /* not go here, but that can happen if the file is corrupted */
            /* so reserve the first 8 bytes before the string to contain null bytes */
            memset(szNumberString, 0, 8);
            sprintf( szNumberString + 8, "%.14g", dfDoubleRet );
            pszStringRet = szNumberString + 8;
        }
        
        *((char **) pReqReturn) = pszStringRet;
        return( TRUE );
    }
    else if( chReqType == 'd' )
    {
        *((double *)pReqReturn) = dfDoubleRet;
        return( TRUE );
    }
    else if( chReqType == 'i' )
    {
        *((int *) pReqReturn) = nIntRet;
        return( TRUE );
    }
    else if( chReqType == 'p' )
    {
        *((GByte **) pReqReturn) = pabyRawData;
        return( TRUE );
    }
    else
    {
        CPLAssert( FALSE );
        return FALSE;
    }
}
Exemplo n.º 2
0
void HFAField::DumpInstValue( FILE *fpOut, 
                           GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
                           const char *pszPrefix )

{
    int		iEntry, nEntries;
    void	*pReturn;
    char	szLongFieldName[256];

    nEntries = GetInstCount( pabyData, nDataSize );

/* -------------------------------------------------------------------- */
/*      Special case for arrays of chars or uchars which are printed    */
/*      as a string.                                                    */
/* -------------------------------------------------------------------- */
    if( (chItemType == 'c' || chItemType == 'C') && nEntries > 0 )
    {
        if( ExtractInstValue( NULL, 0,
                              pabyData, nDataOffset, nDataSize,
                              's', &pReturn ) )
            VSIFPrintf( fpOut, "%s%s = `%s'\n",
                        pszPrefix, pszFieldName,
                        (char *) pReturn );
        else
            VSIFPrintf( fpOut, "%s%s = (access failed)\n",
                        pszPrefix, pszFieldName );

        return;
    }
            
/* -------------------------------------------------------------------- */
/*      For BASEDATA objects, we want to first dump their dimension     */
/*      and type.                                                       */
/* -------------------------------------------------------------------- */
    if( chItemType == 'b' )
    {
        int nDataType, nRows, nColumns;
        int bSuccess = ExtractInstValue( NULL, -3, pabyData, nDataOffset, 
                          nDataSize, 'i', &nDataType );
        if (bSuccess)
        {
            ExtractInstValue( NULL, -2, pabyData, nDataOffset, 
                            nDataSize, 'i', &nColumns );
            ExtractInstValue( NULL, -1, pabyData, nDataOffset, 
                            nDataSize, 'i', &nRows );
            VSIFPrintf( fpOut, "%sBASEDATA(%s): %dx%d of %s\n", 
                        pszPrefix, pszFieldName,
                        nColumns, nRows, HFAGetDataTypeName( nDataType ) );
        }
        else
        {
            VSIFPrintf( fpOut, "%sBASEDATA(%s): empty\n", 
                        pszPrefix, pszFieldName );
        }
    }
        
/* -------------------------------------------------------------------- */
/*      Dump each entry in the field array.                             */
/* -------------------------------------------------------------------- */
    for( iEntry = 0; iEntry < MIN(MAX_ENTRY_REPORT,nEntries); iEntry++ )
    {
        if( nEntries == 1 )
            VSIFPrintf( fpOut, "%s%s = ", pszPrefix, pszFieldName );
        else
            VSIFPrintf( fpOut, "%s%s[%d] = ",
                        pszPrefix, pszFieldName, iEntry );
        
        switch( chItemType )
        {
          case 'f':
          case 'd':
          {
              double  dfValue;
              if( ExtractInstValue( NULL, iEntry,
                                    pabyData, nDataOffset, nDataSize,
                                    'd', &dfValue ) )
                  VSIFPrintf( fpOut, "%f\n", dfValue );
              else
                  VSIFPrintf( fpOut, "(access failed)\n" );
          }
          break;

          case 'b':
          {
              double dfValue;

              if( ExtractInstValue( NULL, iEntry, 
                                    pabyData, nDataOffset, nDataSize, 
                                    'd', &dfValue ) )
                  VSIFPrintf( fpOut, "%s%.15g\n", pszPrefix, dfValue );
              else
                  VSIFPrintf( fpOut, "%s(access failed)\n", pszPrefix );
          }
          break;

          case 'e':
            if( ExtractInstValue( NULL, iEntry,
                                  pabyData, nDataOffset, nDataSize,
                                  's', &pReturn ) )
                VSIFPrintf( fpOut, "%s\n", (char *) pReturn );
            else
                VSIFPrintf( fpOut, "(access failed)\n" );
            break;

          case 'o':
            if( !ExtractInstValue( NULL, iEntry,
                                   pabyData, nDataOffset, nDataSize,
                                   'p', &pReturn ) )
            {
                VSIFPrintf( fpOut, "(access failed)\n" );
            }
            else
            {
                int		nByteOffset;

                VSIFPrintf( fpOut, "\n" );
                
                nByteOffset = ((GByte *) pReturn) - pabyData;
            
                sprintf( szLongFieldName, "%s    ", pszPrefix );
            
                if( poItemObjectType )
                    poItemObjectType->DumpInstValue( fpOut,
                                                     pabyData + nByteOffset,
                                                     nDataOffset + nByteOffset,
                                                     nDataSize - nByteOffset,
                                                     szLongFieldName );
            }
            break;

          default:
          {
              GInt32 nIntValue;

              if( ExtractInstValue( NULL, iEntry,
                                    pabyData, nDataOffset, nDataSize,
                                    'i', &nIntValue ) )
                  VSIFPrintf( fpOut, "%d\n", nIntValue );
              else
                  VSIFPrintf( fpOut, "(access failed)\n" );
          }
          break;
        }
    }

    if( nEntries > MAX_ENTRY_REPORT )
        printf( "%s ... remaining instances omitted ...\n", pszPrefix );

    if( nEntries == 0 )
        VSIFPrintf( fpOut, "%s%s = (no values)\n", pszPrefix, pszFieldName );

}
Exemplo n.º 3
0
void *HFAField::ExtractInstValue( const char * pszField, int nIndexValue,
                               GByte *pabyData, int nDataOffset, int nDataSize,
                               char chReqType )

{
    char		*pszStringRet = NULL;
    static int		nIntRet = 0;
    static double	dfDoubleRet = 0.0;
    int			nInstItemCount = GetInstCount( pabyData );
    GByte		*pabyRawData = NULL;

/* -------------------------------------------------------------------- */
/*      Check the index value is valid.                                 */
/*                                                                      */
/*      Eventually this will have to account for variable fields.       */
/* -------------------------------------------------------------------- */
    if( nIndexValue < 0 || nIndexValue >= nInstItemCount )
        return NULL;

/* -------------------------------------------------------------------- */
/*	If this field contains a pointer, then we will adjust the	*/
/*	data offset relative to it.    					*/
/* -------------------------------------------------------------------- */
    if( chPointer != '\0' )
    {
        GUInt32		nOffset;

        memcpy( &nOffset, pabyData+4, 4 );
        HFAStandard( 4, &nOffset );

        if( nOffset != (GUInt32) (nDataOffset + 8) )
        {
#ifdef notdef            
            CPLError( CE_Warning, CPLE_AppDefined,
                      "%s.%s points at %d, not %d as expected\n",
                      pszFieldName, pszField ? pszField : "",
                      nOffset, nDataOffset+8 );
#endif            
        }
        
        pabyData += 8;

        nDataOffset += 8;
        nDataSize -= 8;
    }

/* -------------------------------------------------------------------- */
/*      pointers to char or uchar arrays requested as strings are       */
/*      handled as a special case.                                      */
/* -------------------------------------------------------------------- */
    if( (chItemType == 'c' || chItemType == 'C') && chReqType == 's' )
        return( pabyData );

/* -------------------------------------------------------------------- */
/*      Handle by type.                                                 */
/* -------------------------------------------------------------------- */
    switch( chItemType )
    {
      case 'c':
      case 'C':
        nIntRet = pabyData[nIndexValue];
        dfDoubleRet = nIntRet;
        break;

      case 'e':
      case 's':
      {
          unsigned short nNumber;

          memcpy( &nNumber, pabyData + nIndexValue*2, 2 );
          HFAStandard( 2, &nNumber );
          nIntRet = nNumber;
          dfDoubleRet = nIntRet;

          if( chItemType == 'e'
              && nIntRet >= 0 && nIntRet < CSLCount(papszEnumNames) )
          {
              pszStringRet = papszEnumNames[nIntRet];
          }
      }
      break;

      case 'S':
      {
          short nNumber;

          memcpy( &nNumber, pabyData + nIndexValue*2, 2 );
          HFAStandard( 2, &nNumber );
          nIntRet = nNumber;
          dfDoubleRet = nIntRet;
      }
      break;
        
      case 't':
      case 'l':
      {
          GUInt32	nNumber;
          
          memcpy( &nNumber, pabyData + nIndexValue*4, 4 );
          HFAStandard( 4, &nNumber );
          nIntRet = nNumber;
          dfDoubleRet = nIntRet;
      }
      break;
      
      case 'L':
      {
          GInt32	nNumber;
          
          memcpy( &nNumber, pabyData + nIndexValue*4, 4 );
          HFAStandard( 4, &nNumber );
          nIntRet = nNumber;
          dfDoubleRet = nIntRet;
      }
      break;
      
      case 'f':
      {
          float		fNumber;
          
          memcpy( &fNumber, pabyData + nIndexValue*4, 4 );
          HFAStandard( 4, &fNumber );
          dfDoubleRet = fNumber;
          nIntRet = (int) fNumber;
      }
      break;
        
      case 'd':
      {
          double	dfNumber;
          
          memcpy( &dfNumber, pabyData + nIndexValue*8, 8 );
          HFAStandard( 8, &dfNumber );
          dfDoubleRet = dfNumber;
          nIntRet = (int) dfNumber;
      }
      break;

      case 'o':
        if( poItemObjectType != NULL )
        {
            int		nExtraOffset = 0;
            int		iIndexCounter;

            if( poItemObjectType->nBytes > 0 )
            {
                nExtraOffset = poItemObjectType->nBytes * nIndexValue;
            }
            else
            {
                for( iIndexCounter = 0;
                     iIndexCounter < nIndexValue;
                     iIndexCounter++ )
                {
                    nExtraOffset +=
                        poItemObjectType->GetInstBytes(pabyData+nExtraOffset);
                }
            }

            pabyRawData = pabyData + nExtraOffset;

            if( pszField != NULL && strlen(pszField) > 0 )
            {
                return( poItemObjectType->
                            ExtractInstValue( pszField, pabyRawData,
                                              nDataOffset + nExtraOffset,
                                              nDataSize - nExtraOffset,
                                              chReqType ) );
            }
        }
        break;

      default:
        return NULL;
        break;
    }

/* -------------------------------------------------------------------- */
/*      Return the appropriate representation.                          */
/* -------------------------------------------------------------------- */
    if( chReqType == 's' )
    {
        if( pszStringRet == NULL )
        {
            static char	szNumber[28];

            sprintf( szNumber, "%d", nIntRet );
            pszStringRet = szNumber;
        }
        
        return( pszStringRet );
    }
    else if( chReqType == 'd' )
        return( &dfDoubleRet );
    else if( chReqType == 'i' )
        return( &nIntRet );
    else if( chReqType == 'p' )
        return( pabyRawData );
    else
    {
        CPLAssert( FALSE );
        return NULL;
    }
}
Exemplo n.º 4
0
void HFAField::DumpInstValue(  FILE *fpOut, 
                               GByte *pabyData, int nDataOffset, int nDataSize,
                               const char *pszPrefix )

{
    int		iEntry, nEntries;
    void	*pReturn;
    char	szLongFieldName[256];

    nEntries = GetInstCount( pabyData );

/* -------------------------------------------------------------------- */
/*      Special case for arrays of chars or uchars which are printed    */
/*      as a string.                                                    */
/* -------------------------------------------------------------------- */
    if( (chItemType == 'c' || chItemType == 'C') && nEntries > 0 )
    {
        pReturn = ExtractInstValue( NULL, 0,
                                    pabyData, nDataOffset, nDataSize,
                                    's' );
        if( pReturn != NULL )
            VSIFPrintf( fpOut, "%s%s = `%s'\n",
                        pszPrefix, pszFieldName,
                        (char *) pReturn );
        else
            VSIFPrintf( fpOut, "%s%s = (access failed)\n",
                        pszPrefix, pszFieldName );

        return;
    }
            
/* -------------------------------------------------------------------- */
/*      Dump each entry in the field array.                             */
/* -------------------------------------------------------------------- */
    for( iEntry = 0; iEntry < MIN(8,nEntries); iEntry++ )
    {
        if( nEntries == 1 )
            VSIFPrintf( fpOut, "%s%s = ", pszPrefix, pszFieldName );
        else
            VSIFPrintf( fpOut, "%s%s[%d] = ",
                        pszPrefix, pszFieldName, iEntry );
        
        switch( chItemType )
        {
          case 'f':
          case 'd':
            pReturn = ExtractInstValue( NULL, iEntry,
                                        pabyData, nDataOffset, nDataSize,
                                        'd' );
            if( pReturn != NULL )
                VSIFPrintf( fpOut, "%f\n",
                            *((double *) pReturn) );
            else
                VSIFPrintf( fpOut, "(access failed)\n" );
            break;

          case 'b':
            VSIFPrintf( fpOut, "(basedata)\n" );
            break;

          case 'e':
            pReturn = ExtractInstValue( NULL, iEntry,
                                        pabyData, nDataOffset, nDataSize,
                                        's' );
            if( pReturn != NULL )
                VSIFPrintf( fpOut, "%s\n",
                            (char *) pReturn );
            else
                VSIFPrintf( fpOut, "(access failed)\n" );
            break;

          case 'o':
            pReturn = ExtractInstValue( NULL, iEntry,
                                        pabyData, nDataOffset, nDataSize,
                                        'p' );

            if( pReturn == NULL )
            {
                VSIFPrintf( fpOut, "(access failed)\n" );
            }
            else
            {
                int		nByteOffset;

                VSIFPrintf( fpOut, "\n" );
                
                nByteOffset = ((GByte *) pReturn) - pabyData;
            
                sprintf( szLongFieldName, "%s    ", pszPrefix );
            
                poItemObjectType->DumpInstValue( fpOut,
                                                 pabyData + nByteOffset,
                                                 nDataOffset + nByteOffset,
                                                 nDataSize - nByteOffset,
                                                 szLongFieldName );
            }
            break;

          default:
            pReturn = ExtractInstValue( NULL, iEntry,
                                        pabyData, nDataOffset, nDataSize,
                                        'i' );
            if( pReturn != NULL )
                VSIFPrintf( fpOut, "%d\n",
                            *((int *) pReturn) );
            else
                VSIFPrintf( fpOut, "(access failed)\n" );
            break;
        }
    }

    if( nEntries > 8 )
        printf( "%s ... remaining instances omitted ...\n", pszPrefix );

    if( nEntries == 0 )
        VSIFPrintf( fpOut, "%s%s = (no values)\n", pszPrefix, pszFieldName );

}
Exemplo n.º 5
0
int
HFAField::ExtractInstValue( const char * pszField, int nIndexValue,
                           GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
                           char chReqType, void *pReqReturn )

{
    char		*pszStringRet = NULL;
    int			nIntRet = 0;
    double		dfDoubleRet = 0.0;
    int			nInstItemCount = GetInstCount( pabyData, nDataSize );
    GByte		*pabyRawData = NULL;

/* -------------------------------------------------------------------- */
/*      Check the index value is valid.                                 */
/*                                                                      */
/*      Eventually this will have to account for variable fields.       */
/* -------------------------------------------------------------------- */
    if( nIndexValue < 0 || nIndexValue >= nInstItemCount )
    {
        if( chItemType == 'b' && nIndexValue >= -3 && nIndexValue < 0 )
            /* ok - special index values */;
        else
            return FALSE;
    }

/* -------------------------------------------------------------------- */
/*	If this field contains a pointer, then we will adjust the	*/
/*	data offset relative to it.    					*/
/* -------------------------------------------------------------------- */
    if( chPointer != '\0' )
    {
        GUInt32		nOffset;

        memcpy( &nOffset, pabyData+4, 4 );
        HFAStandard( 4, &nOffset );

        if( nOffset != (GUInt32) (nDataOffset + 8) )
        {
#ifdef notdef            
            CPLError( CE_Warning, CPLE_AppDefined,
                      "%s.%s points at %d, not %d as expected\n",
                      pszFieldName, pszField ? pszField : "",
                      nOffset, nDataOffset+8 );
#endif            
        }
        
        pabyData += 8;

        nDataOffset += 8;
        nDataSize -= 8;
    }

/* -------------------------------------------------------------------- */
/*      pointers to char or uchar arrays requested as strings are       */
/*      handled as a special case.                                      */
/* -------------------------------------------------------------------- */
    if( (chItemType == 'c' || chItemType == 'C') && chReqType == 's' )
    {
        *((GByte **)pReqReturn) = pabyData;
        return( pabyData != NULL );
    }

/* -------------------------------------------------------------------- */
/*      Handle by type.                                                 */
/* -------------------------------------------------------------------- */
    switch( chItemType )
    {
      case 'c':
      case 'C':
        nIntRet = pabyData[nIndexValue];
        dfDoubleRet = nIntRet;
        break;

      case 'e':
      case 's':
      {
          unsigned short nNumber;

          memcpy( &nNumber, pabyData + nIndexValue*2, 2 );
          HFAStandard( 2, &nNumber );
          nIntRet = nNumber;
          dfDoubleRet = nIntRet;

          if( chItemType == 'e'
              && nIntRet >= 0 && nIntRet < CSLCount(papszEnumNames) )
          {
              pszStringRet = papszEnumNames[nIntRet];
          }
      }
      break;

      case 'S':
      {
          short nNumber;

          memcpy( &nNumber, pabyData + nIndexValue*2, 2 );
          HFAStandard( 2, &nNumber );
          nIntRet = nNumber;
          dfDoubleRet = nIntRet;
      }
      break;
        
      case 't':
      case 'l':
      {
          GUInt32	nNumber;
          
          memcpy( &nNumber, pabyData + nIndexValue*4, 4 );
          HFAStandard( 4, &nNumber );
          nIntRet = nNumber;
          dfDoubleRet = nIntRet;
      }
      break;
      
      case 'L':
      {
          GInt32	nNumber;
          
          memcpy( &nNumber, pabyData + nIndexValue*4, 4 );
          HFAStandard( 4, &nNumber );
          nIntRet = nNumber;
          dfDoubleRet = nIntRet;
      }
      break;
      
      case 'f':
      {
          float		fNumber;
          
          memcpy( &fNumber, pabyData + nIndexValue*4, 4 );
          HFAStandard( 4, &fNumber );
          dfDoubleRet = fNumber;
          nIntRet = (int) fNumber;
      }
      break;
        
      case 'd':
      {
          double	dfNumber;
          
          memcpy( &dfNumber, pabyData + nIndexValue*8, 8 );
          HFAStandard( 8, &dfNumber );
          dfDoubleRet = dfNumber;
          nIntRet = (int) dfNumber;
      }
      break;

      case 'b':
      {
          GInt32 nRows, nColumns;
          GInt16 nBaseItemType;

          if( nDataSize < 12 )
              return FALSE;
        
          memcpy( &nRows, pabyData, 4 );
          HFAStandard( 4, &nRows );
          memcpy( &nColumns, pabyData+4, 4 );
          HFAStandard( 4, &nColumns );
          memcpy( &nBaseItemType, pabyData+8, 2 );
          HFAStandard( 2, &nBaseItemType );
          // We ignore the 2 byte objecttype value. 

          if( nIndexValue < -3 || nIndexValue >= nRows * nColumns )
              return FALSE;

          pabyData += 12;

          if( nIndexValue == -3 ) 
          {
              dfDoubleRet = nIntRet = nBaseItemType;
          }
          else if( nIndexValue == -2 )
          {
              dfDoubleRet = nIntRet = nColumns;
          }
          else if( nIndexValue == -1 )
          {
              dfDoubleRet = nIntRet = nRows;
          }
          else if( nBaseItemType == EPT_u8 )
          {
              dfDoubleRet = pabyData[nIndexValue];
              nIntRet = pabyData[nIndexValue];
          }
          else if( nBaseItemType == EPT_s16 )
          {
              GInt16  nValue;
              
              memcpy( &nValue, pabyData + 2*nIndexValue, 2 );
              HFAStandard( 2, &nValue );

              dfDoubleRet = nValue;
              nIntRet = nValue;
          }
          else if( nBaseItemType == EPT_u16 )
          {
              GUInt16  nValue;
              
              memcpy( &nValue, pabyData + 2*nIndexValue, 2 );
              HFAStandard( 2, &nValue );

              dfDoubleRet = nValue;
              nIntRet = nValue;
          }
          else if( nBaseItemType == EPT_s32 )
          {
              GInt32  nValue;
              
              memcpy( &nValue, pabyData + 4*nIndexValue, 4 );
              HFAStandard( 4, &nValue );

              dfDoubleRet = nValue;
              nIntRet = nValue;
          }
          else if( nBaseItemType == EPT_u32 )
          {
              GUInt32  nValue;
              
              memcpy( &nValue, pabyData + 4*nIndexValue, 4 );
              HFAStandard( 4, &nValue );

              dfDoubleRet = nValue;
              nIntRet = nValue;
          }
          else if( nBaseItemType == EPT_f32 )
          {
              float fValue;
              
              memcpy( &fValue, pabyData + 4*nIndexValue, 4 );
              HFAStandard( 4, &fValue );

              dfDoubleRet = fValue;
              nIntRet = (int) fValue;
          }
          else if( nBaseItemType == EPT_f64 )
          {
              double dfValue;
              
              memcpy( &dfValue, pabyData+8*nIndexValue, 8 );
              HFAStandard( 8, &dfValue );

              dfDoubleRet = dfValue;
              nIntRet = (int) dfValue;
          }
          else
          {
              CPLAssert( FALSE );
              return FALSE;
          }
      }
      break;

      case 'o':
        if( poItemObjectType != NULL )
        {
            int		nExtraOffset = 0;
            int		iIndexCounter;

            if( poItemObjectType->nBytes > 0 )
            {
                nExtraOffset = poItemObjectType->nBytes * nIndexValue;
            }
            else
            {
                for( iIndexCounter = 0;
                     iIndexCounter < nIndexValue;
                     iIndexCounter++ )
                {
                    nExtraOffset +=
                        poItemObjectType->GetInstBytes(pabyData + nExtraOffset,
                                                       nDataSize - nExtraOffset);
                }
            }

            pabyRawData = pabyData + nExtraOffset;

            if( pszField != NULL && strlen(pszField) > 0 )
            {
                return( poItemObjectType->
                        ExtractInstValue( pszField, pabyRawData,
                                          nDataOffset + nExtraOffset,
                                          nDataSize - nExtraOffset,
                                          chReqType, pReqReturn ) );
            }
        }
        break;

      default:
        return FALSE;
        break;
    }

/* -------------------------------------------------------------------- */
/*      Return the appropriate representation.                          */
/* -------------------------------------------------------------------- */
    if( chReqType == 's' )
    {
        if( pszStringRet == NULL )
        {
            sprintf( szNumberString, "%.14g", dfDoubleRet );
            pszStringRet = szNumberString;
        }
        
        *((char **) pReqReturn) = pszStringRet;
        return( TRUE );
    }
    else if( chReqType == 'd' )
    {
        *((double *)pReqReturn) = dfDoubleRet;
        return( TRUE );
    }
    else if( chReqType == 'i' )
    {
        *((int *) pReqReturn) = nIntRet;
        return( TRUE );
    }
    else if( chReqType == 'p' )
    {
        *((GByte **) pReqReturn) = pabyRawData;
        return( TRUE );
    }
    else
    {
        CPLAssert( FALSE );
        return FALSE;
    }
}