예제 #1
0
int HFAField::GetInstCount( GByte * pabyData, int nDataSize )

{
    if( chPointer == '\0' )
        return nItemCount;
    else if( chItemType == 'b' )
    {
        GInt32 nRows, nColumns;

        if( nDataSize < 20 )
            return 0;

        memcpy( &nRows, pabyData+8, 4 );
        HFAStandard( 4, &nRows );
        memcpy( &nColumns, pabyData+12, 4 );
        HFAStandard( 4, &nColumns );

        return nRows * nColumns;
    }
    else
    {
        GInt32 nCount;

        if( nDataSize < 4 )
            return 0;

        memcpy( &nCount, pabyData, 4 );
        HFAStandard( 4, &nCount );
        return nCount;
    }
}
예제 #2
0
int HFAField::GetInstBytes( GByte *pabyData, int nDataSize )

{
    int		nCount;
    int		nInstBytes = 0;
    
    if( nBytes > -1 )
        return nBytes;

    if( chPointer != '\0' )
    {
        memcpy( &nCount, pabyData, 4 );
        HFAStandard( 4, &nCount );

        pabyData += 8;
        nInstBytes += 8;
    }
    else
        nCount = 1;

    if( chItemType == 'b' && nCount != 0 ) // BASEDATA
    {
        GInt32 nRows, nColumns;
        GInt16 nBaseItemType;
        
        memcpy( &nRows, pabyData, 4 );
        HFAStandard( 4, &nRows );
        memcpy( &nColumns, pabyData+4, 4 );
        HFAStandard( 4, &nColumns );
        memcpy( &nBaseItemType, pabyData+8, 2 );
        HFAStandard( 2, &nBaseItemType );

        nInstBytes += 12;

        nInstBytes += 
            ((HFAGetDataTypeBits(nBaseItemType) + 7) / 8) * nRows * nColumns;
    }
    else if( poItemObjectType == NULL )
    {
        nInstBytes += nCount * HFADictionary::GetItemSize(chItemType);
    }
    else
    {
        int		i;

        for( i = 0; i < nCount; i++ )
        {
            int	nThisBytes;

            nThisBytes =
                poItemObjectType->GetInstBytes( pabyData,
                                                nDataSize - nInstBytes );
            nInstBytes += nThisBytes;
            pabyData += nThisBytes;
        }
    }

    return( nInstBytes );
}
예제 #3
0
파일: hfaband.cpp 프로젝트: hkaiser/TRiAS
CPLErr HFABand::GetPCT( int * pnColors,
                        double **ppadfRed,
                        double **ppadfGreen,
                        double **ppadfBlue )

{
    *pnColors = 0;
    *ppadfRed = NULL;
    *ppadfGreen = NULL;
    *ppadfBlue = NULL;
        
/* -------------------------------------------------------------------- */
/*      If we haven't already tried to load the colors, do so now.      */
/* -------------------------------------------------------------------- */
    if( nPCTColors == -1 )
    {
        HFAEntry	*poColumnEntry;
        int		i, iColumn;

        nPCTColors = 0;

        poColumnEntry = poNode->GetNamedChild("Descriptor_Table.Red");
        if( poColumnEntry == NULL )
            return( CE_Failure );

        nPCTColors = poColumnEntry->GetIntField( "numRows" );
        for( iColumn = 0; iColumn < 3; iColumn++ )
        {
            apadfPCT[iColumn] = (double *)CPLMalloc(sizeof(double)*nPCTColors);
            if( iColumn == 0 )
                poColumnEntry = poNode->GetNamedChild("Descriptor_Table.Red");
            else if( iColumn == 1 )
                poColumnEntry= poNode->GetNamedChild("Descriptor_Table.Green");
            else if( iColumn == 2 )
                poColumnEntry = poNode->GetNamedChild("Descriptor_Table.Blue");


            VSIFSeek( psInfo->fp, poColumnEntry->GetIntField("columnDataPtr"),
                      SEEK_SET );
            VSIFRead( apadfPCT[iColumn], sizeof(double), nPCTColors,
                      psInfo->fp);

            for( i = 0; i < nPCTColors; i++ )
                HFAStandard( 8, apadfPCT[iColumn] + i );
        }
    }

/* -------------------------------------------------------------------- */
/*      Return the values.                                              */
/* -------------------------------------------------------------------- */
    if( nPCTColors == 0 )
        return( CE_Failure );

    *pnColors = nPCTColors;
    *ppadfRed = apadfPCT[0];
    *ppadfGreen = apadfPCT[1];
    *ppadfBlue = apadfPCT[2];
    
    return( CE_None );
}
예제 #4
0
파일: hfaentry.cpp 프로젝트: hkaiser/TRiAS
HFAEntry::HFAEntry( HFAInfo_t * psHFAIn, GUInt32 nPos,
                    HFAEntry * poParentIn, HFAEntry * poPrevIn )

