First public contribution.
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_array.cpp
26 NONSHARABLE_CLASS(TSwapArray) : public TSwap
29 inline TSwapArray(CBufBase *aBase,TInt aRecordLength);
30 TUint8 *At(TInt anIndex) const;
31 virtual void Swap(TInt aLeft,TInt aRight) const;
36 inline TSwapArray::TSwapArray(CBufBase *aBase,TInt aRecordLength)
37 : iBase(aBase),iLength(aRecordLength)
40 TUint8 *TSwapArray::At(TInt anIndex) const
42 // Return a pointer to the array element
46 return((TUint8 *)iBase->Ptr(anIndex*iLength).Ptr());
49 void TSwapArray::Swap(TInt aLeft,TInt aRight) const
51 // Swap two elements of the array.
55 Mem::Swap(At(aLeft),At(aRight),iLength);
61 EXPORT_C TKeyArrayFix::TKeyArrayFix(TInt anOffset,TKeyCmpText aType)
62 : TKey(anOffset,aType)
64 Constructs the characteristics of a descriptor key.
66 No length value is passed as this is taken from the descriptor type key.
68 @param anOffset The offset of the key from the start of an array element.
69 @param aType An enumeration which defines the type of comparison to be made
70 between two descriptor keys.
78 EXPORT_C TKeyArrayFix::TKeyArrayFix(TInt anOffset,TKeyCmpText aType,TInt aLength)
79 : TKey(anOffset,aType,aLength)
81 Constructs the characteristics of a text key.
83 @param anOffset The offset of the key from the start of an array element.
84 @param aType An enumeration which defines the type of comparison to be made
85 between two text keys.
86 @param aLength The length of the text key.
95 EXPORT_C TKeyArrayFix::TKeyArrayFix(TInt anOffset,TKeyCmpNumeric aType)
96 : TKey(anOffset,aType)
98 Constructs the characteristics of a numeric key.
100 @param anOffset The offset of the key from the start of an array element.
101 @param aType An enumeration which defines the type of the numeric key.
110 EXPORT_C void TKeyArrayFix::Set(CBufBase *aBase,TInt aRecordLength)
112 // Set the base and record length
117 iRecordLength=aRecordLength;
120 EXPORT_C TAny *TKeyArrayFix::At(TInt anIndex) const
122 // Return an address in the array.
126 if (anIndex==KIndexPtr)
127 return((TUint8 *)iPtr+iKeyOffset);
128 return((TAny *)(iBase->Ptr(anIndex*iRecordLength).Ptr()+iKeyOffset));
134 EXPORT_C TKeyArrayVar::TKeyArrayVar(TInt anOffset,TKeyCmpText aType)
135 : TKey(anOffset,aType)
137 Constructs the characteristics of a descriptor key.
139 No length value is passed as this is taken from the descriptor type key.
141 @param anOffset The offset of the key from the start of an array element.
142 @param aType An enumeration which defines the type of comparison to be made
143 between two descriptor keys.
152 EXPORT_C TKeyArrayVar::TKeyArrayVar(TInt anOffset,TKeyCmpText aType,TInt aLength)
153 : TKey(anOffset,aType,aLength)
155 Constructs the characteristics of a text key.
157 @param anOffset The offset of the key from the start of an array element.
158 @param aType An enumeration which defines the type of comparison to be made
159 between two text keys.
160 @param aLength The length of the text key.
169 EXPORT_C TKeyArrayVar::TKeyArrayVar(TInt anOffset,TKeyCmpNumeric aType)
170 : TKey(anOffset,aType)
172 Constructs the characteristics of a numeric key.
174 @param anOffset The offset of the key from the start of an array element.
175 @param aType An enumeration which defines the type of the numeric key.
184 EXPORT_C void TKeyArrayVar::Set(CBufBase *aBase)
186 // Set the private variable iBase to aBase.
193 EXPORT_C TAny *TKeyArrayVar::At(TInt anIndex) const
195 // Return an address in the array.
199 if (anIndex==KIndexPtr)
200 return((TUint8 *)iPtr+iKeyOffset);
201 SVarRec *pV=(SVarRec *)iBase->Ptr(anIndex*sizeof(SVarRec)).Ptr();
202 return(((TUint8 *)pV->data)+iKeyOffset);
208 EXPORT_C TKeyArrayPak::TKeyArrayPak(TInt anOffset,TKeyCmpText aType)
209 : TKeyArrayVar(anOffset,aType)
211 Constructs the characteristics of a descriptor key.
213 No length value is passed as this is taken from the descriptor type key.
215 @param anOffset The offset of the key from the start of an array element.
216 @param aType An enumeration which defines the type of comparison to be made
217 between two descriptor keys.
226 EXPORT_C TKeyArrayPak::TKeyArrayPak(TInt anOffset,TKeyCmpText aType,TInt aLength)
227 : TKeyArrayVar(anOffset,aType,aLength)
229 Constructs the characteristics of a text key.
231 @param anOffset The offset of the key from the start of an array element.
232 @param aType An enumeration which defines the type of comparison to be made
233 between two text keys.
234 @param aLength The length of the text key.
243 EXPORT_C TKeyArrayPak::TKeyArrayPak(TInt anOffset,TKeyCmpNumeric aType)
244 : TKeyArrayVar(anOffset,aType)
246 Constructs the characteristics of a numeric key.
248 @param anOffset The offset of the key from the start of an array element.
249 @param aType An enumeration which defines the type of the numeric key.
258 EXPORT_C void TKeyArrayPak::Set(CBufBase *aBase)
260 // Set the private variable iBase to aBase.
269 EXPORT_C TAny *TKeyArrayPak::At(TInt anIndex) const
271 // Return a pointer to the data in the record with index anIndex.
275 // When anIndex is equal to KIndexPtr (HighValues) this means that we should return the address of
276 // the iPtr+iKeyOffset which will have been set up by the TKeyArrayPak constructor.
278 if (anIndex==KIndexPtr)
279 return((TUint8 *)iPtr+iKeyOffset);
281 // Otherwise get the offset into the buffer of the record with index anIndex.
285 if (iCacheIndex<=anIndex)
287 curIndex=iCacheIndex;
290 TAny *pRecord=(TAny *)iBase->Ptr(offset).Ptr();
291 while (curIndex<anIndex)
293 TInt lenData=(*(TInt *)pRecord);
294 offset+=Align4(lenData)+sizeof(TUint);
295 pRecord=(TAny *)iBase->Ptr(offset).Ptr();
298 (TInt &)iCacheIndex=anIndex;
299 (TInt &)iCacheOffset=offset;
300 TAny *pData=(TAny *)((TInt *)pRecord + 1);
301 return((TUint8 *)pData+iKeyOffset);
304 EXPORT_C CArrayFixBase::CArrayFixBase(TBufRep aRep,TInt aRecordLength,TInt aGranularity)
313 __ASSERT_ALWAYS(aRecordLength>0,Panic(EArrayFixInvalidLength));
314 __ASSERT_ALWAYS(aGranularity>0,Panic(EArrayFixInvalidGranularity));
317 iLength=aRecordLength;
318 iGranularity=aGranularity;
322 EXPORT_C CArrayFixBase::~CArrayFixBase()
326 This frees all resources owned by the object, prior to its destruction.
333 EXPORT_C void CArrayFixBase::Compress()
335 Compresses the array.
337 The function removes the excess space from the array buffer. The effect is
338 to reduce the memory allocated to the array buffer so that it is just
339 sufficient to contain the elements of the array. This applies to both flat
340 and segmented array buffers.
342 If the array is empty, then the memory allocated to the array buffer is freed.
350 EXPORT_C void CArrayFixBase::Reset()
352 Deletes all elements from the array and frees the memory allocated
362 EXPORT_C TInt CArrayFixBase::Sort(TKeyArrayFix &aKey)
364 Sorts the elements of the array into key sequence.
366 @param aKey The key object defining the properties of the key.
368 @return KErrNone if the sort completes successfully.
369 KErrGeneral if the stack overflows
375 TSwapArray aSwap(iBase,iLength);
377 return(User::QuickSort(iCount,aKey,aSwap));
380 EXPORT_C TAny *CArrayFixBase::At(TInt anIndex) const
382 // Index into the array.
389 __ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
390 return((TAny *)iBase->Ptr(anIndex*iLength).Ptr());
393 EXPORT_C TAny *CArrayFixBase::End(TInt anIndex) const
395 // Return a pointer past contiguous elements starting at anIndex.
402 __ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
403 TPtr8 p=iBase->Ptr(anIndex*iLength);
404 return((TAny *)(p.Ptr()+p.Length()));
407 EXPORT_C TAny *CArrayFixBase::Back(TInt anIndex) const
409 // Return a pointer to contiguous elements before anIndex.
416 __ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
417 TPtr8 p=iBase->BackPtr(anIndex*iLength);
418 return((TAny *)p.Ptr());
421 EXPORT_C void CArrayFixBase::Delete(TInt anIndex)
423 Deletes a single element from the array at a specified position.
425 Deleting elements from the array does not cause the array buffer to be
426 automatically compressed. Call CArrayFixBase::Compress() to return excess space
429 @param anIndex The position within the array at which to delete the element,
430 This is a value relative to zero.
432 @panic E32USER-CBase 21, if anIndex is negative or is greater
433 than or equal to the number of elements currently
435 @see CArrayFixBase::Compress
442 EXPORT_C void CArrayFixBase::Delete(TInt anIndex,TInt aCount)
444 Deletes one or more contiguous elements from the array, starting at a specific
447 Deleting elements from the array does not cause the array buffer to be
448 automatically compressed. Call CArrayFixBase::Compress() to return excess space
451 @param anIndex The position within the array from where deletion of elements
452 is to start. The position is relative to zero, i.e. zero implies
453 that elements, starting with the first, are deleted from the
456 @param aCount The number of contiguous elements to be deleted from the array.
458 @panic E32USER-CBase 21, if anIndex is negative, or is greater than or equal to
459 the number of elements currently in the array.
460 @panic E32USER-CBase 22, if aCount is negative.
461 @panic E32USER-CBase 29, if the sum of anIndex and aCount is greater than or equal
462 to the number of elements currently in the array.
468 __ASSERT_ALWAYS(aCount>0,Panic(EArrayCountNegative));
469 __ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
470 __ASSERT_ALWAYS(anIndex+aCount<=iCount,Panic(EArrayCountTooBig));
471 iBase->Delete(anIndex*iLength,aCount*iLength);
475 EXPORT_C TAny *CArrayFixBase::ExpandL(TInt anIndex)
477 // Expand the array to make room for a new record at anIndex.
485 iBase=(*iCreateRep)(iLength*iGranularity);
486 __ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
487 iBase->ExpandL(anIndex*iLength,iLength);
489 return((TAny *)iBase->Ptr(anIndex*iLength).Ptr());
492 EXPORT_C TInt CArrayFixBase::Find(const TAny *aPtr,TKeyArrayFix &aKey,TInt &anIndex) const
494 // Find in the array using a sequential search.
512 TInt j=aKey.Compare(i,KIndexPtr);
524 EXPORT_C TInt CArrayFixBase::FindIsq(const TAny *aPtr,TKeyArrayFix &aKey,TInt &anIndex) const
526 // Find in the array using a binary search.
540 return(User::BinarySearch(Count(),aKey,anIndex));
543 EXPORT_C void CArrayFixBase::InsertL(TInt anIndex,const TAny *aPtr)
545 // Insert a record into the array.
552 InsertL(anIndex,aPtr,1);
555 EXPORT_C void CArrayFixBase::InsertL(TInt anIndex,const TAny *aPtr,TInt aCount)
557 // Insert aCount records into the array.
567 iBase=(*iCreateRep)(iLength*iGranularity);
568 __ASSERT_ALWAYS(aCount>0,Panic(EArrayCountNegative2));
569 __ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
570 iBase->InsertL(anIndex*iLength,aPtr,aCount*iLength);
574 EXPORT_C void CArrayFixBase::InsertRepL(TInt anIndex,const TAny *aPtr,TInt aReplicas)
576 // Insert aReplicas copies of a record into the array.
586 iBase=(*iCreateRep)(iLength*iGranularity);
587 __ASSERT_ALWAYS(aReplicas>0,Panic(EArrayReplicasNegative));
588 __ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
589 TInt pos=anIndex*iLength;
590 TInt len=aReplicas*iLength;
591 iBase->ExpandL(pos,len);
592 for (TInt end=pos+len;pos<end;pos+=iLength)
593 iBase->Write(pos,aPtr,iLength);
597 EXPORT_C TInt CArrayFixBase::InsertIsqL(const TAny *aPtr,TKeyArrayFix &aKey)
599 // Insert in sequence, no duplicates allowed.
607 TInt r=FindIsq(aPtr,aKey,i);
608 if (r==0) // a duplicate, leave
609 User::Leave(KErrAlreadyExists);
614 EXPORT_C TInt CArrayFixBase::InsertIsqAllowDuplicatesL(const TAny *aPtr,TKeyArrayFix &aKey)
616 // Insert in sequence, allow duplicates.
624 TInt r=FindIsq(aPtr,aKey,i);
625 if (r==0) // a duplicate, insert after
631 EXPORT_C void CArrayFixBase::ResizeL(TInt aCount,const TAny *aPtr)
633 // Resize the array to contain aCount records, copying a record into any new slots.
640 __ASSERT_ALWAYS(aCount>=0,Panic(EArrayCountNegative3));
641 TInt excess=iCount-aCount;
643 Delete(aCount,excess);
645 InsertRepL(iCount,aPtr,-excess);
648 EXPORT_C void CArrayFixBase::SetReserveFlatL(TInt aCount)
650 // Reserve space to contain aCount items. Only for flat arrays!
657 __ASSERT_ALWAYS(aCount>=iCount,Panic(EArrayReserveTooSmall));
659 iBase=(*iCreateRep)(iLength*iGranularity);
660 ((CBufFlat*)iBase)->SetReserveL(iLength*aCount); // dodgy cast. Can we assert the type?
663 EXPORT_C void CArrayFixBase::SetKey(TKeyArrayFix &aKey) const
672 aKey.Set(iBase,iLength);
675 EXPORT_C TInt CArrayFixBase::CountR(const CBase *aPtr)
677 // Return the number of items in the array.
684 return(((CArrayFixBase *)aPtr)->Count());
687 EXPORT_C const TAny *CArrayFixBase::AtR(const CBase *aPtr,TInt anIndex)
689 // Return the address of an item in the array.
696 return(((CArrayFixBase *)aPtr)->At(anIndex));
699 EXPORT_C CArrayVarBase::CArrayVarBase(TBufRep aRep,TInt aGranularity)
708 __ASSERT_ALWAYS(aGranularity>0,Panic(EArrayVarInvalidGranularity));
711 iGranularity=aGranularity;
715 EXPORT_C CArrayVarBase::~CArrayVarBase()
719 Frees all resources owned by the object, prior to its destruction.
730 EXPORT_C TInt CArrayVarBase::Length(TInt anIndex) const
732 Gets the length of a specific element.
734 @param anIndex The position of the element within the array. The position
735 is relative to zero, (i.e. the first element in the array is
738 @return The length of the element at position anIndex.
740 @panic E32USER-CBase 21, if anIndex is negative or is greater than the number
741 of elements currently in the array.
745 __ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
746 return(((SVarRec *)iBase->Ptr(anIndex*sizeof(SVarRec)).Ptr())->len);
749 EXPORT_C void CArrayVarBase::Compress()
751 Removes excess space from the array buffer.
753 The effect is to reduce the memory allocated to the array buffer so that it is
754 just sufficient to represent the array. This applies to both flat and segmented
757 If the array is empty, then the memory allocated to the array buffer is freed.
765 EXPORT_C void CArrayVarBase::Reset()
767 Deletes all elements from the array and frees the memory allocated to the array
770 As each element of a variable array is contained within its own heap cell,
771 this function has the effect of freeing all such cells.
778 EXPORT_C TInt CArrayVarBase::Sort(TKeyArrayVar &aKey)
780 Sorts the elements of the array into key sequence.
782 @param aKey The key object defining the properties of the key.
784 @return KErrNone, if the sort completes successfully.
785 KErrGeneral, if the stack overflows.
791 TSwapArray aSwap(iBase,sizeof(SVarRec));
793 return(User::QuickSort(iCount,aKey,aSwap));
796 EXPORT_C TAny * CArrayVarBase::At(TInt anIndex) const
798 // Return a pointer to the data in the array.
805 __ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
806 return(((SVarRec *)iBase->Ptr(anIndex*sizeof(SVarRec)).Ptr())->data);
809 EXPORT_C void CArrayVarBase::Delete(TInt anIndex)
811 Removes one element from the array.
813 Deleting elements from the array does not cause the array buffer to be
814 automatically compressed. Call CArrayVarBase::Compress() to return excess
817 @param anIndex The position within the array of the element to delete. The
818 position is relative to zero.
820 @panic E32USER-CBase 21, if anIndex is negative or greater than the number
821 of elements currently in the array.
828 EXPORT_C void CArrayVarBase::Delete(TInt anIndex,TInt aCount)
830 Removes one or more contiguous elements from the array, starting at the
833 Deleting elements from the array does not cause the array buffer to be
834 automatically compressed. Call CArrayVarBase::Compress() to return excess
837 @param anIndex The position within the array from where deletion of elements is
838 to start. The position is relative to zero, i.e. zero implies
839 that elements, starting with the first, are deleted from the
842 @param aCount The number of elements to be deleted from the array.
844 @panic E32USER-CBase 21, if anIndex is negative or greater than or equal to the
845 number of elements currently in the array.
846 @panic E32USER-CBase 25, if aCount is negative.
847 @panic E32USER-CBase 29, if the sum of anIndexPos and aCount is greater than
848 the number of elements currently in the array.
854 __ASSERT_ALWAYS(aCount>0,Panic(EArrayCountNegative4));
855 __ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
856 TInt end=anIndex+aCount;
857 __ASSERT_ALWAYS(end<=iCount,Panic(EArrayCountTooBig));
858 for (TInt i=anIndex;i<end;i++)
860 TPtr8 p=iBase->Ptr(i*sizeof(SVarRec));
861 User::Free(((SVarRec *)p.Ptr())->data);
863 iBase->Delete(anIndex*sizeof(SVarRec),aCount*sizeof(SVarRec));
867 EXPORT_C TAny *CArrayVarBase::ExpandL(TInt anIndex,TInt aLength)
869 // Expand the array at anIndex.
877 iBase=(*iCreateRep)(sizeof(SVarRec)*iGranularity);
878 __ASSERT_ALWAYS(aLength>=0,Panic(EArrayLengthNegative));
879 __ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
880 TAny *pV=User::AllocL(aLength);
884 TRAPD(r,iBase->InsertL(anIndex*sizeof(SVarRec),&s,sizeof(SVarRec)));
894 EXPORT_C TInt CArrayVarBase::Find(const TAny *aPtr,TKeyArrayVar &aKey,TInt &anIndex) const
896 // Find using a sequential search.
914 TInt j=aKey.Compare(i,KIndexPtr);
926 EXPORT_C TInt CArrayVarBase::FindIsq(const TAny *aPtr,TKeyArrayVar &aKey,TInt &anIndex) const
928 // Find using a binary search.
942 return(User::BinarySearch(Count(),aKey,anIndex));
945 EXPORT_C void CArrayVarBase::InsertL(TInt anIndex,const TAny *aPtr,TInt aLength)
947 // Insert a new record in the array.
954 TAny *pV=ExpandL(anIndex,aLength);
955 Mem::Copy(pV,aPtr,aLength);
958 EXPORT_C TInt CArrayVarBase::InsertIsqL(const TAny *aPtr,TInt aLength,TKeyArrayVar &aKey)
960 // Insert in sequence, no duplicates allowed.
968 TInt r=FindIsq(aPtr,aKey,i);
969 if (r==0) // a duplicate, leave
970 User::Leave(KErrAlreadyExists);
971 InsertL(i,aPtr,aLength);
975 EXPORT_C TInt CArrayVarBase::InsertIsqAllowDuplicatesL(const TAny *aPtr,TInt aLength,TKeyArrayVar &aKey)
977 // Insert in sequence, allow duplicates.
985 TInt r=FindIsq(aPtr,aKey,i);
986 if (r==0) // a duplicate, insert after
988 InsertL(i,aPtr,aLength);
992 EXPORT_C void CArrayVarBase::SetKey(TKeyArrayVar &aKey) const
1004 EXPORT_C TInt CArrayVarBase::CountR(const CBase *aPtr)
1006 // Return the number of items in the array.
1013 return(((CArrayVarBase *)aPtr)->Count());
1016 EXPORT_C const TAny *CArrayVarBase::AtR(const CBase *aPtr,TInt anIndex)
1018 // Return the address of an item in the array.
1025 return(((CArrayVarBase *)aPtr)->At(anIndex));
1028 EXPORT_C CArrayPakBase::CArrayPakBase(TBufRep aRep,TInt aGranularity)
1037 __ASSERT_ALWAYS(aGranularity>0,Panic(EArrayPakInvalidGranularity));
1040 iGranularity=aGranularity;
1044 EXPORT_C CArrayPakBase::~CArrayPakBase()
1048 Frees all resources owned by the object, prior to its destruction.
1059 EXPORT_C TInt CArrayPakBase::Length(TInt anIndex) const
1061 Gets the length of the specified element.
1063 @param anIndex The position of the element within the array. The position
1064 is relative to zero, (i.e. the first element in the array is
1067 @return The length of the element at position anIndex.
1069 @panic E32USER-CBase 21, if anIndex is negative or is greater than the number
1070 of elements currently in the array.
1074 __ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
1075 return(*((TInt *)iBase->Ptr(GetOffset(anIndex)).Ptr()));
1078 EXPORT_C void CArrayPakBase::Compress()
1080 Removes excess space from the array buffer.
1082 The effect is to reduce the memory allocated to the array buffer so that it
1083 is just sufficient to contain the elements of the array.
1085 If the array is empty, then the memory allocated to the array buffer is freed.
1093 EXPORT_C void CArrayPakBase::Reset()
1095 Deletes all elements from the array and frees the memory allocated to the array
1103 EXPORT_C void CArrayPakBase::SortL(TKeyArrayVar &aKey)
1105 // Builds a transient CArrayVarFlat array, sorts it
1106 // and then copies it back to the original array.
1109 Sorts the elements of the array into key sequence.
1111 Note that the function requires a TKeyArrayVar key object because SortL()
1112 creates a temporary CArrayVarFlat array in its implementation and uses that array's
1113 Sort() member function.
1115 @param aKey The key object defining the properties of the key.
1124 // First build a variable length flat array.
1126 CArrayVarFlat<TAny> *pVarFlat=NULL;
1127 TRAPD(r,BuildVarArrayL(pVarFlat))
1133 r=pVarFlat->Sort(aKey);
1137 // Delete the records and copy back from pVarFlat.
1139 Reset(); // Deletes the records but leaves the memory
1140 TInt tCount=pVarFlat->Count();
1141 for (TInt anIndex=0;anIndex<tCount;anIndex++)
1143 TInt lenData=pVarFlat->Length(anIndex);
1144 TAny *pdata=pVarFlat->At(anIndex);
1145 TRAP(r,InsertL(anIndex,pdata,lenData));
1152 User::LeaveIfError(r);
1155 EXPORT_C TAny *CArrayPakBase::At(TInt anIndex) const
1157 // TAny points to the data associated with the record with anIndex.
1164 __ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
1165 TInt *pR=(TInt *)iBase->Ptr(GetOffset(anIndex)).Ptr();
1166 return((TAny *)(pR+1));
1169 EXPORT_C void CArrayPakBase::Delete(TInt anIndex)
1171 Removes a single element from the array.
1173 Deleting elements from the array does not cause the array buffer to be
1174 automatically compressed. Call CArrayPakBase::Compress() to return excess
1177 @param anIndex The position within the array of the element to delete, relative
1179 @panic E32USER-CBase 21, if anIndex is negative or is greater than the
1180 number of elements currently in the array.
1182 @see CArrayPakBase::Compress
1189 EXPORT_C void CArrayPakBase::Delete(TInt anIndex,TInt aCount)
1191 Removes one or more contiguous elements from the array, starting at a specific
1194 Deleting elements from the array does not cause the array buffer to be
1195 automatically compressed. Call CArrayPakBase::Compress() to return excess
1198 @param anIndex The position within the array from where deletion of elements
1199 is to start, relative to zero.
1201 @param aCount The number of elements to be deleted from the array.
1203 @panic E32USER-CBase 21, if anIndex is negative or greater than the number of
1204 elements currently in the array.
1205 @panic E32USER-CBase 26, if aCount is negative.
1207 @see CArrayPakBase::Compress
1213 __ASSERT_ALWAYS(aCount>0,Panic(EArrayCountNegative5));
1214 __ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
1215 TInt end=anIndex+aCount;
1216 __ASSERT_ALWAYS(end<=iCount,Panic(EArrayCountTooBig));
1217 TInt totalToDelete=0;
1218 TInt firstRecOffset=0;
1219 for (TInt i=anIndex;i<end;i++)
1221 TInt offset=GetOffset(i);
1224 firstRecOffset=offset;
1226 iCacheOffset=offset;
1228 TAny *pRecord=(TAny *)iBase->Ptr(offset).Ptr();
1229 TInt lenData=(*(TInt *)pRecord);
1230 totalToDelete+=Align4(lenData)+sizeof(TUint);
1232 iBase->Delete(firstRecOffset,totalToDelete);
1236 EXPORT_C TAny *CArrayPakBase::ExpandL(TInt anIndex,TInt aLength)
1238 // Expand the array at anIndex.
1246 iBase=(*iCreateRep)(iGranularity);
1247 __ASSERT_ALWAYS(aLength>=0,Panic(EArrayLengthNegative));
1248 __ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
1249 TInt offset=GetOffset(anIndex);
1250 iCacheIndex=anIndex;
1251 iCacheOffset=offset;
1252 iBase->ExpandL(offset,Align4(aLength+sizeof(TInt)));
1253 TInt *pR=(TInt *)iBase->Ptr(offset).Ptr();
1256 return((TAny *)(pR+1));
1259 EXPORT_C TInt CArrayPakBase::Find(const TAny *aPtr,TKeyArrayPak &aKey,TInt &anIndex) const
1261 // Find using a sequential search.
1279 TInt j=aKey.Compare(i,KIndexPtr);
1291 EXPORT_C TInt CArrayPakBase::FindIsq(const TAny *aPtr,TKeyArrayPak &aKey,TInt &anIndex) const
1293 // Find using a binary search.
1307 return(User::BinarySearch(Count(),aKey,anIndex));
1310 EXPORT_C void CArrayPakBase::InsertL(TInt anIndex,const TAny *aPtr,TInt aLength)
1312 // Inserts a record at index anIndex.
1319 TAny *pV=ExpandL(anIndex,aLength);
1320 Mem::Copy(pV,aPtr,aLength);
1323 EXPORT_C TInt CArrayPakBase::InsertIsqL(const TAny *aPtr,TInt aLength,TKeyArrayPak &aKey)
1325 // Insert in sequence, no duplicates allowed.
1333 TInt r=FindIsq(aPtr,aKey,i);
1334 if (r==0) // a duplicate, leave
1335 User::Leave(KErrAlreadyExists);
1336 InsertL(i,aPtr,aLength);
1340 EXPORT_C TInt CArrayPakBase::InsertIsqAllowDuplicatesL(const TAny *aPtr,TInt aLength,TKeyArrayPak &aKey)
1342 // Insert in sequence, allow duplicates.
1350 TInt r=FindIsq(aPtr,aKey,i);
1351 if (r==0) // a duplicate, insert after
1353 InsertL(i,aPtr,aLength);
1357 EXPORT_C void CArrayPakBase::SetKey(TKeyArrayPak &aKey) const
1359 // Set the key data.
1369 EXPORT_C TInt CArrayPakBase::GetOffset(TInt anIndex) const
1371 // Return the offset into the buffer of the record with index anIndex;
1380 if (iCacheIndex<=anIndex)
1382 curIndex=iCacheIndex;
1383 offset=iCacheOffset;
1385 TAny *pRecord=(TAny *)iBase->Ptr(offset).Ptr();
1386 while (curIndex<anIndex)
1388 TInt lenData=(*(TInt *)pRecord);
1389 offset+=Align4(lenData)+sizeof(TUint);
1390 pRecord=(TAny *)iBase->Ptr(offset).Ptr();
1393 (TInt &)iCacheIndex=anIndex;
1394 (TInt &)iCacheOffset=offset;
1398 EXPORT_C void CArrayPakBase::BuildVarArrayL(CArrayVarFlat<TAny> * &aVarFlat)
1400 // Make a copy of the current array as a CArrayVarFlat
1407 aVarFlat=new(ELeave) CArrayVarFlat<TAny>(iGranularity);
1408 for (TInt anIndex=0;anIndex<iCount;anIndex++)
1410 TInt offset=GetOffset(anIndex);
1411 TAny *pRecord=(TAny *)iBase->Ptr(offset).Ptr();
1412 TInt lengthData=(*(TInt *)pRecord);
1413 TAny *pData=(TAny *)((TInt *)pRecord+1);
1414 aVarFlat->InsertL(anIndex,pData,lengthData);
1418 EXPORT_C TInt CArrayPakBase::CountR(const CBase *aPtr)
1420 // Return the number of items in the array.
1427 return(((CArrayPakBase *)aPtr)->Count());
1430 EXPORT_C const TAny *CArrayPakBase::AtR(const CBase *aPtr,TInt anIndex)
1432 // Return the address of an item in the array.
1439 return(((CArrayPakBase *)aPtr)->At(anIndex));
1442 EXPORT_C CArrayFixFlat<TInt>::CArrayFixFlat(TInt aGranularity)
1443 : CArrayFix<TInt>((TBufRep)CBufFlat::NewL,aGranularity)
1445 Constructs the array, with the specified granularity, to contain elements of
1448 Note that no memory is allocated to the array buffer by this C++ constructor.
1450 @param aGranularity The granularity of the array.
1452 @panic E32USER-CBase 18 if aGranularity is not positive.
1456 EXPORT_C CArrayFixFlat<TInt>::~CArrayFixFlat()
1462 EXPORT_C CArrayFixFlat<TUid>::CArrayFixFlat(TInt aGranularity)
1463 : CArrayFix<TUid>((TBufRep)CBufFlat::NewL,aGranularity)
1465 Constructs the array, with the specified granularity, to contain elements of
1468 Note that no memory is allocated to the array buffer by this C++ constructor.
1470 @param aGranularity The granularity of the array.
1472 @panic E32USER-CBase 18 if aGranularity is not positive.
1476 EXPORT_C CArrayFixFlat<TUid>::~CArrayFixFlat()