⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddfrecord.cpp

📁 开源的电子海图程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        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;    }    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 );    }/* -------------------------------------------------------------------- */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -