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 

OSCL API
Posting Version: CORE_8.000.1.1_RC4