{
    psHFA = psHFAIn;
    
    nFilePos = nPos;

    poParent = poParentIn;
    poPrev = poPrevIn;

/* -------------------------------------------------------------------- */
/*      Initialize fields to null values in case there is a read        */
/*      error, so the entry will be in a harmless state.                */
/* -------------------------------------------------------------------- */
    poNext = poChild = NULL;

    nDataPos = nDataSize = 0;
    nNextPos = nChildPos = 0;

    szName[0] = szType[0] = '\0';

    pabyData = NULL;

    poType = NULL;

/* -------------------------------------------------------------------- */
/*      Read the entry information from the file.                       */
/* -------------------------------------------------------------------- */
    GInt32	anEntryNums[6];
    int		i;

    if( VSIFSeek( psHFA->fp, nFilePos, SEEK_SET ) == -1
        || VSIFRead( anEntryNums, sizeof(GInt32), 6, psHFA->fp ) < 1 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "VSIFRead() failed in HFAEntry()." );
        return;
    }

    for( i = 0; i < 6; i++ )
        HFAStandard( 4, anEntryNums + i );

    nNextPos = anEntryNums[0];
    nChildPos = anEntryNums[3];
    nDataPos = anEntryNums[4];
    nDataSize = anEntryNums[5];

/* -------------------------------------------------------------------- */
/*      Read the name, and type.                                        */
/* -------------------------------------------------------------------- */
    if( VSIFRead( szName, 1, 64, psHFA->fp ) < 1
        || VSIFRead( szType, 1, 32, psHFA->fp ) < 1 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "VSIFRead() failed in HFAEntry()." );
        return;
    }
}
예제 #5
0
HFAEntry* HFAEntry::New( HFAInfo_t * psHFAIn, GUInt32 nPos,
                         HFAEntry * poParentIn, HFAEntry * poPrevIn )

{
    HFAEntry* poEntry = new HFAEntry;
    poEntry->psHFA = psHFAIn;

    poEntry->nFilePos = nPos;
    poEntry->poParent = poParentIn;
    poEntry->poPrev = poPrevIn;

/* -------------------------------------------------------------------- */
/*      Read the entry information from the file.                       */
/* -------------------------------------------------------------------- */
    GInt32 anEntryNums[6] = {};

    if( VSIFSeekL( poEntry->psHFA->fp, poEntry->nFilePos, SEEK_SET ) == -1
        || VSIFReadL( anEntryNums, sizeof(GInt32), 6, poEntry->psHFA->fp ) < 1 )
    {
        CPLError( CE_Failure, CPLE_FileIO,
                  "VSIFReadL(%p,6*4) @ %d failed in HFAEntry().\n%s",
                  poEntry->psHFA->fp, poEntry->nFilePos, VSIStrerror( errno ) );
        delete poEntry;
        return NULL;
    }

    for( int i = 0; i < 6; i++ )
        HFAStandard( 4, anEntryNums + i );

    poEntry->nNextPos = anEntryNums[0];
    poEntry->nChildPos = anEntryNums[3];
    poEntry->nDataPos = anEntryNums[4];
    poEntry->nDataSize = anEntryNums[5];

/* -------------------------------------------------------------------- */
/*      Read the name, and type.                                        */
/* -------------------------------------------------------------------- */
    if( VSIFReadL( poEntry->szName, 1, 64, poEntry->psHFA->fp ) < 1
        || VSIFReadL( poEntry->szType, 1, 32, poEntry->psHFA->fp ) < 1 )
    {
        poEntry->szName[sizeof(poEntry->szName)-1] = '\0';
        poEntry->szType[sizeof(poEntry->szType)-1] = '\0';
        CPLError( CE_Failure, CPLE_FileIO,
                  "VSIFReadL() failed in HFAEntry()." );
        delete poEntry;
        return NULL;
    }
    poEntry->szName[sizeof(poEntry->szName)-1] = '\0';
    poEntry->szType[sizeof(poEntry->szType)-1] = '\0';
    return poEntry;
}
예제 #6
0
파일: hfafield.cpp 프로젝트: hkaiser/TRiAS
int HFAField::GetInstCount( GByte * pabyData )

