📄 ddfrecord.cpp
字号:
* @return The value of the subfield, or zero if it failed for some reason. */double DDFRecord::GetFloatSubfield( const char * pszField, int iFieldIndex, const char * pszSubfield, int iSubfieldIndex, int * pnSuccess ){ DDFField *poField; int nDummyErr; if( pnSuccess == NULL ) pnSuccess = &nDummyErr; *pnSuccess = FALSE; /* -------------------------------------------------------------------- *//* Fetch the field. If this fails, return zero. *//* -------------------------------------------------------------------- */ poField = FindField( pszField, iFieldIndex ); if( poField == NULL ) return 0;/* -------------------------------------------------------------------- *//* Get the subfield definition *//* -------------------------------------------------------------------- */ DDFSubfieldDefn *poSFDefn; poSFDefn = poField->GetFieldDefn()->FindSubfieldDefn( pszSubfield ); if( poSFDefn == NULL ) return 0;/* -------------------------------------------------------------------- *//* Get a pointer to the data. *//* -------------------------------------------------------------------- */ int nBytesRemaining; const char *pachData = poField->GetSubfieldData(poSFDefn, &nBytesRemaining, iSubfieldIndex);/* -------------------------------------------------------------------- *//* Return the extracted value. *//* -------------------------------------------------------------------- */ *pnSuccess = TRUE; return( poSFDefn->ExtractFloatData( pachData, nBytesRemaining, NULL ) );}/************************************************************************//* GetStringSubfield() *//************************************************************************//** * Fetch value of a subfield as a string. This is a convenience * function for fetching a subfield of a field within this record. * * @param pszField The name of the field containing the subfield. * @param iFieldIndex The instance of this field within the record. Use * zero for the first instance of this field. * @param pszSubfield The name of the subfield within the selected field. * @param iSubfieldIndex The instance of this subfield within the record. * Use zero for the first instance. * @param pnSuccess Pointer to an int which will be set to TRUE if the fetch * succeeds, or FALSE if it fails. Use NULL if you don't want to check * success. * @return The value of the subfield, or NULL if it failed for some reason. * The returned pointer is to internal data and should not be modified or * freed by the application. */const char *DDFRecord::GetStringSubfield( const char * pszField, int iFieldIndex, const char * pszSubfield, int iSubfieldIndex, int * pnSuccess ){ DDFField *poField; int nDummyErr; if( pnSuccess == NULL ) pnSuccess = &nDummyErr; *pnSuccess = FALSE; /* -------------------------------------------------------------------- *//* Fetch the field. If this fails, return zero. *//* -------------------------------------------------------------------- */ poField = FindField( pszField, iFieldIndex ); if( poField == NULL ) return NULL;/* -------------------------------------------------------------------- *//* Get the subfield definition *//* -------------------------------------------------------------------- */ DDFSubfieldDefn *poSFDefn; poSFDefn = poField->GetFieldDefn()->FindSubfieldDefn( pszSubfield ); if( poSFDefn == NULL ) return NULL;/* -------------------------------------------------------------------- *//* Get a pointer to the data. *//* -------------------------------------------------------------------- */ int nBytesRemaining; const char *pachData = poField->GetSubfieldData(poSFDefn, &nBytesRemaining, iSubfieldIndex);/* -------------------------------------------------------------------- *//* Return the extracted value. *//* -------------------------------------------------------------------- */ *pnSuccess = TRUE; return( poSFDefn->ExtractStringData( pachData, nBytesRemaining, NULL ) );}/************************************************************************//* Clone() *//************************************************************************//** * Make a copy of a record. * * This method is used to make a copy of a record that will become (mostly) * the properly of application. However, it is automatically destroyed if * the DDFModule it was created relative to is destroyed, as it's field * and subfield definitions relate to that DDFModule. However, it does * persist even when the record returned by DDFModule::ReadRecord() is * invalidated, such as when reading a new record. This allows an application * to cache whole DDFRecords. * * @return A new copy of the DDFRecord. This can be delete'd by the * application when no longer needed, otherwise it will be cleaned up when * the DDFModule it relates to is destroyed or closed. */DDFRecord * DDFRecord::Clone(){ DDFRecord *poNR; poNR = new DDFRecord( poModule ); poNR->nReuseHeader = FALSE; poNR->nFieldOffset = nFieldOffset; poNR->nDataSize = nDataSize; poNR->pachData = (char *) CPLMalloc(nDataSize); memcpy( poNR->pachData, pachData, nDataSize ); poNR->nFieldCount = nFieldCount; poNR->paoFields = new DDFField[nFieldCount]; for( int i = 0; i < nFieldCount; i++ ) { int nOffset; nOffset = (paoFields[i].GetData() - pachData); poNR->paoFields[i].Initialize( paoFields[i].GetFieldDefn(), poNR->pachData + nOffset, paoFields[i].GetDataSize() ); } poNR->bIsClone = TRUE; poModule->AddCloneRecord( poNR ); return poNR;}/************************************************************************//* CloneOn() *//************************************************************************//** * Recreate a record referencing another module. * * Works similarly to the DDFRecord::Clone() method, but creates the * new record with reference to a different DDFModule. All DDFFieldDefn * references are transcribed onto the new module based on field names. * If any fields don't have a similarly named field on the target module * the operation will fail. No validation of field types and properties * is done, but this operation is intended only to be used between * modules with matching definitions of all affected fields. * * The new record will be managed as a clone by the target module in * a manner similar to regular clones. * * @param poTargetModule the module on which the record copy should be * created. * * @return NULL on failure or a pointer to the cloned record. */DDFRecord *DDFRecord::CloneOn( DDFModule *poTargetModule ){/* -------------------------------------------------------------------- *//* Verify that all fields have a corresponding field definition *//* on the target module. *//* -------------------------------------------------------------------- */ int i; for( i = 0; i < nFieldCount; i++ ) { DDFFieldDefn *poDefn = paoFields[i].GetFieldDefn(); if( poTargetModule->FindFieldDefn( poDefn->GetName() ) == NULL ) return NULL; }/* -------------------------------------------------------------------- *//* Create a clone. *//* -------------------------------------------------------------------- */ DDFRecord *poClone; poClone = Clone();/* -------------------------------------------------------------------- *//* Update all internal information to reference other module. *//* -------------------------------------------------------------------- */ for( i = 0; i < nFieldCount; i++ ) { DDFField *poField = poClone->paoFields+i; DDFFieldDefn *poDefn; poDefn = poTargetModule->FindFieldDefn( poField->GetFieldDefn()->GetName() ); poField->Initialize( poDefn, poField->GetData(), poField->GetDataSize() ); } poModule->RemoveCloneRecord( poClone ); poClone->poModule = poTargetModule; poTargetModule->AddCloneRecord( poClone ); return poClone;}/************************************************************************//* DeleteField() *//************************************************************************//** * Delete a field instance from a record. * * Remove a field from this record, cleaning up the data * portion and repacking the fields list. We don't try to * reallocate the data area of the record to be smaller. * * NOTE: This method doesn't actually remove the header * information for this field from the record tag list yet. * This should be added if the resulting record is even to be * written back to disk! * * @param poTarget the field instance on this record to delete. * * @return TRUE on success, or FALSE on failure. Failure can occur if * poTarget isn't really a field on this record. */int DDFRecord::DeleteField( DDFField *poTarget ){ int iTarget, i;/* -------------------------------------------------------------------- *//* Find which field we are to delete. *//* -------------------------------------------------------------------- */ for( iTarget = 0; iTarget < nFieldCount; iTarget++ ) { if( paoFields + iTarget == poTarget ) break; } if( iTarget == nFieldCount ) return FALSE;/* -------------------------------------------------------------------- *//* Change the target fields data size to zero. This takes care *//* of repacking the data array, and updating all the following *//* field data pointers. *//* -------------------------------------------------------------------- */ ResizeField( poTarget, 0 );/* -------------------------------------------------------------------- *//* remove the target field, moving down all the other fields *//* one step in the field list. *//* -------------------------------------------------------------------- */ for( i = iTarget; i < nFieldCount-1; i++ ) { paoFields[i] = paoFields[i+1]; } nFieldCount--; return TRUE;}/************************************************************************//* ResizeField() *//************************************************************************//** * Alter field data size within record. * * This method will rearrange a DDFRecord altering the amount of space * reserved for one of the existing fields. All following fields will * be shifted accordingly. This includes updating the DDFField infos, * and actually moving stuff within the data array after reallocating * to the desired size. * * @param poField the field to alter. * @param nNewDataSize the number of data bytes to be reserved for the field. * * @return TRUE on success or FALSE on failure. */int DDFRecord::ResizeField( DDFField *poField, int nNewDataSize ){ int iTarget, i; int nBytesToMove;/* -------------------------------------------------------------------- *//* Find which field we are to resize. *//* -------------------------------------------------------------------- */ for( iTarget = 0; iTarget < nFieldCount; iTarget++ ) { if( paoFields + iTarget == poField ) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -