Main Page Modules Class Hierarchy Data Structures File List Data Fields Globals Related Pages

# oscl_file_async_read.h

Go to the documentation of this file.

    00001 /*
    00002 * ============================================================================
    00003 *  Name        : oscl_async_file.h
    00004 *  Part of     : osclio
    00005 *  Interface   :
    00006 *  Description :
    00007 *  Version     :
    00008 * ==============================================================================
    00009 */
    00010
    00011 #ifndef OSCL_FILE_ASYNC_READ_H_INCLUDED
    00012 #define OSCL_FILE_ASYNC_READ_H_INCLUDED
    00013
    00014
    00015 #include "oscl_base.h"
    00016 #include "osclconfig_io.h"
    00017 #include "oscl_vector.h"
    00018 #include "oscl_mem.h"
    00019 #include "oscl_scheduler_ao.h"
    00020 #include "oscl_file_io.h"
    00021
    00022 #ifndef OSCL_SEMAPHORE_H_INCLUDED
    00023 #include "oscl_semaphore.h"
    00024 #endif
    00025
    00026 class OsclNativeFile;
    00027
    00028 //non-modifiable buffer pointer container
    00029 class OsclPtrC: public HeapBase
    00030 {
    00031     public:
    00032         OsclPtrC(const uint8* ptr, int32 len, int32 max): iPtr(ptr), iMaxLength(max), iLength(len)
    00033         {}
    00034         OsclPtrC(const OsclPtrC& d): HeapBase(d), iPtr(d.iPtr), iMaxLength(d.iMaxLength), iLength(d.iLength)
    00035         {}
    00036         const uint8* Ptr()
    00037         {
    00038             return iPtr;
    00039         }
    00040         void SetLength(int32 l)
    00041         {
    00042             OSCL_ASSERT(l <= iMaxLength);
    00043             iLength = l;
    00044         }
    00045         int32 Length()
    00046         {
    00047             return iLength;
    00048         }
    00049         void Zero()
    00050         {
    00051             iLength = 0;
    00052         }
    00053         void Set(OsclPtrC* v)
    00054         {
    00055             iPtr = v->iPtr;
    00056             iMaxLength = v->iMaxLength;
    00057             iLength = v->iLength;
    00058         }
    00059         void Set(uint8* ptr, int32 len, int32 max)
    00060         {
    00061             iPtr = ptr;
    00062             iLength = len;
    00063             iMaxLength = max;
    00064         }
    00065         //extract the right-most data
    00066         OsclPtrC Right(int32 size)
    00067         {
    00068             OSCL_ASSERT(iLength >= size);
    00069             OsclPtrC des(iPtr + iLength - size, size, size);
    00070             return des;
    00071         }
    00072         //extract the left-most data
    00073         OsclPtrC Left(int32 size)
    00074         {
    00075             OSCL_ASSERT(iLength >= size);
    00076             OsclPtrC des(iPtr, size, size);
    00077             return des;
    00078         }
    00079     private:
    00080         const uint8* iPtr;
    00081         int32 iMaxLength;
    00082         int32 iLength;
    00083 };
    00084
    00085 //modifiable buffer pointer container
    00086 class OsclPtr: public HeapBase
    00087 {
    00088     public:
    00089         OsclPtr(uint8* ptr, int32& len, int32 max): iPtr(ptr), iMaxLength(max), iLength(len)
    00090         {}
    00091         OsclPtr(const OsclPtr& d): HeapBase(d), iPtr(d.iPtr), iMaxLength(d.iMaxLength), iLength(d.iLength)
    00092         {}
    00093         uint8* Ptr()
    00094         {
    00095             return iPtr;
    00096         }
    00097         void SetLength(int32 l)
    00098         {
    00099             OSCL_ASSERT(l <= iMaxLength);
    00100             iLength = l;
    00101         }
    00102         int32 Length()
    00103         {
    00104             return iLength;
    00105         }
    00106         void Zero()
    00107         {
    00108             iLength = 0;
    00109         }
    00110         void Set(OsclPtr &v)
    00111         {
    00112             iPtr = v.iPtr;
    00113             iMaxLength = v.iMaxLength;
    00114             iLength = v.iLength;
    00115         }
    00116         void Set(uint8* ptr, int32 len, int32 max)
    00117         {
    00118             iPtr = ptr;
    00119             iLength = len;
    00120             iMaxLength = max;
    00121         }
    00122         void Append(OsclPtrC &v)
    00123         {
    00124             OSCL_ASSERT(iLength + v.Length() <= iMaxLength);
    00125             oscl_memmove(iPtr + iLength, v.Ptr(), v.Length());
    00126             iLength += v.Length();
    00127         }
    00128     private:
    00129         uint8* iPtr;
    00130         int32 iMaxLength;
    00131         int32& iLength;
    00132 };
    00133
    00134 //buffer container that allocates from the heap
    00135 class OsclBuf: public HeapBase
    00136 {
    00137     public:
    00138         static OsclBuf* NewL(int32 size)
    00139         {
    00140             OsclBuf* self = OSCL_NEW(OsclBuf, (size));
    00141             self->iBuffer = (uint8*)OSCL_MALLOC(self->iMaxLength);
    00142             if (!self->iBuffer)
    00143             {
    00144                 OSCL_DELETE(self);
    00145                 OsclError::Leave(OsclErrNoMemory);
    00146             }
    00147             return self;
    00148         }
    00149
    00150         static void Delete(OsclBuf* a)
    00151         {
    00152             if (a)
    00153             {
    00154                 if (a->iBuffer)
    00155                     OSCL_FREE(a->iBuffer);
    00156                 OSCL_DELETE(a);
    00157             }
    00158         }
    00159
    00160         OsclBuf(int32 size): iBuffer(NULL), iMaxLength(size), iLength(0)
    00161         {}
    00162
    00163         int32 Length()
    00164         {
    00165             return iLength;
    00166         }
    00167
    00168         OsclPtr Des()
    00169         {
    00170             OsclPtr des(iBuffer, iLength, iMaxLength);
    00171             return des;
    00172         }
    00173         OsclPtrC DesC()
    00174         {
    00175             OsclPtrC des(iBuffer, iLength, iMaxLength);
    00176             return des;
    00177         }
    00178
    00179         uint8* iBuffer;
    00180         int32 iMaxLength;
    00181         int32 iLength;
    00182 };
    00183
    00184
    00190 class OsclAsyncFileBuffer: public HeapBase
    00191 {
    00192     public:
    00193         static OsclAsyncFileBuffer* NewL(int32 aBufferSize, int32 aId);
    00194         ~OsclAsyncFileBuffer();
    00195
    00196     public:
    00197         void CleanInUse()
    00198         {
    00199             iInUse = false;
    00200         }
    00201         void SetInUse()
    00202         {
    00203             iInUse = true;
    00204         }
    00205         bool IsInUse()
    00206         {
    00207             return iInUse;
    00208         }
    00209         bool IsValid()
    00210         {
    00211             return iValid;
    00212         }
    00213         TOsclFileOffset Offset()
    00214         {
    00215             return iOffset;
    00216         }
    00217         void SetOffset(TOsclFileOffset aOffset)
    00218         {
    00219             iOffset = aOffset;
    00220         }
    00221         int32 Length()
    00222         {
    00223             return iLength;
    00224         }
    00225         bool HasThisOffset(TOsclFileOffset aOffset);
    00226         int32 Id()
    00227         {
    00228             return iId;
    00229         }
    00230         OsclBuf* Buffer();
    00231         void UpdateData();
    00232         void StartAsyncRead(bool aStartAsyncRead);
    00233
    00234     private:
    00235         OsclAsyncFileBuffer(int32 aBufferSize, int32 aId);
    00236         void ConstructL();
    00237
    00238     private:
    00239         OsclBuf* iBuffer;
    00240         TOsclFileOffset iOffset;
    00241         bool iInUse;
    00242         int32 iLength;
    00243         bool iValid;
    00244         int32 iBufferSize;
    00245         int32 iId;
    00246 };
    00247
    00248
    00252 class OsclAsyncFile : public OsclActiveObject
    00253 {
    00254     public:
    00272         static OsclAsyncFile* NewL(OsclNativeFile& aAsyncFile, int32 aCacheSize, PVLogger*);
    00273         static void Delete(OsclAsyncFile*);
    00274
    00278         ~OsclAsyncFile();
    00279
    00280     private:
    00281         //From OsclActiveObject
    00282         void Run();
    00283         void DoCancel();
    00284
    00285     public:
    00287         // File IO methods.
    00289
    00290         int32  Open(const oscl_wchar *filename, uint32 mode
    00291                     , const OsclNativeFileParams& params
    00292                     , Oscl_FileServer& fileserv);
    00293         int32  Open(const char *filename, uint32 mode
    00294                     , const OsclNativeFileParams& params
    00295                     , Oscl_FileServer& fileserv);
    00296
    00297         int32 Seek(TOsclFileOffset offset, Oscl_File::seek_type origin);
    00298         TOsclFileOffset Tell();
    00299         uint32 Read(OsclAny* aBuffer1, uint32 aDataSize, uint32 aNumElements);
    00300         int32 EndOfFile();
    00301         TOsclFileOffset Size();
    00302         int32 Close();
    00303
    00304         uint32 Write(const OsclAny* aBuffer1, uint32 aDataSize, uint32 aNumElements)
    00305         {
    00306             OSCL_UNUSED_ARG(aBuffer1);
    00307             OSCL_UNUSED_ARG(aDataSize);
    00308             OSCL_UNUSED_ARG(aNumElements);
    00309             return 0;//not supported
    00310         }
    00311         uint32 Flush()
    00312         {
    00313             return ((uint32) - 1);//not supported
    00314         }
    00315
    00316     private:
    00317         OsclAsyncFile(OsclNativeFile& aAsyncFile, int32 aCacheSize, PVLogger*);
    00321         void ConstructL();
    00322
    00323     private:
    00324         // private utility methods
    00325         void StartAsyncRead(bool aStartAsyncRead);
    00326         bool FindDataBuffer(OsclAsyncFileBuffer*& aDataBuffer, int32& aBufferId, TOsclFileOffset aOffset, int32 aSize);
    00327         void UpdateReading();
    00328         int32 BytesReadAhead();
    00329         int32 SortDataBuffers();
    00330         bool GetNextDataBuffer(OsclAsyncFileBuffer*& aDataBuffer, TOsclFileOffset aFilePointerToReadFrom);
    00331         void StartNextRead(TOsclFileOffset aPosToReadFrom);
    00332         void ReOrderBuffersQueue(int32 aFirstBufferId);
    00333         bool IsLinkedDataBuffer(OsclAsyncFileBuffer* aDataBuffer);
    00334         bool CanBeLinked(OsclAsyncFileBuffer* aDataBuffer);
    00335         uint32 doRead(uint8*& aBuffer1, uint32 aDataSize, uint32 aNumElements, TOsclFileOffset aOffset);
    00336
    00337     private:
    00338         TOsclFileOffset iFileSize;
    00339
    00340         // File object to do async read from
    00341         OsclNativeFile& iNativeFile;
    00342
    00343         // File position for async reads.
    00344         TOsclFileOffset iAsyncFilePosition;
    00345
    00346         // For verification
    00347         OsclNativeFile* iNativeFileVerify;
    00348         int32 iVerifyCount;
    00349
    00350         // Duplicate file handle for sync read
    00351         OsclNativeFile* iNativeFileDuplicate;
    00352
    00353         // File position for sync reads.
    00354         TOsclFileOffset iSyncFilePosition;
    00355
    00356         // Arrays of data buffers
    00357         Oscl_Vector<OsclAsyncFileBuffer*, OsclMemAllocator> iDataBufferArray;
    00358         Oscl_Vector<OsclAsyncFileBuffer*, OsclMemAllocator> iSortedDataBufferArray;
    00359         Oscl_Vector<OsclAsyncFileBuffer*, OsclMemAllocator> iLinkedDataBufferArray;
    00360
    00361         // Local data buffer
    00362         OsclAsyncFileBuffer* iDataBuffer;
    00363         OsclAsyncFileBuffer* iDataBufferInUse;
    00364
    00365         // Buffer for synchronous read
    00366         OsclBuf* iSyncBuffer;
    00367
    00368         // Initialized in constructor. Determines the size of each data buffer
    00369         uint32 iTotalCacheSize;
    00370
    00371         // Logical File Position (as seen by the client of this class)
    00372         TOsclFileOffset iFilePosition;
    00373
    00374         // Last offset after a user read operation
    00375         TOsclFileOffset iLastUserFileRead;
    00376
    00377         // Start async read enable flag
    00378         bool iStartAsyncRead;
    00379
    00380         // Pointer to buffer for asynchronous read
    00381         int32 iReadPtrDummyLen;
    00382         OsclPtr iReadPtr;
    00383
    00384         // For profiling
    00385         PVLogger* iLogger;
    00386
    00388         // Configuration parameters.
    00390
    00391         //   Number of buffers in the linked list
    00392         int32 iKCacheBufferCount ;
    00393
    00394         //   This defines the limit on how much data we will
    00395         //   read ahead of the current position
    00396         int32 iKMinBytesReadAhead ;
    00397
    00398         //   This defines the size of the individual async read operations.
    00399         int32 iKAsyncReadBufferSize ;
    00400
    00402         // The non-native async read implementation.
    00404
    00405         // Keeps track of whether we have native async read or not
    00406         bool iHasNativeAsyncRead;
    00407
    00408         // Thread control sems
    00409         OsclSemaphore iAsyncReadSem;
    00410         OsclSemaphore iAsyncReadExitSem;
    00411
    00412         // To keep track of the tread state:
    00413         // EAsyncReadNotActive - the thread is not created or the thread is stopped
    00414         // EAsyncReadActive    - the thread is running
    00415         enum TAsyncReadThreadState {EAsyncReadNotActive, EAsyncReadActive};
    00416         TAsyncReadThreadState iAsyncReadThreadState;
    00417
    00418         // To signal the thread to exit
    00419         bool iAsyncReadThreadExitFlag;
    00420
    00421         // Number of bytes read in the last call
    00422         int32 iAsyncReadNumBytes;
    00423
    00424         // Thread routine
    00425         void InThread();
    00426         static TOsclThreadFuncRet OSCL_THREAD_DECL iAsyncReadThreadFunc(TOsclThreadFuncArg);
    00427
    00428         // Thread start/stop.
    00429         void LaunchAsyncReadThread();
    00430         void StopAsyncReadThread();
    00431
    00432         // Request an async read.
    00433         void StartNonNativeAsyncRead();
    00434
    00435     public:
    00436         // for test&stat
    00437         uint32 iNumOfRun;
    00438         uint32 iNumOfRunErr;
    00439 };
    00440
    00441 #endif
    00442