ole32: Use the storage vtable to read streams.

This commit is contained in:
Vincent Povirk 2009-11-30 10:35:55 -06:00 committed by Alexandre Julliard
parent ee39a21d2b
commit 62e54bacba
3 changed files with 83 additions and 52 deletions

View File

@ -264,7 +264,6 @@ static HRESULT WINAPI StgStreamImpl_Read(
StgStreamImpl* const This=(StgStreamImpl*)iface;
ULONG bytesReadBuffer;
ULONG bytesToReadFromBuffer;
HRESULT res;
TRACE("(%p, %p, %d, %p)\n",
@ -283,60 +282,21 @@ static HRESULT WINAPI StgStreamImpl_Read(
if (pcbRead==0)
pcbRead = &bytesReadBuffer;
/*
* Using the known size of the stream, calculate the number of bytes
* to read from the block chain
*/
bytesToReadFromBuffer = min( This->streamSize.u.LowPart - This->currentPosition.u.LowPart, cb);
/*
* Depending on the type of chain that was opened when the stream was constructed,
* we delegate the work to the method that reads the block chains.
*/
if (This->smallBlockChain!=0)
{
res = SmallBlockChainStream_ReadAt(This->smallBlockChain,
This->currentPosition,
bytesToReadFromBuffer,
pv,
pcbRead);
}
else if (This->bigBlockChain!=0)
{
res = BlockChainStream_ReadAt(This->bigBlockChain,
This->currentPosition,
bytesToReadFromBuffer,
pv,
pcbRead);
}
else
{
/*
* Small and big block chains are both NULL. This case will happen
* when a stream starts with BLOCK_END_OF_CHAIN and has size zero.
*/
*pcbRead = 0;
res = S_OK;
goto end;
}
res = StorageBaseImpl_StreamReadAt(This->parentStorage,
This->dirEntry,
This->currentPosition,
cb,
pv,
pcbRead);
if (SUCCEEDED(res))
{
/*
* We should always be able to read the proper amount of data from the
* chain.
*/
assert(bytesToReadFromBuffer == *pcbRead);
/*
* Advance the pointer for the number of positions read.
*/
This->currentPosition.u.LowPart += *pcbRead;
/*
* Advance the pointer for the number of positions read.
*/
This->currentPosition.u.LowPart += *pcbRead;
}
end:
TRACE("<-- %08x\n", res);
return res;
}

View File

@ -2192,6 +2192,60 @@ static HRESULT StorageImpl_BaseReadDirEntry(StorageBaseImpl *base,
return StorageImpl_ReadDirEntry(This, index, data);
}
static HRESULT StorageImpl_StreamReadAt(StorageBaseImpl *base, DirRef index,
ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead)
{
StorageImpl *This = (StorageImpl*)base;
DirEntry data;
HRESULT hr;
ULONG bytesToRead;
hr = StorageImpl_ReadDirEntry(This, index, &data);
if (FAILED(hr)) return hr;
if (data.size.QuadPart == 0)
{
*bytesRead = 0;
return S_OK;
}
if (offset.QuadPart + size > data.size.QuadPart)
{
bytesToRead = data.size.QuadPart - offset.QuadPart;
}
else
{
bytesToRead = size;
}
if (data.size.QuadPart < LIMIT_TO_USE_SMALL_BLOCK)
{
SmallBlockChainStream *stream;
stream = SmallBlockChainStream_Construct(This, NULL, index);
if (!stream) return E_OUTOFMEMORY;
hr = SmallBlockChainStream_ReadAt(stream, offset, bytesToRead, buffer, bytesRead);
SmallBlockChainStream_Destroy(stream);
return hr;
}
else
{
BlockChainStream *stream;
stream = BlockChainStream_Construct(This, NULL, index);
if (!stream) return E_OUTOFMEMORY;
hr = BlockChainStream_ReadAt(stream, offset, bytesToRead, buffer, bytesRead);
BlockChainStream_Destroy(stream);
return hr;
}
}
/*
* Virtual function table for the IStorage32Impl class.
*/
@ -2223,7 +2277,8 @@ static const StorageBaseImplVtbl StorageImpl_BaseVtbl =
StorageImpl_CreateDirEntry,
StorageImpl_BaseWriteDirEntry,
StorageImpl_BaseReadDirEntry,
StorageImpl_DestroyDirEntry
StorageImpl_DestroyDirEntry,
StorageImpl_StreamReadAt
};
static HRESULT StorageImpl_Construct(
@ -3671,6 +3726,13 @@ static HRESULT StorageInternalImpl_DestroyDirEntry(StorageBaseImpl *base,
index);
}
static HRESULT StorageInternalImpl_StreamReadAt(StorageBaseImpl *base,
DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead)
{
return StorageBaseImpl_StreamReadAt(&base->ancestorStorage->base,
index, offset, size, buffer, bytesRead);
}
/******************************************************************************
**
** Storage32InternalImpl_Commit
@ -4117,7 +4179,8 @@ static const StorageBaseImplVtbl StorageInternalImpl_BaseVtbl =
StorageInternalImpl_CreateDirEntry,
StorageInternalImpl_WriteDirEntry,
StorageInternalImpl_ReadDirEntry,
StorageInternalImpl_DestroyDirEntry
StorageInternalImpl_DestroyDirEntry,
StorageInternalImpl_StreamReadAt
};
/******************************************************************************

View File

@ -252,6 +252,7 @@ struct StorageBaseImplVtbl {
HRESULT (*WriteDirEntry)(StorageBaseImpl*,DirRef,const DirEntry*);
HRESULT (*ReadDirEntry)(StorageBaseImpl*,DirRef,DirEntry*);
HRESULT (*DestroyDirEntry)(StorageBaseImpl*,DirRef);
HRESULT (*StreamReadAt)(StorageBaseImpl*,DirRef,ULARGE_INTEGER,ULONG,void*,ULONG*);
};
static inline void StorageBaseImpl_Destroy(StorageBaseImpl *This)
@ -283,6 +284,13 @@ static inline HRESULT StorageBaseImpl_DestroyDirEntry(StorageBaseImpl *This,
return This->baseVtbl->DestroyDirEntry(This, index);
}
/* Read up to size bytes from this directory entry's stream at the given offset. */
static inline HRESULT StorageBaseImpl_StreamReadAt(StorageBaseImpl *This,
DirRef index, ULARGE_INTEGER offset, ULONG size, void *buffer, ULONG *bytesRead)
{
return This->baseVtbl->StreamReadAt(This, index, offset, size, buffer, bytesRead);
}
/****************************************************************************
* StorageBaseImpl stream list handlers
*/