{
    if( chPointer == '\0' )
        return nItemCount;
    else
    {
        GInt32 nCount;

        memcpy( &nCount, pabyData, 4 );
        HFAStandard( 4, &nCount );
        return nCount;
    }
}
예제 #7
0
파일: hfafield.cpp 프로젝트: hkaiser/TRiAS
int HFAField::GetInstBytes( GByte * pabyData )

{
    int		nCount;
    int		nInstBytes = 0;
    
    if( nBytes > -1 )
        return nBytes;

    if( chPointer != '\0' )
    {
        memcpy( &nCount, pabyData, 4 );
        HFAStandard( 4, &nCount );

        pabyData += 8;
        nInstBytes += 8;
    }
    else
        nCount = 1;

    if( poItemObjectType == NULL )
    {
        nInstBytes += nCount * HFADictionary::GetItemSize(chItemType);
    }
    else
    {
        int		i;

        for( i = 0; i < nCount; i++ )
        {
            int	nThisBytes;

            nThisBytes = poItemObjectType->GetInstBytes( pabyData );
            nInstBytes += nThisBytes;
            pabyData += nThisBytes;
        }
    }

    return( nInstBytes );
}
예제 #8
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;
    }
}
예제 #9
0
CPLErr
HFAField::SetInstValue( const char * pszField, int nIndexValue,
                        GByte *pabyData, GUInt32 nDataOffset, int nDataSize,
                        char chReqType, void *pValue )

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

         /* set the count for fixed sized arrays */
        if( nBytes > -1 )
            nCount = nItemCount;

        // The count returned for BASEDATA's are the contents, 
        // but here we really want to mark it as one BASEDATA instance
        // (see #2144)
        if( chItemType == 'b' ) 
            nCount = 1;

        /* Set the size from string length */
        else if( chReqType == 's' && (chItemType == 'c' || chItemType == 'C'))
        {
            if( pValue == NULL )
                nCount = 0;
            else
                nCount = strlen((char *) pValue) + 1;
        }

        /* set size based on index ... assumes in-order setting of array */
        else
            nCount = nIndexValue+1;

        if( (int) nCount + 8 > nDataSize )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Attempt to extend field %s in node past end of data,\n"
                      "not currently supported.",
                      pszField );
            return CE_Failure;
        }

        // we will update the object count iff we are writing beyond the end
        memcpy( &nOffset, pabyData, 4 );
        HFAStandard( 4, &nOffset );
        if( nOffset < nCount )
        {
            nOffset = nCount;
            HFAStandard( 4, &nOffset );
            memcpy( pabyData, &nOffset, 4 );
        }

        if( pValue == NULL )
            nOffset = 0;
        else
            nOffset = nDataOffset + 8;
        HFAStandard( 4, &nOffset );
        memcpy( pabyData+4, &nOffset, 4 );

        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' )
    {
        int	nBytesToCopy;
        
        if( nBytes == -1 )
        {
            if( pValue == NULL )
                nBytesToCopy = 0;
            else
                nBytesToCopy = strlen((char *) pValue) + 1;
        }
        else
            nBytesToCopy = nBytes;

        if( nBytesToCopy > nDataSize )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Attempt to extend field %s in node past end of data,\n"
                      "not currently supported.",
                      pszField );
            return CE_Failure;
        }

        memset( pabyData, 0, nBytesToCopy );

        if( pValue != NULL )
            strncpy( (char *) pabyData, (char *) pValue, nBytesToCopy );

        return CE_None;
    }

