Vincent Povirk : ole32: Use the storage vtable to read streams.
Alexandre Julliard
julliard at winehq.org
Tue Dec 8 11:10:36 CST 2009
Module: wine
Branch: master
Commit: 62e54bacba086cf279936c28f75942c019b887cd
URL: http://source.winehq.org/git/wine.git/?a=commit;h=62e54bacba086cf279936c28f75942c019b887cd
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Mon Nov 30 10:35:55 2009 -0600
ole32: Use the storage vtable to read streams.
---
dlls/ole32/stg_stream.c | 58 ++++++----------------------------------
dlls/ole32/storage32.c | 67 +++++++++++++++++++++++++++++++++++++++++++++-
dlls/ole32/storage32.h | 8 +++++
3 files changed, 82 insertions(+), 51 deletions(-)
diff --git a/dlls/ole32/stg_stream.c b/dlls/ole32/stg_stream.c
index 6200126..0888180 100644
--- a/dlls/ole32/stg_stream.c
+++ b/dlls/ole32/stg_stream.c
@@ -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);
+ res = StorageBaseImpl_StreamReadAt(This->parentStorage,
+ This->dirEntry,
+ This->currentPosition,
+ cb,
+ pv,
+ pcbRead);
- }
- else if (This->bigBlockChain!=0)
- {
- res = BlockChainStream_ReadAt(This->bigBlockChain,
- This->currentPosition,
- bytesToReadFromBuffer,
- pv,
- pcbRead);
- }
- else
+ if (SUCCEEDED(res))
{
/*
- * 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.
+ * Advance the pointer for the number of positions read.
*/
-
- *pcbRead = 0;
- res = S_OK;
- goto end;
- }
-
- 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;
+ This->currentPosition.u.LowPart += *pcbRead;
}
-end:
TRACE("<-- %08x\n", res);
return res;
}
diff --git a/dlls/ole32/storage32.c b/dlls/ole32/storage32.c
index 53c2c87..0e5861d 100644
--- a/dlls/ole32/storage32.c
+++ b/dlls/ole32/storage32.c
@@ -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
};
/******************************************************************************
diff --git a/dlls/ole32/storage32.h b/dlls/ole32/storage32.h
index 12cff71..24070d1 100644
--- a/dlls/ole32/storage32.h
+++ b/dlls/ole32/storage32.h
@@ -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
*/
More information about the wine-cvs
mailing list