userlibandfileserver/fileserver/sfat32/sl_fatcache.h
changeset 2 4122176ea935
child 6 0173bcd7697c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/userlibandfileserver/fileserver/sfat32/sl_fatcache.h	Mon Dec 21 16:14:42 2009 +0000
@@ -0,0 +1,380 @@
+// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// f32\sfat\sl_facache.h
+// FAT cache base classes definition
+// FAT12 and FAT16 cache classes definition
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#ifndef SL_FAT_CACHE_H
+#define SL_FAT_CACHE_H
+
+
+//-----------------------------------------------------------------------------
+
+/**
+    A simple abstraction of the 32 bit flags
+*/
+class T32Bits
+{
+ public:
+    T32Bits() : iData(0) {}
+
+    inline void  Clear();
+    inline TBool HasBitsSet() const;
+    inline void SetBit(TUint32 aIndex);
+    inline TBool operator[](TUint32 aIndex) const;
+
+ private:
+    TUint32 iData; ///< 32 bits data
+};
+
+//-----------------------------------------------------------------------------
+
+class CFatBitCache;
+
+/**
+    An abstract base class for all types of FAT caches.
+    Provides user interface and some common for all types of FAT caches functionality.
+*/
+class CFatCacheBase : public CBase
+{
+ public:
+
+    virtual ~CFatCacheBase();
+
+    //-- public interface
+    virtual void Close(TBool /*aDiscardDirtyData*/) {};
+    virtual void FlushL() = 0;
+
+    virtual TUint32 ReadEntryL(TUint32 aIndex) = 0;
+    virtual void WriteEntryL(TUint32 aIndex, TUint32 aEntry) = 0;
+    
+    virtual TInt Invalidate() = 0;
+    virtual TInt InvalidateRegion(TUint32 aStartEntry, TUint32 aNumEntries) = 0;
+
+    TInt ReadFatData(TUint32 aPos, TUint32 aLen, TDes8& aData) const;
+    TInt WriteFatData(TUint32 aPos, const TDesC8& aData) const;
+
+    inline TUint32  FatStartPos() const;
+    inline TUint32  FatSize() const;
+    inline TFatType FatType() const;
+
+ public:
+    
+    //-- auxilary interface to additional bit supercache (it may exist only in FAT32 cache implementation)
+    virtual CFatBitCache* BitCacheInterface();
+
+
+ protected:
+    CFatCacheBase();
+
+    virtual void InitialiseL(CFatMountCB* aOwner);
+
+    inline TBool IsDirty() const;
+    inline void SetDirty(TBool aDirty);
+    inline TUint NumFATs() const;
+
+    TBool CheckInvalidatingDirtyCache() const;
+
+    inline TUint FAT_SectorSzLog2() const;
+    inline TUint FAT_SectorSz() const; 
+    inline TUint FAT_ClusterSzLog2() const;
+
+ protected:
+    
+    enum {KInvalidFatNo = 0xFF}; ///< used to invalidate current FAT no.
+    TUint   iCurrentFatNo;       ///< current FAT number WriteFatData will write to.
+
+ private:    
+    //-- values cached from owning mount.
+    TUint32     iFatStartPos;   ///< media position of FAT1 start 
+    TUint32     iFatSize;       ///< size of FAT in bytes
+    TUint16     iNumFATs;       ///< number of FATs on the volume
+    TUint16     iFatSecSzLog2;  ///< Log2(FAT Sector size)
+    TUint16     iFatClustSzLog2;///< Log2(FAT cluster size)
+    TFatType    iFatType;       ///< FAT type
+    TFatDriveInterface* ipDrive;///< interface to the media driver
+    //---
+
+    TBool       iDirty;         ///< ETrue if the cache is dirty
+};
+
+
+//-----------------------------------------------------------------------------
+
+/**
+    Fixed FAT12 cache. This is a contiguous cache that caches whole FAT12.
+    This cache is logically divided to sectors, maximal number of sectors in this cache is KMaxSectorsInCache (32).
+    
+    Read granularity: whole cache; anyway it can't be larger than 6126 bytes.
+    Write granularity: cache sector size, which is always "FAT Sector Size" and non-configurable.
+*/
+class CFat12Cache : public CFatCacheBase
+{
+ public:
+    static CFat12Cache* NewL(CFatMountCB* aOwner, TUint32 aFatSize);
+
+    //-- overrides from base class
+    virtual void Close(TBool aDiscardDirtyData);
+    virtual void FlushL();
+
+    virtual TUint32 ReadEntryL(TUint32 aIndex);
+    virtual void WriteEntryL(TUint32 aIndex, TUint32 aEntry);
+
+    virtual TInt Invalidate();
+    virtual TInt InvalidateRegion(TUint32 aStartEntry, TUint32 aNumEntries);
+    //------------------------------------
+
+ private:
+    
+    void InitialiseL(CFatMountCB* aOwner, TUint32 aFatSize); 
+
+    CFat12Cache();
+    CFat12Cache(const CFat12Cache&);
+    CFat12Cache& operator=(const CFat12Cache&);
+
+
+    inline TUint32 NumSectors() const;
+    void AssertCacheReallyClean() const;
+
+ private:
+
+    enum {KMaxSectorsInCache = 32};  ///< maximal number sectors in FAT12 cache
+    enum {KFat12EntryMask = 0x0FFF}; ///< FAT12 entry mask
+
+    TUint32 iSectorsInCache;    ///< total number sectors in the cache, KMaxSectorsInCache max.
+    T32Bits iDirtySectors;      ///< dirty sectors bitmap. '1' bit corresponds to the dirty sector;
+    RBuf8   iData;              ///< Whole FAT12 cache data.
+};
+
+
+//-----------------------------------------------------------------------------
+
+/**
+    Abstract base class for paged caches, i.e. those that consist of some number of cache pages.
+    In this case the most of the functionality is implemented in page classes and this is just a page container.
+    Each cache page in turn is logically divided to sectors. The sector is a logical unit of write granularity
+    See also CFatCachePageBase et al.
+*/
+class CFatPagedCacheBase : public CFatCacheBase
+{
+ public:
+
+    inline TUint PageSizeLog2()  const;
+    inline TUint PageSize()      const;
+    
+    inline TUint SectorSizeLog2() const;
+    inline TUint SectorsInPage()  const;
+
+ protected:
+    CFatPagedCacheBase();
+
+ protected:
+    
+    enum {KMaxSectorsInPage = 32}; ///< maximal number sectors in FAT cache page
+
+    TUint iPageSizeLog2;    ///< Log2(page size)
+    TUint iSectorSizeLog2;  ///< Log2(page sector size)
+ 
+};
+
+//-----------------------------------------------------------------------------
+
+class CFat16FixedCachePage;
+
+/**
+    FAT16 fixed paged cache. Used for FAT16 only and caches whole FAT16 (its max size is 131048 bytes).
+    Consists of the fixed array of cache pages; Pages are allocated on demand and never get evicted.
+    Each page is logically divided to page sectors. The number of pages depends on the FAT16 size.
+
+    Read granularity: One page, which size is 2^aRdGranularityLog2
+    Write granularity: cache's page sector; its size is 2^aWrGranularityLog2
+*/
+class CFat16FixedCache : public CFatPagedCacheBase
+{
+ public:
+
+    static CFat16FixedCache* NewL(CFatMountCB* aOwner, TUint32 aFatSize, TUint32 aRdGranularityLog2, TUint32 aWrGranularityLog2);
+
+    //-- overrides from base class
+    virtual void Close(TBool aDiscardDirtyData);
+    virtual void FlushL();
+
+    virtual TUint32 ReadEntryL(TUint32 aIndex);
+    virtual void WriteEntryL(TUint32 aIndex, TUint32 aEntry);
+    
+
+    virtual TInt Invalidate();
+    virtual TInt InvalidateRegion(TUint32 aStartEntry, TUint32 aNumEntries);
+    //------------------------------------
+
+ private:
+
+    void InitialiseL(CFatMountCB* aOwner, TUint32 aFatSize, TUint32 aRdGranularityLog2, TUint32 aWrGranularityLog2); 
+    
+    CFat16FixedCache();
+    CFat16FixedCache(const CFat16FixedCache&);
+    CFat16FixedCache& operator=(const CFat16FixedCache&);
+
+    inline TUint NumPages() const;
+    void AssertCacheReallyClean() const;
+
+ private:    
+    RPointerArray<CFat16FixedCachePage> iPages;  ///< array of pointer to the cahe pages; if the entry is NULL, it means that the page isn't allocated yet.
+
+};
+
+
+//-----------------------------------------------------------------------------
+
+
+/**
+    An abstract base class for the cache page. Paged caches, i.e derived form CFatPagedCacheBase uses this functionality.
+    Provides an interface and common functionality for all types of cache pages.
+
+    The FAT cache page contains a number of FAT16 or FAT32 entries, their number is always the power of 2.
+    The page is logically divided into sectors, the maximal number of sectors in the page is KMaxSectorsInPage (32).
+    The page read granularity is whole page and the write granularity is the sector  (see aRdGranularityLog2, aWrGranularityLog2 from the cache)
+
+    The caching is write-back, i.e WriteCachedEntryL() modifies data in the cache and marks corresponding page sector as dirty.
+    FlushL() shall be called to flust all dirty sectors in page to the media
+
+*/
+class CFatCachePageBase : public CBase
+{
+public:
+    
+    ~CFatCachePageBase();
+
+    //----------------
+    virtual TBool ReadCachedEntryL (TUint32 aFatIndex, TUint32& aResult) = 0;
+    virtual TBool WriteCachedEntryL(TUint32 aFatIndex, TUint32 aFatEntry) = 0; 
+    virtual TUint32 ReadFromMediaL(TUint32 aFatIndex) = 0;
+    virtual void FlushL(TBool aKeepDirty);
+    
+    //----------------
+    inline TBool IsEntryCached(TUint32 aFatIndex) const ;
+    void Invalidate(TBool aIgnoreDirtyData = EFalse);
+    
+    inline TBool IsDirty() const;
+    inline TBool IsValid() const;
+    
+    inline TUint32 StartFatIndex() const;
+
+protected:
+    CFatCachePageBase(CFatPagedCacheBase& aCache);
+
+    /** possible states of the page */
+    enum TState
+        {
+        EInvalid, ///< the page's data are invalid
+        EClean,   ///< the page is clean, data valid and the same as on the media  
+        EDirty    ///< the page is dirty, there are data eventually to be flushed to the media, iDirtySectors contains dirty sectors bitmap.
+        };
+
+    inline void SetState(TState aState);
+    inline TState State() const;
+    inline void SetClean();
+    inline TUint32 PageSize() const; 
+    inline TUint32 NumSectors() const; 
+    
+    virtual void DoWriteSectorL(TUint32 aSector)=0;
+    inline TUint32 EntriesInPage() const;
+
+protected:
+    TUint32 iStartIndexInFAT;   ///< FAT index this page starts from
+    T32Bits iDirtySectors;      ///< dirty sectors bitmap. '1' bit corresponds to the dirty sector;
+    CFatPagedCacheBase& iCache; ///< reference to the owher cache
+    RBuf8   iData;              ///< page Data
+
+private:
+    TState  iState;             ///< page state
+    TUint32 iFatEntriesInPage;  ///< number of FAT entries in the page. 
+
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------------------
+
+/**
+    FAT16 cache page. Used only by CFat16FixedCache.
+*/
+class CFat16FixedCachePage : public CFatCachePageBase
+{
+ public:
+    ~CFat16FixedCachePage() {}
+    
+    static CFat16FixedCachePage* NewL(CFatPagedCacheBase& aCache);
+
+    //-- overrides
+    virtual TBool ReadCachedEntryL (TUint32 aFatIndex, TUint32& aResult);
+    virtual TBool WriteCachedEntryL(TUint32 aFatIndex, TUint32 aFatEntry); 
+    virtual TUint32 ReadFromMediaL(TUint32 aFatIndex);
+    //----
+
+ private:
+    CFat16FixedCachePage(CFatPagedCacheBase& aCache);
+
+    //-- outlaws here
+    CFat16FixedCachePage();
+    CFat16FixedCachePage(const CFat16FixedCachePage&);
+    CFat16FixedCachePage& operator=(const CFat16FixedCachePage&);
+
+    virtual void DoWriteSectorL(TUint32 aSector);
+
+    inline TFat16Entry* GetEntryPtr(TUint32 aFatIndex) const;
+
+ private:
+    enum {KFat16EntryMask = 0xFFFF}; ///< FAT16 entry mask
+};
+
+
+
+//---------------------------------------------------------------------------------------------------------------------------------
+
+
+
+#include "sl_fatcache.inl"
+
+
+#endif //SL_FAT_CACHE_H
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+