/* -------------------------------------------------------------------- */
/*      Translate the passed type into different representations.       */
/* -------------------------------------------------------------------- */
    int		nIntValue;
    double      dfDoubleValue;

    if( chReqType == 's' )
    {
        nIntValue = atoi((char *) pValue);
        dfDoubleValue = atof((char *) pValue);
    }
    else if( chReqType == 'd' )
    {
        dfDoubleValue = *((double *) pValue);
        nIntValue = (int) dfDoubleValue;
    }
    else if( chReqType == 'i' )
    {
        dfDoubleValue = *((int *) pValue);
        nIntValue = *((int *) pValue);
    }
    else if( chReqType == 'p' )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
            "HFAField::SetInstValue() not supported yet for pointer values." );
        
        return CE_Failure;
    }
    else
    {
        CPLAssert( FALSE );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Handle by type.                                                 */
/* -------------------------------------------------------------------- */
    switch( chItemType )
    {
      case 'c':
      case 'C':
        if( nIndexValue + 1 > nDataSize )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Attempt to extend field %s in node past end of data,\n"
                      "not currently supported.",
                      pszField );
              return CE_Failure;
        }

        if( chReqType == 's' )
            pabyData[nIndexValue] = ((char *) pValue)[0];
        else
            pabyData[nIndexValue] = (char) nIntValue;
        break;

      case 'e':
      case 's':
      {
          if( chItemType == 'e' && chReqType == 's' )
          {
              nIntValue = CSLFindString( papszEnumNames, (char *) pValue );
              if( nIntValue == -1 )
              {
                  CPLError( CE_Failure, CPLE_AppDefined, 
                            "Attempt to set enumerated field with unknown"
                            " value `%s'.", 
                            (char *) pValue );
                  return CE_Failure;
              }
          }

          unsigned short nNumber = (unsigned short) nIntValue;

          if( nIndexValue*2 + 2 > nDataSize )
          {
              CPLError( CE_Failure, CPLE_AppDefined,
                        "Attempt to extend field %s in node past end of data,\n"
                        "not currently supported.",
                        pszField );
              return CE_Failure;
          }

          HFAStandard( 2, &nNumber );
          memcpy( pabyData + nIndexValue*2, &nNumber, 2 );
      }
      break;

      case 'S':
      {
          short nNumber;

          if( nIndexValue*2 + 2 > nDataSize )
          {
              CPLError( CE_Failure, CPLE_AppDefined,
                        "Attempt to extend field %s in node past end of data,\n"
                        "not currently supported.",
                        pszField );
              return CE_Failure;
          }

          nNumber = (short) nIntValue;
          HFAStandard( 2, &nNumber );
          memcpy( pabyData + nIndexValue*2, &nNumber, 2 );
      }
      break;
        
      case 't':
      case 'l':
      {
          GUInt32	nNumber = nIntValue;

          if( nIndexValue*4 + 4 > nDataSize )
          {
              CPLError( CE_Failure, CPLE_AppDefined,
                        "Attempt to extend field %s in node past end of data,\n"
                        "not currently supported.",
                        pszField );
              return CE_Failure;
          }

          HFAStandard( 4, &nNumber );
          memcpy( pabyData + nIndexValue*4, &nNumber, 4 );
      }
      break;
      
      case 'L':
      {
          GInt32	nNumber = nIntValue;
          
          if( nIndexValue*4 + 4 > nDataSize )
          {
              CPLError( CE_Failure, CPLE_AppDefined,
                        "Attempt to extend field %s in node past end of data,\n"
                        "not currently supported.",
                        pszField );
              return CE_Failure;
          }

          HFAStandard( 4, &nNumber );
          memcpy( pabyData + nIndexValue*4, &nNumber, 4 );
      }
      break;
      
      case 'f':
      {
          float		fNumber = (float) dfDoubleValue;
          
          if( nIndexValue*4 + 4 > nDataSize )
          {
              CPLError( CE_Failure, CPLE_AppDefined,
                        "Attempt to extend field %s in node past end of data,\n"
                        "not currently supported.",
                        pszField );
              return CE_Failure;
          }

          HFAStandard( 4, &fNumber );
          memcpy( pabyData + nIndexValue*4, &fNumber, 4 );
      }
      break;
        
      case 'd':
      {
          double	dfNumber = dfDoubleValue;
          
          if( nIndexValue*8 + 8 > nDataSize )
          {
              CPLError( CE_Failure, CPLE_AppDefined,
                        "Attempt to extend field %s in node past end of data,\n"
                        "not currently supported.",
                        pszField );
              return CE_Failure;
          }

          HFAStandard( 8, &dfNumber );
          memcpy( pabyData + nIndexValue*8, &dfNumber, 8 );
      }
      break;

    case 'b': 
    { 
        GInt32 nRows = 1; 
        GInt32 nColumns = 1; 
        GInt16 nBaseItemType;

        // Extract existing rows, columns, and datatype.
        memcpy( &nRows, pabyData, 4 );
        HFAStandard( 4, &nRows );
        memcpy( &nColumns, pabyData+4, 4 );
        HFAStandard( 4, &nColumns );
        memcpy( &nBaseItemType, pabyData+8, 2 );
        HFAStandard( 2, &nBaseItemType );

        // Are we using special index values to update the rows, columnrs
        // or type?
        
        if( nIndexValue == -3 )
            nBaseItemType = nIntValue;
        else if( nIndexValue == -2 )
            nColumns = nIntValue;
        else if( nIndexValue == -1 )
            nRows = nIntValue;

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

        // Write back the rows, columns and basedatatype.
        HFAStandard( 4, &nRows ); 
        memcpy( pabyData, &nRows, 4 ); 
        HFAStandard( 4, &nColumns ); 
        memcpy( pabyData+4, &nColumns, 4 ); 
        HFAStandard( 2, &nBaseItemType ); 
        memcpy ( pabyData + 8, &nBaseItemType, 2 ); 
        HFAStandard( 2, &nBaseItemType ); // swap back for our use.

        // We ignore the 2 byte objecttype value.  

        nDataSize -= 12; 

        if( nIndexValue >= 0 )
        { 
            if( (nIndexValue+1) * (HFAGetDataTypeBits(nBaseItemType)/8)
                > nDataSize ) 
            { 
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "Attempt to extend field %s in node past end of data,\n" 
                          "not currently supported.", 
                          pszField ); 
                return CE_Failure; 
            } 

            if( nBaseItemType == EPT_f64 )
            {
                double dfNumber = dfDoubleValue; 

                HFAStandard( 8, &dfNumber ); 
                memcpy( pabyData + 12 + nIndexValue * 8, &dfNumber, 8 ); 
            }
            else
            {
                CPLError( CE_Failure, CPLE_AppDefined, 
                          "Setting basedata field %s with type %s not currently supported.", 
                          pszField, HFAGetDataTypeName( nBaseItemType ) ); 
                return CE_Failure; 
            }
        } 
    } 
    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;

            if( pszField != NULL && strlen(pszField) > 0 )
            {
                return( poItemObjectType->
                            SetInstValue( pszField, pabyData + nExtraOffset,
                                          nDataOffset + nExtraOffset,
                                          nDataSize - nExtraOffset,
                                          chReqType, pValue ) );
            }
            else
            {
                CPLAssert( FALSE );
                return CE_Failure;
            }
        }
        break;

      default:
        CPLAssert( FALSE );
        return CE_Failure;
        break;
    }

    return CE_None;
}
예제 #10
0
int HFAField::GetInstBytes( GByte *pabyData, int nDataSize )

