📄 ddfrecord.cpp
字号:
/* Create new image of this whole field. *//* -------------------------------------------------------------------- */ char *pachNewImage; int nPreBytes, nPostBytes, nNewFieldSize; nNewFieldSize = poField->GetDataSize() - nInstanceSize + nRawDataSize; pachNewImage = (char *) CPLMalloc(nNewFieldSize); nPreBytes = pachWrkData - poField->GetData(); nPostBytes = poField->GetDataSize() - nPreBytes - nInstanceSize; memcpy( pachNewImage, poField->GetData(), nPreBytes ); memcpy( pachNewImage + nPreBytes + nRawDataSize, poField->GetData() + nPreBytes + nInstanceSize, nPostBytes ); memcpy( pachNewImage + nPreBytes, pachRawData, nRawDataSize );/* -------------------------------------------------------------------- *//* Resize the field to the desired new size. *//* -------------------------------------------------------------------- */ ResizeField( poField, nNewFieldSize ); memcpy( (void *) poField->GetData(), pachNewImage, nNewFieldSize ); CPLFree( pachNewImage ); return TRUE;}/************************************************************************//* UpdateFieldRaw() *//************************************************************************/intDDFRecord::UpdateFieldRaw( DDFField *poField, int iIndexWithinField, int nStartOffset, int nOldSize, const char *pachRawData, int nRawDataSize ){ int iTarget, nRepeatCount;/* -------------------------------------------------------------------- *//* Find which field we are to update. *//* -------------------------------------------------------------------- */ for( iTarget = 0; iTarget < nFieldCount; iTarget++ ) { if( paoFields + iTarget == poField ) break; } if( iTarget == nFieldCount ) return FALSE; nRepeatCount = poField->GetRepeatCount(); if( iIndexWithinField < 0 || iIndexWithinField >= nRepeatCount ) return FALSE;/* -------------------------------------------------------------------- *//* Figure out how much pre and post data there is. *//* -------------------------------------------------------------------- */ char *pachWrkData; int nInstanceSize, nPostBytes, nPreBytes; pachWrkData = (char *) poField->GetInstanceData( iIndexWithinField, &nInstanceSize ); nPreBytes = pachWrkData - poField->GetData() + nStartOffset; nPostBytes = poField->GetDataSize() - nPreBytes - nOldSize;/* -------------------------------------------------------------------- *//* If we aren't changing the size, just copy over the existing *//* data. *//* -------------------------------------------------------------------- */ if( nOldSize == nRawDataSize ) { memcpy( pachWrkData + nStartOffset, pachRawData, nRawDataSize ); return TRUE; }/* -------------------------------------------------------------------- *//* If we are shrinking, move in the new data, and shuffle down *//* the old before resizing. *//* -------------------------------------------------------------------- */ if( nRawDataSize < nOldSize ) { memcpy( ((char*) poField->GetData()) + nPreBytes, pachRawData, nRawDataSize ); memmove( ((char *) poField->GetData()) + nPreBytes + nRawDataSize, ((char *) poField->GetData()) + nPreBytes + nOldSize, nPostBytes ); }/* -------------------------------------------------------------------- *//* Resize the whole buffer. *//* -------------------------------------------------------------------- */ if( !ResizeField( poField, poField->GetDataSize() - nOldSize + nRawDataSize ) ) return FALSE;/* -------------------------------------------------------------------- *//* If we growing the buffer, shuffle up the post data, and *//* move in our new values. *//* -------------------------------------------------------------------- */ 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -