📄 mitab_mapcoordblock.cpp
字号:
if ((!bCompressed && (WriteInt32(nX) != 0 || WriteInt32(nY) != 0 ) ) ||
(bCompressed && (WriteInt16(nX - m_nComprOrgX) != 0 ||
WriteInt16(nY - m_nComprOrgY) != 0) ) )
{
return -1;
}
/*-----------------------------------------------------------------
* Update block MBR
*----------------------------------------------------------------*/
//__TODO__ Do we still need to track the block MBR???
if (nX < m_nMinX)
m_nMinX = nX;
if (nX > m_nMaxX)
m_nMaxX = nX;
if (nY < m_nMinY)
m_nMinY = nY;
if (nY > m_nMaxY)
m_nMaxY = nY;
/*-------------------------------------------------------------
* Also keep track of current feature MBR.
*------------------------------------------------------------*/
if (nX < m_nFeatureXMin)
m_nFeatureXMin = nX;
if (nX > m_nFeatureXMax)
m_nFeatureXMax = nX;
if (nY < m_nFeatureYMin)
m_nFeatureYMin = nY;
if (nY > m_nFeatureYMax)
m_nFeatureYMax = nY;
return 0;
}
/**********************************************************************
* TABMAPCoordBlock::SetMAPBlockManagerRef()
*
* Pass a reference to the block manager object for the file this
* block belongs to. The block manager will be used by this object
* when it needs to automatically allocate a new block.
**********************************************************************/
void TABMAPCoordBlock::SetMAPBlockManagerRef(TABBinBlockManager *poBlockMgr)
{
m_poBlockManagerRef = poBlockMgr;
};
/**********************************************************************
* TABMAPCoordBlock::ReadBytes()
*
* Cover function for TABRawBinBlock::ReadBytes() that will automagically
* load the next coordinate block in the chain before reading the
* requested bytes if we are at the end of the current block and if
* m_nNextCoordBlock is a valid block.
*
* Then the control is passed to TABRawBinBlock::ReadBytes() to finish the
* work:
* 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 TABMAPCoordBlock::ReadBytes(int numBytes, GByte *pabyDstBuf)
{
int nStatus;
if (m_pabyBuf &&
m_nCurPos >= (m_numDataBytes+MAP_COORD_HEADER_SIZE) &&
m_nNextCoordBlock > 0)
{
// We're at end of current block... advance to next block.
if ( (nStatus=GotoByteInFile(m_nNextCoordBlock, TRUE)) != 0)
{
// Failed.... an error has already been reported.
return nStatus;
}
GotoByteInBlock(MAP_COORD_HEADER_SIZE); // Move pointer past header
m_numBlocksInChain++;
}
if (m_pabyBuf &&
m_nCurPos < (m_numDataBytes+MAP_COORD_HEADER_SIZE) &&
m_nCurPos+numBytes > (m_numDataBytes+MAP_COORD_HEADER_SIZE) &&
m_nNextCoordBlock > 0)
{
// Data overlaps on more than one block
// Read until end of this block and then recursively call ReadBytes()
// for the rest.
int numBytesInThisBlock =
(m_numDataBytes+MAP_COORD_HEADER_SIZE)-m_nCurPos;
nStatus = TABRawBinBlock::ReadBytes(numBytesInThisBlock, pabyDstBuf);
if (nStatus == 0)
nStatus = TABMAPCoordBlock::ReadBytes(numBytes-numBytesInThisBlock,
pabyDstBuf+numBytesInThisBlock);
return nStatus;
}
return TABRawBinBlock::ReadBytes(numBytes, pabyDstBuf);
}
/**********************************************************************
* TABMAPCoordBlock::WriteBytes()
*
* Cover function for TABRawBinBlock::WriteBytes() that will automagically
* CommitToFile() the current block and create a new one if we are at
* the end of the current block.
*
* Then the control is passed to TABRawBinBlock::WriteBytes() to finish the
* work.
*
* Passing pabySrcBuf = NULL will only move the write 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 TABMAPCoordBlock::WriteBytes(int nBytesToWrite, GByte *pabySrcBuf)
{
if (m_eAccess != TABWrite && m_eAccess != TABReadWrite )
{
CPLError(CE_Failure, CPLE_AppDefined,
"WriteBytes(): Block does not support write operations.");
return -1;
}
if (m_poBlockManagerRef && (m_nBlockSize - m_nCurPos) < nBytesToWrite)
{
if (nBytesToWrite <= (m_nBlockSize-MAP_COORD_HEADER_SIZE))
{
// Data won't fit in this block but can fit inside a single
// block, so we'll allocate a new block for it. This will
// prevent us from overlapping coordinate values on 2 blocks, but
// still allows strings longer than one block (see 'else' below).
//
if ( m_nNextCoordBlock != 0 )
{
// We're in read/write mode and there is already an allocated
// block following this one in the chain ... just reload it
// and continue writing to it
CPLAssert( m_eAccess == TABReadWrite );
if (CommitToFile() != 0 ||
ReadFromFile(m_fp, m_nNextCoordBlock, m_nBlockSize) != 0)
{
// An error message should have already been reported.
return -1;
}
}
else
{
// Need to alloc a new block.
int nNewBlockOffset = m_poBlockManagerRef->AllocNewBlock();
SetNextCoordBlock(nNewBlockOffset);
if (CommitToFile() != 0 ||
InitNewBlock(m_fp, m_nBlockSize, nNewBlockOffset) != 0)
{
// An error message should have already been reported.
return -1;
}
m_numBlocksInChain++;
}
}
else
{
// Data to write is longer than one block... so we'll have to
// split it over multiple block through multiple calls.
//
int nStatus = 0;
while(nStatus == 0 && nBytesToWrite > 0)
{
int nBytes = m_nBlockSize-MAP_COORD_HEADER_SIZE;
if ( (m_nBlockSize - m_nCurPos) > 0 )
{
// Use free room in current block
nBytes = (m_nBlockSize - m_nCurPos);
}
nBytes = MIN(nBytes, nBytesToWrite);
// The following call will result in a new block being
// allocated in the if() block above.
nStatus = TABMAPCoordBlock::WriteBytes(nBytes,
pabySrcBuf);
nBytesToWrite -= nBytes;
pabySrcBuf += nBytes;
}
return nStatus;
}
}
if (m_nCurPos >= MAP_COORD_HEADER_SIZE)
{
// Keep track of Coordinate data... this means ignore header bytes
// that could be written.
m_nTotalDataSize += nBytesToWrite;
m_nFeatureDataSize += nBytesToWrite;
}
return TABRawBinBlock::WriteBytes(nBytesToWrite, pabySrcBuf);
}
/**********************************************************************
* TABMAPObjectBlock::SeekEnd()
*
* Move read/write pointer to end of used part of the block
**********************************************************************/
void TABMAPCoordBlock::SeekEnd()
{
m_nCurPos = m_nSizeUsed;
}
/**********************************************************************
* TABMAPCoordBlock::StartNewFeature()
*
* Reset all member vars that are used to keep track of data size
* and MBR for the current feature. This is info is not needed by
* the coord blocks themselves, but it helps a lot the callers to
* have this class take care of that for them.
*
* See Also: GetFeatureDataSize() and GetFeatureMBR()
**********************************************************************/
void TABMAPCoordBlock::StartNewFeature()
{
m_nFeatureDataSize = 0;
m_nFeatureXMin = 1000000000;
m_nFeatureYMin = 1000000000;
m_nFeatureXMax = -1000000000;
m_nFeatureYMax = -1000000000;
}
/**********************************************************************
* TABMAPCoordBlock::GetFeatureMBR()
*
* Return the MBR of all the coords written using WriteIntCoord() since
* the last call to StartNewFeature().
**********************************************************************/
void TABMAPCoordBlock::GetFeatureMBR(GInt32 &nXMin, GInt32 &nYMin,
GInt32 &nXMax, GInt32 &nYMax)
{
nXMin = m_nFeatureXMin;
nYMin = m_nFeatureYMin;
nXMax = m_nFeatureXMax;
nYMax = m_nFeatureYMax;
}
/**********************************************************************
* TABMAPCoordBlock::Dump()
*
* Dump block contents... available only in DEBUG mode.
**********************************************************************/
#ifdef DEBUG
void TABMAPCoordBlock::Dump(FILE *fpOut /*=NULL*/)
{
if (fpOut == NULL)
fpOut = stdout;
fprintf(fpOut, "----- TABMAPCoordBlock::Dump() -----\n");
if (m_pabyBuf == NULL)
{
fprintf(fpOut, "Block has not been initialized yet.");
}
else
{
fprintf(fpOut,"Coordinate Block (type %d) at offset %d.\n",
m_nBlockType, m_nFileOffset);
fprintf(fpOut," m_numDataBytes = %d\n", m_numDataBytes);
fprintf(fpOut," m_nNextCoordBlock = %d\n", m_nNextCoordBlock);
}
fflush(fpOut);
}
#endif // DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -