Update contrib.
1 // Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\euser\cbase\ub_obj.cpp
20 const TInt KObjectIxGranularity=8;
21 const TInt KObjectConMinSize=8; // must be power of 2 or 3*power of 2
22 const TInt KObjectConIxGranularity=4;
23 const TInt KObjectIndexMask=0x7fff;
24 const TInt KObjectMaxIndex=0x7fff;
25 const TInt KObjectInstanceShift=16;
26 const TInt KObjectInstanceMask=0x3fff;
27 const TInt KObjectUniqueIDShift=16;
28 const TInt KObjectUniqueIDMask=0xffff;
29 const TInt KObjectIxMaxHandles=0x8000;
30 const TInt KObjectConIxMaxSize=0x10000-1;
32 inline TInt index(TInt aHandle)
33 {return(aHandle&KObjectIndexMask);}
34 inline TInt instance(TInt aHandle)
35 {return((aHandle>>KObjectInstanceShift)&KObjectInstanceMask);}
36 inline TInt instanceLimit(TInt& aCount)
37 {return ((aCount&KObjectInstanceMask)==0) ? ((++aCount)&KObjectInstanceMask) : aCount&KObjectInstanceMask;}
38 inline TInt makeHandle(TInt anIndex,TInt anInstance)
39 {return((TInt)((anInstance<<KObjectInstanceShift)|anIndex));}
41 inline TInt uniqueID(TInt aHandle)
42 {return((aHandle>>KObjectUniqueIDShift)&KObjectUniqueIDMask);}
43 inline TInt makeFindHandle(TInt anIndex,TInt anUniqueID)
44 {return((TInt)((anUniqueID<<KObjectUniqueIDShift)|anIndex));}
51 LOCAL_C void makeFullName(TFullName &aFullName,const CObject *anOwner,const TDesC &aName)
53 // Make a name from its owner name and aName.
60 makeFullName(aFullName,anOwner->Owner(),anOwner->Name());
70 Constructs the object and initializes the reference count to one.
72 Once constructed, a reference counting object cannot be deleted until its
73 reference count is reduced to zero.
77 EXPORT_C CObject::CObject()
92 It removes this reference counting object from its object container,
95 @panic E32USER-CBase 33 if the reference count is not zero when
96 the destructor is called.
100 EXPORT_C CObject::~CObject()
103 __ASSERT_ALWAYS(AccessCount()==0,Panic(EObjObjectStillReferenced));
107 CObjectCon *p=iContainer;
117 Opens this reference counting object.
119 The default behaviour increments the reference count by one and
121 Where a derived class implements its own version of this function, it must
122 either use the protected member function Inc() to increment the reference
123 count or make a base call to this function.
127 EXPORT_C TInt CObject::Open()
138 Closes this reference counting object.
140 The default behaviour decrements the reference count by one. If this becomes
141 zero, then the function deletes this reference counting object.
143 Where a derived class implements its own version of this function, it can
144 use the protected member function Dec() to decrement the reference count or
145 make a base call to this function.
147 @panic E32USER-CBase 34 if the reference count is negative when this
150 EXPORT_C void CObject::Close()
154 __ASSERT_ALWAYS(AccessCount()>=0,Panic(EObjNegativeAccessCount));
155 if (AccessCount()==0)
162 LOCAL_C TName GetLocalObjectName(const CObject *anObj)
164 TName n=_L("Local-");
165 n.AppendNumFixedWidth((TInt)anObj,EHex,8);
173 Gets the name of this reference counting object.
175 The default behaviour provided by this function depends on whether a name
176 has been explicitly set into the object:
178 if a name has previously been set, then the function returns that name.
180 if a name has not been set, then the function builds a default name. This
181 is fourteen characters and has the format: LOCAL-nnnnnnnn where nnnnnnnn is
182 the hexadecimal character representation of this reference counting object's
183 address. This default name is, therefore, guaranteed to be unique within the
186 @return A modifiable buffer descriptor with a defined maximum length containing
187 the name of this reference counting object.
189 EXPORT_C TName CObject::Name() const
193 return GetLocalObjectName(this);
200 Gets the full name of this reference counting object.
202 By default, the full name is a concatenation of this reference counting
203 object's name with the full name of its owning reference counting object.
205 @return A modifiable buffer descriptor with a defined maximum length containing
206 the full name of this reference counting object.
208 EXPORT_C TFullName CObject::FullName() const
212 makeFullName(n,Owner(),Name());
220 Sets or clears this reference counting object's name.
222 To set the name, the specified descriptor must contain the name to be set.
223 Once the name has been successfully set, then the specified source descriptor
226 To clear an existing name, specify a NULL argument.
228 @param aName A pointer to the descriptor containing the name to be set, or
229 NULL if an existing name is to be cleared.
231 @return KErrNone, if the function is successful;
232 KerrNoMemory, if there is insufficient memory available.
234 @panic USER 11 if the length of aName is greater than KMaxName
235 for a 16-bit descriptor.
236 @panic USER 23 if the length of aName is greater than KMaxName
237 for an 8-bit descriptor.
239 EXPORT_C TInt CObject::SetName(const TDesC *aName)
246 iName=aName->Alloc();
248 return(KErrNoMemory);
257 Sets or clears this reference counting object's name, and leaves on error.
259 To set the name, the specified descriptor must contain the name to be set.
260 Once the name has been successfully set, then the specified source descriptor
263 To clear an existing name, specify a NULL argument.
265 The function leaves if there is insufficient memory.
267 @param aName A pointer to the descriptor containing the name to be set, or
268 NULL if an existing name is to be cleared.
270 @panic USER 11 if the length of aName is greater than KMaxName
271 for a 16-bit descriptor.
272 @panic USER 23 if the length of aName is greater than KMaxName
273 for an 8-bit descriptor.
275 EXPORT_C void CObject::SetNameL(const TDesC *aName)
281 iName=aName->AllocL();
292 EXPORT_C TInt CObject::Extension_(TUint aExtensionId, TAny*& a0, TAny* a1)
294 return CBase::Extension_(aExtensionId, a0, a1);
301 Creates a new object index.
303 @return A pointer to the newly created object index.
305 EXPORT_C CObjectIx* CObjectIx::NewL()
308 return new(ELeave) CObjectIx;
317 EXPORT_C CObjectIx::CObjectIx()
318 : iNextInstance(1), iFree(-1)
328 Frees all resources owned by the object index, prior to its destruction.
329 In particular, it calls Close() on all reference counting objects in the index.
333 EXPORT_C CObjectIx::~CObjectIx()
335 // We have to be very careful here. Calling Close() on the objects in the array
336 // may result in other entries being removed from the array before we delete
337 // them here, and may result in the array being ReAlloc()ed, corrupting the removed
338 // entries, hence we must check the iHighWaterMark value each time round the loop.
340 while(++i<iHighWaterMark)
342 SObjectIxRec* pS=iObjects+i;
347 pS->obj=NULL; // invalidate entry after closing it
356 Adds the specified reference counting object into this object index and
357 returns the handle number that represents it.
359 @param anObj The reference counting object to be added to this object index.
361 @return The handle number.
363 EXPORT_C TInt CObjectIx::AddL(CObject* anObj)
365 TInt index=iFree; //iFree contains the index of the first empty slot or -1 if there is no such.
366 if (index<0) //Check if the free list is empty
368 // The free list is empty, so more slots must be allocated.
369 if (iHighWaterMark==KObjectIxMaxHandles)
370 User::LeaveNoMemory();
372 //Those are internal checking of the object consistency
373 __ASSERT_DEBUG(iAllocated==iHighWaterMark,Panic(EObjInconsistent));
374 __ASSERT_DEBUG(iAllocated==iNumEntries,Panic(EObjInconsistent));
376 //Double allocated memory
377 TInt newAlloc=iAllocated ? 2*iAllocated : KObjectIxGranularity;
378 if(newAlloc>KObjectIxMaxHandles)
379 newAlloc=KObjectIxMaxHandles;
380 SObjectIxRec* pA=(SObjectIxRec*)User::ReAllocL(iObjects, newAlloc*sizeof(SObjectIxRec));
383 //NOTE: There is no need to initialize newly allocated memory (e.g. to zero iObjects) as it all goes
384 //beyond HWM and will be not considered when search in At(...) or operator[]() methods.
385 //As the free list is initially ordered, each slot must go to the states as follows:
386 //-Created as the part of the free list beyond HWM. - uninitialized and not searched in any method.
387 //-In use - initialized.
388 //-The part of the free list within HWM - initialized to zero.
389 //Also, UpdateState() does not reorder free list beyond HWM but keep it preserverd.
391 iAllocated=newAlloc; //Update the number of allocated slots
392 iUpdateDisabled = iAllocated/2;//The number of Remove() calls before the object update (free list, HWM,...)
394 //Connect all newly allocated slots into the list and set 'index' to point to the first one.
396 pA[index].nextEmpty = -1;
397 while (iHighWaterMark <= --index)
398 pA[index].nextEmpty=index+1;
402 //At this point, 'index' variable points to the slot that will be used for the new entry.
403 //It also represents the first element in the list of empty slots.
405 SObjectIxRec *pS=iObjects+index; // pS points to the object that will be used for the new entry.
406 iFree=pS->nextEmpty; // Update iFree to point to the next empty slot.
408 //Initialize data of the new element of the array.
410 pS->str.uniqueID=(TUint16)anObj->UniqueID();
411 pS->str.instance=(TUint16)instanceLimit(iNextInstance);
415 if (index>=iHighWaterMark) //Update HWM to points to the slot after the last in use.
416 iHighWaterMark=index+1;
420 __ASSERT_DEBUG( (iFree==-1 && iAllocated==iHighWaterMark && iAllocated==iNumEntries)
421 ||(iFree!=-1 && iAllocated>iNumEntries),Panic(EObjInconsistent));
423 return(makeHandle(index,pS->str.instance)); //Create and return the handle
430 Removes the reference counting object identified by handle number from this
431 object index and closes it.
433 If the reference counting object cannot be closed, because CObjectIx::ENoClose
434 is ORed into the handle number, then it is neither removed from the object
437 @param aHandle The handle number of the reference counting object to be removed
440 @panic E32USER-CBase 37 if aHandle does not represent an object known to this
443 EXPORT_C void CObjectIx::Remove(TInt aHandle)
445 if (aHandle&ENoClose)
447 TInt i=index(aHandle);
448 __ASSERT_ALWAYS(i<iHighWaterMark,Panic(EObjRemoveBadHandle));
449 SObjectIxRec* pR=iObjects+i;
451 if (!pO || pR->str.instance!=instance(aHandle) || pR->str.uniqueID!=pO->UniqueID())
452 Panic(EObjRemoveBadHandle);
458 // Add the entry onto the free list
463 iUpdateDisabled--; //Count down till state update is enabled again.
465 if ( //Update the states(HWM, resort free list & memory shrink) if:
466 (!iUpdateDisabled) && //There were a number of Remove() calls since the last ReAlloc
467 (iAllocated>=2*KObjectIxGranularity))//Allocated memory is above the limit.
470 iUpdateDisabled = iAllocated/2;//The number of Remove() calls before the next update comes.
475 //There is no any CObject left. Reset the object to initial state (except iNextInstance)
480 iFree=-1; //Empty free list
483 //This is internal checking of the object consistency
484 __ASSERT_DEBUG( (iFree==-1 && iAllocated==iHighWaterMark && iAllocated==iNumEntries)
485 ||(iFree!=-1 && iAllocated>iNumEntries),Panic(EObjInconsistent));
489 //1. Reorder free list.
490 //2. Update iHighWaterMark. This is the only place where HWM is decreased, while it can be increased during AddL().
491 //3. Shrinks the heap memory (pointed by iObjects) if it can be at least halved.
492 //The function is entered with at least one occupied slot in iObjects array.
493 //The array is searched from its end. Special care is given to the case where
494 //HWM is less then KObjectIxGranularity as the size of the arrey does not go below it.
495 void CObjectIx::UpdateState()
497 TBool toShrink = EFalse;
498 TBool foundFreeBelowLimit = EFalse;//Used to handle spacial case when HWM is below the minimum alloc. limit
501 //Start from the HWM as all slots beyond are free and sorted already.
502 TInt current = iHighWaterMark;
503 TInt prevFreeSlot = iHighWaterMark == iAllocated ? -1 : iHighWaterMark;
506 if (iObjects[current].obj)
508 //This is the slot with the valid entry. Check if this is the last in the array.
511 //This is the first occupied slot we found => It is new HWM.
513 if (current < iAllocated/2)
515 //At this point we decide to shrink memory.
517 //Once we find HWM and decide to shrink, all slots after that point should be removed
518 //from the free list as that memory will be freed. The exception is the case when HWM is below
519 //the minimum of allocated memory (8 slots as the moment).
520 if((current >= KObjectIxGranularity) || (!foundFreeBelowLimit))
521 prevFreeSlot = -1; //The next free slot to find will be the last one in the list.
527 //This is the free slot.
528 if ((!newHWM) && (!foundFreeBelowLimit) &&(current<KObjectIxGranularity))
531 //We just reached the first free slot below minimum alloc. size and still we found no occupied slots.
532 iObjects[current].nextEmpty = -1; //This will be the end of free list.
533 foundFreeBelowLimit = ETrue; //Mark that we found the special case
537 iObjects[current].nextEmpty = prevFreeSlot;//Link the empty slot in the free list.
539 prevFreeSlot = current;
543 iHighWaterMark = newHWM;
544 iFree = prevFreeSlot;
548 //Do not reallocate less then the initial value.
549 iAllocated = Max(newHWM,KObjectIxGranularity);
550 //Update member data and re-allocate memory. ReAlloc cannot return NULL as we are asking for less memory.
551 iObjects=(SObjectIxRec*)User::ReAlloc(iObjects,iAllocated*sizeof(SObjectIxRec));
558 Gets the number of occurrences of the specified reference counting object
559 within this object index.
561 Note that the same reference counting object can be added to an object index
564 @param anObject The reference counting object.
566 @return The number of occurrences.
568 EXPORT_C TInt CObjectIx::Count(CObject* anObject) const
574 SObjectIxRec* pS=iObjects;
575 SObjectIxRec* pE=pS+iHighWaterMark;
578 if (pS->obj==anObject)
588 #ifndef __COBJECT_MACHINE_CODED__
590 Gets a pointer to the reference counting object with the specified handle
591 number and matching unique ID.
593 @param aHandle The handle number of the reference counting object.
594 @param aUniqueID The unique ID.
596 @return A pointer to the reference counting object. If there is no matching
597 object, then this is NULL.
599 EXPORT_C CObject *CObjectIx::At(TInt aHandle,TInt aUniqueID)
601 TInt i=index(aHandle);
602 if (i>=iHighWaterMark)
604 SObjectIxRec *pS=iObjects+i;
605 if (pS->str.instance!=instance(aHandle) || pS->str.uniqueID!=aUniqueID)
614 Gets a pointer to the reference counting object with the specified
617 @param aHandle The handle number of the reference counting object.
619 @return A pointer to the reference counting object. If there is no matching
620 object, then this is NULL.
622 EXPORT_C CObject *CObjectIx::At(TInt aHandle)
624 TInt i=index(aHandle);
625 if (i>=iHighWaterMark)
627 SObjectIxRec *pS=iObjects+i;
628 if (pS->str.instance!=instance(aHandle))
639 Constructs and returns the handle number representing the specified reference
640 counting object within this object index.
642 @param anObj The reference counting object.
644 @return The handle number representing the reference counting object;
645 KErrNotFound, if the reference counting object could not be found
646 within the object index.
648 EXPORT_C TInt CObjectIx::At(const CObject* anObj) const
653 SObjectIxRec* pS=iObjects;
654 SObjectIxRec* pE=pS+iHighWaterMark;
656 while(pS<pE && pS->obj!=anObj)
659 return(makeHandle(i,pS->str.instance));
668 Gets a pointer to the reference counting object with the specified handle
669 number and matching unique ID.
671 @param aHandle The handle number of the reference counting object.
672 @param aUniqueID The unique ID.
674 @return A pointer to the reference counting object.
676 @leave KErrBadHandle if there is no matching object.
678 EXPORT_C CObject *CObjectIx::AtL(TInt aHandle,TInt aUniqueID)
681 CObject* pO=At(aHandle,aUniqueID);
683 User::Leave(KErrBadHandle);
691 Gets a pointer to the reference counting object with the specified handle
694 @param aHandle The handle number of the reference counting object.
696 @return A pointer to the reference counting object.
698 @leave KErrBadHandle if there is no matching object.
700 EXPORT_C CObject *CObjectIx::AtL(TInt aHandle)
703 CObject* pO=At(aHandle);
705 User::Leave(KErrBadHandle);
712 #ifndef __COBJECT_MACHINE_CODED__
714 Gets a pointer to a reference counting object located at the specified offset
715 within the object index.
717 @param anIndex The offset of the reference counting object within the object
718 index. Offset is relative to zero.
720 @return A pointer to the reference counting object.
722 @panic E32USER-CBase 21 if the value of anIndex is negative or is greater than
723 or equal to the total number of objects held by
726 EXPORT_C CObject* CObjectIx::operator[](TInt anIndex)
729 __ASSERT_ALWAYS(anIndex>=0 && anIndex<iHighWaterMark,Panic(EArrayIndexOutOfRange));
730 return iObjects[anIndex].obj;
733 GLDEF_C void PanicCObjectIxIndexOutOfRange(void)
735 Panic(EArrayIndexOutOfRange);
743 Creates an object container.
745 Open code rarely, if ever, explicitly calls this function. Instead, call the
746 CreateL() member function of the container index, CObjectConIx, which uses
747 this function in its implementation.
749 @return A pointer to the new object container.
751 @see CObjectConIx::CreateL
753 EXPORT_C CObjectCon* CObjectCon::NewL()
756 return new(ELeave) CObjectCon(ENotOwnerID);
763 Constructor taking a unique Id.
765 @param aUniqueID The unique Id value.
767 EXPORT_C CObjectCon::CObjectCon(TInt aUniqueID)
768 : iUniqueID(aUniqueID)
781 Frees all resources owned by the object container, prior to its destruction.
783 In particular, it destroys all contained reference counting objects.
787 EXPORT_C CObjectCon::~CObjectCon()
790 if (iUniqueID!=ENotOwnerID && iCount)
792 // Careful here in case deleting one object causes other objects in the array
793 // to be removed and Count to change.
797 CObject* pS=iObjects[i];
808 Adds a reference counting object to this object container.
810 If the specified reference counting object has a name, it must be valid,
811 otherwise the function leaves with KErrBadName; in addition, the reference
812 counting object's full name must be unique to this object container, otherwise
813 the function leaves with KErrAlreadyExists.
815 If the specified reference counting object has no name, then the object itself
816 must be unique to the object container, i.e. the object container should not
817 already contain the same reference counting object, otherwise the function
818 leaves with KErrAlreadyExists.
820 @param anObj A pointer to the reference counting object to be added.
822 EXPORT_C void CObjectCon::AddL(CObject* anObj)
825 User::LeaveIfError(CheckUniqueFullName(anObj));
826 if (iCount==iAllocated)
830 newAlloc = KObjectConMinSize;
833 // increase in sequence 8, 12, 16, 24, ... , 2^n, 3*2^n-1, ...
834 // can't get sign problems since iAllocated can't exceed 0x20000000
835 newAlloc = iAllocated + (iAllocated>>1) - ((iAllocated&(iAllocated-1))>>2);
837 iObjects=(CObject**)User::ReAllocL(iObjects, newAlloc*sizeof(CObject*));
840 iObjects[iCount++]=anObj;
841 if (iUniqueID!=ENotOwnerID)
842 anObj->iContainer=this;
849 Removes a reference counting object from this object container.
851 The specified reference counting object is destroyed on removal.
853 @param anObj A pointer to the reference counting object to be removed.
855 @panic E32USER-CBase 35 if the reference counting object is not held by this
858 EXPORT_C void CObjectCon::Remove(CObject *anObj)
860 CObject** pS=iObjects;
861 CObject** pE=pS+iCount;
866 Mem::Move((TAny*)pS,(TAny*)(pS+1),TInt(pE)-TInt(pS)-sizeof(CObject*));
867 TInt used = --iCount;
868 if (used) // if now empty, free all memory
870 if (iAllocated > KObjectConMinSize) // don't shrink below minimum size
872 // calculate next size down
873 TInt newAlloc = iAllocated - (iAllocated>>2) - ((iAllocated&(iAllocated-1))>>3);
875 // shrink if half full or 64 less than next size down, whichever comes first
876 if (used <= Max(iAllocated>>1, newAlloc-64))
878 iObjects=(CObject**)User::ReAlloc(iObjects,newAlloc*sizeof(CObject*));
889 if (iUniqueID!=ENotOwnerID && anObj->iContainer)
892 // An object's destructor can scan the container so its best
893 // to remove the object from the container before destroying it.
895 anObj->iContainer=NULL;
902 Panic(EObjRemoveObjectNotFound);
908 #ifndef __COBJECT_MACHINE_CODED__
910 Gets a pointer to the reference counting object located at the specified offset
911 within the object container.
913 @param anIndex The offset of the reference counting object within the object
914 container. Offset is relative to zero.
916 @return A pointer to the owning reference counting object.
918 @panic E32USER-CBase 21 if anIndex is negative or is greater than or equal to
919 the total number of objects held by the container.
921 EXPORT_C CObject *CObjectCon::operator[](TInt anIndex)
923 __ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount, Panic(EArrayIndexOutOfRange));
924 return iObjects[anIndex];
931 Gets a pointer to the reference counting object with the specified find-handle
934 A find-handle number is an integer which uniquely identifies a reference
935 counting object with respect to its object container.
937 @param aFindHandle The find-handle number of the reference counting object.
938 The unique Id part of this number must be the same as the
939 unique Id of this container.
940 The index part of the find-handle number must be
943 @return A pointer to the reference counting object.
945 @panic E32User-CBase 38 if the unique Id part of aFindHandle is not the same as
946 the unique Id of this container.
947 @panic E32User-CBase 39 if the index part of aFindHandle is negative or greater
948 than or equal to the total number of reference counting
949 objects held by this object container.
951 EXPORT_C CObject *CObjectCon::At(TInt aFindHandle) const
954 __ASSERT_ALWAYS(uniqueID(aFindHandle)==iUniqueID,Panic(EObjFindBadHandle));
955 TInt ix=index(aFindHandle);
956 __ASSERT_ALWAYS(ix<iCount,Panic(EObjFindIndexOutOfRange));
964 Gets a pointer to the reference counting object with the specified find-handle
965 number, and leaves on error..
967 A find-handle number is an integer which uniquely identifies a reference
968 counting object with respect to its object container.
970 @param aFindHandle The find-handle number of the reference counting object.
971 The unique Id part of this number must be the same as
972 the unique Id of this container.
973 The index part of the find-handle number must be
976 @return A pointer to the reference counting object.
978 @leave KErrBadHandle if the unique Id part of aFindHandle is not the same as
979 the unique Id of this container.
980 @leave KErrArgument if the index part of aFindHandle is negative or greater
981 than or equal to the total number of reference counting
982 objects held by this object container.
984 EXPORT_C CObject *CObjectCon::AtL(TInt aFindHandle) const
987 __ASSERT_ALWAYS(uniqueID(aFindHandle)==iUniqueID,User::Leave(KErrBadHandle));
988 TInt ix=index(aFindHandle);
989 __ASSERT_ALWAYS(ix<iCount,User::Leave(KErrArgument));
993 GLDEF_C void PanicCObjectConFindBadHandle(void)
995 Panic(EObjFindBadHandle);
1002 GLDEF_C void PanicCObjectConFindIndexOutOfRange(void)
1004 Panic(EObjFindIndexOutOfRange);
1007 GLDEF_C void PanicCObjectConIndexOutOfRange(void)
1009 Panic(EArrayIndexOutOfRange);
1017 Checks whether a specified name is a valid CObject name.
1019 A name is deemed to be invalid, if it contains any of the characters:
1020 "*", "?", ":" i.e. the characters: asterisk, question mark and single colon.
1022 @param aName A reference to the descriptor containing the name to be checked.
1024 @return KErrBadName, if the name is invalid. KErrNone, otherwise.
1028 EXPORT_C TInt User::ValidateName(const TDesC &aName)
1031 TUint16* pName = const_cast<TUint16*>(aName.Ptr());
1033 TUint8* pName = const_cast<TUint8*>(aName.Ptr());
1035 TInt pNameLen = aName.Length();
1036 for(;pNameLen;pName++,pNameLen--)
1037 if(*pName>0x7e || *pName<0x20 || *pName=='*' || *pName=='?' || *pName==':')
1038 return(KErrBadName);
1046 Checks that a name will be unique.
1048 The function checks that no reference counting object exists in this object
1049 container with the same full name as that generated from the specified name
1050 and the specified owning reference counting object.
1052 This is a useful test to ensure that the name for a potential new reference
1053 counting object will result in a unique full name.
1055 @param anOwner A pointer to a potential owning reference counting object.
1056 @param aName The name for a potential new reference counting object.
1058 @return KErrNone, if the full name does not already exist in this
1060 KErrBadName, if the specified name is invalid;
1061 KErrAlreadyExists, if a reference counting object with the same
1062 fullname as the generated one already exists in this object container.
1064 EXPORT_C TInt CObjectCon::CheckUniqueFullName(const CObject *anOwner,const TDesC &aName) const
1067 TInt r=User::ValidateName(aName);
1071 makeFullName(n,anOwner,aName);
1074 if (FindByFullName(h,n,res)==KErrNone)
1075 r=KErrAlreadyExists;
1086 protected recursive function for use by CheckUniqueFullName
1088 TBool CObjectCon::NamesMatch(const CObject* anObject, const CObject* aCurrentObject) const
1091 if (aCurrentObject->iName==NULL) // current object has no name, therefore not the same
1093 if ((anObject->Name()).Compare(aCurrentObject->Name())!=0) // short names are different, therefore not the same
1095 if ((aCurrentObject->Owner()==NULL)&&(anObject->Owner()==NULL)) // same short name, no owners = same
1097 if ((aCurrentObject->Owner()==NULL)||(anObject->Owner()==NULL)) // one has no owner, therefore not the same
1099 return(NamesMatch(anObject->Owner(),aCurrentObject->Owner())); // go recursive
1105 protected recursive function for use by CheckUniqueFullName
1107 TBool CObjectCon::NamesMatch(const CObject* anObject, const TName& anObjectName, const CObject* aCurrentObject) const
1110 if (aCurrentObject->iName==NULL) // current object has no name, therefore not the same
1112 if (anObjectName.Compare(aCurrentObject->Name())!=0) // short names are different, therefore not the same
1114 if ((aCurrentObject->Owner()==NULL)&&(anObject->Owner()==NULL)) // same short name, no owners = same
1116 if ((aCurrentObject->Owner()==NULL)||(anObject->Owner()==NULL)) // one has no owner, therefore not the same
1118 return(NamesMatch(anObject->Owner(),aCurrentObject->Owner())); // go recursive
1125 Checks that the specified reference counting object does not already exist in
1126 this object container.
1128 Uniqueness is decided by name, if the object has a name, otherwise by pointer.
1130 If the reference counting object has a name, then it is unique only if there
1131 is no other reference counting object in the container with the same full
1134 If the reference counting object has no name, then it is unique only if there
1135 is no other reference counting object in the container with the same pointer.
1137 @param anObject A pointer to the reference counting object to be checked.
1139 @return KErrNone, if the reference counting object does not already exist in
1140 this object container;
1141 KErrBadName, if the name of the reference counting
1143 KErrAlreadyExists, if the reference counting object already exists.
1145 EXPORT_C TInt CObjectCon::CheckUniqueFullName(const CObject* anObject) const
1148 TName name(anObject->Name());
1149 TInt r=User::ValidateName(name);
1156 CObject** pS=iObjects;
1157 CObject** pE=pS+iCount;
1159 // if it's name is null, just need to check it's not already there
1160 if (!anObject->iName)
1165 return KErrAlreadyExists;
1172 if (NamesMatch(anObject,name,*pS))
1173 return KErrAlreadyExists;
1182 Searches for the reference counting object whose name matches the specified
1185 The search starts at the reference counting object following the one associated
1186 with the specified find-handle number. If the specified find-handle number
1187 is zero, then searching starts at the beginning of the object container.
1191 1. names are folded for the purpose of pattern matching
1193 2. if the specified find-handle number is non-zero, then the unique Id part of
1194 the number must be the same as the unique Id of this container.
1196 @param aFindHandle On entry, contains the find-handle number of a reference
1197 counting object from where searching is to start, or zero.
1198 On return, if an object is found, then this is set to the
1199 find-handle number of that object;
1200 if no object is found, then this is set to a generated
1201 number, the index part of which has the value 0x7fff.
1202 If the object container is empty, then this
1203 reference is not changed.
1204 @param aMatch The match pattern.
1205 @param aName A modifiable buffer descriptor with a defined maximum
1206 length. On return, if an object is found, then this
1207 contains the name of that object; if no object is found,
1208 then the length of this descriptor is set to zero.
1209 If the object container is empty, then this reference is
1212 @return KErrNone, if a matching reference counting object is found;
1213 KErrNotFound, if no matching reference counting object can be found or
1214 the object container is empty.
1216 @panic E32User-CBase 38 if aFindHandle is non-zero and the unique Id part of
1217 it is not the same as the unique Id of this container.
1219 EXPORT_C TInt CObjectCon::FindByName(TInt &aFindHandle,const TDesC &aMatch,TName &aName) const
1223 return KErrNotFound;
1227 __ASSERT_ALWAYS(uniqueID(aFindHandle)==iUniqueID,Panic(EObjFindBadHandle));
1228 ix=index(aFindHandle)+1;
1230 CObject** pS=iObjects;
1231 CObject** pE=pS+iCount;
1235 aName=(*pS++)->Name();
1236 if (aName.MatchF(aMatch)!=KErrNotFound)
1238 aFindHandle=makeFindHandle(ix,iUniqueID);
1244 aFindHandle=makeFindHandle(KObjectMaxIndex,iUniqueID);
1245 return KErrNotFound;
1252 Searches for the reference counting object whose full name matches the
1253 specified match pattern.
1255 The search starts at the reference counting object following the one associated
1256 with the specified find-handle number. If the specified find-handle number
1257 is zero, then searching starts at the beginning of the object container.
1261 1. names are folded for the purpose of pattern matching
1263 2. if the specified find-handle number is non-zero, then the unique Id part of
1264 the number must be the same as the unique Id of this container.
1266 @param aFindHandle On entry, contains the find-handle number of a reference
1267 counting object from where searching is to start or zero.
1268 On return, if an object is found, then this is set to the
1269 find-handle number of that object;
1270 if no object is found, then this is set to a generated
1271 number, the index part of which has the value 0x7fff.
1272 If the object container is empty, then this reference is
1274 @param aMatch The match pattern.
1275 @param aFullName A modifiable buffer descriptor with a defined maximum length.
1276 On return, if an object is found, then this contains the
1277 full name of that object;
1278 if no object is found, then the length of this descriptor
1280 If the object container is empty, then this reference is not
1283 @return KErrNone, if a matching reference counting object is found;
1284 KErrNotFound, if no matching reference counting object can be found or
1285 the object container is empty.
1287 @panic E32User-CBase 38 if aFindHandle is non-zero and the unique Id part of
1288 it is not the same as the unique Id of this container.
1290 EXPORT_C TInt CObjectCon::FindByFullName(TInt &aFindHandle,const TDesC &aMatch,TFullName &aFullName) const
1294 return KErrNotFound;
1298 __ASSERT_ALWAYS(uniqueID(aFindHandle)==iUniqueID,Panic(EObjFindBadHandle));
1299 ix=index(aFindHandle)+1;
1301 CObject** pS=iObjects;
1302 CObject** pE=pS+iCount;
1306 aFullName=(*pS++)->FullName();
1307 if (aFullName.MatchF(aMatch)!=KErrNotFound)
1309 aFindHandle=makeFindHandle(ix,iUniqueID);
1315 aFindHandle=makeFindHandle(KObjectMaxIndex,UniqueID());
1316 return KErrNotFound;
1323 Creates a new container index.
1325 @return A pointer to the newly created container index.
1327 EXPORT_C CObjectConIx* CObjectConIx::NewL()
1330 return new(ELeave) CObjectConIx;
1337 Default constructor.
1339 EXPORT_C CObjectConIx::CObjectConIx()
1350 Frees all resources owned by the container index, prior to its destruction.
1352 In particular, it destroys all of its contained object containers.
1354 EXPORT_C CObjectConIx::~CObjectConIx()
1361 CObjectCon* pS=iContainers[i];
1374 Actually create the container
1376 EXPORT_C void CObjectConIx::CreateContainerL(CObjectCon*& aContainer)
1379 aContainer=CObjectCon::NewL();
1380 if (iUniqueIDHasWrapped)
1382 // Must search for next free id
1383 while (LookupByUniqueId(iNextUniqueID) != NULL)
1386 if (iNextUniqueID == 0)
1390 aContainer->iUniqueID=iNextUniqueID;
1391 if (iCount==iAllocated)
1393 TInt newAlloc=iAllocated+KObjectConIxGranularity;
1394 iContainers=(CObjectCon**)User::ReAllocL(iContainers, newAlloc*sizeof(CObjectCon*));
1395 iAllocated=newAlloc;
1397 iContainers[iCount++]=aContainer;
1404 Creates a new object container and adds it into this container
1407 In addition to creating the object container, the function assigns
1408 the next available unique ID to it.
1410 @return A pointer to the new object container.
1412 EXPORT_C CObjectCon* CObjectConIx::CreateL()
1415 if (iCount == KObjectConIxMaxSize)
1416 User::Leave(KErrOverflow);
1417 CObjectCon* pC=NULL;
1418 TRAPD(r,CreateContainerL(pC))
1425 if (iNextUniqueID == 0)
1428 iUniqueIDHasWrapped = 1;
1437 Removes the specified object container from this container index and
1440 @param aCon A pointer to the object container to be removed. If the pointer is NULL,
1441 the function just returns.
1443 @panic E32USER-CBASE 36 if the object container cannnot be found.
1445 EXPORT_C void CObjectConIx::Remove(CObjectCon* aCon)
1449 CObjectCon** pS=iContainers;
1450 CObjectCon** pE=pS+iCount;
1455 Mem::Move((TAny*)pS,(TAny*)(pS+1),TInt(pE)-TInt(pS)-sizeof(CObjectCon*));
1456 TInt newAlloc=--iCount;
1458 iUniqueIDHasWrapped = 0;
1459 newAlloc=(newAlloc+(KObjectConIxGranularity-1))&~(KObjectConIxGranularity-1);
1460 if (newAlloc!=iAllocated)
1463 iContainers=(CObjectCon**)User::ReAlloc(iContainers,newAlloc*sizeof(CObjectCon*));
1469 iAllocated=newAlloc;
1476 Panic(EObjRemoveContainerNotFound);
1483 Gets a pointer to the object container with the specified unique ID, or NULL.
1485 CObjectCon* CObjectConIx::LookupByUniqueId(TInt aUniqueId) const
1488 CObjectCon** pS=iContainers;
1489 CObjectCon** pE=pS+iCount;
1492 CObjectCon *pO=*pS++;
1493 if (pO->iUniqueID==aUniqueId)
1503 Gets a pointer to the object container with the unique ID from the specified
1506 @param aFindHandle The find handle.
1508 @return A pointer to the object container with a matching unique ID. If no
1509 matching object container can be found, then this is NULL.
1511 EXPORT_C CObjectCon* CObjectConIx::Lookup(TInt aFindHandle) const
1514 return LookupByUniqueId(uniqueID(aFindHandle));