00001
00002
00003
00004
00005
00006
00007
00008
00009 #pragma once
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 class CAsyncIo;
00020 class CAsyncStream;
00021
00022
00023
00024
00025 class CAsyncStream
00026 {
00027 public:
00028 virtual ~CAsyncStream() {};
00029 virtual HRESULT SetPointer(LONGLONG llPos) = 0;
00030 virtual HRESULT Read(PBYTE pbBuffer,
00031 DWORD dwBytesToRead,
00032 BOOL bAlign,
00033 LPDWORD pdwBytesRead) = 0;
00034 virtual LONGLONG Size(LONGLONG *pSizeAvailable = NULL) = 0;
00035 virtual DWORD Alignment() = 0;
00036 virtual void Lock() = 0;
00037 virtual void Unlock() = 0;
00038
00039 };
00040
00041
00042
00043
00044 class CAsyncRequest
00045 {
00046 CAsyncIo *m_pIo;
00047 CAsyncStream *m_pStream;
00048 LONGLONG m_llPos;
00049 BOOL m_bAligned;
00050 LONG m_lLength;
00051 BYTE* m_pBuffer;
00052 LPVOID m_pContext;
00053 DWORD m_dwUser;
00054 HRESULT m_hr;
00055
00056 public:
00057
00058
00059 HRESULT Request(
00060 CAsyncIo *pIo,
00061 CAsyncStream *pStream,
00062 LONGLONG llPos,
00063 LONG lLength,
00064 BOOL bAligned,
00065 BYTE* pBuffer,
00066 LPVOID pContext,
00067 DWORD dwUser);
00068
00069
00070
00071 HRESULT Complete();
00072
00073
00074 HRESULT Cancel()
00075 {
00076 return S_OK;
00077 };
00078
00079
00080 LPVOID GetContext()
00081 {
00082 return m_pContext;
00083 };
00084
00085 DWORD GetUser()
00086 {
00087 return m_dwUser;
00088 };
00089
00090 HRESULT GetHResult() {
00091 return m_hr;
00092 };
00093
00094
00095 LONG GetActualLength() {
00096 return m_lLength;
00097 };
00098
00099 LONGLONG GetStart() {
00100 return m_llPos;
00101 };
00102 };
00103
00104
00105 typedef CGenericList<CAsyncRequest> CRequestList;
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 class CAsyncIo
00130 {
00131
00132 CCritSec m_csReader;
00133 CAsyncStream *m_pStream;
00134
00135 CCritSec m_csLists;
00136 BOOL m_bFlushing;
00137 CRequestList m_listWork;
00138 CRequestList m_listDone;
00139 CAMEvent m_evWork;
00140 CAMEvent m_evDone;
00141
00142
00143 LONG m_cItemsOut;
00144 BOOL m_bWaiting;
00145 CAMEvent m_evAllDone;
00146
00147
00148 CAMEvent m_evStop;
00149 HANDLE m_hThread;
00150
00151 LONGLONG Size() {
00152 ASSERT(m_pStream != NULL);
00153 return m_pStream->Size();
00154 };
00155
00156
00157 HRESULT StartThread(void);
00158
00159
00160 HRESULT CloseThread(void);
00161
00162
00163
00164
00165
00166 CAsyncRequest* GetWorkItem();
00167
00168
00169 CAsyncRequest* GetDoneItem();
00170
00171
00172 HRESULT PutWorkItem(CAsyncRequest* pRequest);
00173
00174
00175 HRESULT PutDoneItem(CAsyncRequest* pRequest);
00176
00177
00178 void ProcessRequests(void);
00179
00180
00181
00182 static DWORD WINAPI InitialThreadProc(LPVOID pv) {
00183 CAsyncIo * pThis = (CAsyncIo*) pv;
00184 return pThis->ThreadProc();
00185 };
00186
00187 DWORD ThreadProc(void);
00188
00189 public:
00190
00191 CAsyncIo(CAsyncStream *pStream);
00192 ~CAsyncIo();
00193
00194
00195 HRESULT Open(LPCTSTR pName);
00196
00197
00198
00199 HRESULT AsyncActive(void);
00200
00201
00202
00203 HRESULT AsyncInactive(void);
00204
00205
00206 HRESULT Request(
00207 LONGLONG llPos,
00208 LONG lLength,
00209 BOOL bAligned,
00210 BYTE* pBuffer,
00211 LPVOID pContext,
00212 DWORD dwUser);
00213
00214
00215 HRESULT WaitForNext(
00216 DWORD dwTimeout,
00217 LPVOID *ppContext,
00218 DWORD * pdwUser,
00219 LONG * pcbActual
00220 );
00221
00222
00223 HRESULT SyncReadAligned(
00224 LONGLONG llPos,
00225 LONG lLength,
00226 BYTE* pBuffer,
00227 LONG* pcbActual,
00228 PVOID pvContext
00229 );
00230
00231
00232
00233 HRESULT SyncRead(
00234 LONGLONG llPos,
00235 LONG lLength,
00236 BYTE* pBuffer);
00237
00238
00239 HRESULT Length(LONGLONG *pllTotal, LONGLONG* pllAvailable);
00240
00241
00242
00243 HRESULT Alignment(LONG* pl);
00244
00245 HRESULT BeginFlush();
00246 HRESULT EndFlush();
00247
00248 LONG Alignment()
00249 {
00250 return m_pStream->Alignment();
00251 };
00252
00253 BOOL IsAligned(LONG l) {
00254 if ((l & (Alignment() -1)) == 0) {
00255 return TRUE;
00256 } else {
00257 return FALSE;
00258 }
00259 };
00260
00261 BOOL IsAligned(LONGLONG ll) {
00262 return IsAligned( (LONG) (ll & 0xffffffff));
00263 };
00264
00265
00266 HANDLE StopEvent() const { return m_evDone; }
00267 };