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

📄 ddfrecord.cpp

📁 国际海图标准S-57格式数据读取源码VC
💻 CPP
📖 第 1 页 / 共 5 页
字号:
              nFieldEntryWidth = _sizeFieldLength + _sizeFieldPos + _sizeFieldTag;        nFieldCount = 0;        for( i = 0; i < nDataSize; i += nFieldEntryWidth )        {            if( pachData[i] == DDF_FIELD_TERMINATOR )                break;                      nFieldCount++;        }    /* -------------------------------------------------------------------- *//*      Allocate, and read field definitions.                           *//* -------------------------------------------------------------------- */        paoFields = new DDFField[nFieldCount];            for( i = 0; i < nFieldCount; i++ )        {            char    szTag[128];            int     nEntryOffset = i*nFieldEntryWidth;            int     nFieldLength, nFieldPos;          /* -------------------------------------------------------------------- *//*      Read the position information and tag.                          *//* -------------------------------------------------------------------- */            strncpy( szTag, pachData+nEntryOffset, _sizeFieldTag );            szTag[_sizeFieldTag] = '\0';                      nEntryOffset += _sizeFieldTag;            nFieldLength = DDFScanInt( pachData+nEntryOffset, _sizeFieldLength );                      nEntryOffset += _sizeFieldLength;            nFieldPos = DDFScanInt( pachData+nEntryOffset, _sizeFieldPos );          /* -------------------------------------------------------------------- *//*      Find the corresponding field in the module directory.           *//* -------------------------------------------------------------------- */            DDFFieldDefn    *poFieldDefn = poModule->FindFieldDefn( szTag );                      if( poFieldDefn == NULL )            {                CPLError( CE_Failure, CPLE_AppDefined,                          "Undefined field `%s' encountered in data record.",                          szTag );                return FALSE;            }/* -------------------------------------------------------------------- *//*      Assign info the DDFField.                                       *//* -------------------------------------------------------------------- */            paoFields[i].Initialize( poFieldDefn,                                      pachData + _fieldAreaStart + nFieldPos - nLeaderSize,                                     nFieldLength );        }              return TRUE;    }/* ==================================================================== *//*      Handle the exceptional case where the record length is          *//*      zero.  In this case we have to read all the data based on       *//*      the size of data items as per ISO8211 spec Annex C, 1.5.1.      *//*                                                                      *//*      See Bugzilla bug 181 and test with file US4CN21M.000.           *//* ==================================================================== */    else {        CPLDebug( "ISO8211",                   "Record with zero length, use variant (C.1.5.1) logic." );        /* ----------------------------------------------------------------- */        /*   _recLength == 0, handle the large record.                       */        /*                                                                   */        /*   Read the remainder of the record.                               */        /* ----------------------------------------------------------------- */        nDataSize = 0;        pachData = NULL;        /* ----------------------------------------------------------------- */        /*   Loop over the directory entries, making a pass counting them.   */        /* ----------------------------------------------------------------- */        int nFieldEntryWidth = _sizeFieldLength + _sizeFieldPos + _sizeFieldTag;        nFieldCount = 0;        int i=0;        char *tmpBuf = (char*)CPLMalloc(nFieldEntryWidth);              // while we're not at the end, store this entry,        // and keep on reading...        do {            // read an Entry:            if(nFieldEntryWidth !=                (int) VSIFRead(tmpBuf, 1, nFieldEntryWidth, poModule->GetFP())) {                CPLError(CE_Failure, CPLE_FileIO,                         "Data record is short on DDF file.");                return FALSE;            }                  // move this temp buffer into more permanent storage:            char *newBuf = (char*)CPLMalloc(nDataSize+nFieldEntryWidth);            if(pachData!=NULL) {                memcpy(newBuf, pachData, nDataSize);                CPLFree(pachData);            }            memcpy(&newBuf[nDataSize], tmpBuf, nFieldEntryWidth);            pachData = newBuf;            nDataSize += nFieldEntryWidth;            if(DDF_FIELD_TERMINATOR != tmpBuf[0]) {                nFieldCount++;            }        }        while(DDF_FIELD_TERMINATOR != tmpBuf[0]);        // Now, rewind a little.  Only the TERMINATOR should have been read:        int rewindSize = nFieldEntryWidth - 1;        FILE *fp = poModule->GetFP();        long pos = ftell(fp) - rewindSize;        fseek(fp, pos, SEEK_SET);        nDataSize -= rewindSize;        // --------------------------------------------------------------------        // Okay, now let's populate the heck out of pachData...        // --------------------------------------------------------------------        for(i=0; i<nFieldCount; i++) {            int nEntryOffset = (i*nFieldEntryWidth) + _sizeFieldTag;            int nFieldLength = DDFScanInt(pachData + nEntryOffset,                                          _sizeFieldLength);            char *tmpBuf = (char*)CPLMalloc(nFieldLength);            // read an Entry:            if(nFieldLength !=                (int) VSIFRead(tmpBuf, 1, nFieldLength, poModule->GetFP())) {                CPLError(CE_Failure, CPLE_FileIO,                         "Data record is short on DDF file.");                return FALSE;            }                  // move this temp buffer into more permanent storage:            char *newBuf = (char*)CPLMalloc(nDataSize+nFieldLength);            memcpy(newBuf, pachData, nDataSize);            CPLFree(pachData);            memcpy(&newBuf[nDataSize], tmpBuf, nFieldLength);            CPLFree(tmpBuf);            pachData = newBuf;            nDataSize += nFieldLength;        }            /* ----------------------------------------------------------------- */        /*     Allocate, and read field definitions.                         */        /* ----------------------------------------------------------------- */        paoFields = new DDFField[nFieldCount];              for( i = 0; i < nFieldCount; i++ )        {            char    szTag[128];            int     nEntryOffset = i*nFieldEntryWidth;            int     nFieldLength, nFieldPos;                      /* ------------------------------------------------------------- */            /* Read the position information and tag.                        */            /* ------------------------------------------------------------- */            strncpy( szTag, pachData+nEntryOffset, _sizeFieldTag );            szTag[_sizeFieldTag] = '\0';                      nEntryOffset += _sizeFieldTag;            nFieldLength = DDFScanInt( pachData+nEntryOffset, _sizeFieldLength );                      nEntryOffset += _sizeFieldLength;            nFieldPos = DDFScanInt( pachData+nEntryOffset, _sizeFieldPos );                      /* ------------------------------------------------------------- */            /* Find the corresponding field in the module directory.         */            /* ------------------------------------------------------------- */            DDFFieldDefn    *poFieldDefn = poModule->FindFieldDefn( szTag );                      if( poFieldDefn == NULL )            {                CPLError( CE_Failure, CPLE_AppDefined,                          "Undefined field `%s' encountered in data record.",                          szTag );                return FALSE;            }            /* ------------------------------------------------------------- */            /* Assign info the DDFField.                                     */            /* ------------------------------------------------------------- */            paoFields[i].Initialize( poFieldDefn,                                      pachData + _fieldAreaStart                                     + nFieldPos - nLeaderSize,                                     nFieldLength );        }              return TRUE;    }}/************************************************************************//*                             FindField()                              *//************************************************************************//** * Find the named field within this record. * * @param pszName The name of the field to fetch.  The comparison is * case insensitive. * @param iFieldIndex The instance of this field to fetch.  Use zero (the * default) for the first instance. * * @return Pointer to the requested DDFField.  This pointer is to an * internal object, and should not be freed.  It remains valid until * the next record read.  */DDFField * DDFRecord::FindField( const char * pszName, int iFieldIndex ){    for( int i = 0; i < nFieldCount; i++ )    {        if( EQUAL(paoFields[i].GetFieldDefn()->GetName(),pszName) )        {            if( iFieldIndex == 0 )                return paoFields + i;            else                iFieldIndex--;        }    }    return NULL;}/************************************************************************//*                              GetField()                              *//************************************************************************//** * Fetch field object based on index. * * @param i The index of the field to fetch.  Between 0 and GetFieldCount()-1. * * @return A DDFField pointer, or NULL if the index is out of range. */DDFField *DDFRecord::GetField( int i ){    if( i < 0 || i >= nFieldCount )        return NULL;    else        return paoFields + i;}/************************************************************************//*                           GetIntSubfield()                           *//************************************************************************//** * Fetch value of a subfield as an integer.  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 zero if it failed for some reason. */int DDFRecord::GetIntSubfield( 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->ExtractIntData( pachData, nBytesRemaining, NULL ) );}/************************************************************************//*                          GetFloatSubfield()                          *//************************************************************************//** * Fetch value of a subfield as a float (double).  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.

⌨️ 快捷键说明

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