📄 ddfrecord.cpp
字号:
/* -------------------------------------------------------------------- */ if( nRawDataSize >= nOldSize ) { memmove( ((char *) poField->GetData()) + nPreBytes + nRawDataSize, ((char *) poField->GetData()) + nPreBytes + nOldSize, nPostBytes ); memcpy( ((char*) poField->GetData()) + nPreBytes, pachRawData, nRawDataSize ); } return TRUE;}/************************************************************************//* ResetDirectory() *//* *//* Re-prepares the directory information for the record. *//************************************************************************/int DDFRecord::ResetDirectory(){ int iField;/* -------------------------------------------------------------------- *//* Eventually we should try to optimize the size of offset and *//* field length. For now we will use 5 for each which is *//* pretty big. *//* -------------------------------------------------------------------- */ _sizeFieldPos = 5; _sizeFieldLength = 5;/* -------------------------------------------------------------------- *//* Compute how large the directory needs to be. *//* -------------------------------------------------------------------- */ int nEntrySize, nDirSize; nEntrySize = _sizeFieldPos + _sizeFieldLength + _sizeFieldTag; nDirSize = nEntrySize * nFieldCount + 1;/* -------------------------------------------------------------------- *//* If the directory size is different than what is currently *//* reserved for it, we must resize. *//* -------------------------------------------------------------------- */ if( nDirSize != nFieldOffset ) { char *pachNewData; int nNewDataSize; nNewDataSize = nDataSize - nFieldOffset + nDirSize; pachNewData = (char *) CPLMalloc(nNewDataSize); memcpy( pachNewData + nDirSize, pachData + nFieldOffset, nNewDataSize - nDirSize ); for( iField = 0; iField < nFieldCount; iField++ ) { int nOffset; DDFField *poField = GetField( iField ); nOffset = poField->GetData() - pachData - nFieldOffset + nDirSize; poField->Initialize( poField->GetFieldDefn(), pachNewData + nOffset, poField->GetDataSize() ); } CPLFree( pachData ); pachData = pachNewData; nDataSize = nNewDataSize; nFieldOffset = nDirSize; }/* -------------------------------------------------------------------- *//* Now set each directory entry. *//* -------------------------------------------------------------------- */ for( iField = 0; iField < nFieldCount; iField++ ) { DDFField *poField = GetField( iField ); DDFFieldDefn *poDefn = poField->GetFieldDefn(); char szFormat[128]; sprintf( szFormat, "%%%ds%%0%dd%%0%dd", _sizeFieldTag, _sizeFieldLength, _sizeFieldPos ); sprintf( pachData + nEntrySize * iField, szFormat, poDefn->GetName(), poField->GetDataSize(), poField->GetData() - pachData - nFieldOffset ); } pachData[nEntrySize * nFieldCount] = DDF_FIELD_TERMINATOR; return TRUE;}/************************************************************************//* CreateDefaultFieldInstance() *//************************************************************************//** * Initialize default instance. * * This method is normally only used internally by the AddField() method * to initialize the new field instance with default subfield values. It * installs default data for one instance of the field in the record * using the DDFFieldDefn::GetDefaultValue() method and * DDFRecord::SetFieldRaw(). * * @param poField the field within the record to be assign a default * instance. * @param iIndexWithinField the instance to set (may not have been tested with * values other than 0). * * @return TRUE on success or FALSE on failure. */int DDFRecord::CreateDefaultFieldInstance( DDFField *poField, int iIndexWithinField ){ int nRawSize, nSuccess; char *pachRawData; pachRawData = poField->GetFieldDefn()->GetDefaultValue( &nRawSize ); if( pachRawData == NULL ) return FALSE; nSuccess = SetFieldRaw( poField, iIndexWithinField, pachRawData, nRawSize); CPLFree( pachRawData ); return nSuccess;}/************************************************************************//* SetStringSubfield() *//************************************************************************//** * Set a string subfield in record. * * The value of a given subfield is replaced with a new string value * formatted appropriately. * * @param pszField the field name to operate on. * @param iFieldIndex the field index to operate on (zero based). * @param pszSubfield the subfield name to operate on. * @param iSubfieldIndex the subfield index to operate on (zero based). * @param pszValue the new string to place in the subfield. This may be * arbitrary binary bytes if nValueLength is specified. * @param nValueLength the number of valid bytes in pszValue, may be -1 to * internally fetch with strlen(). * * @return TRUE if successful, and FALSE if not. */int DDFRecord::SetStringSubfield( const char *pszField, int iFieldIndex, const char *pszSubfield, int iSubfieldIndex, const char *pszValue, int nValueLength ){/* -------------------------------------------------------------------- *//* Fetch the field. If this fails, return zero. *//* -------------------------------------------------------------------- */ DDFField *poField; poField = FindField( pszField, iFieldIndex ); if( poField == NULL ) return FALSE;/* -------------------------------------------------------------------- *//* Get the subfield definition *//* -------------------------------------------------------------------- */ DDFSubfieldDefn *poSFDefn; poSFDefn = poField->GetFieldDefn()->FindSubfieldDefn( pszSubfield ); if( poSFDefn == NULL ) return FALSE;/* -------------------------------------------------------------------- *//* How long will the formatted value be? *//* -------------------------------------------------------------------- */ int nFormattedLen; if( !poSFDefn->FormatStringValue( NULL, 0, &nFormattedLen, pszValue, nValueLength ) ) return FALSE;/* -------------------------------------------------------------------- *//* Get a pointer to the data. *//* -------------------------------------------------------------------- */ int nMaxBytes; char *pachSubfieldData = (char *) poField->GetSubfieldData(poSFDefn, &nMaxBytes, iSubfieldIndex);/* -------------------------------------------------------------------- *//* Add new instance if we have run out of data. *//* -------------------------------------------------------------------- */ if( nMaxBytes == 0 || (nMaxBytes == 1 && pachSubfieldData[0] == DDF_FIELD_TERMINATOR) ) { CreateDefaultFieldInstance( poField, iSubfieldIndex ); // Refetch. pachSubfieldData = (char *) poField->GetSubfieldData(poSFDefn, &nMaxBytes, iSubfieldIndex); }/* -------------------------------------------------------------------- *//* If the new length matches the existing length, just overlay *//* and return. *//* -------------------------------------------------------------------- */ int nExistingLength; poSFDefn->GetDataLength( pachSubfieldData, nMaxBytes, &nExistingLength ); if( nExistingLength == nFormattedLen ) { return poSFDefn->FormatStringValue( pachSubfieldData, nFormattedLen, NULL, pszValue, nValueLength ); }/* -------------------------------------------------------------------- *//* We will need to resize the raw data. *//* -------------------------------------------------------------------- */ const char *pachFieldInstData; int nInstanceSize, nStartOffset, nSuccess; char *pachNewData; pachFieldInstData = poField->GetInstanceData( iFieldIndex, &nInstanceSize ); nStartOffset = pachSubfieldData - pachFieldInstData; pachNewData = (char *) CPLMalloc(nFormattedLen); poSFDefn->FormatStringValue( pachNewData, nFormattedLen, NULL, pszValue, nValueLength ); nSuccess = UpdateFieldRaw( poField, iFieldIndex, nStartOffset, nExistingLength, pachNewData, nFormattedLen ); CPLFree( pachNewData ); return nSuccess;}/************************************************************************//* SetIntSubfield() *//************************************************************************//** * Set an integer subfield in record. * * The value of a given subfield is replaced with a new integer value * formatted appropriately. * * @param pszField the field name to operate on. * @param iFieldIndex the field index to operate on (zero based). * @param pszSubfield the subfield name to operate on. * @param iSubfieldIndex the subfield index to operate on (zero based). * @param nNewValue the new value to place in the subfield. * * @return TRUE if successful, and FALSE if not. */int DDFRecord::SetIntSubfield( const char *pszField, int iFieldIndex, const char *pszSubfield, int iSubfieldIndex, int nNewValue ){/* -------------------------------------------------------------------- *//* Fetch the field. If this fails, return zero. *//* -------------------------------------------------------------------- */ DDFField *poField; poField = FindField( pszField, iFieldIndex ); if( poField == NULL ) return FALSE;/* -------------------------------------------------------------------- *//* Get the subfield definition *//* -------------------------------------------------------------------- */ DDFSubfieldDefn *poSFDefn; poSFDefn = poField->GetFieldDefn()->FindSubfieldDefn( pszSubfield ); if( poSFDefn == NULL ) return FALSE;/* -------------------------------------------------------------------- *//* How long will the formatted value be? *//* -------------------------------------------------------------------- */ int nFormattedLen; if( !poSFDefn->FormatIntValue( NULL, 0, &nFormattedLen, nNewValue ) ) return FALSE;/* -------------------------------------------------------------------- *//* Get a pointer to the data. *//* -------------------------------------------------------------------- */ int nMaxBytes; char *pachSubfieldData = (char *) poField->GetSubfieldData(poSFDefn, &nMaxBytes, iSubfieldIndex);/* -------------------------------------------------------------------- *//* Add new instance if we have run out of data. *//* -------------------------------------------------------------------- */ if( nMaxBytes == 0 || (nMaxBytes == 1 && pachSubfieldData[0] == DDF_FIELD_TERMINATOR) ) { CreateDefaultFieldInstance( poField, iSubfieldIndex ); // Refetch. pachSubfieldData = (char *) poField->GetSubfieldData(poSFDefn, &nMaxBytes, iSubfieldIndex); }/* -------------------------------------------------------------------- *//* If the new length matches the existing length, just overlay *//* and return. *//* -------------------------------------------------------------------- */ int nExistingLength; poSFDefn->GetDataLength( pachSubfieldData, nMaxBytes, &nExistingLength ); if( nExistingLength == nFormattedLen ) { return poSFDefn->FormatIntValue( pachSubfieldData, nFormattedLen,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -