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