📄 ddfrecord.cpp
字号:
} if( iTarget == nFieldCount ) return FALSE;/* -------------------------------------------------------------------- *//* Reallocate the data buffer accordingly. *//* -------------------------------------------------------------------- */ int nBytesToAdd = nNewDataSize - poField->GetDataSize(); const char *pachOldData = pachData; pachData = (char *) CPLRealloc(pachData, nDataSize + nBytesToAdd ); nDataSize += nBytesToAdd;/* -------------------------------------------------------------------- *//* Shift data after the target field on by the bytes added. *//* -------------------------------------------------------------------- */ nBytesToMove = nDataSize - (poField->GetData()+poField->GetDataSize()-pachOldData+nBytesToAdd); memmove( (char *)poField->GetData() + poField->GetDataSize() + nBytesToAdd, (char *)poField->GetData() + poField->GetDataSize(), nBytesToMove ); /* -------------------------------------------------------------------- *//* Update fields to point into newly allocated buffer. *//* -------------------------------------------------------------------- */ for( i = 0; i < nFieldCount; i++ ) { int nOffset; nOffset = paoFields[i].GetData() - pachOldData; paoFields[i].Initialize( paoFields[i].GetFieldDefn(), pachData + nOffset, paoFields[i].GetDataSize() ); }/* -------------------------------------------------------------------- *//* Update the target fields info. *//* -------------------------------------------------------------------- */ poField->Initialize( poField->GetFieldDefn(), poField->GetData(), poField->GetDataSize() + nBytesToAdd );/* -------------------------------------------------------------------- *//* Shift all following fields down, and update their data *//* locations. *//* -------------------------------------------------------------------- */ if( nBytesToAdd < 0 ) { for( i = iTarget+1; i < nFieldCount; i++ ) { char *pszOldDataLocation; pszOldDataLocation = (char *) paoFields[i].GetData(); paoFields[i].Initialize( paoFields[i].GetFieldDefn(), pszOldDataLocation + nBytesToAdd, paoFields[i].GetDataSize() ); } } else { for( i = nFieldCount-1; i > iTarget; i-- ) { char *pszOldDataLocation; pszOldDataLocation = (char *) paoFields[i].GetData(); paoFields[i].Initialize( paoFields[i].GetFieldDefn(), pszOldDataLocation + nBytesToAdd, paoFields[i].GetDataSize() ); } } return TRUE;}/************************************************************************//* AddField() *//************************************************************************//** * Add a new field to record. * * Add a new zero sized field to the record. The new field is always * added at the end of the record. * * NOTE: This method doesn't currently update the header information for * the record to include the field information for this field, so the * resulting record image isn't suitable for writing to disk. However, * everything else about the record state should be updated properly to * reflect the new field. * * @param poDefn the definition of the field to be added. * * @return the field object on success, or NULL on failure. */DDFField *DDFRecord::AddField( DDFFieldDefn *poDefn ){/* -------------------------------------------------------------------- *//* Reallocate the fields array larger by one, and initialize *//* the new field. *//* -------------------------------------------------------------------- */ DDFField *paoNewFields; paoNewFields = new DDFField[nFieldCount+1]; if( nFieldCount > 0 ) { memcpy( paoNewFields, paoFields, sizeof(DDFField) * nFieldCount ); delete[] paoFields; } paoFields = paoNewFields; nFieldCount++;/* -------------------------------------------------------------------- *//* Initialize the new field properly. *//* -------------------------------------------------------------------- */ if( nFieldCount == 1 ) { paoFields[0].Initialize( poDefn, GetData(), 0 ); } else { paoFields[nFieldCount-1].Initialize( poDefn, paoFields[nFieldCount-2].GetData() + paoFields[nFieldCount-2].GetDataSize(), 0 ); }/* -------------------------------------------------------------------- *//* Initialize field. *//* -------------------------------------------------------------------- */ CreateDefaultFieldInstance( paoFields + nFieldCount-1, 0 ); return paoFields + (nFieldCount - 1);}/************************************************************************//* SetFieldRaw() *//************************************************************************//** * Set the raw contents of a field instance. * * @param poField the field to set data within. * @param iIndexWithinField The instance of this field to replace. Must * be a value between 0 and GetRepeatCount(). If GetRepeatCount() is used, a * new instance of the field is appeneded. * @param pachRawData the raw data to replace this field instance with. * @param nRawDataSize the number of bytes pointed to by pachRawData. * * @return TRUE on success or FALSE on failure. */intDDFRecord::SetFieldRaw( DDFField *poField, int iIndexWithinField, 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;/* -------------------------------------------------------------------- *//* Are we adding an instance? This is easier and different *//* than replacing an existing instance. *//* -------------------------------------------------------------------- */ if( iIndexWithinField == nRepeatCount || !poField->GetFieldDefn()->IsRepeating() ) { char *pachFieldData; int nOldSize; if( !poField->GetFieldDefn()->IsRepeating() && iIndexWithinField != 0 ) return FALSE; nOldSize = poField->GetDataSize(); if( nOldSize == 0 ) nOldSize++; // for added DDF_FIELD_TERMINATOR. if( !ResizeField( poField, nOldSize + nRawDataSize ) ) return FALSE; pachFieldData = (char *) poField->GetData(); memcpy( pachFieldData + nOldSize - 1, pachRawData, nRawDataSize ); pachFieldData[nOldSize+nRawDataSize-1] = DDF_FIELD_TERMINATOR; return TRUE; }/* -------------------------------------------------------------------- *//* Get a pointer to the start of the existing data for this *//* iteration of the field. *//* -------------------------------------------------------------------- */ const char *pachWrkData; int nInstanceSize; // We special case this to avoid alot of warnings when initializing // the field the first time. if( poField->GetDataSize() == 0 ) { pachWrkData = poField->GetData(); nInstanceSize = 0; } else { pachWrkData = poField->GetInstanceData( iIndexWithinField, &nInstanceSize ); }/* -------------------------------------------------------------------- *//* 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. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -