mitab_rawbinblock.cpp

来自「支持各种栅格图像和矢量图像读取的库」· C++ 代码 · 共 1,055 行 · 第 1/3 页

CPP
1,055
字号
 * * Returns a block type >= 0 if succesful or -1 if an error happened, in  * which case  CPLError() will have been called. **********************************************************************/int     TABRawBinBlock::GetBlockType(){    if (m_pabyBuf == NULL)    {        CPLError(CE_Failure, CPLE_AppDefined,                 "GetBlockType(): Block has not been initialized.");        return -1;    }    if (m_nBlockType > TABMAP_LAST_VALID_BLOCK_TYPE)    {        CPLError(CE_Failure, CPLE_NotSupported,                 "GetBlockType(): Unsupported block type %d.",                  m_nBlockType);        return -1;    }    return m_nBlockType;}/********************************************************************** *                   TABRawBinBlock::GotoByteInBlock() * * Move the block pointer to the specified position relative to the  * beginning of the block. * * Returns 0 if succesful or -1 if an error happened, in which case  * CPLError() will have been called. **********************************************************************/int     TABRawBinBlock::GotoByteInBlock(int nOffset){    if ( (m_eAccess == TABRead && nOffset > m_nSizeUsed) ||         (m_eAccess != TABRead && nOffset > m_nBlockSize) )    {        CPLError(CE_Failure, CPLE_AppDefined,                 "GotoByteInBlock(): Attempt to go past end of data block.");        return -1;    }    if (nOffset < 0)    {        CPLError(CE_Failure, CPLE_AppDefined,               "GotoByteInBlock(): Attempt to go before start of data block.");        return -1;    }    m_nCurPos = nOffset;        m_nSizeUsed = MAX(m_nSizeUsed, m_nCurPos);    return 0;}/********************************************************************** *                   TABRawBinBlock::GotoByteRel() * * Move the block pointer by the specified number of bytes relative * to its current position. * * Returns 0 if succesful or -1 if an error happened, in which case  * CPLError() will have been called. **********************************************************************/int     TABRawBinBlock::GotoByteRel(int nOffset){    return GotoByteInBlock(m_nCurPos + nOffset);}/********************************************************************** *                   TABRawBinBlock::GotoByteInFile() * * Move the block pointer to the specified position relative to the  * beginning of the file.   *  * In read access, the current block may be reloaded to contain a right * block of binary data if necessary. * * In write mode, the current block may automagically be committed to  * disk and a new block initialized if necessary. * * bForceReadFromFile is used in write mode to read the new block data from * file instead of creating an empty block. (Useful for TABCollection * or other cases that need to do random access in the file in write mode.) * * bOffsetIsEndOfData is set to TRUE to indicate that the nOffset * to which we are attempting to go is the end of the used data in this * block (we are positioninig ourselves to append data), so if the nOffset  * corresponds to the beginning of a 512 bytes block then we should really  * be positioning ourselves at the end of the block that ends at this  * address instead of at the beginning of the blocks that starts at this  * address. This case can happen when going back and forth to write collection * objects to a Coordblock and is documented in bug 1657. * * Returns 0 if succesful or -1 if an error happened, in which case  * CPLError() will have been called. **********************************************************************/int     TABRawBinBlock::GotoByteInFile(int nOffset,                                        GBool bForceReadFromFile /*=FALSE*/,                                       GBool bOffsetIsEndOfData /*=FALSE*/){    int nNewBlockPtr;    if (nOffset < 0)    {        CPLError(CE_Failure, CPLE_AppDefined,               "GotoByteInFile(): Attempt to go before start of file.");        return -1;    }    nNewBlockPtr = ( (nOffset-m_nFirstBlockPtr)/m_nBlockSize)*m_nBlockSize +                     m_nFirstBlockPtr;    if (m_eAccess == TABRead)    {        if ( (nOffset<m_nFileOffset || nOffset>=m_nFileOffset+m_nSizeUsed) &&             ReadFromFile(m_fp, nNewBlockPtr, m_nBlockSize) != 0)        {            // Failed reading new block... error has already been reported.            return -1;        }    }    else if (m_eAccess == TABWrite)    {        if ( (nOffset<m_nFileOffset || nOffset>=m_nFileOffset+m_nBlockSize) &&             (CommitToFile() != 0 ||              InitNewBlock(m_fp, m_nBlockSize, nNewBlockPtr) != 0 ) )        {            // Failed reading new block... error has already been reported.            return -1;        }    }    else if (m_eAccess == TABReadWrite)    {        // TODO: THIS IS NOT REAL read/write access (it's more extended write)        // Currently we try to read from file only if explicitly requested.        // If we ever want true read/write mode we should implement        // more smarts to detect whether the caller wants an existing block to        // be read, or a new one to be created from scratch.        // CommitToFile() should only be called only if something changed.        //        if (bOffsetIsEndOfData &&  nOffset%m_nBlockSize == 0)        {            /* We're trying to go byte 512 of a block that's full of data.             * In this case it's okay to place the m_nCurPos at byte 512             * which is past the end of the block.             */            if ( (nOffset < m_nFileOffset ||                   nOffset > m_nFileOffset+m_nBlockSize) &&                 (CommitToFile() != 0 ||                  (!bForceReadFromFile &&                    InitNewBlock(m_fp, m_nBlockSize, nNewBlockPtr) != 0) ||                  (bForceReadFromFile &&                   ReadFromFile(m_fp, nNewBlockPtr, m_nBlockSize) != 0) )  )            {                // Failed reading new block... error has already been reported.                return -1;            }        }        else        {            if ( (nOffset < m_nFileOffset ||                   nOffset >= m_nFileOffset+m_nBlockSize) &&                 (CommitToFile() != 0 ||                  (!bForceReadFromFile &&                    InitNewBlock(m_fp, m_nBlockSize, nNewBlockPtr) != 0) ||                  (bForceReadFromFile &&                   ReadFromFile(m_fp, nNewBlockPtr, m_nBlockSize) != 0) )  )            {                // Failed reading new block... error has already been reported.                return -1;            }        }    }    else    {        CPLError(CE_Failure, CPLE_NotSupported,                 "Access mode not supported yet!");        return -1;    }    m_nCurPos = nOffset-m_nFileOffset;    m_nSizeUsed = MAX(m_nSizeUsed, m_nCurPos);    return 0;}/********************************************************************** *                   TABRawBinBlock::SetFirstBlockPtr() * * Set the position in the file at which the first block starts. * This value will usually be the header size and needs to be specified  * only if the header size is different from the other blocks size.  * * This value will be used by GotoByteInFile() to properly align the data * blocks that it loads automatically when a requested position is outside * of the block currently in memory. **********************************************************************/void  TABRawBinBlock::SetFirstBlockPtr(int nOffset){    m_nFirstBlockPtr = nOffset;}/********************************************************************** *                   TABRawBinBlock::GetNumUnusedBytes() * * Return the number of unused bytes in this block. **********************************************************************/int     TABRawBinBlock::GetNumUnusedBytes(){    return (m_nBlockSize - m_nSizeUsed);}/********************************************************************** *                   TABRawBinBlock::GetFirstUnusedByteOffset() * * Return the position of the first unused byte in this block relative * to the beginning of the file, or -1 if the block is full. **********************************************************************/int     TABRawBinBlock::GetFirstUnusedByteOffset(){    if (m_nSizeUsed < m_nBlockSize)        return m_nFileOffset + m_nSizeUsed;    else        return -1;}/********************************************************************** *                   TABRawBinBlock::GetCurAddress() * * Return the current pointer position, relative to beginning of file. **********************************************************************/int     TABRawBinBlock::GetCurAddress(){    return (m_nFileOffset + m_nCurPos);}/********************************************************************** *                   TABRawBinBlock::ReadBytes() * * Copy the number of bytes from the data block's internal buffer to * the user's buffer pointed by pabyDstBuf. * * Passing pabyDstBuf = NULL will only move the read pointer by the * specified number of bytes as if the copy had happened... but it  * won't crash. * * Returns 0 if succesful or -1 if an error happened, in which case  * CPLError() will have been called. **********************************************************************/int     TABRawBinBlock::ReadBytes(int numBytes, GByte *pabyDstBuf){    /*----------------------------------------------------------------     * Make sure block is initialized with Read access and that the     * operation won't go beyond the buffer's size.     *---------------------------------------------------------------*/    if (m_pabyBuf == NULL)    {        CPLError(CE_Failure, CPLE_AppDefined,                 "ReadBytes(): Block has not been initialized.");        return -1;    }    if (m_eAccess != TABRead && m_eAccess != TABReadWrite )    {        CPLError(CE_Failure, CPLE_AppDefined,                 "ReadBytes(): Block does not support read operations.");        return -1;    }    if (m_nCurPos + numBytes > m_nSizeUsed)    {        CPLError(CE_Failure, CPLE_AppDefined,                 "ReadBytes(): Attempt to read past end of data block.");        return -1;    }    if (pabyDstBuf)    {        memcpy(pabyDstBuf, m_pabyBuf + m_nCurPos, numBytes);    }    m_nCurPos += numBytes;    return 0;}/********************************************************************** *                   TABRawBinBlock::Read<datatype>() * * MapInfo files are binary files with LSB first (Intel) byte  * ordering.  The following functions will read from the input file * and return a value with the bytes ordered properly for the current  * platform. **********************************************************************/GByte  TABRawBinBlock::ReadByte(){    GByte byValue;    ReadBytes(1, (GByte*)(&byValue));    return byValue;}GInt16  TABRawBinBlock::ReadInt16(){    GInt16 n16Value;    ReadBytes(2, (GByte*)(&n16Value));#ifdef CPL_MSB    return (GInt16)CPL_SWAP16(n16Value);#else    return n16Value;#endif}GInt32  TABRawBinBlock::ReadInt32(){    GInt32 n32Value;    ReadBytes(4, (GByte*)(&n32Value));#ifdef CPL_MSB    return (GInt32)CPL_SWAP32(n32Value);#else    return n32Value;#endif}float   TABRawBinBlock::ReadFloat(){    float fValue;    ReadBytes(4, (GByte*)(&fValue));#ifdef CPL_MSB    *(GUInt32*)(&fValue) = CPL_SWAP32(*(GUInt32*)(&fValue));#endif    return fValue;}double  TABRawBinBlock::ReadDouble(){    double dValue;    ReadBytes(8, (GByte*)(&dValue));

⌨️ 快捷键说明

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