Ejemplo n.º 1
0
/**********************************************************************
 *                   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.
 *
 * Returns 0 if succesful or -1 if an error happened, in which case 
 * CPLError() will have been called.
 **********************************************************************/
int     TABRawBinBlock::GotoByteInFile(int nOffset)
{
    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
    {
        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;
}
Ejemplo n.º 2
0
/**********************************************************************
 *                   TABMAPToolBlock::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 successful or -1 if an error happened, in which case
 * CPLError() will have been called.
 **********************************************************************/
int  TABMAPToolBlock::WriteBytes(int nBytesToWrite, const GByte *pabySrcBuf)
{
    if (m_eAccess == TABWrite && m_poBlockManagerRef &&
        (m_nBlockSize - m_nCurPos) < nBytesToWrite)
    {
        int nNewBlockOffset = m_poBlockManagerRef->AllocNewBlock("TOOL");
        SetNextToolBlock(nNewBlockOffset);

        if (CommitToFile() != 0 ||
            InitNewBlock(m_fp, m_nBlockSize, nNewBlockOffset) != 0)
        {
            // An error message should have already been reported.
            return -1;
        }

        m_numBlocksInChain ++;
    }

    return TABRawBinBlock::WriteBytes(nBytesToWrite, pabySrcBuf);
}
Ejemplo n.º 3
0
/**********************************************************************
 *                   TABMAPToolBlock::CheckAvailableSpace()
 *
 * Check if an object of the specified type can fit in
 * current block.  If it can't fit then force committing current block
 * and allocating a new one.
 *
 * Returns 0 if successful or -1 if an error happened, in which case
 * CPLError() will have been called.
 **********************************************************************/
int  TABMAPToolBlock::CheckAvailableSpace(int nToolType)
{
    int nBytesToWrite = 0;

    switch(nToolType)
    {
      case TABMAP_TOOL_PEN:
        nBytesToWrite = 11;
        break;
      case TABMAP_TOOL_BRUSH:
        nBytesToWrite = 13;
        break;
      case TABMAP_TOOL_FONT:
        nBytesToWrite = 37;
        break;
      case TABMAP_TOOL_SYMBOL:
        nBytesToWrite = 13;
        break;
      default:
        CPLAssert(false);
    }

    if (GetNumUnusedBytes() < nBytesToWrite)
    {
        int nNewBlockOffset = m_poBlockManagerRef->AllocNewBlock("TOOL");
        SetNextToolBlock(nNewBlockOffset);

        if (CommitToFile() != 0 ||
            InitNewBlock(m_fp, m_nBlockSize, nNewBlockOffset) != 0)
        {
            // An error message should have already been reported.
            return -1;
        }

        m_numBlocksInChain ++;
    }

    return 0;
}
Ejemplo n.º 4
0
/**********************************************************************
 *                   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 positioning ourselves to append data), so if the nOffset
 * corresponds to the beginning of a 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 successful 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*/)
{
    if (nOffset < 0)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
               "GotoByteInFile(): Attempt to go before start of file.");
        return -1;
    }

    int 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 m_nBlockSize of a block that's full of data.
             * In this case it's okay to place the m_nCurPos at byte m_nBlockSize
             * which is past the end of the block.
             */

            /* Make sure we request the block that ends with requested
             * address and not the following block that doesn't exist
             * yet on disk */
            nNewBlockPtr -= m_nBlockSize;

            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( !bForceReadFromFile && m_nFileSize > 0 &&
                nOffset < m_nFileSize )
            {
                bForceReadFromFile = TRUE;
                if ( !(nOffset < m_nFileOffset ||
                       nOffset >= m_nFileOffset+m_nBlockSize) )
                {
                    if ( (nOffset<m_nFileOffset || nOffset>=m_nFileOffset+m_nSizeUsed) &&
                         (CommitToFile() != 0 ||
                          ReadFromFile(m_fp, nNewBlockPtr, m_nBlockSize) != 0) )
                    {
                        // Failed reading new block... error has already been reported.
                        return -1;
                    }
                }
            }

            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;
}