{
    int		nCount;
    int		nInstBytes = 0;
    
    if( nBytes > -1 )
        return nBytes;

    if( chPointer != '\0' )
    {
        if (nDataSize < 4)
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
            return -1;
        }

        memcpy( &nCount, pabyData, 4 );
        HFAStandard( 4, &nCount );

        pabyData += 8;
        nInstBytes += 8;
    }
    else
        nCount = 1;

    if( chItemType == 'b' && nCount != 0 ) // BASEDATA
    {
        if (nDataSize - nInstBytes < 4+4+2)
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Buffer too small");
            return -1;
        }

        GInt32 nRows, nColumns;
        GInt16 nBaseItemType;
        
        memcpy( &nRows, pabyData, 4 );
        HFAStandard( 4, &nRows );
        memcpy( &nColumns, pabyData+4, 4 );
        HFAStandard( 4, &nColumns );
        memcpy( &nBaseItemType, pabyData+8, 2 );
        HFAStandard( 2, &nBaseItemType );

        nInstBytes += 12;
        
        if (nRows < 0 || nColumns < 0)
            return -1;
        if (nColumns != 0 && nRows > INT_MAX / nColumns)
            return -1;
        if (nColumns != 0 && ((HFAGetDataTypeBits(nBaseItemType) + 7) / 8) * nRows > INT_MAX / nColumns)
            return -1;
        if (((HFAGetDataTypeBits(nBaseItemType) + 7) / 8) * nRows * nColumns > INT_MAX - nInstBytes)
            return -1;

        nInstBytes += 
            ((HFAGetDataTypeBits(nBaseItemType) + 7) / 8) * nRows * nColumns;
    }
    else if( poItemObjectType == NULL )
    {
        if (nCount != 0 && HFADictionary::GetItemSize(chItemType) > INT_MAX / nCount)
            return -1;
        nInstBytes += nCount * HFADictionary::GetItemSize(chItemType);
    }
    else
    {
        int		i;

        for( i = 0; i < nCount &&
                    nInstBytes < nDataSize &&
                    nInstBytes >= 0; i++ )
        {
            int	nThisBytes;

            nThisBytes =
                poItemObjectType->GetInstBytes( pabyData,
                                                nDataSize - nInstBytes );
            if (nThisBytes < 0 || nInstBytes > INT_MAX - nThisBytes)
            {
                CPLError(CE_Failure, CPLE_AppDefined, "Invalid return value");
                return -1;
            }

            nInstBytes += nThisBytes;
            pabyData += nThisBytes;
        }
    }

    return( nInstBytes );
}
예제 #11
0
파일: hfaopen.cpp 프로젝트: hkaiser/TRiAS
HFAHandle HFAOpen( const char * pszFilename, const char * pszAccess )

