Logo Search packages:      
Sourcecode: libpodofo version File versions  Download package

void PoDoFo::PdfRefCountedBuffer::ReallyResize ( size_t  lSize ) [private]

Do the hard work of resizing the buffer if it turns out not to already be big enough.

See also:
Resize

Definition at line 89 of file PdfRefCountedBuffer.cpp.

References Detach(), PoDoFo::ePdfError_OutOfMemory, PoDoFo::PDF_MAX(), PODOFO_RAISE_ERROR, PODOFO_RAISE_ERROR_INFO, and PODOFO_RAISE_LOGIC_IF.

Referenced by Resize().

{
    if( m_pBuffer )
    {
        // Resizing the buffer counts as altering it, so detach as per copy on write behaviour. If the detach
        // actually has to do anything it'll reallocate the buffer at the new desired size.
        this->Detach( static_cast<size_t>(m_pBuffer->m_lBufferSize) < lSize ? lSize - static_cast<size_t>(m_pBuffer->m_lBufferSize) : 0 );
        // We might have pre-allocated enough to service the request already
        if( static_cast<size_t>(m_pBuffer->m_lBufferSize) < lSize )
        {
            // Allocate more space, since we need it. We over-allocate so that clients can efficiently
            // request lots of small resizes if they want, but these over allocations are not visible
            // to clients.
            //
            const size_t lAllocSize = PDF_MAX(lSize, m_pBuffer->m_lBufferSize) << 1;
            if ( m_pBuffer->m_bPossesion && m_pBuffer->m_bOnHeap )
            {
                // We have an existing on-heap buffer that we own. Realloc()
                // it, potentially saving us a memcpy and free().
                void* temp = realloc( m_pBuffer->m_pHeapBuffer, lAllocSize );
                if (!temp)
                {
                    PODOFO_RAISE_ERROR_INFO( ePdfError_OutOfMemory, "PdfRefCountedBuffer::Resize failed!" );
                }
                m_pBuffer->m_pHeapBuffer = static_cast<char*>(temp);
                m_pBuffer->m_lBufferSize = lAllocSize;
            }
            else
            {
                // Either we don't own the buffer or it's a local static buffer that's no longer big enough.
                // Either way, it's time to move to a heap-allocated buffer we own.
                char* pBuffer = static_cast<char*>(malloc( sizeof(char) * lAllocSize ));
                if( !pBuffer ) 
                {
                    PODOFO_RAISE_ERROR_INFO( ePdfError_OutOfMemory, "PdfRefCountedBuffer::Resize failed!" );
                }
                // Only bother copying the visible portion of the buffer. It's completely incorrect
                // to rely on anything more than that, and not copying it will help catch those errors.
                memcpy( pBuffer, m_pBuffer->GetRealBuffer(), m_pBuffer->m_lVisibleSize );
                // Record the newly allocated buffer's details. The visible size gets updated later.
                m_pBuffer->m_lBufferSize = lAllocSize;
                m_pBuffer->m_pHeapBuffer = pBuffer;
                m_pBuffer->m_bOnHeap = true;
            }
        }
        else
        {
            // Allocated buffer is large enough, do nothing
        }
    }
    else
    {
        // No buffer was allocated at all, so we need to make one.
        m_pBuffer = new TRefCountedBuffer();
        m_pBuffer->m_lRefCount       = 1;
        m_pBuffer->m_bOnHeap   = (lSize > TRefCountedBuffer::INTERNAL_BUFSIZE);
        if ( m_pBuffer->m_bOnHeap )
        {
            m_pBuffer->m_pHeapBuffer = static_cast<char*>(malloc( sizeof(char)*lSize ));
        }
        else
        {
            m_pBuffer->m_pHeapBuffer = 0;
        }

        m_pBuffer->m_lBufferSize     = PDF_MAX( lSize, static_cast<size_t>(+TRefCountedBuffer::INTERNAL_BUFSIZE) );
        m_pBuffer->m_bPossesion      = true;

        if( m_pBuffer->m_bOnHeap && !m_pBuffer->m_pHeapBuffer ) 
        {
            delete m_pBuffer;
            m_pBuffer = NULL;

            PODOFO_RAISE_ERROR( ePdfError_OutOfMemory );
        }
    }
    m_pBuffer->m_lVisibleSize = lSize;

    PODOFO_RAISE_LOGIC_IF ( m_pBuffer->m_lVisibleSize > m_pBuffer->m_lBufferSize, "Buffer improperly allocated/resized");
}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index