/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
////////////////////////////// class StgPage // This class implements buffer functionality. The cache will always return // a page buffer, even if a read fails. It is up to the caller to determine // the correctness of the I/O.
StgPage::StgPage( short nSize, sal_Int32 nPage )
: mnPage( nPage )
, mpData( new sal_uInt8[ nSize ] )
, mnSize( nSize )
{
OSL_ENSURE( mnSize >= 512, "Unexpected page size is provided!" ); // We will write this data to a permanent file later // best to clear if first.
memset( mpData.get(), 0, mnSize );
}
// Copy an existing page into a new page. Use this routine // to duplicate an existing stream or to create new entries. // The new page is initially marked dirty. No owner is copied.
rtl::Reference< StgPage > StgCache::Copy( sal_Int32 nNew, sal_Int32 nOld )
{
rtl::Reference< StgPage > p = Find( nNew ); if( !p.is() )
p = Create( nNew ); if( nOld >= 0 )
{ // old page: we must have this data!
rtl::Reference< StgPage > q = Get( nOld, true ); if( q.is() )
{
OSL_ENSURE( p->GetSize() == q->GetSize(), "Unexpected page size!" );
memcpy( p->GetData(), q->GetData(), p->GetSize() );
}
}
SetDirty( p );
return p;
}
// Historically this wrote pages in a sorted, ascending order; // continue that tradition. bool StgCache::Commit()
{ if ( Good() ) // otherwise Write does nothing
{
std::vector< StgPage * > aToWrite;
aToWrite.reserve(maDirtyPages.size()); for (constauto& rEntry : maDirtyPages)
aToWrite.push_back( rEntry.second.get() );
bool StgCache::Read( sal_Int32 nPage, void* pBuf )
{
sal_uInt32 nRead = 0, nBytes = m_nPageSize; if( Good() )
{ /* #i73846# real life: a storage may refer to a page one-behind the last valid page (see document attached to the issue). In that case (if nPage==nPages), just do nothing here and let the caller work on
the empty zero-filled buffer. */ if ( nPage > m_nPages )
SetError( SVSTREAM_READ_ERROR ); elseif ( nPage < m_nPages )
{
sal_uInt32 nPos;
sal_Int32 nPg2; // fixed address and size for the header if( nPage == -1 )
{
nPos = 0;
nPg2 = 1;
nBytes = 512;
} else
{
nPos = Page2Pos(nPage);
nPg2 = ((nPage + 1) > m_nPages) ? m_nPages - nPage : 1;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.