{
    FILE	*fp;
    char	szHeader[16];
    HFAInfo_t	*psInfo;
    GUInt32	nHeaderPos;
    HFAEntry	*poNode;

/* -------------------------------------------------------------------- */
/*      Open the file.                                                  */
/* -------------------------------------------------------------------- */
    if( EQUAL(pszAccess,"r") || EQUAL(pszAccess,"rb" ) )
        fp = VSIFOpen( pszFilename, "rb" );
    else
        fp = VSIFOpen( pszFilename, "r+b" );

    /* should this be changed to use some sort of CPLFOpen() which will
       set the error? */
    if( fp == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed,
                  "File open of %s failed.",
                  pszFilename );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Read and verify the header.                                     */
/* -------------------------------------------------------------------- */
    if( VSIFRead( szHeader, 16, 1, fp ) < 1 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Attempt to read 16 byte header failed for\n%s.",
                  pszFilename );

        return NULL;
    }

    if( !EQUALN(szHeader,"EHFA_HEADER_TAG",15) )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "File %s is not an Imagine HFA file ... header wrong.",
                  pszFilename );

        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create the HFAInfo_t                                            */
/* -------------------------------------------------------------------- */
    psInfo = (HFAInfo_t *) CPLCalloc(sizeof(HFAInfo_t),1);

    psInfo->fp = fp;

/* -------------------------------------------------------------------- */
/*	Where is the header?						*/
/* -------------------------------------------------------------------- */
    VSIFRead( &nHeaderPos, sizeof(GInt32), 1, fp );
    HFAStandard( 4, &nHeaderPos );

/* -------------------------------------------------------------------- */
/*      Read the header.                                                */
/* -------------------------------------------------------------------- */
    VSIFSeek( fp, nHeaderPos, SEEK_SET );

    VSIFRead( &(psInfo->nVersion), sizeof(GInt32), 1, fp );
    HFAStandard( 4, &(psInfo->nVersion) );
    
    VSIFRead( szHeader, 4, 1, fp ); /* skip freeList */

    VSIFRead( &(psInfo->nRootPos), sizeof(GInt32), 1, fp );
    HFAStandard( 4, &(psInfo->nRootPos) );
    
    VSIFRead( &(psInfo->nEntryHeaderLength), sizeof(GInt16), 1, fp );
    HFAStandard( 2, &(psInfo->nEntryHeaderLength) );
    
    VSIFRead( &(psInfo->nDictionaryPos), sizeof(GInt32), 1, fp );
    HFAStandard( 4, &(psInfo->nDictionaryPos) );

/* -------------------------------------------------------------------- */
/*      Instantiate the root entry.                                     */
/* -------------------------------------------------------------------- */
    psInfo->poRoot = new HFAEntry( psInfo, psInfo->nRootPos, NULL, NULL );

/* -------------------------------------------------------------------- */
/*      Read the dictionary                                             */
/* -------------------------------------------------------------------- */
    psInfo->pszDictionary = HFAGetDictionary( psInfo );
    psInfo->poDictionary = new HFADictionary( psInfo->pszDictionary );

/* -------------------------------------------------------------------- */
/*      Find the first band node.                                       */
/* -------------------------------------------------------------------- */
    psInfo->nBands = 0;
    poNode = psInfo->poRoot->GetChild();
    while( poNode != NULL )
    {
        if( EQUAL(poNode->GetType(),"Eimg_Layer") )
        {
            if( psInfo->nBands == 0 )
            {
                psInfo->nXSize = poNode->GetIntField("width");
                psInfo->nYSize = poNode->GetIntField("height");
            }
            else if( poNode->GetIntField("width") != psInfo->nXSize
                     || poNode->GetIntField("height") != psInfo->nYSize )
            {
                CPLAssert( FALSE );
                continue;
            }

            psInfo->papoBand = (HFABand **)
                CPLRealloc(psInfo->papoBand,
                           sizeof(HFABand *) * (psInfo->nBands+1));
            psInfo->papoBand[psInfo->nBands] = new HFABand( psInfo, poNode );
            psInfo->nBands++;
        }
        
        poNode = poNode->GetNext();
    }

    return psInfo;
}
예제 #12
0
파일: hfafield.cpp 프로젝트: hkaiser/TRiAS
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;
    }
}
예제 #13
0
CPLErr HFAEntry::FlushToDisk()

