sl@0: // Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32\include\e32base.h sl@0: // sl@0: // sl@0: sl@0: #ifndef __E32BASE_H__ sl@0: #define __E32BASE_H__ sl@0: #include sl@0: sl@0: /** sl@0: * Container Base Class sl@0: */ sl@0: class CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Base class for all classes to be instantiated on the heap. sl@0: sl@0: By convention, all classes derived from CBase have a name beginning with the sl@0: letter 'C'. sl@0: sl@0: The class has two important features: sl@0: sl@0: 1. A virtual destructor that allows instances of derived classes to be destroyed sl@0: and properly cleaned up through a CBase* pointer. All CBase derived objects sl@0: can be pushed, as CBase* pointers, onto the cleanup stack, and destroyed through sl@0: a call to CleanupStack::PopAndDestroy(). sl@0: sl@0: 2. Initialisation of the CBase derived object to binary zeroes through a specific sl@0: CBase::operator new() - this means that members, whose initial value should sl@0: be zero, do not have to be initialised in the constructor. This allows safe sl@0: destruction of a partially-constructed object. sl@0: sl@0: Note that using C++ arrays of CBase-derived types is not recommended, as objects sl@0: in the array will not be zero-initialised (as there is no operator new[] member). sl@0: You should use an array class such as RPointerArray instead for arrays of sl@0: CBase-derived types. sl@0: sl@0: @see CleanupStack sl@0: */ sl@0: { sl@0: public: sl@0: /** sl@0: Default constructor sl@0: */ sl@0: inline CBase() {} sl@0: IMPORT_C virtual ~CBase(); sl@0: inline TAny* operator new(TUint aSize, TAny* aBase) __NO_THROW; sl@0: inline TAny* operator new(TUint aSize) __NO_THROW; sl@0: inline TAny* operator new(TUint aSize, TLeave); sl@0: inline TAny* operator new(TUint aSize, TUint aExtraSize) __NO_THROW; sl@0: inline TAny* operator new(TUint aSize, TLeave, TUint aExtraSize); sl@0: IMPORT_C static void Delete(CBase* aPtr); sl@0: protected: sl@0: IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1); sl@0: private: sl@0: CBase(const CBase&); sl@0: CBase& operator=(const CBase&); sl@0: private: sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CBufBase : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Defines the interface for dynamic buffers. sl@0: sl@0: The basic functions, InsertL(), Read(), Write(), Delete(), Reset() and Size(), sl@0: transfer data between the buffer and other places, and allow that data to sl@0: be deleted sl@0: sl@0: The ExpandL() and Resize() functions allow some operations to be carried out sl@0: with greater efficiency sl@0: sl@0: A Compress() function frees (back to the heap) any space which may have been sl@0: allocated, but not used sl@0: sl@0: Ptr() and BackPtr() allow look-up of contiguous data from any given position, sl@0: forward or backward sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C ~CBufBase(); sl@0: inline TInt Size() const; sl@0: IMPORT_C void Reset(); sl@0: IMPORT_C void Read(TInt aPos,TDes8& aDes) const; sl@0: IMPORT_C void Read(TInt aPos,TDes8& aDes,TInt aLength) const; sl@0: IMPORT_C void Read(TInt aPos,TAny* aPtr,TInt aLength) const; sl@0: IMPORT_C void Write(TInt aPos,const TDesC8& aDes); sl@0: IMPORT_C void Write(TInt aPos,const TDesC8& aDes,TInt aLength); sl@0: IMPORT_C void Write(TInt aPos,const TAny* aPtr,TInt aLength); sl@0: IMPORT_C void InsertL(TInt aPos,const TDesC8& aDes); sl@0: IMPORT_C void InsertL(TInt aPos,const TDesC8& aDes,TInt aLength); sl@0: IMPORT_C void InsertL(TInt aPos,const TAny* aPtr,TInt aLength); sl@0: IMPORT_C void ExpandL(TInt aPos,TInt aLength); sl@0: IMPORT_C void ResizeL(TInt aSize); sl@0: // Pure virtual sl@0: /** sl@0: Compresses the buffer so as to occupy minimal space. sl@0: sl@0: Normally, you would call this when a buffer has reached its final size, sl@0: or when you know it will not expand again for a while, or when an sl@0: out-of-memory error has occurred and your program is taking measures to sl@0: save space. Compression in these circumstances releases memory for other sl@0: programs to use, but has no adverse effect on performance. sl@0: sl@0: Derived classes provide the implementation. sl@0: sl@0: @see CBufFlat::Compress sl@0: @see CBufSeg::Compress sl@0: */ sl@0: virtual void Compress()=0; sl@0: /** sl@0: Deletes data from the buffer. sl@0: sl@0: Derived classes provide the implementation. sl@0: sl@0: @param aPos Buffer position where the deletion will begin; must be in the sl@0: range zero to (Size() minus the length of the data sl@0: to be deleted). sl@0: @param aLength The number of bytes to be deleted; must be non-negative. sl@0: sl@0: @see CBufFlat::Delete sl@0: @see CBufSeg::Delete sl@0: */ sl@0: virtual void Delete(TInt aPos,TInt aLength)=0; sl@0: /** sl@0: Gets a pointer descriptor to represent the data from the specified position to sl@0: the end of the contiguous region containing that byte. sl@0: sl@0: Derived classes provide the implementation. sl@0: sl@0: @param aPos Buffer position: must be in range zero to Size(). sl@0: sl@0: @return Descriptor representing the data starting at aPos, and whose length sl@0: indicates the number of contiguous bytes stored in the buffer, sl@0: forward from that point. The length will be non-zero unless aPos==Size(). sl@0: sl@0: @see CBufFlat::Ptr sl@0: @see CBufSeg::Ptr sl@0: */ sl@0: virtual TPtr8 Ptr(TInt aPos)=0; sl@0: /** sl@0: Gets a pointer descriptor to represent data from just before the specified sl@0: data byte backward to the beginning of the contiguous region containing sl@0: that byte. sl@0: sl@0: Derived classes provide the implementation. sl@0: sl@0: @param aPos Buffer position: must be in range zero to Size(). sl@0: sl@0: @return Descriptor representing the back contiguous region. sl@0: The address in the descriptor is the pointer to the bytes at the sl@0: buffer position, unless the buffer position was at the beginning of sl@0: a non-first segment in the buffer: in this case, the address is a sl@0: pointer just beyond the last data byte in the previous segment. sl@0: The length is the number of contiguous bytes from the address sl@0: backwards to the beginning of the segment. sl@0: sl@0: @see CBufFlat::BackPtr sl@0: @see CBufSeg::BackPtr sl@0: */ sl@0: virtual TPtr8 BackPtr(TInt aPos)=0; sl@0: private: sl@0: virtual void DoInsertL(TInt aPos,const TAny* aPtr,TInt aLength)=0; sl@0: protected: sl@0: IMPORT_C CBufBase(TInt anExpandSize); sl@0: protected: sl@0: TInt iSize; sl@0: TInt iExpandSize; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CBufFlat : public CBufBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Provides a flat storage dynamic buffer. sl@0: sl@0: This class should be used when high-speed pointer lookup is an important sl@0: consideration, and you are reasonably confident that the insertion of sl@0: data will not fail. sl@0: sl@0: This class is an implementation of the abstract buffer interface provided sl@0: by CBufBase and uses a single heap cell to contain the data. sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C ~CBufFlat(); sl@0: IMPORT_C static CBufFlat* NewL(TInt anExpandSize); sl@0: inline TInt Capacity() const; sl@0: IMPORT_C void SetReserveL(TInt aSize); sl@0: IMPORT_C void Compress(); sl@0: IMPORT_C void Delete(TInt aPos,TInt aLength); sl@0: IMPORT_C TPtr8 Ptr(TInt aPos); sl@0: IMPORT_C TPtr8 BackPtr(TInt aPos); sl@0: protected: sl@0: IMPORT_C CBufFlat(TInt anExpandSize); sl@0: private: sl@0: IMPORT_C void DoInsertL(TInt aPos,const TAny* aPtr,TInt aLength); sl@0: private: sl@0: TInt iMaxSize; sl@0: TUint8* iPtr; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class TBufSegLink; sl@0: class CBufSeg : public CBufBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Provides a segmented dynamic buffer. sl@0: sl@0: This class should be used when the object has a long life-time and an sl@0: unpredictable number of insertions, or there is concern about the performance sl@0: of insertion and deletion operations into large buffers. sl@0: sl@0: This class is an implementation of the abstract buffer interface provided sl@0: by CBufBase and uses doubly-linked list of heap cells to contain the data; sl@0: each cell containing a segment of the buffer. sl@0: sl@0: Its (private) data members include an anchor for the doubly-linked list, and also a sl@0: reference to the buffer position used by the last operation. This reference sl@0: acts as a cache; if the next operation uses a similar buffer position, then sl@0: calculation of the pointer corresponding to its buffer position is much faster. sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C ~CBufSeg(); sl@0: IMPORT_C static CBufSeg* NewL(TInt anExpandSize); sl@0: IMPORT_C void Compress(); sl@0: IMPORT_C void Delete(TInt aPos,TInt aLength); sl@0: IMPORT_C TPtr8 Ptr(TInt aPos); sl@0: IMPORT_C TPtr8 BackPtr(TInt aPos); sl@0: protected: sl@0: IMPORT_C CBufSeg(TInt anExpandSize); sl@0: void InsertIntoSegment(TBufSegLink* aSeg,TInt anOffset,const TAny* aPtr,TInt aLength); sl@0: void DeleteFromSegment(TBufSegLink* aSeg,TInt anOffset,TInt aLength); sl@0: void FreeSegment(TBufSegLink* aSeg); sl@0: void SetSBO(TInt aPos); sl@0: void AllocSegL(TBufSegLink* aSeg,TInt aNumber); sl@0: private: sl@0: IMPORT_C void DoInsertL(TInt aPos,const TAny* aPtr,TInt aLength); sl@0: private: sl@0: TDblQue iQue; sl@0: TBufSegLink* iSeg; sl@0: TInt iBase; sl@0: TInt iOffset; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class TKeyArrayFix : public TKey sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Defines the characteristics of a key used to access the elements of arrays sl@0: of fixed length objects. sl@0: sl@0: An object of this type can represent three categories of key, depending on sl@0: the constructor used: sl@0: sl@0: 1. a descriptor key sl@0: sl@0: 2. a text key sl@0: sl@0: 3. a numeric key. sl@0: sl@0: The Sort(), InsertIsqL(), Find() and FindIsqL() member functions of the CArrayFixFlat sl@0: and CArrayFixSeg class hierarchies need a TKeyArrayFix object as an argument sl@0: to define the location and type of key within an array element. sl@0: sl@0: @see CArrayFixFlat sl@0: @see CArrayFixSeg sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C TKeyArrayFix(TInt anOffset,TKeyCmpText aType); sl@0: IMPORT_C TKeyArrayFix(TInt anOffset,TKeyCmpText aType,TInt aLength); sl@0: IMPORT_C TKeyArrayFix(TInt anOffset,TKeyCmpNumeric aType); sl@0: protected: sl@0: IMPORT_C virtual void Set(CBufBase* aBase,TInt aRecordLength); sl@0: IMPORT_C TAny* At(TInt anIndex) const; sl@0: protected: sl@0: TInt iRecordLength; sl@0: CBufBase* iBase; sl@0: friend class CArrayFixBase; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: typedef CBufBase*(*TBufRep)(TInt anExpandSize); sl@0: class CArrayFixBase : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Base class for arrays of fixed length objects. sl@0: sl@0: It provides implementation and public functions which are common to all arrays sl@0: of this type. sl@0: sl@0: The class is always derived from and is never instantiated explicitly. sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C ~CArrayFixBase(); sl@0: inline TInt Count() const; sl@0: inline TInt Length() const; sl@0: IMPORT_C void Compress(); sl@0: IMPORT_C void Reset(); sl@0: IMPORT_C TInt Sort(TKeyArrayFix& aKey); sl@0: IMPORT_C TAny* At(TInt anIndex) const; sl@0: IMPORT_C TAny* End(TInt anIndex) const; sl@0: IMPORT_C TAny* Back(TInt anIndex) const; sl@0: IMPORT_C void Delete(TInt anIndex); sl@0: IMPORT_C void Delete(TInt anIndex,TInt aCount); sl@0: IMPORT_C TAny* ExpandL(TInt anIndex); sl@0: IMPORT_C TInt Find(const TAny* aPtr,TKeyArrayFix& aKey,TInt& anIndex) const; sl@0: IMPORT_C TInt FindIsq(const TAny* aPtr,TKeyArrayFix& aKey,TInt& anIndex) const; sl@0: IMPORT_C void InsertL(TInt anIndex,const TAny* aPtr); sl@0: IMPORT_C void InsertL(TInt anIndex,const TAny* aPtr,TInt aCount); sl@0: IMPORT_C TInt InsertIsqL(const TAny* aPtr,TKeyArrayFix& aKey); sl@0: IMPORT_C TInt InsertIsqAllowDuplicatesL(const TAny* aPtr,TKeyArrayFix& aKey); sl@0: IMPORT_C void ResizeL(TInt aCount,const TAny* aPtr); sl@0: protected: sl@0: IMPORT_C CArrayFixBase(TBufRep aRep,TInt aRecordLength,TInt aGranularity); sl@0: IMPORT_C void InsertRepL(TInt anIndex,const TAny* aPtr,TInt aReplicas); sl@0: IMPORT_C void SetKey(TKeyArrayFix& aKey) const; sl@0: IMPORT_C void SetReserveFlatL(TInt aCount); sl@0: IMPORT_C static TInt CountR(const CBase* aPtr); sl@0: IMPORT_C static const TAny* AtR(const CBase* aPtr,TInt anIndex); sl@0: private: sl@0: TInt iCount; sl@0: TInt iGranularity; sl@0: TInt iLength; sl@0: TBufRep iCreateRep; sl@0: CBufBase* iBase; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: class CArrayFix : public CArrayFixBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A thin templated base class for arrays of fixed length objects. sl@0: sl@0: The public functions provide standard array behaviour. sl@0: sl@0: The class is always derived from and is never instantiated explicitly. sl@0: */ sl@0: { sl@0: public: sl@0: inline CArrayFix(TBufRep aRep,TInt aGranularity); sl@0: inline const T& operator[](TInt anIndex) const; sl@0: inline T& operator[](TInt anIndex); sl@0: inline const T& At(TInt anIndex) const; sl@0: inline const T* End(TInt anIndex) const; sl@0: inline const T* Back(TInt anIndex) const; sl@0: inline T& At(TInt anIndex); sl@0: inline T* End(TInt anIndex); sl@0: inline T* Back(TInt anIndex); sl@0: inline void AppendL(const T& aRef); sl@0: inline void AppendL(const T* aPtr,TInt aCount); sl@0: inline void AppendL(const T& aRef,TInt aReplicas); sl@0: inline T& ExpandL(TInt anIndex); sl@0: inline T& ExtendL(); sl@0: inline TInt Find(const T& aRef,TKeyArrayFix& aKey,TInt& anIndex) const; sl@0: inline TInt FindIsq(const T& aRef,TKeyArrayFix& aKey,TInt& anIndex) const; sl@0: inline void InsertL(TInt anIndex,const T& aRef); sl@0: inline void InsertL(TInt anIndex,const T* aPtr,TInt aCount); sl@0: inline void InsertL(TInt anIndex,const T& aRef,TInt aReplicas); sl@0: inline TInt InsertIsqL(const T& aRef,TKeyArrayFix& aKey); sl@0: inline TInt InsertIsqAllowDuplicatesL(const T& aRef,TKeyArrayFix& aKey); sl@0: inline void ResizeL(TInt aCount); sl@0: inline void ResizeL(TInt aCount,const T& aRef); sl@0: inline const TArray Array() const; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: TEMPLATE_SPECIALIZATION class CArrayFix : public CArrayFixBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A template specialisation base class for arrays of fixed length sl@0: untyped objects. sl@0: sl@0: The public functions provide standard array behaviour. sl@0: sl@0: The class is always derived from and is never instantiated explicitly. sl@0: */ sl@0: { sl@0: public: sl@0: inline CArrayFix(TBufRep aRep,TInt aRecordLength,TInt aGranularity); sl@0: inline const TAny* At(TInt anIndex) const; sl@0: inline const TAny* End(TInt anIndex) const; sl@0: inline const TAny* Back(TInt anIndex) const; sl@0: inline TAny* At(TInt anIndex); sl@0: inline TAny* End(TInt anIndex); sl@0: inline TAny* Back(TInt anIndex); sl@0: inline void AppendL(const TAny* aPtr); sl@0: inline void AppendL(const TAny* aPtr,TInt aCount); sl@0: inline TAny* ExtendL(); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: class CArrayFixFlat : public CArrayFix sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Array of fixed length objects contained within a flat dynamic buffer. sl@0: sl@0: The elements of the array are instances of the template class T. sl@0: sl@0: The flat dynamic buffer is an instance of a CBufFlat. sl@0: sl@0: The elements can be T or R type objects and must have an accessible default sl@0: constructor. sl@0: sl@0: Note that, where possible, use the RArray class as this is more sl@0: efficient. sl@0: sl@0: @see CBufFlat sl@0: @see RArray sl@0: */ sl@0: { sl@0: public: sl@0: inline explicit CArrayFixFlat(TInt aGranularity); sl@0: inline void SetReserveL(TInt aCount); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: TEMPLATE_SPECIALIZATION class CArrayFixFlat : public CArrayFix sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: An array of fixed length untyped objects using a flat dynamic buffer. sl@0: sl@0: The array elements are contained within a CBufFlat. sl@0: sl@0: The class is useful for constructing an array of fixed length buffers, where sl@0: the length is decided at run time. sl@0: sl@0: This class is also useful as a data member of a base class in a thin template sl@0: class/base class pair where the type of the array element is not known until sl@0: the owning thin template class is instantiated. sl@0: sl@0: @see CBufFlat sl@0: */ sl@0: { sl@0: public: sl@0: inline CArrayFixFlat(TInt aRecordLength,TInt aGranularity); sl@0: inline void SetReserveL(TInt aCount); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: TEMPLATE_SPECIALIZATION class CArrayFixFlat : public CArrayFix sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Template specialisation base class for arrays of TInt types implemented in a sl@0: flat dynamic buffer. sl@0: sl@0: @see TInt sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C explicit CArrayFixFlat(TInt aGranularity); sl@0: IMPORT_C ~CArrayFixFlat(); sl@0: inline void SetReserveL(TInt aCount); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: TEMPLATE_SPECIALIZATION class CArrayFixFlat : public CArrayFix sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Template specialisation base class for arrays of TUid types implemented in a sl@0: flat dynamic buffer. sl@0: sl@0: @see TUid sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C explicit CArrayFixFlat(TInt aGranularity); sl@0: IMPORT_C ~CArrayFixFlat(); sl@0: inline void SetReserveL(TInt aCount); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: class CArrayFixSeg : public CArrayFix sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Array of fixed length objects contained within a segmented buffer. sl@0: sl@0: The elements of the array are instances of the template class T. sl@0: sl@0: The segmented buffer is an instance of a CBufSeg. sl@0: sl@0: The elements can be T or R type objects and must have an accessible default sl@0: constructor. sl@0: sl@0: @see CBufSeg sl@0: */ sl@0: { sl@0: public: sl@0: inline explicit CArrayFixSeg(TInt aGranularity); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: TEMPLATE_SPECIALIZATION class CArrayFixSeg : public CArrayFix sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: An array of fixed length untyped objects using a segmented dynamic buffer. sl@0: sl@0: The array elements are contained within a CBufSeg. sl@0: sl@0: The class is useful for constructing an array of fixed length buffers, where sl@0: the length is decided at run time. sl@0: sl@0: This class is also useful as a data member of a base class in a thin template sl@0: class/base class pair where the type of the array element is not known until sl@0: the owning thin template class is instantiated. sl@0: sl@0: @see CBufSeg sl@0: */ sl@0: { sl@0: public: sl@0: inline CArrayFixSeg(TInt aRecordLength,TInt aGranularity); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: class CArrayPtr : public CArrayFix sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A thin templated base class for arrays of pointers to objects. sl@0: sl@0: The public functions contribute to standard array behaviour. sl@0: sl@0: The class is always derived from and is never instantiated explicitly. sl@0: */ sl@0: { sl@0: public: sl@0: inline CArrayPtr(TBufRep aRep,TInt aGranularity); sl@0: void ResetAndDestroy(); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: class CArrayPtrFlat : public CArrayPtr sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Array of pointers to objects implemented using a flat dynamic buffer. sl@0: sl@0: The elements of the array are pointers to instances of the template class T sl@0: and are contained within a CBufFlat. sl@0: sl@0: This type of array has the full behaviour of flat arrays but, in addition, sl@0: the CArrayPtr::ResetAndDestroy() function offers a way of destroying sl@0: all of the objects whose pointers form the elements of the array, before sl@0: resetting the array. sl@0: sl@0: Note that where possible, use the RPointerArray class as this is sl@0: more efficient. sl@0: sl@0: @see CBufFlat sl@0: @see CArrayPtr::ResetAndDestroy sl@0: @see RPointerArray sl@0: */ sl@0: { sl@0: public: sl@0: inline explicit CArrayPtrFlat(TInt aGranularity); sl@0: inline void SetReserveL(TInt aCount); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: class CArrayPtrSeg : public CArrayPtr sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Array of pointers to objects implemented using a segmented dynamic buffer. sl@0: sl@0: The elements of the array are pointers to instances of the template class T sl@0: and are contained within a CBufSeg. sl@0: sl@0: This type of array has the full behaviour of segmented arrays but, in addition, sl@0: the CArrayPtr::ResetAndDestroy() function offers a way of destroying sl@0: all of the objects whose pointers form the elements of the array before sl@0: resetting the array. sl@0: sl@0: @see CBufSeg sl@0: @see CArrayPtr::ResetAndDestroy sl@0: */ sl@0: { sl@0: public: sl@0: inline explicit CArrayPtrSeg(TInt aGranularity); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class TKeyArrayVar : public TKey sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Defines the characteristics of a key used to access the elements of arrays sl@0: of variable length objects. sl@0: sl@0: An object of this type can represent three categories of key, depending on sl@0: the constructor used: sl@0: sl@0: 1. a descriptor key sl@0: sl@0: 2. a text key sl@0: sl@0: 3. a numeric key. sl@0: sl@0: The Sort(), InsertIsqL(), Find() and FindIsqL() member functions of the CArrayVarFlat sl@0: and CArrayVarSeg class hierarchies need a TKeyArrayVar object as an argument sl@0: to define the location and type of key within an array element. sl@0: sl@0: A TKeyArrayVar object is also required for sorting a packed array. The implementation sl@0: of the SortL() member function of the CArrayPakFlat class constructs a temporary sl@0: CArrayVarFlat object which requires the TKeyArrayVar object. sl@0: sl@0: @see CArrayVarFlat sl@0: @see CArrayVarSeg sl@0: @see CArrayPakFlat sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C TKeyArrayVar(TInt anOffset,TKeyCmpText aType); sl@0: IMPORT_C TKeyArrayVar(TInt anOffset,TKeyCmpText aType,TInt aLength); sl@0: IMPORT_C TKeyArrayVar(TInt anOffset,TKeyCmpNumeric aType); sl@0: protected: sl@0: IMPORT_C virtual void Set(CBufBase* aBase); sl@0: IMPORT_C TAny* At(TInt anIndex) const; sl@0: protected: sl@0: CBufBase* iBase; sl@0: friend class CArrayVarBase; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: class CArrayVarBase : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: An implementation base class for variable length arrays. sl@0: sl@0: It provides implementation and public functions which are common to all sl@0: variable length type arrays. sl@0: sl@0: The class is always derived from and is never instantiated explicitly. sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C ~CArrayVarBase(); sl@0: inline TInt Count() const; sl@0: IMPORT_C TInt Length(TInt anIndex) const; sl@0: IMPORT_C void Compress(); sl@0: IMPORT_C void Reset(); sl@0: IMPORT_C TInt Sort(TKeyArrayVar& aKey); sl@0: IMPORT_C TAny* At(TInt anIndex) const; sl@0: IMPORT_C void Delete(TInt anIndex); sl@0: IMPORT_C void Delete(TInt anIndex,TInt aCount); sl@0: IMPORT_C TAny* ExpandL(TInt anIndex,TInt aLength); sl@0: IMPORT_C TInt Find(const TAny* aPtr,TKeyArrayVar& aKey,TInt& anIndex) const; sl@0: IMPORT_C TInt FindIsq(const TAny* aPtr,TKeyArrayVar& aKey,TInt& anIndex) const; sl@0: IMPORT_C void InsertL(TInt anIndex,const TAny* aPtr,TInt aLength); sl@0: IMPORT_C TInt InsertIsqL(const TAny* aPtr,TInt aLength,TKeyArrayVar& aKey); sl@0: IMPORT_C TInt InsertIsqAllowDuplicatesL(const TAny* aPtr,TInt aLength,TKeyArrayVar& aKey); sl@0: protected: sl@0: IMPORT_C CArrayVarBase(TBufRep aRep,TInt aGranularity); sl@0: IMPORT_C void SetKey(TKeyArrayVar& aKey) const; sl@0: IMPORT_C static TInt CountR(const CBase* aPtr); sl@0: IMPORT_C static const TAny* AtR(const CBase* aPtr,TInt anIndex); sl@0: private: sl@0: TInt iCount; sl@0: TInt iGranularity; sl@0: TBufRep iCreateRep; sl@0: CBufBase* iBase; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: class CArrayVar : public CArrayVarBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A thin templated base class for variable length arrays. sl@0: sl@0: The public functions provide standard array behaviour. sl@0: sl@0: The class is always derived from and is never instantiated explicitly. sl@0: */ sl@0: { sl@0: public: sl@0: inline CArrayVar(TBufRep aRep,TInt aGranularity); sl@0: inline const T& operator[](TInt anIndex) const; sl@0: inline T& operator[](TInt anIndex); sl@0: inline const T& At(TInt anIndex) const; sl@0: inline T& At(TInt anIndex); sl@0: inline void AppendL(const T& aRef,TInt aLength); sl@0: inline T& ExpandL(TInt anIndex,TInt aLength); sl@0: inline T& ExtendL(TInt aLength); sl@0: inline TInt Find(const T& aRef,TKeyArrayVar& aKey,TInt& anIndex) const; sl@0: inline TInt FindIsq(const T& aRef,TKeyArrayVar& aKey,TInt& anIndex) const; sl@0: inline void InsertL(TInt anIndex,const T& aRef,TInt aLength); sl@0: inline TInt InsertIsqL(const T& aRef,TInt aLength,TKeyArrayVar& aKey); sl@0: inline TInt InsertIsqAllowDuplicatesL(const T& aRef,TInt aLength,TKeyArrayVar& aKey); sl@0: inline const TArray Array() const; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: TEMPLATE_SPECIALIZATION class CArrayVar : public CArrayVarBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A template specialisation base class for variable length arrays. sl@0: sl@0: The array buffer organisation is defined at construction. sl@0: sl@0: The class is useful for constructing an array of variable length buffers, sl@0: where the length is decided at run time. sl@0: sl@0: This class is also useful as a data member of a base class in a thin template sl@0: class/base class pair, where the type of the array element is not known until sl@0: the owning thin template class is instantiated. sl@0: */ sl@0: { sl@0: public: sl@0: inline CArrayVar(TBufRep aRep,TInt aGranularity); sl@0: inline const TAny* At(TInt anIndex) const; sl@0: inline TAny* At(TInt anIndex); sl@0: inline void AppendL(const TAny* aPtr,TInt aLength); sl@0: inline TAny* ExtendL(TInt aLength); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: class CArrayVarFlat : public CArrayVar sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Array of variable length objects implemented using a flat dynamic buffer. sl@0: sl@0: The elements of the array are instances of the template class T and are sl@0: contained within their own heap cells. Pointers to the elements are maintained sl@0: within the flat dynamic buffer, a CBufFlat. sl@0: sl@0: The elements can be T or R type objects and must have an accessible default sl@0: constructor. sl@0: sl@0: @see CBufFlat sl@0: */ sl@0: { sl@0: public: sl@0: inline explicit CArrayVarFlat(TInt aGranularity); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: class CArrayVarSeg : public CArrayVar sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Array of variable length objects implemented using a segmented dynamic buffer. sl@0: sl@0: The elements of the array are instances of the template class T and are sl@0: contained within their own heap cells. Pointers to the elements are maintained sl@0: within a segmented dynamic buffer, a CBufSeg. sl@0: sl@0: The elements can be T or R type objects and must have an accessible default sl@0: constructor. sl@0: sl@0: @see CBufSeg sl@0: */ sl@0: { sl@0: public: sl@0: inline explicit CArrayVarSeg(TInt aGranularity); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class TKeyArrayPak : public TKeyArrayVar sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Defines the characteristics of a key used to access the elements of packed sl@0: arrays. sl@0: sl@0: An object of this type can represent three categories of key, depending on sl@0: the constructor used: sl@0: sl@0: 1. a descriptor key sl@0: sl@0: 2. a text key sl@0: sl@0: 3. a numeric key. sl@0: sl@0: The InsertIsqL(), Find() and FindIsqL() member functions of the CArrayPakFlat sl@0: class hierarchy need a TKeyArrayPak object as an argument to define the location sl@0: and type of key within an array element. sl@0: sl@0: Note that a TKeyArrayVar object is required for sorting a packed array. The sl@0: implementation of the SortL() member function of the CArrayPakFlat class constructs sl@0: a temporary CArrayVarFlat object which requires the TKeyArrayVar object. sl@0: sl@0: @see CArrayVarSeg sl@0: @see CArrayPakFlat sl@0: @see TKeyArrayVar sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C TKeyArrayPak(TInt anOffset,TKeyCmpText aType); sl@0: IMPORT_C TKeyArrayPak(TInt anOffset,TKeyCmpText aType,TInt aLength); sl@0: IMPORT_C TKeyArrayPak(TInt anOffset,TKeyCmpNumeric aType); sl@0: protected: sl@0: IMPORT_C virtual void Set(CBufBase* aBase); sl@0: IMPORT_C TAny* At(TInt anIndex) const; sl@0: private: sl@0: TInt iCacheIndex; sl@0: TInt iCacheOffset; sl@0: friend class CArrayPakBase; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CArrayPakBase : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: An implementation base class for all variable length, packed arrays. sl@0: sl@0: The class is always derived from and is never instantiated explicitly. sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C ~CArrayPakBase(); sl@0: inline TInt Count() const; sl@0: IMPORT_C TInt Length(TInt anIndex) const; sl@0: IMPORT_C void Compress(); sl@0: IMPORT_C void Reset(); sl@0: IMPORT_C void SortL(TKeyArrayVar& aKey); sl@0: IMPORT_C TAny* At(TInt anIndex) const; sl@0: IMPORT_C void Delete(TInt anIndex); sl@0: IMPORT_C void Delete(TInt anIndex,TInt aCount); sl@0: IMPORT_C TAny* ExpandL(TInt anIndex,TInt aLength); sl@0: IMPORT_C TInt Find(const TAny* aPtr,TKeyArrayPak& aKey,TInt& anIndex) const; sl@0: IMPORT_C TInt FindIsq(const TAny* aPtr,TKeyArrayPak& aKey,TInt& anIndex) const; sl@0: IMPORT_C void InsertL(TInt anIndex,const TAny* aPtr,TInt aLength); sl@0: IMPORT_C TInt InsertIsqL(const TAny* aPtr,TInt aLength,TKeyArrayPak& aKey); sl@0: IMPORT_C TInt InsertIsqAllowDuplicatesL(const TAny* aPtr,TInt aLength,TKeyArrayPak& aKey); sl@0: protected: sl@0: IMPORT_C CArrayPakBase(TBufRep aRep,TInt aGranularity); sl@0: IMPORT_C void SetKey(TKeyArrayPak& aKey) const; sl@0: IMPORT_C TInt GetOffset(TInt anIndex) const; sl@0: IMPORT_C void BuildVarArrayL(CArrayVarFlat*& aVarFlat); sl@0: IMPORT_C static TInt CountR(const CBase* aPtr); sl@0: IMPORT_C static const TAny* AtR(const CBase* aPtr,TInt anIndex); sl@0: private: sl@0: TInt iCount; sl@0: TInt iGranularity; sl@0: TBufRep iCreateRep; sl@0: CBufBase* iBase; sl@0: TInt iCacheIndex; sl@0: TInt iCacheOffset; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: class CArrayPak : public CArrayPakBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A thin templated base class for variable length, packed, arrays. sl@0: sl@0: The public functions provide standard array behaviour. sl@0: sl@0: The class is always derived from and is never instantiated explicitly. sl@0: */ sl@0: { sl@0: public: sl@0: inline CArrayPak(TBufRep aRep,TInt aGranularity); sl@0: inline const T& operator[](TInt anIndex) const; sl@0: inline T& operator[](TInt anIndex); sl@0: inline const T& At(TInt anIndex) const; sl@0: inline T& At(TInt anIndex); sl@0: inline void AppendL(const T& aRef,TInt aLength); sl@0: inline T& ExpandL(TInt anIndex,TInt aLength); sl@0: inline T& ExtendL(TInt aLength); sl@0: inline TInt Find(const T& aRef,TKeyArrayPak& aKey,TInt& anIndex) const; sl@0: inline TInt FindIsq(const T& aRef,TKeyArrayPak& aKey,TInt& anIndex) const; sl@0: inline void InsertL(TInt anIndex,const T& aRef,TInt aLength); sl@0: inline TInt InsertIsqL(const T& aRef,TInt aLength,TKeyArrayPak& aKey); sl@0: inline TInt InsertIsqAllowDuplicatesL(const T& aRef,TInt aLength,TKeyArrayPak& aKey); sl@0: inline const TArray Array() const; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: TEMPLATE_SPECIALIZATION class CArrayPak : public CArrayPakBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A template specialisation base class for variable length, packed, arrays. sl@0: sl@0: The array buffer organisation is defined at construction. sl@0: sl@0: The class is useful for constructing an array of variable length buffers, sl@0: where the length is decided at run time. sl@0: sl@0: This class is also useful as a data member of a base class in a thin template sl@0: class/base class pair where the type of the array element is not known until sl@0: the owning thin template class is instantiated. sl@0: */ sl@0: { sl@0: public: sl@0: inline CArrayPak(TBufRep aRep,TInt aGranularity); sl@0: inline const TAny* At(TInt anIndex) const; sl@0: inline TAny* At(TInt anIndex); sl@0: inline void AppendL(const TAny* aPtr,TInt aLength); sl@0: inline TAny* ExtendL(TInt aLength); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: class CArrayPakFlat : public CArrayPak sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Array of variable length objects packed into a flat buffer. sl@0: sl@0: The elements of the array are instances of the template class T and are sl@0: contained within a flat dynamic buffer, a CBufFlat. sl@0: sl@0: The elements can be T or R type objects and must have an accessible default sl@0: constructor. sl@0: sl@0: @see CBufFlat sl@0: */ sl@0: { sl@0: public: sl@0: inline explicit CArrayPakFlat(TInt aGranularity); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CObjectCon; sl@0: class CObject : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Implements reference counting to track concurrent references to itself. sl@0: sl@0: An object of this type arranges automatic destruction of itself when the final sl@0: reference is removed. sl@0: sl@0: A reference counting object is any object which has CObject as its base class. sl@0: Constructing a CObject derived type or calling its Open() member function sl@0: adds a reference to that object by adding one to the reference count; calling sl@0: its Close() member function removes a reference by subtracting one from the sl@0: reference count; when the last user of the object calls Close(), the reference sl@0: count becomes zero and the object is automatically destroyed. sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C CObject(); sl@0: IMPORT_C ~CObject(); sl@0: IMPORT_C virtual TInt Open(); sl@0: IMPORT_C virtual void Close(); sl@0: IMPORT_C virtual TName Name() const; sl@0: IMPORT_C virtual TFullName FullName() const; sl@0: IMPORT_C TInt SetName(const TDesC* aName); sl@0: IMPORT_C void SetNameL(const TDesC* aName); sl@0: inline CObject* Owner() const; sl@0: inline void SetOwner(CObject* anOwner); sl@0: inline TInt AccessCount() const; sl@0: protected: sl@0: IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1); sl@0: protected: sl@0: inline TInt UniqueID() const; sl@0: inline void Inc(); sl@0: inline void Dec(); sl@0: private: sl@0: TInt iAccessCount; sl@0: CObject* iOwner; sl@0: CObjectCon* iContainer; sl@0: HBufC* iName; sl@0: TAny* iSpare1; sl@0: TAny* iSpare2; sl@0: friend class CObjectCon; sl@0: friend class CObjectIx; sl@0: __DECLARE_TEST; sl@0: }; sl@0: sl@0: //Forward declaration of SObjectIxRec sl@0: struct SObjectIxRec; sl@0: sl@0: class CObjectIx : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Generates handle numbers for reference counting objects. sl@0: sl@0: This is referred to as an object index. sl@0: sl@0: Adding a reference counting object to an object index is the way in which sl@0: a unique handle number can be generated for that object. A handle number is sl@0: the way in which an object, which is owned or managed by another thread or sl@0: process can be identified. sl@0: sl@0: @see CObject sl@0: */ sl@0: { sl@0: public: sl@0: enum { sl@0: /** sl@0: When ORd into the handle number, indicates that the reference sl@0: counting object cannot be closed. sl@0: */ sl@0: ENoClose=KHandleNoClose, sl@0: sl@0: sl@0: /** sl@0: When ORed into the handle number, indicates that the handle sl@0: is a local handle. sl@0: */ sl@0: ELocalHandle=KHandleFlagLocal sl@0: }; sl@0: public: sl@0: IMPORT_C static CObjectIx* NewL(); sl@0: IMPORT_C ~CObjectIx(); sl@0: IMPORT_C TInt AddL(CObject* anObj); sl@0: IMPORT_C void Remove(TInt aHandle); sl@0: IMPORT_C CObject* At(TInt aHandle,TInt aUniqueID); sl@0: IMPORT_C CObject* At(TInt aHandle); sl@0: IMPORT_C CObject* AtL(TInt aHandle,TInt aUniqueID); sl@0: IMPORT_C CObject* AtL(TInt aHandle); sl@0: IMPORT_C TInt At(const CObject* anObject) const; sl@0: IMPORT_C TInt Count(CObject* anObject) const; sl@0: IMPORT_C CObject* operator[](TInt anIndex); sl@0: inline TInt Count() const; sl@0: inline TInt ActiveCount() const; sl@0: protected: sl@0: IMPORT_C CObjectIx(); sl@0: private: sl@0: void UpdateState(); sl@0: private: sl@0: TInt iNumEntries; // Number of actual entries in the index sl@0: TInt iHighWaterMark; // points to at least 1 above the highest active index sl@0: TInt iAllocated; // Max entries before realloc needed sl@0: TInt iNextInstance; sl@0: SObjectIxRec *iObjects; sl@0: TInt iFree; // The index of the first free slot or -1. sl@0: TInt iUpdateDisabled; // If >0, disables HWM update, reorder of the free list and memory shrinking. sl@0: TAny* iSpare1; sl@0: TAny* iSpare2; sl@0: }; sl@0: // sl@0: inline TBool IsLocalHandle(TInt aHandle) sl@0: {return(aHandle&CObjectIx::ELocalHandle);} sl@0: inline void SetLocalHandle(TInt &aHandle) sl@0: {aHandle|=CObjectIx::ELocalHandle;} sl@0: inline void UnSetLocalHandle(TInt &aHandle) sl@0: {aHandle&=(~CObjectIx::ELocalHandle);} sl@0: sl@0: sl@0: sl@0: sl@0: class CObjectCon : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: An object container. sl@0: sl@0: An object container acts as a home for a set of related reference counting sl@0: objects. sl@0: sl@0: A reference counting object, a CObject type, must be added to an object sl@0: container. Only one instance of a given reference counting object can be sl@0: held by an object container, i.e. each object within an object container sl@0: must be distinct. sl@0: sl@0: Object containers are constructed by an object container index, a CObjectConIx sl@0: type. sl@0: sl@0: Note that this class is not intended for user derivation. sl@0: sl@0: @see CObject sl@0: @see CObjectConIx sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C static CObjectCon* NewL(); sl@0: IMPORT_C ~CObjectCon(); sl@0: IMPORT_C void Remove(CObject* anObj); sl@0: IMPORT_C void AddL(CObject* anObj); sl@0: IMPORT_C CObject* operator[](TInt anIndex); sl@0: IMPORT_C CObject* At(TInt aFindHandle) const; sl@0: IMPORT_C CObject* AtL(TInt aFindHandle) const; sl@0: IMPORT_C TInt CheckUniqueFullName(const CObject* anOwner,const TDesC& aName) const; sl@0: IMPORT_C TInt CheckUniqueFullName(const CObject* anObject) const; sl@0: IMPORT_C TInt FindByName(TInt& aFindHandle,const TDesC& aMatch,TName& aName) const; sl@0: IMPORT_C TInt FindByFullName(TInt& aFindHandle,const TDesC& aMatch,TFullName& aFullName) const; sl@0: inline TInt UniqueID() const; sl@0: inline TInt Count() const; sl@0: protected: sl@0: IMPORT_C CObjectCon(TInt aUniqueID); sl@0: TBool NamesMatch(const CObject* anObject, const CObject* aCurrentObject) const; sl@0: TBool NamesMatch(const CObject* anObject, const TName& anObjectName, const CObject* aCurrentObject) const; sl@0: public: sl@0: /** sl@0: The object container's unique Id value. sl@0: */ sl@0: TInt iUniqueID; sl@0: private: sl@0: TInt iCount; sl@0: TInt iAllocated; sl@0: CObject** iObjects; sl@0: TAny* iSpare1; sl@0: TAny* iSpare2; sl@0: friend class CObjectConIx; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CObjectConIx : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A container for object containers sl@0: sl@0: This is referred to as a container index. sl@0: sl@0: The class provides the mechanism through which object containers, CObjectCon sl@0: types, are created. sl@0: sl@0: @see CObjectCon sl@0: @see CObject sl@0: */ sl@0: { sl@0: #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS sl@0: protected: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: enum {ENotOwnerID}; sl@0: #endif sl@0: sl@0: public: sl@0: IMPORT_C static CObjectConIx* NewL(); sl@0: IMPORT_C ~CObjectConIx(); sl@0: IMPORT_C CObjectCon* Lookup(TInt aFindHandle) const; sl@0: IMPORT_C CObjectCon* CreateL(); sl@0: IMPORT_C void Remove(CObjectCon* aCon); sl@0: protected: sl@0: IMPORT_C CObjectConIx(); sl@0: IMPORT_C void CreateContainerL(CObjectCon*& anObject); sl@0: private: sl@0: CObjectCon* LookupByUniqueId(TInt aUniqueId) const; sl@0: private: sl@0: TInt iCount; sl@0: TInt iAllocated; sl@0: TUint16 iNextUniqueID; sl@0: TUint16 iUniqueIDHasWrapped; sl@0: CObjectCon** iContainers; sl@0: TAny* iSpare1; sl@0: TAny* iSpare2; sl@0: }; sl@0: sl@0: // Forward Declaration of TCleanupStackItem sl@0: class TCleanupStackItem; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Defines a function which takes a single argument of type TAny* and returns sl@0: void. sl@0: sl@0: An argument of this type is required by the constructors of a TCleanupItem sl@0: object. sl@0: */ sl@0: typedef void (*TCleanupOperation)(TAny*); sl@0: sl@0: sl@0: sl@0: sl@0: class TCleanupItem sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Encapsulates a cleanup operation and an object on which the operation sl@0: is to be performed. sl@0: sl@0: The class allows cleanup to be more sophisticated than simply deleting objects, sl@0: for example, releasing access to some shared resource. sl@0: */ sl@0: { sl@0: public: sl@0: inline TCleanupItem(TCleanupOperation anOperation); sl@0: inline TCleanupItem(TCleanupOperation anOperation,TAny* aPtr); sl@0: private: sl@0: TCleanupOperation iOperation; sl@0: TAny* iPtr; sl@0: friend class TCleanupStackItem; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CCleanup : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Implements the cleanup stack. sl@0: sl@0: An object of this type is created and used by the cleanup stack sl@0: interface, CTrapCleanup. sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C static CCleanup* New(); sl@0: IMPORT_C static CCleanup* NewL(); sl@0: IMPORT_C ~CCleanup(); sl@0: IMPORT_C void NextLevel(); sl@0: IMPORT_C void PreviousLevel(); sl@0: IMPORT_C void PushL(TAny* aPtr); sl@0: IMPORT_C void PushL(CBase* anObject); sl@0: IMPORT_C void PushL(TCleanupItem anItem); sl@0: IMPORT_C void Pop(); sl@0: IMPORT_C void Pop(TInt aCount); sl@0: IMPORT_C void PopAll(); sl@0: IMPORT_C void PopAndDestroy(); sl@0: IMPORT_C void PopAndDestroy(TInt aCount); sl@0: IMPORT_C void PopAndDestroyAll(); sl@0: IMPORT_C void Check(TAny* aExpectedItem); sl@0: protected: sl@0: IMPORT_C void DoPop(TInt aCount,TBool aDestroy); sl@0: IMPORT_C void DoPopAll(TBool aDestroy); sl@0: protected: sl@0: IMPORT_C CCleanup(); sl@0: protected: sl@0: /** sl@0: Pointer to the bottom of the cleanup stack. sl@0: */ sl@0: TCleanupStackItem* iBase; sl@0: sl@0: sl@0: /** sl@0: Pointer to the top of the cleanup stack. sl@0: */ sl@0: TCleanupStackItem* iTop; sl@0: sl@0: sl@0: /** sl@0: Pointer to the next availaible slot in the cleanup stack. sl@0: */ sl@0: TCleanupStackItem* iNext; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: NONSHARABLE_CLASS(TCleanupTrapHandler) : public TTrapHandler sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Implementation for a handler to work with the TRAP mechanism. sl@0: sl@0: This class does not normally need to be used or accessed directly by applications sl@0: and third party code. sl@0: */ sl@0: { sl@0: public: sl@0: TCleanupTrapHandler(); sl@0: virtual void Trap(); sl@0: virtual void UnTrap(); sl@0: sl@0: virtual void Leave(TInt aValue); sl@0: inline CCleanup& Cleanup(); sl@0: private: sl@0: CCleanup* iCleanup; sl@0: friend class CTrapCleanup; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: class TAutoClose sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Automatically calls Close() on an object when that object goes out of scope. sl@0: sl@0: The behaviour takes advantage of the fact that the compiler automatically sl@0: destroys objects that go out of scope. sl@0: */ sl@0: { sl@0: public: sl@0: inline ~TAutoClose(); sl@0: inline void PushL(); sl@0: inline void Pop(); sl@0: private: sl@0: static void Close(TAny *aObj); sl@0: public: sl@0: /** sl@0: An instance of the template class. sl@0: */ sl@0: T iObj; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CTrapCleanup : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Cleanup stack interface. sl@0: sl@0: The creation and destruction of a cleanup stack is done automatically by GUI sl@0: applications and servers. sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C static CTrapCleanup* New(); sl@0: IMPORT_C ~CTrapCleanup(); sl@0: protected: sl@0: IMPORT_C CTrapCleanup(); sl@0: private: sl@0: TCleanupTrapHandler iHandler; sl@0: TTrapHandler* iOldHandler; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CCirBufBase : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Base class for circular buffers. sl@0: sl@0: The class is part of the implementation of circular buffers and is never sl@0: instantiated. sl@0: sl@0: The class provides member functions that form part of the interface. sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C ~CCirBufBase(); sl@0: inline TInt Count() const; sl@0: inline TInt Length() const; sl@0: IMPORT_C void SetLengthL(TInt aLength); sl@0: IMPORT_C void Reset(); sl@0: protected: sl@0: IMPORT_C CCirBufBase(TInt aSize); sl@0: IMPORT_C TInt DoAdd(const TUint8* aPtr); sl@0: IMPORT_C TInt DoAdd(const TUint8* aPtr,TInt aCount); sl@0: IMPORT_C TInt DoRemove(TUint8* aPtr); sl@0: IMPORT_C TInt DoRemove(TUint8* aPtr,TInt aCount); sl@0: protected: sl@0: TInt iCount; sl@0: TInt iSize; sl@0: TInt iLength; sl@0: TUint8* iPtr; sl@0: TUint8* iPtrE; sl@0: TUint8* iHead; sl@0: TUint8* iTail; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: template sl@0: class CCirBuf : public CCirBufBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A circular buffer containing objects of a type defined by the sl@0: template parameter. sl@0: */ sl@0: { sl@0: public: sl@0: inline CCirBuf(); sl@0: #if defined(__VC32__) sl@0: inline ~CCirBuf() {} sl@0: #endif sl@0: inline TInt Add(const T* aPtr); sl@0: inline TInt Add(const T* aPtr,TInt aCount); sl@0: inline TInt Remove(T* aPtr); sl@0: inline TInt Remove(T* aPtr,TInt aCount); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CCirBuffer : public CCirBuf sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Circular buffer of unsigned 8-bit integers. sl@0: sl@0: The integer values range from 0 to 255. sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C CCirBuffer(); sl@0: IMPORT_C ~CCirBuffer(); sl@0: IMPORT_C TInt Get(); sl@0: IMPORT_C TInt Put(TInt aVal); sl@0: }; sl@0: // sl@0: sl@0: sl@0: sl@0: class CActive : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: The core class of the active object abstraction. sl@0: sl@0: It encapsulates both the issuing of a request to an asynchronous service provider sl@0: and the handling of completed requests. An application can have one or more sl@0: active objects whose processing is controlled by an active scheduler. sl@0: */ sl@0: { sl@0: public: sl@0: sl@0: /** sl@0: Defines standard priorities for active objects. sl@0: */ sl@0: enum TPriority sl@0: { sl@0: /** sl@0: A low priority, useful for active objects representing sl@0: background processing. sl@0: */ sl@0: EPriorityIdle=-100, sl@0: sl@0: sl@0: /** sl@0: A priority higher than EPriorityIdle but lower than EPriorityStandard. sl@0: */ sl@0: EPriorityLow=-20, sl@0: sl@0: sl@0: /** sl@0: Most active objects will have this priority. sl@0: */ sl@0: EPriorityStandard=0, sl@0: sl@0: sl@0: /** sl@0: A priority higher than EPriorityStandard; useful for active objects sl@0: handling user input. sl@0: */ sl@0: EPriorityUserInput=10, sl@0: sl@0: sl@0: /** sl@0: A priority higher than EPriorityUserInput. sl@0: */ sl@0: EPriorityHigh=20, sl@0: }; sl@0: public: sl@0: IMPORT_C ~CActive(); sl@0: IMPORT_C void Cancel(); sl@0: IMPORT_C void Deque(); sl@0: IMPORT_C void SetPriority(TInt aPriority); sl@0: inline TBool IsActive() const; sl@0: inline TBool IsAdded() const; sl@0: inline TInt Priority() const; sl@0: protected: sl@0: IMPORT_C CActive(TInt aPriority); sl@0: IMPORT_C void SetActive(); sl@0: sl@0: sl@0: /** sl@0: Implements cancellation of an outstanding request. sl@0: sl@0: This function is called as part of the active object's Cancel(). sl@0: sl@0: It must call the appropriate cancel function offered by the active object's sl@0: asynchronous service provider. The asynchronous service provider's cancel sl@0: is expected to act immediately. sl@0: sl@0: DoCancel() must not wait for event completion; this is handled by Cancel(). sl@0: sl@0: @see CActive::Cancel sl@0: */ sl@0: virtual void DoCancel() =0; sl@0: sl@0: sl@0: /** sl@0: Handles an active object's request completion event. sl@0: sl@0: A derived class must provide an implementation to handle the sl@0: completed request. If appropriate, it may issue another request. sl@0: sl@0: The function is called by the active scheduler when a request sl@0: completion event occurs, i.e. after the active scheduler's sl@0: WaitForAnyRequest() function completes. sl@0: sl@0: Before calling this active object's RunL() function, the active scheduler sl@0: has: sl@0: sl@0: 1. decided that this is the highest priority active object with sl@0: a completed request sl@0: sl@0: 2. marked this active object's request as complete (i.e. the request is no sl@0: longer outstanding) sl@0: sl@0: RunL() runs under a trap harness in the active scheduler. If it leaves, sl@0: then the active scheduler calls RunError() to handle the leave. sl@0: sl@0: Note that once the active scheduler's Start() function has been called, sl@0: all user code is run under one of the program's active object's RunL() or sl@0: RunError() functions. sl@0: sl@0: @see CActiveScheduler::Start sl@0: @see CActiveScheduler::Error sl@0: @see CActiveScheduler::WaitForAnyRequest sl@0: @see TRAPD sl@0: */ sl@0: virtual void RunL() =0; sl@0: IMPORT_C virtual TInt RunError(TInt aError); sl@0: protected: sl@0: IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1); sl@0: public: sl@0: sl@0: /** sl@0: The request status associated with an asynchronous request. sl@0: sl@0: This is passed as a parameter to all asynchronous service providers. sl@0: sl@0: The active scheduler uses this to check whether the active object's request sl@0: has completed. sl@0: sl@0: The function can use the completion code to judge the success or otherwise sl@0: of the request. sl@0: */ sl@0: TRequestStatus iStatus; sl@0: private: sl@0: // TBool iActive; sl@0: TPriQueLink iLink; sl@0: TAny* iSpare; sl@0: friend class CActiveScheduler; sl@0: friend class CServer; sl@0: friend class CServer2; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CIdle : public CActive sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: An active object that performs low-priority processing when no higher-priority sl@0: active objects are ready to run. sl@0: sl@0: An idle time active object together with its associated callback function sl@0: may be used to implement potentially long running background tasks, such as sl@0: spreadsheet recalculation and word processor repagination. sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C static CIdle* New(TInt aPriority); sl@0: IMPORT_C static CIdle* NewL(TInt aPriority); sl@0: IMPORT_C ~CIdle(); sl@0: IMPORT_C void Start(TCallBack aCallBack); sl@0: protected: sl@0: IMPORT_C CIdle(TInt aPriority); sl@0: IMPORT_C void RunL(); sl@0: IMPORT_C void DoCancel(); sl@0: protected: sl@0: sl@0: /** sl@0: The callback object that encapsulates the background task. sl@0: sl@0: @see Start sl@0: */ sl@0: TCallBack iCallBack; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CAsyncOneShot : public CActive sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: An active object that performs processing that is only performed once. sl@0: sl@0: The active object is intended to be given a low priority, so that it runs sl@0: only when no higher-priority active objects are ready to run. In addition, sl@0: the class ensures that the current thread cannot be closed until the active sl@0: object is destroyed. sl@0: sl@0: The class needs to be derived from to make use of its behaviour, in particular, sl@0: it needs to define and implement a RunL() function. sl@0: sl@0: NB: the constructor creates a process-relative handle to the current thread sl@0: and this is stored within this object. If the thread subsequently dies abnormally, sl@0: then this handle will not be closed, and the thread will not be destroyed sl@0: until the process terminates. sl@0: sl@0: NB: if Call() is called from a different thread (for example, to implement sl@0: a kind of inter-thread communication), a client-specific mechanism must be sl@0: used to ensure that the thread that created this object is still alive. sl@0: sl@0: NB: if the thread that created this object has its own heap and terminates sl@0: abnormally, then the handle stored within this object is lost. sl@0: sl@0: @see CActive::RunL sl@0: @see CAsyncOneShot::Call sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C CAsyncOneShot(TInt aPriority); sl@0: IMPORT_C virtual void DoCancel(); sl@0: IMPORT_C virtual void Call(); sl@0: IMPORT_C virtual ~CAsyncOneShot(); sl@0: inline RThread& Thread(); sl@0: private: sl@0: void Setup(); sl@0: RThread iThread; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CAsyncCallBack : public CAsyncOneShot sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: An active object that performs its processing through an associated call back sl@0: function, and which is only performed once. sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C CAsyncCallBack(TInt aPriority); sl@0: IMPORT_C CAsyncCallBack(const TCallBack& aCallBack, TInt aPriority); sl@0: IMPORT_C void Set(const TCallBack& aCallBack); sl@0: IMPORT_C void CallBack(); sl@0: IMPORT_C virtual ~CAsyncCallBack(); sl@0: protected: sl@0: virtual void RunL(); sl@0: // sl@0: protected: sl@0: /** sl@0: The callback object that encapsulates the callback function. sl@0: */ sl@0: TCallBack iCallBack; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class TDeltaTimerEntry sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A timed event entry. sl@0: sl@0: An object of this type is added to a queue of timed events, as represented sl@0: by a CDeltaTimer object. It represents a call back function that is called sl@0: when the associated timed event expires. sl@0: sl@0: @see CDeltaTimer sl@0: */ sl@0: { sl@0: friend class CDeltaTimer; sl@0: public: sl@0: inline TDeltaTimerEntry(const TCallBack& aCallback); sl@0: inline TDeltaTimerEntry(); sl@0: inline void Set(TCallBack& aCallback); sl@0: private: sl@0: TCallBack iCallBack; sl@0: TTickCountQueLink iLink; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CDeltaTimer : public CActive sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A queue of timed events. sl@0: sl@0: A timed event is a callback function encapsulated by a TDeltaTimerEntry object, sl@0: and is intended to be called when the time interval represented by the event sl@0: expires. sl@0: sl@0: The queue itself is a TDeltaQue list. A timed event entry is added into a sl@0: position in the queue that is determined by the time interval specified for sl@0: that event. Although the time interval for a timed event is specified as an sl@0: interval from the present moment, when added to the queue the implementation sl@0: treats each event as having an interval from the previous timed event (or now). sl@0: sl@0: CDeltaTimer is an active object, driven by an RTimer which is usually set to sl@0: expire upon completion of the event at the head of the queue. If the time to sl@0: the next event is too great or an event at the head of the queue has been sl@0: removed, the timer may be set to expire prior to the event at the head of the sl@0: queue (if any). sl@0: sl@0: When the timer completes, the head of the queue is inspected to see whether sl@0: the timed event at the head of the queue has expired. On expiry, the callback sl@0: function represented by that timed event is called, and the timed event entry sl@0: is removed from the queue. The queue then inspects further events for expiry, sl@0: calling and removing them as necessary until either the queue is empty or there sl@0: is an event in the future to wait for. sl@0: sl@0: Note that the tick period is the minimum time interval for an event and the sl@0: granularity of all timings using the queue. Note that in general, any event sl@0: may be called back some time after it has expired and that specifically the sl@0: duration of all events will at least be rounded up to a muliple of the tick sl@0: period. sl@0: sl@0: sl@0: @see TDeltaTimerEntry sl@0: @see TDeltaQue sl@0: @see RTimer sl@0: */ sl@0: { sl@0: public: sl@0: // Queue management sl@0: IMPORT_C virtual void Queue(TTimeIntervalMicroSeconds32 aTimeInMicroSeconds, TDeltaTimerEntry& aEntry); sl@0: IMPORT_C virtual void Remove(TDeltaTimerEntry& aEntry); sl@0: IMPORT_C TInt QueueLong(TTimeIntervalMicroSeconds aTimeInMicroSeconds, TDeltaTimerEntry& aEntry); sl@0: sl@0: // Factory functions sl@0: IMPORT_C static CDeltaTimer* NewL(TInt aPriority); sl@0: IMPORT_C static CDeltaTimer* NewL(TInt aPriority, TTimeIntervalMicroSeconds32 aGranularity); sl@0: sl@0: // Destructor sl@0: ~CDeltaTimer(); sl@0: sl@0: private: sl@0: // Construction sl@0: CDeltaTimer(TInt aPriority, TInt aTickPeriod); sl@0: sl@0: // From CActive sl@0: void DoCancel(); sl@0: void RunL(); sl@0: sl@0: // Utility sl@0: void Activate(TBool aRequeueTimer = EFalse); sl@0: sl@0: private: sl@0: /** sl@0: The asynchronous timer. sl@0: */ sl@0: RTimer iTimer; sl@0: sl@0: /** sl@0: The list of timed event entries. sl@0: */ sl@0: TTickCountQue iQueue; sl@0: sl@0: /** sl@0: The period of a tick count. sl@0: */ sl@0: const TInt iTickPeriod; sl@0: sl@0: /** sl@0: Pseudo-lock on the the queue to avoid reentrancy problems sl@0: */ sl@0: TBool iQueueBusy; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CTimer : public CActive sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Base class for a timer active object. sl@0: sl@0: This is an active object that uses the asynchronous services provided by RTimer, sl@0: to generate events. These events occur either at a specific time specified sl@0: as a TTime, or after an interval specified in microseconds. sl@0: sl@0: The RunL() virtual member function is called by the active scheduler after sl@0: this event occurs. sl@0: sl@0: To write a class derived from CTimer, first define and implement a constructor sl@0: through which the priority of the CTimer active object can be specified. Then sl@0: define and implement a suitable RunL() function to handle the completion of sl@0: a timer request. This function is not defined by CTimer itself and must, therefore, sl@0: be provided by the derived class. sl@0: sl@0: This class is ultimately implemented in terms of the nanokernel tick, and sl@0: therefore the granularity of the generated events is limited to the period of sl@0: this timer. This is variant specific, but is usually 1 millisecond. sl@0: sl@0: Note that the CPeriodic and CHeartbeat classes are derived from CTimer, and sl@0: answer most timing needs. sl@0: sl@0: @see CHeartbeat sl@0: @see CPeriodic sl@0: @see CHeartbeat sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C ~CTimer(); sl@0: IMPORT_C void At(const TTime& aTime); sl@0: IMPORT_C void AtUTC(const TTime& aTimeInUTC); sl@0: IMPORT_C void After(TTimeIntervalMicroSeconds32 anInterval); sl@0: IMPORT_C void Lock(TTimerLockSpec aLock); sl@0: IMPORT_C void Inactivity(TTimeIntervalSeconds aSeconds); sl@0: IMPORT_C void HighRes(TTimeIntervalMicroSeconds32 aInterval); sl@0: protected: sl@0: IMPORT_C CTimer(TInt aPriority); sl@0: IMPORT_C void ConstructL(); sl@0: IMPORT_C void DoCancel(); sl@0: private: sl@0: RTimer iTimer; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CPeriodic : public CTimer sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Periodic timer active object. sl@0: sl@0: This class generates regular timer events and handles them with a callback sl@0: function. The callback is specified as a parameter to Start(). sl@0: sl@0: The callback may not be called immediately after the signal from the timer sl@0: request has been generated, for the following reasons: sl@0: sl@0: 1. the RunL() of another active object may be running at the time of the signal sl@0: sl@0: 2. other active objects may have a higher priority than the CPeriodic sl@0: sl@0: If timing accuracy is important to your application, you can minimise the sl@0: first problem by ensuring all RunL()s complete quickly, and can eliminate sl@0: the second by giving the CPeriodic a higher priority than any other active sl@0: object. Although it is generally recommended that timer-related active objects sl@0: have a high priority, this will not address the problem of CPeriodic timers sl@0: running behind, because active object scheduling is not pre-emptive. sl@0: sl@0: After a timer signal generated by a CPeriodic, the next signal is requested sl@0: just before running the callback, and this request can be delayed for the sl@0: same reasons that running the callback can be delayed. Therefore, a large sl@0: number N of periods may add up to somewhat more than N times the requested sl@0: period time. If absolute precision is required in tracking time, do not rely sl@0: on counting the number of times the callback is called: read the value of sl@0: the system clock every time you need it. sl@0: sl@0: For many applications, such precision is not required, for example, tick sl@0: counting is sufficiently accurate for controlling time-outs in a communications sl@0: program. sl@0: sl@0: Note that you should be familiar with CActive in order to understand sl@0: CPeriodic behaviour, but not necessarily with CTimer. sl@0: sl@0: @see CHeartbeat sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C static CPeriodic* New(TInt aPriority); sl@0: IMPORT_C static CPeriodic* NewL(TInt aPriority); sl@0: IMPORT_C ~CPeriodic(); sl@0: IMPORT_C void Start(TTimeIntervalMicroSeconds32 aDelay,TTimeIntervalMicroSeconds32 anInterval,TCallBack aCallBack); sl@0: protected: sl@0: IMPORT_C CPeriodic(TInt aPriority); sl@0: IMPORT_C void RunL(); sl@0: private: sl@0: TTimeIntervalMicroSeconds32 iInterval; sl@0: TCallBack iCallBack; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class MBeating sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Heartbeat timer call-back handling interface. sl@0: sl@0: The interface provides a pair of functions to handle the beating and sl@0: synchronisation of heartbeat timers. sl@0: sl@0: The CHeartbeat active object class uses an object implementing the MBeating sl@0: interface. sl@0: sl@0: @see CHeartbeat::Start sl@0: */ sl@0: { sl@0: public: sl@0: /** sl@0: Handles a regular heartbeat timer event. sl@0: sl@0: This type of event is one where the timer completes in synchronisation sl@0: with the system clock. sl@0: */ sl@0: virtual void Beat() =0; sl@0: sl@0: /** sl@0: Synchronises the heartbeat timer with system clock. sl@0: sl@0: This function handles a heartbeat timer event where the timer completes out sl@0: of synchronisation with the system clock, (i.e. one or more heartbeats have sl@0: been missed). sl@0: */ sl@0: virtual void Synchronize() =0; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CHeartbeat : public CTimer sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Heatbeat timer. sl@0: sl@0: This class generates regular heartbeat events on a fixed fraction of a second. sl@0: It is more accurate than a CPeriodic timer, because it provides a function sl@0: to restore timer accuracy if it gets out of synchronisation with the system sl@0: clock. sl@0: sl@0: The protected RunL() function is called when the timer completes. The RunL() sl@0: function in turn calls either the MBeating::Beat() or the MBeating::Synchronize() sl@0: functions; MBeating is specified as a parameter to the Start() function sl@0: used to start the heartbeat timer. sl@0: sl@0: The relevant MBeating function may not be called immediately after the signal sl@0: from the timer request has been generated, for the following reasons: sl@0: sl@0: 1. the RunL() of another active object may be running at the time of the signal sl@0: sl@0: 2. other active objects may have a higher priority than the CHeartbeat sl@0: sl@0: If no heartbeat is missed, then the Beat() function is called. sl@0: sl@0: If one or more heartbeats are missed then the Synchronize() function is called. sl@0: It is important to bear in mind that the machine might be switched off after sl@0: a few beats of the heart, and then Synchronize() will be called several days sl@0: later. It is therefore essential that synchronisation is achieved as quickly sl@0: as possible, rather than trying to catch up a tick at a time. In the context sl@0: of an analogue clock, for instance, the clock should just redraw itself with sl@0: the current time - rather than moving the hands round in steps until the time sl@0: is correct. sl@0: sl@0: CHeartbeat is an active object, derived from CActive (via CTimer). You should sl@0: be familiar with CActive in order to understand CHeartbeat behaviour, but sl@0: not necessarily with CTimer. sl@0: sl@0: @see MBeating sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C static CHeartbeat* New(TInt aPriority); sl@0: IMPORT_C static CHeartbeat* NewL(TInt aPriority); sl@0: IMPORT_C ~CHeartbeat(); sl@0: IMPORT_C void Start(TTimerLockSpec aLock,MBeating *aBeating); sl@0: protected: sl@0: IMPORT_C CHeartbeat(TInt aPriority); sl@0: IMPORT_C void RunL(); sl@0: private: sl@0: TTimerLockSpec iLock; sl@0: MBeating *iBeating; sl@0: }; sl@0: // sl@0: sl@0: class CServer2; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Represents a session (version 2) for a client thread on the server-side. sl@0: sl@0: A session acts as a channel of communication between the client and the server. sl@0: A client thread can have multiple concurrent sessions with a server. sl@0: sl@0: A session can be: sl@0: - restricted to the creating thread sl@0: - can be shared with other threads in the same process sl@0: - can be shared by all threads in the system. sl@0: sl@0: A server must define and implement a derived class. In particular, sl@0: it must provide an implementation for the ServiceL() virtual function. sl@0: sl@0: (Note that this class should be used instead of CSession) sl@0: */ sl@0: class CSession2 : public CBase sl@0: { sl@0: friend class CServer2; sl@0: public: sl@0: IMPORT_C virtual ~CSession2() =0; sl@0: private: sl@0: IMPORT_C virtual void CreateL(); // Default method, does nothing sl@0: public: sl@0: inline const CServer2* Server() const; sl@0: IMPORT_C void ResourceCountMarkStart(); sl@0: IMPORT_C void ResourceCountMarkEnd(const RMessage2& aMessage); sl@0: IMPORT_C virtual TInt CountResources(); sl@0: sl@0: /** sl@0: Handles the servicing of a client request that has been passed sl@0: to the server. sl@0: sl@0: This function must be implemented in a derived class. The details of sl@0: the request are contained within the message. sl@0: sl@0: @param aMessage The message containing the details of the client request. sl@0: */ sl@0: virtual void ServiceL(const RMessage2& aMessage) =0; sl@0: IMPORT_C virtual void ServiceError(const RMessage2& aMessage,TInt aError); sl@0: protected: sl@0: IMPORT_C CSession2(); sl@0: IMPORT_C virtual void Disconnect(const RMessage2& aMessage); sl@0: IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1); sl@0: public: sl@0: IMPORT_C void SetServer(const CServer2* aServer); sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: enum TPanicNo {ESesCountResourcesNotImplemented=1,ESesFoundResCountHeaven}; sl@0: sl@0: private: sl@0: TInt iResourceCountMark; sl@0: TDblQueLink iLink; sl@0: const CServer2* iServer; sl@0: TAny* iSpare; sl@0: }; sl@0: sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Abstract base class for servers (version 2). sl@0: sl@0: This is an active object. It accepts requests from client threads and forwards sl@0: them to the relevant server-side client session. It also handles the creation sl@0: of server-side client sessions as a result of requests from client threads. sl@0: sl@0: A server must define and implement a derived class. sl@0: sl@0: (Note that this class should be used instead of CServer) sl@0: */ sl@0: class CServer2 : public CActive sl@0: { sl@0: public: sl@0: sl@0: /** sl@0: This enumeration defines the maximum sharability of sessions opened sl@0: with this server; for backwards compatibilty, these should be have sl@0: the same values as the corresponding EIpcSessionType enumeration sl@0: */ sl@0: enum TServerType sl@0: { sl@0: EUnsharableSessions = EIpcSession_Unsharable, sl@0: ESharableSessions = EIpcSession_Sharable, sl@0: EGlobalSharableSessions = EIpcSession_GlobalSharable, sl@0: }; sl@0: sl@0: public: sl@0: IMPORT_C virtual ~CServer2() =0; sl@0: IMPORT_C TInt Start(const TDesC& aName); sl@0: IMPORT_C void StartL(const TDesC& aName); sl@0: IMPORT_C void ReStart(); sl@0: IMPORT_C void SetPinClientDescriptors(TBool aPin); sl@0: sl@0: /** sl@0: Gets a handle to the server. sl@0: sl@0: Note that the RServer2 object is classified as Symbian internal, and its sl@0: member functions cannot be acessed. However, the handle can be passed sl@0: to the RSessionBase::CreateSession() variants that take a server handle. sl@0: sl@0: @return The handle to the server. sl@0: */ sl@0: inline RServer2 Server() const { return iServer; } sl@0: protected: sl@0: inline const RMessage2& Message() const; sl@0: IMPORT_C CServer2(TInt aPriority, TServerType aType=EUnsharableSessions); sl@0: IMPORT_C void DoCancel(); sl@0: IMPORT_C void RunL(); sl@0: IMPORT_C TInt RunError(TInt aError); sl@0: IMPORT_C virtual void DoConnect(const RMessage2& aMessage); sl@0: IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1); sl@0: private: sl@0: sl@0: /** sl@0: Creates a server-side session object. sl@0: sl@0: The session represents a communication link between a client and a server, sl@0: and its creation is initiated by the client through a call to one of sl@0: the RSessionBase::CreateSession() variants. sl@0: sl@0: A server must provide an implementation, which as a minimum should: sl@0: sl@0: - check that the version of the server is compatible with the client by sl@0: comparing the client supplied version number against the server's version sl@0: number; it should leave if there is incompatibility. sl@0: sl@0: - construct and return the server side client session object. sl@0: sl@0: @param aVersion The version information supplied by the client. sl@0: @param aMessage Represents the details of the client request that is requesting sl@0: the creation of the session. sl@0: sl@0: @return A pointer to the newly created server-side session object. sl@0: sl@0: @see User::QueryVersionSupported() sl@0: */ sl@0: IMPORT_C virtual CSession2* NewSessionL(const TVersion& aVersion,const RMessage2& aMessage) const =0; sl@0: void Connect(const RMessage2& aMessage); sl@0: void DoConnectL(const RMessage2& aMessage,CSession2* volatile& aSession); sl@0: public: sl@0: IMPORT_C void SetMaster(const CServer2* aServer); sl@0: sl@0: /** sl@0: @internalComponent sl@0: */ sl@0: enum TPanic sl@0: { sl@0: EBadMessageNumber, sl@0: ESessionNotConnected, sl@0: ESessionAlreadyConnected, sl@0: EClientDoesntHaveRequiredCaps, sl@0: }; sl@0: sl@0: private: sl@0: TUint8 iSessionType; sl@0: TUint8 iServerRole; sl@0: TUint16 iServerOpts; sl@0: RServer2 iServer; sl@0: RMessage2 iMessage; sl@0: TAny* iSpare; sl@0: TDblQue iSessionQ; sl@0: sl@0: protected: sl@0: TDblQueIter iSessionIter; sl@0: private: sl@0: void Disconnect(const RMessage2& aMessage); sl@0: static void BadMessage(const RMessage2& aMessage); sl@0: static void NotConnected(const RMessage2& aMessage); sl@0: friend class CPolicyServer; sl@0: }; sl@0: sl@0: sl@0: sl@0: /** sl@0: A security policy framework built on top of the normal CServer2 class. sl@0: sl@0: The two major functions of the Policy Server framework are to check a received sl@0: message against a security policy and then to perform an action depending on sl@0: the result of this check. The exact behaviour is defined by the contents of sl@0: the TPolicy structure given in the constructor for CPolicyServer. sl@0: sl@0: The processing performed when a server receives a message are describe below. sl@0: This should aid understanding of the interaction of the TPolicy structure and sl@0: virtual member functions which may be implemented by classes derived from CPolicyServer. sl@0: sl@0: Checking the Security Policy sl@0: sl@0: On receipt of a message, the message function number is used to search the sl@0: list of ranges pointed to by TPolicy::iRanges. This yields a range sl@0: number R, which is between 0 and TPolicy::iRangeCount-1. sl@0: The policy index, X, for this range is then fetched from TPolicy::iElementsIndex[R]. sl@0: If the message is a Connect message, then X is fetched directly from TPolicy::iOnConnect sl@0: instead. sl@0: sl@0: The further action taken is determined by the value of X. sl@0: - If X==TSpecialCase::EAlwaysPass, sl@0: the message is processed as normal; either by passing it to the ServiceL() sl@0: method of a session, or, in the case of a connection message, a new session sl@0: is created. sl@0: - If X==TSpecialCase::ENotSupported, sl@0: the message is completed with KErrNotSupported. sl@0: - If X==TSpecialCase::ECustomCheck, sl@0: a call to the virtual function CustomSecurityCheckL() is made. The implementation sl@0: of this method must return one of the TCustomResult enumerations which determine sl@0: what further action is to be taken: sl@0: - TCustomResult::EPass sl@0: The message is processed as normal; either by passing it to the ServiceL() sl@0: method of a session, or, in the case of a connection message, a new session sl@0: is created. sl@0: - TCustomResult::EFail sl@0: This causes CheckFailedL() to be called with the action specified by the sl@0: aAction reference given to CustomSecurityCheckL() (This defaults to sl@0: TFailureAction::EFailClient.) sl@0: - TCustomResult::EAsync sl@0: The derived class is responsible for further processing of the message, sl@0: the Policy Server framework will do nothing more with it. sl@0: - If X < TSpecialCase::ESpecialCaseHardLimit, sl@0: X is taken as an index into the array of TPolicyElement objects pointed sl@0: to by TPolicy::iElements. The platform security attributes of the process sl@0: which sent the message being processed are checked against the security sl@0: policy specified in this TPolicyElement. If the process possesses all of sl@0: the attributes specified then the message processed as normal. Otherwise, sl@0: CheckFailedL() is called with the action value specified in the TPolicyElement . sl@0: sl@0: Handling Policy Check Failure sl@0: sl@0: The CheckFailedL() method is called when a security check has failed. It performs sl@0: an action according to the aAction value given to it: sl@0: sl@0: - If aAction==TFailureAction::EFailClient, the message is completed with sl@0: KErrPermissionDenied. sl@0: - If aAction==TFailureAction::EPanicClient, the client thread is panicked. sl@0: - If aAction < 0 a call to the virtual function CustomFailureActionL() is made. sl@0: The implementation of this method must return one of the TCustomResult sl@0: enumerations which determine what further action is to be taken: sl@0: - TCustomResult::EPass sl@0: The message is processed as normal; either by passing it to the ServiceL() sl@0: method of a session, or, in the case of a connection message, a new session sl@0: is created. sl@0: - TCustomResult::EFail sl@0: The message is completed with KErrPermissionDenied. sl@0: - TCustomResult::EAsync sl@0: The derived class is responsible for further processing of the message, sl@0: the Policy Server framework will do nothing more with it. sl@0: sl@0: @publishedAll sl@0: @released sl@0: */ sl@0: class CPolicyServer : public CServer2 sl@0: { sl@0: public: sl@0: /** Enumeration specifying action to take if a security check fails. sl@0: Values >= 0 are handled by CheckFailedL(). Values < 0 are specific to the sl@0: derived implementation of the policy server and will result in a call to sl@0: CustomFailureActionL() if a security check fails. Attempts to use undefined sl@0: values >= 0 will result in a panic in CheckFailedL(). sl@0: */ sl@0: enum TFailureAction sl@0: { sl@0: EFailClient = 0, /**< Complete message with KErrPermissionDenied */ sl@0: EPanicClient= 1, /**< Panic client */ sl@0: }; sl@0: sl@0: /** Enumeration of acceptable return codes from both of sl@0: CustomSecurityCheckL() and CustomFailureActionL(). Results of EPass or EFail sl@0: are handled by the CPolicyServer framework. No other action is required on sl@0: the part of the derived implementation. However, results of EAsync imply sl@0: that the derived implementation will call the appropriate function once the sl@0: result is known. See CustomSecurityCheckL() and CustomFailureActionL for sl@0: more information. sl@0: */ sl@0: enum TCustomResult sl@0: { sl@0: EPass = 0, /**< Security check passed. */ sl@0: EFail = 1, /**< Security check failed. */ sl@0: EAsync = 2, /**< Security checking will be performed asynchronously. */ sl@0: }; sl@0: sl@0: /** Class specifying a security check and the action to take sl@0: sl@0: If iAction is >=0 it must be a member of TFailureAction sl@0: If iAction is <0 it is assumed to specify a custom action specific to the sl@0: derived implementation. In this case, CustomFailureActionL must be implemented sl@0: by the derived class. sl@0: */ sl@0: class TPolicyElement sl@0: { sl@0: public: sl@0: /** Security policy to check against the client which sent a message. sl@0: sl@0: This class can specify a security policy consisting of either: sl@0: sl@0: -# A check for between 0 and 7 capabilities sl@0: -# A check for a given Secure ID along with 0-3 capabilities sl@0: -# A check for a given Vendor ID along with 0-3 capabilities sl@0: sl@0: This member should only be initialised by one of the following macros: sl@0: sl@0: - _INIT_SECURITY_POLICY_PASS sl@0: - _INIT_SECURITY_POLICY_FAIL sl@0: - _INIT_SECURITY_POLICY_C1 sl@0: - _INIT_SECURITY_POLICY_C2 sl@0: - _INIT_SECURITY_POLICY_C3 sl@0: - _INIT_SECURITY_POLICY_C4 sl@0: - _INIT_SECURITY_POLICY_C5 sl@0: - _INIT_SECURITY_POLICY_C6 sl@0: - _INIT_SECURITY_POLICY_C7 sl@0: - _INIT_SECURITY_POLICY_S0 sl@0: - _INIT_SECURITY_POLICY_S1 sl@0: - _INIT_SECURITY_POLICY_S2 sl@0: - _INIT_SECURITY_POLICY_S3 sl@0: - _INIT_SECURITY_POLICY_V0 sl@0: - _INIT_SECURITY_POLICY_V1 sl@0: - _INIT_SECURITY_POLICY_V2 sl@0: - _INIT_SECURITY_POLICY_V3 sl@0: sl@0: @see TPolicy sl@0: */ sl@0: TStaticSecurityPolicy iPolicy; sl@0: sl@0: /** Action to take on failure. Either a value from TFailureAction sl@0: or a negative value which has meaning to the CustomFailureActionL() sl@0: method of a derived class. sl@0: */ sl@0: TInt iAction; sl@0: }; sl@0: sl@0: /** Special case values which can be used instead of a policy element index sl@0: contained in the array TPolicy::iElementsIndex sl@0: */ sl@0: enum TSpecialCase sl@0: { sl@0: /** Indicates a custom check should be made by calling CustomSecurityCheckL() */ sl@0: ECustomCheck =255u, sl@0: sl@0: /** Indicates that message is requesting an unsupported function. sl@0: The message is completed with KErrNotSupported. */ sl@0: ENotSupported =254u, sl@0: sl@0: /** Indicates that the message is requesting an unrestricted function sl@0: and therefore should be processed without any further checks. */ sl@0: EAlwaysPass =253u, sl@0: sl@0: ESpecialCaseLimit =252u, /**< @internalTechnology */ sl@0: ESpecialCaseHardLimit =250u /**< @internalTechnology */ sl@0: }; sl@0: sl@0: /** Object specifying which security checks to perform on each request sl@0: number and what action to take if the check fails. sl@0: sl@0: Explanations of each of the members of this class are detailed below. sl@0: sl@0: As explained in CPolicyServer::CPolicyServer, it is important that the sl@0: instance of this class (CPolicyServer::TPolicy) given to the policy sl@0: server constructor, exists for the lifetime of the server. For this sl@0: reason, as well as code size considerations, it is recommended that sl@0: the TPolicy instance is const static data. sl@0: The following code segment shows the recommended way of doing this. sl@0: Further detail on what each of these statements means is given below. sl@0: sl@0: @code sl@0: const TUint myRangeCount = 4; sl@0: const TInt myRanges[myRangeCount] = sl@0: { sl@0: 0, //range is 0-2 inclusive sl@0: 3, //range is 3-6 inclusive sl@0: 7, //range is 7 sl@0: 8, //range is 8-KMaxTInt inclusive sl@0: }; sl@0: const TUint8 myElementsIndex[myRangeCount] = sl@0: { sl@0: 1, //applies to 0th range (req num: 0-2) sl@0: CPolicyServer::ECustomCheck, //applies to 1st range (req num: 3-6) sl@0: 0, //applies to 2nd range (req num: 7) sl@0: CPolicyServer::ENotSupported, //applies to 3rd range (req num: 8-KMaxTInt) sl@0: }; sl@0: const CPolicyServer::TPolicyElement myElements[] = sl@0: { sl@0: {_INIT_SECURITY_POLICY_C1(ECapabilityDiskAdmin), CPolicyServer::EFailClient}, sl@0: {_INIT_SECURITY_POLICY_C1(ECapabilityLocation), CMyPolicyServer::EQueryUser}, sl@0: } sl@0: const CPolicySErver::TPolicy myPolicy = sl@0: { sl@0: CPolicyServer::EAlwaysPass, //specifies all connect attempts should pass sl@0: myRangeCount, sl@0: myRanges, sl@0: myElementsIndex, sl@0: myElements, sl@0: } sl@0: @endcode sl@0: */ sl@0: class TPolicy sl@0: { sl@0: public: sl@0: /** The index into iElements, or an allowed value of TSpecialCase, sl@0: that is used to check a connection attempt . */ sl@0: TUint8 iOnConnect; sl@0: sl@0: /** Number of ranges in the iRanges array. */ sl@0: TUint16 iRangeCount; sl@0: sl@0: /** A pointer to an array of ordered ranges of request numbers. Each sl@0: element in this array refers to the starting request number of a range. sl@0: The range of the previous element is up to and including the current sl@0: element minus 1. Thus an array like: sl@0: @code sl@0: const TInt myRanges[4] = {0, 3, 7, 8}; sl@0: @endcode sl@0: means that: sl@0: - the 0th range is 0-2 (inclusive). sl@0: - the 1st range is 3-6 (inclusive). sl@0: - the 2nd range is solely request number 7. sl@0: - the 3rd range is 8-KMaxTInt (inclusive). sl@0: sl@0: Note that the all possible request numbers must be accounted for. This sl@0: implies that the first element must be 0. It also implies that the sl@0: last range goes from the that element to KMaxTint. Finally, each sl@0: element must be strictly greater than the previous element. As the sl@0: first element is 0, this clearly implies that iRanges must not contain sl@0: negative elements. sl@0: */ sl@0: const TInt* iRanges; sl@0: sl@0: /** A pointer to an array of TUint8 values specifying the appropriate action sl@0: to take for each range in iRanges. For example, the 0th element of sl@0: iElementsIndex specifies the appropriate action to take for the 0th sl@0: range in iRanges. As such, iElementsIndex must have precisely the same sl@0: number of elements as iRanges. sl@0: sl@0: The following rules apply to the value of each element in iElementsIndex: sl@0: -# Each value must be a valid index into iElements (that is, less than sl@0: the number of elements in iElements) OR a valid value from sl@0: TSpecialCase. sl@0: -# Elements' values need not follow any special ordering. sl@0: -# Elements may repeat values. sl@0: sl@0: Continuing the example from iRanges: sl@0: @code sl@0: const TInt myRanges[4] = {0, 3, 7, 8}; sl@0: const TUInt8 myElementsIndex[4] = { sl@0: 1, sl@0: CPolicyServer::ECustomCheck, sl@0: 0, sl@0: CPolicyServer::ENotSupported sl@0: }; sl@0: @endcode sl@0: This means that: sl@0: -# Requests within the first range of myRanges (request numbers 0-2) sl@0: will be checked against the policy specified by the 1st element of sl@0: iElements. sl@0: -# Requests with the the second range of myRanges (request numbers sl@0: 3-6) require a custom check to determine if they are allowed. This requires sl@0: derived server implementations to implement CustomSecurityCheckL() sl@0: -# Requests within the third range of myRanges (request number 7) will sl@0: be checked against the policy specified by the 0th element of iElements. sl@0: -# Requests within the fourth range of myRanges (request numbers sl@0: 8-KMaxTInt) will automatically be completed with KErrNotSupported by sl@0: the policy server framework. sl@0: */ sl@0: const TUint8* iElementsIndex; sl@0: sl@0: /** A pointer to an array of distinct policy elements. sl@0: sl@0: Continuing with the previous examples: sl@0: @code sl@0: const TInt myRanges[4] = {0, 3, 7, 8}; sl@0: const TUInt8 myElementsIndex[4] = { sl@0: 1, sl@0: CPolicyServer::ECustomCheck, sl@0: 0, sl@0: CPolicyServer::ENotSupported sl@0: }; sl@0: const TPolicyElement iElements[] = { sl@0: {_INIT_SECURITY_POLICY_C1(ECapabilityDiskAdmin), CPolicyServer::EFailClient}, sl@0: {_INIT_SECURITY_POLICY_C1(ECapabilityLocation), CMyPolicyServer::EQueryUser} sl@0: } sl@0: @endcode sl@0: sl@0: The instantiation of iElements specifies that: sl@0: -# Request numbers 0-2 require the Location capability. As the sl@0: iAction member of the 1st element specifies a custom action sl@0: (represented by the negative number, CMyPolicyServer::EQueryUser), sl@0: requests without Location will passed to the reimplementation of sl@0: CustomFailureActionL. sl@0: -# Request number 7 requires the DiskAdmin capability. Requestors sl@0: without DiskAdmin will have their request completed with sl@0: KErrPermissionDenied. sl@0: */ sl@0: const TPolicyElement* iElements; sl@0: }; sl@0: sl@0: public: sl@0: /** Process an accepted message which has passed its policy check. sl@0: sl@0: The message is either passed to the ServiceL() method of a session, sl@0: or, in the case of a connection message, a new session is created. sl@0: sl@0: This is called by RunL() to process a message which has passed its security sl@0: check. If the server implementation returns EAsync from either sl@0: CustomSecurityCheckL() or CustomFailureActionL(), then it is the responsibility sl@0: of the derived server implementation to call ProcessL at a later point if sl@0: the messages passes the asynchronous check. sl@0: sl@0: This function should only ever be called by derived implementations if sl@0: asynchronous security checks are in use. sl@0: */ sl@0: IMPORT_C void ProcessL(const RMessage2& aMsg); sl@0: sl@0: /** Called when a security check has failed. sl@0: sl@0: The aAction parameter determines the action taken: sl@0: - If aAction==TFailureAction::EFailClient, the message is completed with sl@0: KErrPermissionDenied. sl@0: - If aAction==TFailureAction::EPanicClient, the client thread is panicked. sl@0: - If aAction < 0 a call to the virtual function CustomFailureActionL() is made. sl@0: sl@0: This function should only ever be called by derived implementations if sl@0: asynchronous security checks are in use. sl@0: sl@0: @param aMsg The message which failed its check. sl@0: @param aAction The action to take. (See description.) sl@0: @param aMissing A list of the security attributes that were missing from sl@0: the checked process. sl@0: */ sl@0: IMPORT_C void CheckFailedL(const RMessage2& aMsg, TInt aAction, const TSecurityInfo& aMissing); sl@0: sl@0: /** Called if a leave occurs during processing of a message. The sl@0: underlying framework ensures that leaves which occur during sl@0: CSession2::ServiceL are passed to CSession2::ServiceError. Leaves occuring sl@0: prior to this (ie. during CustomSecurityCheckL() or CustomFailureActionL() ) are sl@0: completed with the leave code. sl@0: sl@0: This function should only ever be called by derived implementations if sl@0: asynchronous security checks are in use. In this case the RunError() of sl@0: that other active object must call ProcessError(). sl@0: sl@0: @param aMsg The message being processed when the leave occurred. sl@0: @param aError The leave code. sl@0: */ sl@0: IMPORT_C void ProcessError(const RMessage2& aMsg, TInt aError); sl@0: sl@0: protected: sl@0: /** Construct a policy server sl@0: sl@0: @param aPriority Active object priority for this server sl@0: @param aPolicy Reference to a policy object describing the security checks sl@0: required for each message type. The server does not make a sl@0: copy of policy, and therefore this object must exist for the sl@0: lifetime of the server. It is recommended that aPolicy sl@0: is in const static data. sl@0: @param aType Type of session sharing supported by this server sl@0: */ sl@0: IMPORT_C CPolicyServer(TInt aPriority, const TPolicy& aPolicy, TServerType aType=EUnsharableSessions); sl@0: sl@0: /** Performs a custom security check. sl@0: Derived server classes must implement this function if any element in sl@0: iElementsIndex has the value CPolicyServer::ECustomCheck. sl@0: Similarly, if CPolicyServer::ECustomCheck is not used, then this function sl@0: can be safely ignored. sl@0: sl@0: If CPolicyServer::ECustomCheck is used, there are two further cases to consider: sl@0: -# The custom security check can synchronously decide if the message sl@0: should pass. In this case, the derived implementation must simply return sl@0: either EPass or EFail depending on the result of the security check. sl@0: -# The custom security check needs to use asynchronous methods in order sl@0: to determine whether the message should procceed. In this case, these sl@0: asysnchronous methods should be started and then the EAsync value returned. sl@0: Furthermore, implmentations returning EAsync commit to the following: sl@0: - If the security check eventually passes, ProcessL() must be called with sl@0: the appropriate message. sl@0: - If the security check eventually fails, CheckFailedL() must be called sl@0: with that message. sl@0: - Pending messages on a given session need to be completed and discarded sl@0: if the session is closed. sl@0: sl@0: IMPORTANT NOTE. When processing a message asynchronously, a copy must be sl@0: made of the RMessage2 object. Saving a refernece or pointer to the original sl@0: message will produce unpredictable defects. This is because the object will sl@0: be reused for the next message that the server receives. sl@0: sl@0: In both cases, synchronous and asynchronous, the derived implementation has the sl@0: option of updating the aAction and/or aMissing parameters if that is sl@0: appropriate. sl@0: sl@0: @param aMsg The message to check. sl@0: @param aAction A reference to the action to take if the security check sl@0: fails. This is either a value from TFailureAction or a negative sl@0: value which has meaning to the CustomFailureActionL() method of sl@0: a derived class. sl@0: The policy server framework gives this value a default of sl@0: EFailClient. If a derived implementation wishes a sl@0: different value, then it should change this. sl@0: @param aMissing A reference to the list of security attributes missing sl@0: from the checked process. The policy server initialises this sl@0: object to zero (that is a sid of 0, a vid of 0, and no capabilities). sl@0: If derived implementations wish to take advantage of a list of sl@0: missing attributes in their implementation of CustomFailureActionL(), sl@0: then they should set those missing attributes here in sl@0: CustomSecurityCheckL(). sl@0: @return A value from TCustomResult. sl@0: @panic CBase 95 If the default implementation is called. sl@0: */ sl@0: IMPORT_C virtual TCustomResult CustomSecurityCheckL(const RMessage2& aMsg, TInt& aAction, TSecurityInfo& aMissing); sl@0: sl@0: /** Performs a custom action after the failure of a security check. sl@0: Derived server classes must implement this function if the aAction value sl@0: passed to CheckFailedL() is less than zero. This can happened if the policy sl@0: specified a negative number in the iAction member of any of the sl@0: TPolicyElements, or, if the derived CustomSecurityCheckL() modified the sl@0: value of aAction prior to returning. sl@0: sl@0: If negative aAction values are used, there are two further cases to consider: sl@0: -# The custom security check can synchronously decide if the message sl@0: should pass. In this case, the derived implementation must simply return sl@0: either EPass or EFail depending on the result of the security check. sl@0: -# The custom security check needs to use asynchronous methods in order sl@0: to determine whether the message should still proceed. In this case, these sl@0: asysnchronous methods should be started and then the EAsync value returned. sl@0: Furthermore, implmentations returning EAsync commit to the following: sl@0: - If the security check eventually passes, ProcessL() must be called with sl@0: the appropriate message. sl@0: - If the security check eventually fails, or if a fatal error condition occurs, sl@0: including if the previously mentioned call to ProcessL() leaves; sl@0: then CPolicyServer::ProcessError() should be called passing the message and sl@0: relevant error code. sl@0: - Pending messages on a given session need to be completed and discarded sl@0: if the session is closed. sl@0: sl@0: IMPORTANT NOTE. When processing a message asynchronously, a copy must be sl@0: made of the RMessage2 object. Saving a refernece or pointer to the original sl@0: message will produce unpredictable defects. This is because the object will sl@0: be reused for the next message that the server receives. sl@0: sl@0: The default implementation of this function panics the server. sl@0: sl@0: @param aMsg The message to check sl@0: @param aAction The custom failure action requested. sl@0: This is either a value from TFailureAction or a negative sl@0: value which has meaning to the CustomFailureActionL() method of sl@0: a derived class. sl@0: @param aMissing A const reference to the list of security attributes missing sl@0: from the checked process. There are two cases to consider: sl@0: (a) If this message was checked (and failed) by a static policy sl@0: applied by the policy server framework, aMissing will contain a sl@0: list of the security attributes that caused the policy to fail. An sl@0: completely zeroed aMissing implies that an always fail policy was sl@0: encountered. sl@0: (b) If this message was failed by a custom security check, then sl@0: aMissing will be zeroed unless the CustomSecurityCheckL() method sl@0: filled it in. sl@0: @return A value from TCustomResult. sl@0: @panic CBase 95 If the default implementation is called. sl@0: */ sl@0: IMPORT_C virtual TCustomResult CustomFailureActionL(const RMessage2& aMsg, TInt aAction, const TSecurityInfo& aMissing); sl@0: sl@0: protected: sl@0: IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1); sl@0: private: sl@0: IMPORT_C virtual void RunL(); sl@0: IMPORT_C virtual TInt RunError(TInt aError); sl@0: const CPolicyServer::TPolicyElement* FindPolicyElement(TInt aFn, TUint& aSpecialCase) const; sl@0: private: sl@0: const TPolicy& iPolicy; sl@0: sl@0: }; sl@0: sl@0: sl@0: sl@0: class CActiveScheduler : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Controls the handling of asynchronous requests as represented by sl@0: active objects. sl@0: sl@0: An active scheduler is used to schedule the sequence in which active object request sl@0: completion events are handled by a single event-handling thread. sl@0: sl@0: An active scheduler can be instantiated and used directly if either: sl@0: sl@0: - the RunL() function of all of its active objects is guaranteed not to leave, or sl@0: sl@0: - each of its active objects implements a suitable RunError() function to provide suitable cleanup sl@0: sl@0: If any of the active scheduler's active objects does not provide a RunError() sl@0: function, then a CActiveScheduler derived class must be defined and an implementation sl@0: of the Error() function provided to perform the cleanup required. sl@0: sl@0: There is one active scheduler per thread and the static functions provided by the sl@0: class always refer to the current active scheduler. sl@0: sl@0: @see CActiveScheduler::Error sl@0: @see CActive sl@0: @see CActiveSchedulerWait sl@0: */ sl@0: { sl@0: friend class CActiveSchedulerWait; sl@0: public: sl@0: struct TLoop; sl@0: typedef TLoop* TLoopOwner; sl@0: public: sl@0: IMPORT_C CActiveScheduler(); sl@0: IMPORT_C ~CActiveScheduler(); sl@0: IMPORT_C static void Install(CActiveScheduler* aScheduler); sl@0: IMPORT_C static CActiveScheduler* Current(); sl@0: IMPORT_C static void Add(CActive* aActive); sl@0: IMPORT_C static void Start(); sl@0: IMPORT_C static void Stop(); sl@0: IMPORT_C static TBool RunIfReady(TInt& aError, TInt aMinimumPriority); sl@0: IMPORT_C static CActiveScheduler* Replace(CActiveScheduler* aNewActiveScheduler); sl@0: IMPORT_C virtual void WaitForAnyRequest(); sl@0: IMPORT_C virtual void Error(TInt aError) const; sl@0: IMPORT_C void Halt(TInt aExitCode) const; sl@0: IMPORT_C TInt StackDepth() const; sl@0: private: sl@0: class TCleanupBundle sl@0: { sl@0: public: sl@0: CCleanup* iCleanupPtr; sl@0: TInt iDummyInt; sl@0: }; sl@0: private: sl@0: static void Start(TLoopOwner* aOwner); sl@0: IMPORT_C virtual void OnStarting(); sl@0: IMPORT_C virtual void OnStopping(); sl@0: IMPORT_C virtual void Reserved_1(); sl@0: IMPORT_C virtual void Reserved_2(); sl@0: void Run(TLoopOwner* const volatile& aLoop); sl@0: void DoRunL(TLoopOwner* const volatile& aLoop, CActive* volatile & aCurrentObj, TCleanupBundle* aCleanupBundle); sl@0: protected: sl@0: IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1); sl@0: protected: sl@0: inline TInt Level() const; // deprecated sl@0: private: sl@0: TLoop* iStack; sl@0: TPriQue iActiveQ; sl@0: TAny* iSpare; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CActiveSchedulerWait : public CBase sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Controls a single scheduling loop in the current active scheduler. sl@0: sl@0: This class provides better control of nested wait loops in the active sl@0: scheduler. sl@0: sl@0: Note that a CActiveSchedulerWait object can be used as a data member sl@0: inside other CBase derived classes. sl@0: sl@0: @see CActiveScheduler sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C CActiveSchedulerWait(); sl@0: IMPORT_C ~CActiveSchedulerWait(); sl@0: IMPORT_C void Start(); sl@0: IMPORT_C void AsyncStop(); sl@0: IMPORT_C void AsyncStop(const TCallBack& aCallMeWhenStopped); sl@0: inline TBool IsStarted() const; sl@0: IMPORT_C TBool CanStopNow() const; sl@0: private: sl@0: CActiveScheduler::TLoopOwner iLoop; sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: class CleanupStack sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A collection of static functions that are used to add resources to and remove sl@0: resources from the cleanup stack. sl@0: */ sl@0: { sl@0: public: sl@0: IMPORT_C static void PushL(TAny* aPtr); sl@0: IMPORT_C static void PushL(CBase* aPtr); sl@0: IMPORT_C static void PushL(TCleanupItem anItem); sl@0: IMPORT_C static void Pop(); sl@0: IMPORT_C static void Pop(TInt aCount); sl@0: IMPORT_C static void PopAndDestroy(); sl@0: IMPORT_C static void PopAndDestroy(TInt aCount); sl@0: IMPORT_C static void Check(TAny* aExpectedItem); sl@0: inline static void Pop(TAny* aExpectedItem); sl@0: inline static void Pop(TInt aCount, TAny* aLastExpectedItem); sl@0: inline static void PopAndDestroy(TAny* aExpectedItem); sl@0: inline static void PopAndDestroy(TInt aCount, TAny* aLastExpectedItem); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A utility class used by the templated function CleanupDeletePushL() to create sl@0: a TCleanupItem item that will perform a delete type operation on sl@0: the class T type object. sl@0: sl@0: @see CleanupDeletePushL() sl@0: */ sl@0: template sl@0: class CleanupDelete sl@0: { sl@0: public: sl@0: inline static void PushL(T* aPtr); sl@0: private: sl@0: static void Delete(TAny *aPtr); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Constructs and pushes a TCleanupItem object onto the cleanup stack. sl@0: sl@0: The TCleanupItem encapsulates: sl@0: sl@0: - the pointer aPtr to the object of type class T which is to be cleaned up sl@0: sl@0: - an associated cleanup operation. sl@0: sl@0: The cleanup operation is the private static function Delete() of the templated sl@0: class CleanupDelete, and is called as a result of a subsequent call sl@0: to CleanupStack::PopAndDestroy(). sl@0: sl@0: CleanupDelete::Delete() is passed a pointer to the class T object to be cleaned sl@0: up, and the function implements cleanup by deleting the passed object. sl@0: sl@0: An example of its use: sl@0: sl@0: @code sl@0: ... sl@0: CTestOne* one = new (ELeave) CTestOne; sl@0: CleanupDeletePushL(one); sl@0: ... sl@0: CleanupStack::PopAndDestroy(); // <--- results in "one" being deleted. sl@0: ... sl@0: @endcode sl@0: sl@0: @param aPtr A pointer to a templated class T type object for which the cleanup item is being created. sl@0: sl@0: @see TCleanupItem sl@0: @see CleanupDelete sl@0: @see CleanupStack::PopAndDestroy() sl@0: */ sl@0: template sl@0: inline void CleanupDeletePushL(T* aPtr); sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A utility class used by the templated function CleanupArrayDeletePushL() to sl@0: create a TCleanupItem item that will perform a delete type operation on an sl@0: array of class T type objects. sl@0: sl@0: @see CleanupArrayDeletePushL() sl@0: */ sl@0: template sl@0: class CleanupArrayDelete sl@0: { sl@0: public: sl@0: inline static void PushL(T* aPtr); sl@0: private: sl@0: static void ArrayDelete(TAny *aPtr); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Constructs and pushes a TCleanupItem object onto the cleanup stack. sl@0: sl@0: The TCleanupItem encapsulates: sl@0: sl@0: - the pointer aPtr to an array of type class T objects to be cleaned up sl@0: sl@0: - an associated cleanup operation. sl@0: sl@0: The cleanup operation is the private static function ArrayDelete() of the sl@0: templated class CleanupArrayDelete, and is called as a result of sl@0: a subsequent call to CleanupStack::PopAndDestroy(). sl@0: sl@0: CleanupArrayDelete::ArrayDelete() is passed a pointer to the array of class T sl@0: objects to be cleaned up, and the function implements cleanup by deleting sl@0: the passed array using the delete [] operator. sl@0: sl@0: An example of its use: sl@0: sl@0: @code sl@0: ... sl@0: RTestOne* one = new (ELeave) RTestOne [KSomeArraySize]; sl@0: CleanupArrayDeletePushL(one); sl@0: ... // Do something with the object......... sl@0: CleanupStack::PopAndDestroy(); // <--- results in the array "one" being deleted. sl@0: ... sl@0: @endcode sl@0: sl@0: @param aPtr A pointer to an array of class T type objects for which sl@0: the cleanup item is being created. sl@0: sl@0: @see TCleanupItem sl@0: @see CleanupArrayDelete sl@0: @see CleanupStack::PopAndDestroy() sl@0: */ sl@0: template sl@0: inline void CleanupArrayDeletePushL(T* aPtr); sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A utility class used by the templated function CleanupClosePushL() to create sl@0: a TCleanupItem item that will perform a close type operation on sl@0: the class T type object. sl@0: sl@0: @see CleanupClosePushL() sl@0: */ sl@0: template sl@0: class CleanupClose sl@0: { sl@0: public: sl@0: inline static void PushL(T& aRef); sl@0: private: sl@0: static void Close(TAny *aPtr); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Constructs and pushes a TCleanupItem object onto the cleanup stack. sl@0: sl@0: The TCleanupItem encapsulates: sl@0: sl@0: 1. a reference aRef to the object of type class T which is to be cleaned up sl@0: sl@0: 2. an associated cleanup operation. sl@0: sl@0: The cleanup operation is the private static function Close() of the templated sl@0: class CleanupClose and is invoked as a result of a subsequent call to sl@0: CleanupStack::PopAndDestroy(). sl@0: sl@0: CleanupClose::Close() is passed a pointer to the class T object to be cleaned sl@0: up, and the function implements cleanup by calling Close() on the passed object. sl@0: The class T object must, therefore, define and implement (or inherit) a Close() sl@0: member function. sl@0: sl@0: An example of its use: sl@0: sl@0: @code sl@0: class RTestTwo; sl@0: { sl@0: public : sl@0: ... sl@0: IMPORT_C void Close(); sl@0: ... sl@0: } sl@0: ... sl@0: RTestTwo two; sl@0: CleanupClosePushL(two); sl@0: ... sl@0: CleanupStack::PopAndDestroy(); // <--- results in Close() being called on "two". sl@0: ...... sl@0: @endcode sl@0: sl@0: In practice, this type of cleanup operation is commonly applied to handles sl@0: to resources; if such handles are constructed on the program stack, then it is sl@0: important that such handles are closed. sl@0: sl@0: @param aRef A reference to a class T type object for which the cleanup item sl@0: is being created. sl@0: sl@0: @see TCleanupItem sl@0: @see CleanupClose sl@0: @see CleanupStack::PopAndDestroy() sl@0: */ sl@0: template sl@0: inline void CleanupClosePushL(T& aRef); sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: A utility class used by the templated function CleanupReleasePushL() to create sl@0: a TCleanupItem item that will perform a release type operation on sl@0: the class T type object. sl@0: sl@0: @see CleanupReleasePushL() sl@0: */ sl@0: template sl@0: class CleanupRelease sl@0: { sl@0: public: sl@0: inline static void PushL(T& aRef); sl@0: private: sl@0: static void Release(TAny *aPtr); sl@0: }; sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: @publishedAll sl@0: @released sl@0: sl@0: Constructs and pushes a TCleanupItem object onto the cleanup stack. sl@0: sl@0: The TCleanupItem encapsulates: sl@0: sl@0: 1. a reference aRef to the object of type class T which is to be cleaned up sl@0: sl@0: 2. an associated cleanup operation. sl@0: sl@0: The cleanup operation is the private static function Release() of the sl@0: templated class CleanupRelease and is invoked as a result of sl@0: a subsequent call to CleanupStack::PopAndDestroy(). sl@0: sl@0: CleanupRelease::Release() is passed a pointer to the class T object to be cleaned sl@0: up, and the function implements cleanup by calling Release() on the passed object. sl@0: The class T object must, therefore, define and implement (or inherit) a Release() sl@0: member function. sl@0: sl@0: An example of its use: sl@0: sl@0: @code sl@0: class RTestThree; sl@0: { sl@0: public : sl@0: ... sl@0: IMPORT_C void Release(); sl@0: ... sl@0: } sl@0: ... sl@0: RTestThree three; sl@0: CleanupReleasePushL(three); sl@0: ... sl@0: CleanupStack::PopAndDestroy(); // <--- results in Release() being called on "three". sl@0: ...... sl@0: @endcode sl@0: sl@0: @param aRef A reference to a class T type object for which the cleanup item sl@0: is being created. sl@0: sl@0: @see TCleanupItem sl@0: @see CleanupRelease sl@0: @see CleanupStack::PopAndDestroy() sl@0: */ sl@0: template sl@0: inline void CleanupReleasePushL(T& aRef); sl@0: sl@0: sl@0: sl@0: sl@0: class CConsoleBase; sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @released sl@0: */ sl@0: class Console sl@0: { sl@0: public: sl@0: IMPORT_C static CConsoleBase* NewL(const TDesC& aTitle,TSize aSize); sl@0: }; sl@0: sl@0: #include sl@0: sl@0: #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS sl@0: #include sl@0: #endif sl@0: sl@0: #endif //__E32BASE_H__