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