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; } }
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 ); }
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; } }
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 ); }
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; } }