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

📄 ddfrecord.cpp

📁 开源的电子海图程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    /* -------------------------------------------------------------------- *//*      Read the 24 byte leader.                                        *//* -------------------------------------------------------------------- */    char        achLeader[nLeaderSize];    int         nReadBytes;    nReadBytes = VSIFRead(achLeader,1,nLeaderSize,poModule->GetFP());    if( nReadBytes == 0 && VSIFEof( poModule->GetFP() ) )    {        return FALSE;    }    else if( nReadBytes != (int) nLeaderSize )    {        CPLError( CE_Failure, CPLE_FileIO,                  "Leader is short on DDF file." );                return FALSE;    }/* -------------------------------------------------------------------- *//*      Extract information from leader.                                *//* -------------------------------------------------------------------- */    int         _recLength, _fieldAreaStart;    char        _leaderIden;        _recLength                    = DDFScanInt( achLeader+0, 5 );    _leaderIden                   = achLeader[6];    _fieldAreaStart               = DDFScanInt(achLeader+12,5);        _sizeFieldLength = achLeader[20] - '0';    _sizeFieldPos = achLeader[21] - '0';    _sizeFieldTag = achLeader[23] - '0';    if( _sizeFieldLength < 0 || _sizeFieldLength > 9         || _sizeFieldPos < 0 || _sizeFieldPos > 9        || _sizeFieldTag < 0 || _sizeFieldTag > 9 )    {        CPLError( CE_Failure, CPLE_AppDefined,                   "ISO8211 record leader appears to be corrupt." );        return FALSE;    }    if( _leaderIden == 'R' )        nReuseHeader = TRUE;    nFieldOffset = _fieldAreaStart - nLeaderSize;/* -------------------------------------------------------------------- *//*      Is there anything seemly screwy about this record?              *//* -------------------------------------------------------------------- */    if(( _recLength < 24 || _recLength > 100000000         || _fieldAreaStart < 24 || _fieldAreaStart > 100000 )       && (_recLength != 0))    {        CPLError( CE_Failure, CPLE_FileIO,                   "Data record appears to be corrupt on DDF file.\n"                  " -- ensure that the files were uncompressed without modifying\n"                  "carriage return/linefeeds (by default WINZIP does this)." );                return FALSE;    }/* ==================================================================== *//*      Handle the normal case with the record length available.        *//* ==================================================================== */    if(_recLength != 0) {/* -------------------------------------------------------------------- *//*      Read the remainder of the record.                               *//* -------------------------------------------------------------------- */        nDataSize = _recLength - nLeaderSize;        pachData = (char *) CPLMalloc(nDataSize);        if( VSIFRead( pachData, 1, nDataSize, poModule->GetFP()) !=            (size_t) nDataSize )        {            CPLError( CE_Failure, CPLE_FileIO,                       "Data record is short on DDF file." );                      return FALSE;        }/* -------------------------------------------------------------------- *//*      If we don't find a field terminator at the end of the record    *//*      we will read extra bytes till we get to it.                     *//* -------------------------------------------------------------------- */        while( pachData[nDataSize-1] != DDF_FIELD_TERMINATOR )        {            nDataSize++;            pachData = (char *) CPLRealloc(pachData,nDataSize);                        if( VSIFRead( pachData + nDataSize - 1, 1, 1, poModule->GetFP() )                != 1 )            {                CPLError( CE_Failure, CPLE_FileIO,                           "Data record is short on DDF file." );                                return FALSE;            }            CPLDebug( "ISO8211",                       "Didn't find field terminator, read one more byte." );        }/* -------------------------------------------------------------------- *//*      Loop over the directory entries, making a pass counting them.   *//* -------------------------------------------------------------------- */        int         i;        int         nFieldEntryWidth;              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;

⌨️ 快捷键说明

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