{
    CPLErr	eErr = CE_None;

/* -------------------------------------------------------------------- */
/*      If we are the root node, call SetPosition() on the whole        */
/*      tree to ensure that all entries have an allocated position.     */
/* -------------------------------------------------------------------- */
    if( poParent == NULL )
        SetPosition();

/* ==================================================================== */
/*      Only write this node out if it is dirty.                        */
/* ==================================================================== */
    if( bDirty )
    {
/* -------------------------------------------------------------------- */
/*      Ensure we know where the relative entries are located.          */
/* -------------------------------------------------------------------- */
        if( poNext != NULL )
            nNextPos = poNext->nFilePos;

        if( poChild != NULL )
            nChildPos = poChild->nFilePos;

/* -------------------------------------------------------------------- */
/*      Write the Ehfa_Entry fields.                                    */
/* -------------------------------------------------------------------- */
        GUInt32		nLong;

        //VSIFFlushL( psHFA->fp );
        if( VSIFSeekL( psHFA->fp, nFilePos, SEEK_SET ) != 0 )
        {
            CPLError( CE_Failure, CPLE_FileIO, 
                      "Failed to seek to %d for writing, out of disk space?",
                      nFilePos );
            return CE_Failure;
        }

        nLong = nNextPos;
        HFAStandard( 4, &nLong );
        VSIFWriteL( &nLong, 4, 1, psHFA->fp );

        if( poPrev != NULL )
            nLong = poPrev->nFilePos;
        else
            nLong = 0;
        HFAStandard( 4, &nLong );
        VSIFWriteL( &nLong, 4, 1, psHFA->fp );

        if( poParent != NULL )
            nLong = poParent->nFilePos;
        else
            nLong = 0;
        HFAStandard( 4, &nLong );
        VSIFWriteL( &nLong, 4, 1, psHFA->fp );

        nLong = nChildPos;
        HFAStandard( 4, &nLong );
        VSIFWriteL( &nLong, 4, 1, psHFA->fp );

        
        nLong = nDataPos;
        HFAStandard( 4, &nLong );
        VSIFWriteL( &nLong, 4, 1, psHFA->fp );

        nLong = nDataSize;
        HFAStandard( 4, &nLong );
        VSIFWriteL( &nLong, 4, 1, psHFA->fp );

        VSIFWriteL( szName, 1, 64, psHFA->fp );
        VSIFWriteL( szType, 1, 32, psHFA->fp );

        nLong = 0; /* Should we keep the time, or set it more reasonably? */
        if( VSIFWriteL( &nLong, 4, 1, psHFA->fp ) != 1 )
        {
            CPLError( CE_Failure, CPLE_FileIO, 
                      "Failed to write HFAEntry %s(%s), out of disk space?",
                      szName, szType );
            return CE_Failure;
        }

/* -------------------------------------------------------------------- */
/*      Write out the data.                                             */
/* -------------------------------------------------------------------- */
        //VSIFFlushL( psHFA->fp );
        if( nDataSize > 0 && pabyData != NULL )
        {
            if( VSIFSeekL( psHFA->fp, nDataPos, SEEK_SET ) != 0 
                || VSIFWriteL( pabyData, nDataSize, 1, psHFA->fp ) != 1 )
            {
                CPLError( CE_Failure, CPLE_FileIO, 
                          "Failed to write %d bytes HFAEntry %s(%s) data,\n"
                          "out of disk space?",
                          nDataSize, szName, szType );
                return CE_Failure;
            }
        }

        //VSIFFlushL( psHFA->fp );
    }

/* -------------------------------------------------------------------- */
/*      Process all the children of this node                           */
/* -------------------------------------------------------------------- */
    for( HFAEntry *poThisChild = poChild; 
         poThisChild != NULL;
         poThisChild = poThisChild->poNext )
    {
        eErr = poThisChild->FlushToDisk();
        if( eErr != CE_None )
            return eErr;
    }

    bDirty = FALSE;

    return CE_None;
}
예제 #14
0
HFAEntry* HFAEntry::BuildEntryFromMIFObject( HFAEntry *poContainer, const char *pszMIFObjectPath )
{
    const char* pszField;
    CPLString osFieldName;

    osFieldName.Printf("%s.%s", pszMIFObjectPath, "MIFDictionary" );
    pszField = poContainer->GetStringField( osFieldName.c_str() );
    if (pszField == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot find %s entry",
                 osFieldName.c_str());
        return NULL;
    }
    CPLString osDictionnary = pszField;

    osFieldName.Printf("%s.%s", pszMIFObjectPath, "type.string" );
    pszField = poContainer->GetStringField( osFieldName.c_str() );
    if (pszField == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot find %s entry",
                 osFieldName.c_str());
        return NULL;
    }
    CPLString osType = pszField;

    osFieldName.Printf("%s.%s", pszMIFObjectPath, "MIFObject" );
    int nRemainingDataSize = 0;
    pszField = poContainer->GetStringField( osFieldName.c_str(),
                                            NULL, &nRemainingDataSize );
    if (pszField == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Cannot find %s entry",
                 osFieldName.c_str());
        return NULL;
    }

    GInt32 nMIFObjectSize;
    // we rudely look before the field data to get at the pointer/size info
    memcpy( &nMIFObjectSize, pszField-8, 4 );
    HFAStandard( 4, &nMIFObjectSize );
    if (nMIFObjectSize <= 0)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Invalid MIF object size (%d)",
                 nMIFObjectSize);
        return NULL;
    }

    // check that we won't copy more bytes than available in the buffer
    if (nMIFObjectSize > nRemainingDataSize)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "Invalid MIF object size (%d > %d)",
                 nMIFObjectSize, nRemainingDataSize);
        return NULL;
    }

    GByte* pabyData = (GByte *) VSIMalloc(nMIFObjectSize);
    if (pabyData == NULL)
        return NULL;

    memcpy( pabyData, pszField, nMIFObjectSize );

    return new HFAEntry(poContainer, pszMIFObjectPath,
                        osDictionnary, osType,
                        nMIFObjectSize, pabyData);

}
예제 #15
0
HFAEntry::HFAEntry( HFAEntry * poContainer,
                    const char *pszMIFObjectPath )

