|         |      1 // Copyright (c) 2006-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 "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". | 
|         |      7 // | 
|         |      8 // Initial Contributors: | 
|         |      9 // Nokia Corporation - initial contribution. | 
|         |     10 // | 
|         |     11 // Contributors: | 
|         |     12 // | 
|         |     13 // Description: | 
|         |     14 // IMAP Folder indexing | 
|         |     15 //  | 
|         |     16 // | 
|         |     17  | 
|         |     18 #include "imappaniccodes.h" | 
|         |     19 #include "cimapfolderindex.h" | 
|         |     20  | 
|         |     21 // Illegal UID we use for marker | 
|         |     22 const TUint KIllegalUID	 = 0xffffffff; | 
|         |     23  | 
|         |     24 CImapFolderIndexEntry::CImapFolderIndexEntry() | 
|         |     25 	{ | 
|         |     26 	// Default values | 
|         |     27 	iUid = 0; | 
|         |     28 	iMsvId = -1; | 
|         |     29 	} | 
|         |     30  | 
|         |     31 CImapFolderIndexEntry::CImapFolderIndexEntry(CImapFolderIndexEntry& aFrom) | 
|         |     32 	{ | 
|         |     33 	// Copy entry | 
|         |     34 	iUid = aFrom.iUid; | 
|         |     35 	iMsvId = aFrom.iMsvId; | 
|         |     36 	} | 
|         |     37  | 
|         |     38 CImapFolderIndexEntry& CImapFolderIndexEntry::operator = (CImapFolderIndexEntry& aFrom) | 
|         |     39 	{ | 
|         |     40 	// Copy entry | 
|         |     41 	iUid = aFrom.iUid; | 
|         |     42 	iMsvId = aFrom.iMsvId; | 
|         |     43 	return(*this); | 
|         |     44 	} | 
|         |     45  | 
|         |     46 CImapFolderIndex::CImapFolderIndex() | 
|         |     47 	{ | 
|         |     48 	__DECLARE_NAME(_S("CImapFolderIndex")); | 
|         |     49 	} | 
|         |     50  | 
|         |     51 CImapFolderIndex::~CImapFolderIndex() | 
|         |     52 	{ | 
|         |     53 	// Dispose of index | 
|         |     54 	delete iIndex; | 
|         |     55 	} | 
|         |     56  | 
|         |     57 void CImapFolderIndex::Reset() | 
|         |     58 	{ | 
|         |     59 	// Dispose of index | 
|         |     60 	delete iIndex; | 
|         |     61 	iIndex = NULL; | 
|         |     62 	iSize = 0; | 
|         |     63 	} | 
|         |     64  | 
|         |     65 void CImapFolderIndex::SetSizeL(const TUint aEntries) | 
|         |     66 	{ | 
|         |     67 	// Set number of entries | 
|         |     68 	if (!iIndex) | 
|         |     69 		{ | 
|         |     70 		// Create new array (granularity 8 entries) | 
|         |     71 		iIndex = new (ELeave) CArrayFixFlat<CImapFolderIndexEntry>(8); | 
|         |     72 		} | 
|         |     73  | 
|         |     74 	// Alter size, filling unused entries with 0xffffffff | 
|         |     75 	CImapFolderIndexEntry blank; | 
|         |     76 	blank.iUid = KIllegalUID; | 
|         |     77 	blank.iMsvId = 0; | 
|         |     78 	iIndex->ResizeL(aEntries,blank); | 
|         |     79  | 
|         |     80 	// Save new size | 
|         |     81 	iSize = aEntries; | 
|         |     82 	} | 
|         |     83  | 
|         |     84 TInt CImapFolderIndex::Size() const | 
|         |     85 	{ | 
|         |     86 	// Return current size | 
|         |     87 	return(iSize); | 
|         |     88 	} | 
|         |     89  | 
|         |     90 void CImapFolderIndex::SetUid(const TUint aMsgNr, const TUint aMsgUid) | 
|         |     91 	{ | 
|         |     92 	__ASSERT_ALWAYS(aMsgNr <= TUint(iSize),User::Panic(_L("CImapFolderIndex"), TImapServerPanic::EMsgnrOutOfRange)); | 
|         |     93  | 
|         |     94 	// Is UID already set? | 
|         |     95 	if ((*iIndex)[aMsgNr-1].iUid != KIllegalUID && (*iIndex)[aMsgNr-1].iUid != aMsgUid) | 
|         |     96 		{ | 
|         |     97 		// CHANGING a UID? No way! | 
|         |     98 		User::Panic(_L("CImapFolderIndex"),TImapServerPanic::ECantChangeUID); | 
|         |     99 		} | 
|         |    100  | 
|         |    101 	// Set a UID for a message number | 
|         |    102 	(*iIndex)[aMsgNr-1].iUid = aMsgUid; | 
|         |    103 	} | 
|         |    104  | 
|         |    105 void CImapFolderIndex::SetMsvId(const TUint aMsgNr, const TMsvId aMsvId) | 
|         |    106 	{ | 
|         |    107 	__ASSERT_ALWAYS(aMsgNr <= TUint(iSize),User::Panic(_L("CImapFolderIndex"), TImapServerPanic::EMsgnrOutOfRange)); | 
|         |    108  | 
|         |    109 	// Is MsvId already set? | 
|         |    110 	if ((*iIndex)[aMsgNr-1].iMsvId != 0 && (*iIndex)[aMsgNr-1].iMsvId != aMsvId) | 
|         |    111 		{ | 
|         |    112 		// CHANGING a MsvId? No way! | 
|         |    113 		User::Panic(_L("CImapFolderIndex"), TImapServerPanic::ECantChangeMsvId); | 
|         |    114 		} | 
|         |    115  | 
|         |    116 	// Set a MsvId for a message number | 
|         |    117 	(*iIndex)[aMsgNr-1].iMsvId = aMsvId; | 
|         |    118 	} | 
|         |    119  | 
|         |    120 void CImapFolderIndex::Expunge(const TUint aMsgNr) | 
|         |    121 	{ | 
|         |    122 	__ASSERT_ALWAYS(aMsgNr <= TUint(iSize),User::Panic(_L("CImapFolderIndex"),TImapServerPanic::EMsgnrOutOfRange)); | 
|         |    123  | 
|         |    124 	// Remove entry from index | 
|         |    125 	iIndex->Delete(aMsgNr-1); | 
|         |    126 	iSize--; | 
|         |    127 	} | 
|         |    128  | 
|         |    129 TUint CImapFolderIndex::FindMsg(const TUint aMsgUid) | 
|         |    130 	{ | 
|         |    131 	__ASSERT_ALWAYS(iSize>0,User::Panic(_L("CImapFolderIndex"),TImapServerPanic::EIndexEmpty)); | 
|         |    132  | 
|         |    133 	// Binary search. | 
|         |    134 	TInt max = iIndex->Count() - 1;   //max index | 
|         |    135 	TInt min = 0;   //min index | 
|         |    136 	TInt index; | 
|         |    137  | 
|         |    138 	index = max/2; | 
|         |    139  | 
|         |    140 	while (((*iIndex)[index].iUid != aMsgUid) && (min <= max)) | 
|         |    141 		{ | 
|         |    142 		if ((*iIndex)[index].iUid > aMsgUid) | 
|         |    143 			{ | 
|         |    144 		    max = --index; | 
|         |    145 		    } | 
|         |    146 		else | 
|         |    147 			{ | 
|         |    148 		    min = ++index; | 
|         |    149 		    } | 
|         |    150  | 
|         |    151 		index = (max + min)/2; | 
|         |    152 		} | 
|         |    153  | 
|         |    154 	if(index < iIndex->Count()) | 
|         |    155 		{ | 
|         |    156 		if((*iIndex)[index].iUid == aMsgUid) | 
|         |    157 			{ | 
|         |    158 			return(++index); | 
|         |    159 			} | 
|         |    160 		} | 
|         |    161 		 | 
|         |    162 	// Failure (0 not a legal message number) | 
|         |    163 	return(0); | 
|         |    164 	} | 
|         |    165  | 
|         |    166 // Access entry directly | 
|         |    167 CImapFolderIndexEntry& CImapFolderIndex::operator[] (const TInt aIndex) | 
|         |    168 	{ | 
|         |    169 	return((*iIndex)[aIndex]); | 
|         |    170 	} | 
|         |    171  | 
|         |    172 // Sort index by UID | 
|         |    173 void CImapFolderIndex::Sort() | 
|         |    174 	{ | 
|         |    175 	// Sorting object | 
|         |    176 	TKeyArrayFix uidKey(_FOFF(CImapFolderIndexEntry,iUid),ECmpTUint32); | 
|         |    177  | 
|         |    178 	// Perform the sort | 
|         |    179 	iIndex->Sort(uidKey); | 
|         |    180 	} |