132 lines
5.0 KiB
C++
132 lines
5.0 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
// this is the unique IReadStream* interface implementation,
|
|
// that refers to the actual read stream (hence the name proxy)
|
|
// The proxy is the per-client unique object that is acquired by the Streaming
|
|
// Engine clients via StartRead() API. Several Proxies can refer to the same
|
|
// Stream (file) but perform their operations independently.
|
|
#ifndef _CRY_SYSTEM_READ_STREAM_PROXY_HDR_
|
|
#define _CRY_SYSTEM_READ_STREAM_PROXY_HDR_
|
|
|
|
#include "IStreamEngine.h"
|
|
|
|
|
|
class CRefReadStreamProxy: public IReadStream
|
|
{
|
|
public:
|
|
// we need a MT-safe reference counting here..
|
|
|
|
// this class sets the priority order for the proxes
|
|
struct Order
|
|
{
|
|
bool operator ()(const CRefReadStreamProxy* pLeft, const CRefReadStreamProxy* pRight)const
|
|
{
|
|
return pLeft->GetPriority() > pRight->GetPriority();
|
|
}
|
|
};
|
|
|
|
// max number of retries - if the file doesn't start reading after this number of retries, unrecoverable error is returned
|
|
enum {g_numMaxRetries = 4};
|
|
// this is the length of the block that's read at once.
|
|
// big requests are splitted into smaller blocks of this size
|
|
enum {g_nBlockLength = 32 * 1024 * 1024}; // 128 k is the max size of the DMA transfer request
|
|
|
|
CRefReadStreamProxy (const char* szSource, class CRefReadStream* pStream, IStreamCallback* pCallback, StreamReadParams* pParams);
|
|
~CRefReadStreamProxy ();
|
|
DWORD_PTR GetUserData() {return m_Params.dwUserData;}
|
|
|
|
// returns true if the file read was not successful.
|
|
bool IsError();
|
|
|
|
// returns true if the file read was completed (successfully or unsuccessfully)
|
|
// check IsError to check if the whole requested file (piece) was read
|
|
bool IsFinished();
|
|
|
|
// returns the number of bytes read so far (the whole buffer size if IsFinished())
|
|
unsigned int GetBytesRead (bool bWait);
|
|
|
|
// returns the buffer into which the data has been or will be read
|
|
// at least GetBytesRead() bytes in this buffer are guaranteed to be already read
|
|
const void* GetBuffer ();
|
|
|
|
// tries to stop reading the stream; this is advisory and may have no effect
|
|
// but the callback will not be called after this. If you just destructing object,
|
|
// dereference this object and it will automatically abort and release all associated resources.
|
|
void Abort();
|
|
|
|
// tries to raise the priority of the read; this is advisory and may have no effect
|
|
void RaisePriority (unsigned nPriority);
|
|
|
|
// unconditionally waits until the callback is called
|
|
// i.e. if the stream hasn't yet finish, it's guaranteed that the user-supplied callback
|
|
// is called before return from this function (unless no callback was specified)
|
|
void Wait();
|
|
|
|
// the interface for the actual stream
|
|
// returns true, if the read start finished (with error or success)
|
|
// or false if it needs to be restarted again
|
|
bool StartRead (unsigned nMemQuota = 0x7FFFFFFF);
|
|
|
|
// returns the total number of pending read operations
|
|
//static unsigned numPendingOperations() {return g_numPendingOperations;}
|
|
|
|
int GetPriority()const{return m_Params.nPriority;}
|
|
|
|
// this returns true after the main IO job has been executed (either in worker or in main thread)
|
|
bool IsIOExecuted();
|
|
|
|
// this gets called upon the IO has been executed to call the callbacks
|
|
void FinalizeIO();
|
|
|
|
const StreamReadParams& GetParams() const {return m_Params;}
|
|
|
|
// finalizes the read operation, forces callback and erases it (so that it doesn't get called twice)
|
|
void OnFinishRead(unsigned nError);
|
|
|
|
string Dump();
|
|
|
|
// returns the size of allocated memory for this object and all subobjects if any
|
|
size_t GetSize();
|
|
protected:
|
|
// the number of times the StartRead was retried; after too many retries unrecoverable error is returned
|
|
unsigned m_numRetries;
|
|
static unsigned g_numPendingOperations;
|
|
void OnIOComplete(unsigned nError, unsigned numBytesRead);
|
|
// on the platforms that support overlapped IO, calls ReadFileEx.
|
|
// on other platforms merely reads the file, calling OnIOComplete()
|
|
DWORD CallReadFileEx ();
|
|
|
|
static VOID CALLBACK FileIOCompletionRoutine(
|
|
DWORD dwErrorCode, // completion code
|
|
DWORD dwNumberOfBytesTransfered, // number of bytes transferred
|
|
LPOVERLAPPED lpOverlapped // I/O information buffer
|
|
);
|
|
|
|
// the actual stream
|
|
class CRefReadStream* m_pStream;
|
|
// the initial data from the user
|
|
StreamReadParams m_Params;
|
|
// the source for debugging
|
|
string m_strClient;
|
|
// the callback; may be NULL
|
|
IStreamCallback* m_pCallback;
|
|
// the actual buffer to read to
|
|
void* m_pBuffer;
|
|
// the number of bytes read so far
|
|
unsigned m_numBytesRead;
|
|
|
|
// the portion of data (offset, length) currently queued for reading.
|
|
// this portion offset is RELATIVELY to the supplied by the client
|
|
// offset within the file; so, the offset within the file is m_nPieceOffset + m_Params.nOffset
|
|
// This is only used during m_bPending is true
|
|
unsigned m_nPieceOffset, m_nPieceLength;
|
|
|
|
// the structure for asynchronous callback
|
|
OVERLAPPED m_Overlapped;
|
|
|
|
bool m_bError, m_bFinished, m_bFreeBuffer, m_bPending;
|
|
unsigned m_nIOError;
|
|
};
|
|
|
|
TYPEDEF_AUTOPTR(CRefReadStreamProxy);
|
|
|
|
#endif |