{
/* -------------------------------------------------------------------- */
/*      Initialize Entry                                                */
/* -------------------------------------------------------------------- */
    nFilePos = 0;

    poParent = poPrev = poNext = poChild = NULL;

    bIsMIFObject = TRUE;

    nDataPos = nDataSize = 0;
    nNextPos = nChildPos = 0;

    memset( szName, 0, 64 );

    pabyData = NULL;
    poType = NULL;

/* -------------------------------------------------------------------- */
/*      Create a dummy HFAInfo_t.                                       */
/* -------------------------------------------------------------------- */
    psHFA = (HFAInfo_t *) CPLCalloc(sizeof(HFAInfo_t),1);

    psHFA->eAccess = HFA_ReadOnly;
    psHFA->bTreeDirty = FALSE;
    psHFA->poRoot = this;

    psHFA->poDictionary = new HFADictionary( 
        poContainer->GetStringField( 
            CPLString().Printf("%s.%s", pszMIFObjectPath, "MIFDictionary" ) ) );

/* -------------------------------------------------------------------- */
/*      Work out the type for this MIFObject.                           */
/* -------------------------------------------------------------------- */
    memset( szType, 0, 32 );
    strncpy( szType, 
             poContainer->GetStringField( 
                 CPLString().Printf("%s.%s", pszMIFObjectPath, "type.string") ),
             32 );
    
    poType = psHFA->poDictionary->FindType( szType );

/* -------------------------------------------------------------------- */
/*      Find the desired field.                                         */
/* -------------------------------------------------------------------- */
    GInt32 nMIFObjectSize;
    const GByte *pabyRawData = (const GByte *) 
        poContainer->GetStringField( 
            CPLString().Printf("%s.%s", pszMIFObjectPath, "MIFObject" ) );

    // we rudely look before the field data to get at the pointer/size info
    memcpy( &nMIFObjectSize, pabyRawData-8, 4 );
    HFAStandard( 4, &nMIFObjectSize );

    nDataSize = nMIFObjectSize;
    pabyData = (GByte *) VSIMalloc(nDataSize);

    memcpy( pabyData, pabyRawData, nDataSize );
}
예제 #16
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;
    }
}