📄 ddfsubfielddefn.cpp
字号:
/************************************************************************//* ExtractIntData() *//************************************************************************//** * Extract a subfield value as an integer. Given a pointer to the data * for this subfield (from within a DDFRecord) this method will return the * int data for this subfield. The number of bytes * consumed as part of this field can also be fetched. This method may be * called for any type of subfield, and will return zero if the subfield is * not numeric. * * @param pachSourceData The pointer to the raw data for this field. This * may have come from DDFRecord::GetData(), taking into account skip factors * over previous subfields data. * @param nMaxBytes The maximum number of bytes that are accessable after * pachSourceData. * @param pnConsumedBytes Pointer to an integer into which the number of * bytes consumed by this field should be written. May be NULL to ignore. * This is used as a skip factor to increment pachSourceData to point to the * next subfields data. * * @return The subfield's numeric value (or zero if it isn't numeric). * * @see ExtractFloatData(), ExtractStringData() */intDDFSubfieldDefn::ExtractIntData( const char * pachSourceData, int nMaxBytes, int * pnConsumedBytes ){ switch( pszFormatString[0] ) { case 'A': case 'I': case 'R': case 'S': case 'C': return atoi(ExtractStringData(pachSourceData, nMaxBytes, pnConsumedBytes)); case 'B': case 'b': { unsigned char abyData[8]; if( nFormatWidth > nMaxBytes ) { CPLError( CE_Warning, CPLE_AppDefined, "Attempt to extract int subfield %s with format %s\n" "failed as only %d bytes available. Using zero.", pszName, pszFormatString, nMaxBytes ); return 0; } if( pnConsumedBytes != NULL ) *pnConsumedBytes = nFormatWidth; // Byte swap the data if it isn't in machine native format. // In any event we copy it into our buffer to ensure it is // word aligned.#ifdef CPL_LSB if( pszFormatString[0] == 'B' )#else if( pszFormatString[0] == 'b' )#endif { for( int i = 0; i < nFormatWidth; i++ ) abyData[nFormatWidth-i-1] = pachSourceData[i]; } else { memcpy( abyData, pachSourceData, nFormatWidth ); } // Interpret the bytes of data. switch( eBinaryFormat ) { case UInt: if( nFormatWidth == 4 ) return( (int) *((GUInt32 *) abyData) ); else if( nFormatWidth == 1 ) return( abyData[0] ); else if( nFormatWidth == 2 ) return( *((GUInt16 *) abyData) ); else { CPLAssert( FALSE ); return 0; } case SInt: if( nFormatWidth == 4 ) return( *((GInt32 *) abyData) ); else if( nFormatWidth == 1 ) return( *((signed char *) abyData) ); else if( nFormatWidth == 2 ) return( *((GInt16 *) abyData) ); else { CPLAssert( FALSE ); return 0; } case FloatReal: if( nFormatWidth == 4 ) return( (int) *((float *) abyData) ); else if( nFormatWidth == 8 ) return( (int) *((double *) abyData) ); else { CPLAssert( FALSE ); return 0; } case NotBinary: case FPReal: case FloatComplex: CPLAssert( FALSE ); return 0; } break; // end of 'b'/'B' case. } default: CPLAssert( FALSE ); return 0; } CPLAssert( FALSE ); return 0;}/************************************************************************//* DumpData() *//* *//* Dump the instance data for this subfield from a data *//* record. This fits into the output dump stream of a DDFField. *//************************************************************************//** * Dump subfield value to debugging file. * * @param pachData Pointer to data for this subfield. * @param nMaxBytes Maximum number of bytes available in pachData. * @param fp File to write report to. */void DDFSubfieldDefn::DumpData( const char * pachData, int nMaxBytes, FILE * fp ){ if( eType == DDFFloat ) fprintf( fp, " Subfield `%s' = %f\n", pszName, ExtractFloatData( pachData, nMaxBytes, NULL ) ); else if( eType == DDFInt ) fprintf( fp, " Subfield `%s' = %d\n", pszName, ExtractIntData( pachData, nMaxBytes, NULL ) ); else if( eType == DDFBinaryString ) { int nBytes, i; GByte *pabyBString = (GByte *) ExtractStringData( pachData, nMaxBytes, &nBytes ); fprintf( fp, " Subfield `%s' = 0x", pszName ); for( i = 0; i < MIN(nBytes,24); i++ ) fprintf( fp, "%02X", pabyBString[i] ); if( nBytes > 24 ) fprintf( fp, "%s", "..." ); fprintf( fp, "\n" ); } else fprintf( fp, " Subfield `%s' = `%s'\n", pszName, ExtractStringData( pachData, nMaxBytes, NULL ) );}/************************************************************************//* GetDefaultValue() *//************************************************************************//** * Get default data. * * Returns the default subfield data contents for this subfield definition. * For variable length numbers this will normally be "0<unit-terminator>". * For variable length strings it will be "<unit-terminator>". For fixed * length numbers it is zero filled. For fixed length strings it is space * filled. For binary numbers it is binary zero filled. * * @param pachData the buffer into which the returned default will be placed. * May be NULL if just querying default size. * @param nBytesAvailable the size of pachData in bytes. * @param pnBytesUsed will receive the size of the subfield default data in * bytes. * * @return TRUE on success or FALSE on failure or if the passed buffer is too * small to hold the default. */int DDFSubfieldDefn::GetDefaultValue( char *pachData, int nBytesAvailable, int *pnBytesUsed ){ int nDefaultSize; if( !bIsVariable ) nDefaultSize = nFormatWidth; else nDefaultSize = 1; if( pnBytesUsed != NULL ) *pnBytesUsed = nDefaultSize; if( pachData == NULL ) return TRUE; if( nBytesAvailable < nDefaultSize ) return FALSE; if( bIsVariable ) { pachData[0] = DDF_UNIT_TERMINATOR; } else { if( GetBinaryFormat() == NotBinary ) { if( GetType() == DDFInt || GetType() == DDFFloat ) memset( pachData, '0', nDefaultSize ); else memset( pachData, ' ', nDefaultSize ); } else memset( pachData, 0, nDefaultSize ); } return TRUE;}/************************************************************************//* FormatStringValue() *//************************************************************************//** * Format string subfield value. * * Returns a buffer with the passed in string value reformatted in a way * suitable for storage in a DDFField for this subfield. */int DDFSubfieldDefn::FormatStringValue( char *pachData, int nBytesAvailable, int *pnBytesUsed, const char *pszValue, int nValueLength ){ int nSize; if( nValueLength == -1 ) nValueLength = strlen(pszValue); if( bIsVariable ) { nSize = nValueLength + 1; } else { nSize = nFormatWidth; } if( pnBytesUsed != NULL ) *pnBytesUsed = nSize; if( pachData == NULL ) return TRUE; if( nBytesAvailable < nSize ) return FALSE; if( bIsVariable ) { strncpy( pachData, pszValue, nSize-1 ); pachData[nSize-1] = DDF_UNIT_TERMINATOR; } else { if( GetBinaryFormat() == NotBinary ) { memset( pachData, ' ', nSize ); memcpy( pachData, pszValue, MIN(nValueLength,nSize) ); } else { memset( pachData, 0, nSize ); memcpy( pachData, pszValue, MIN(nValueLength,nSize) ); } } return TRUE;}/************************************************************************//* FormatIntValue() *//************************************************************************//** * Format int subfield value. * * Returns a buffer with the passed in int value reformatted in a way * suitable for storage in a DDFField for this subfield. */int DDFSubfieldDefn::FormatIntValue( char *pachData, int nBytesAvailable, int *pnBytesUsed, int nNewValue ){ int nSize; char szWork[30]; sprintf( szWork, "%d", nNewValue ); if( bIsVariable ) { nSize = strlen(szWork) + 1; } else { nSize = nFormatWidth; if( GetBinaryFormat() == NotBinary && (int) strlen(szWork) > nSize ) return FALSE; } if( pnBytesUsed != NULL ) *pnBytesUsed = nSize; if( pachData == NULL ) return TRUE; if( nBytesAvailable < nSize ) return FALSE; if( bIsVariable ) { strncpy( pachData, szWork, nSize-1 ); pachData[nSize-1] = DDF_UNIT_TERMINATOR; } else { GUInt32 nMask = 0xff; int i; switch( GetBinaryFormat() ) { case NotBinary: memset( pachData, '0', nSize ); strncpy( pachData + nSize - strlen(szWork), szWork, strlen(szWork) ); break; case UInt: case SInt: for( i = 0; i < nFormatWidth; i++ ) { int iOut; // big endian required? if( pszFormatString[0] == 'B' ) iOut = nFormatWidth - i - 1; else iOut = i; pachData[iOut] = (nNewValue & nMask) >> (i*8); nMask *= 256; } break; case FloatReal: CPLAssert( FALSE ); break; default: CPLAssert( FALSE ); break; } } return TRUE;}/************************************************************************//* FormatFloatValue() *//************************************************************************//** * Format float subfield value. * * Returns a buffer with the passed in float value reformatted in a way * suitable for storage in a DDFField for this subfield. */int DDFSubfieldDefn::FormatFloatValue( char *pachData, int nBytesAvailable, int *pnBytesUsed, double dfNewValue ){ int nSize; char szWork[120]; sprintf( szWork, "%.16g", dfNewValue ); if( bIsVariable ) { nSize = strlen(szWork) + 1; } else { nSize = nFormatWidth; if( GetBinaryFormat() == NotBinary && (int) strlen(szWork) > nSize ) return FALSE; } if( pnBytesUsed != NULL ) *pnBytesUsed = nSize; if( pachData == NULL ) return TRUE; if( nBytesAvailable < nSize ) return FALSE; if( bIsVariable ) { strncpy( pachData, szWork, nSize-1 ); pachData[nSize-1] = DDF_UNIT_TERMINATOR; } else { if( GetBinaryFormat() == NotBinary ) { memset( pachData, '0', nSize ); strncpy( pachData + nSize - strlen(szWork), szWork, strlen(szWork) ); } else { CPLAssert( FALSE ); /* implement me */ } } return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -