|
1 // Copyright (c) 2001-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 "Symbian Foundation License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #ifndef __STRINGPOOLIMPLEMENTATION_H__ |
|
17 #define __STRINGPOOLIMPLEMENTATION_H__ |
|
18 |
|
19 #include <e32base.h> |
|
20 #include <stringpool.h> |
|
21 #include <stringtablesupport.h> |
|
22 |
|
23 /** |
|
24 This is an 8 bit value with every bit set except bit 5 (value |
|
25 32). The ASCII codes of upper and lower case characters differ by |
|
26 32. |
|
27 @internalComponent |
|
28 */ |
|
29 const TUint KCaseInsensitive = 223; |
|
30 |
|
31 /** |
|
32 @internalComponent |
|
33 */ |
|
34 const TInt KHashModulo = 32; |
|
35 |
|
36 /** |
|
37 Bit 0 represents if it is a table (set) or not (unset). |
|
38 Bit 1 represents case sensitivity (set) or not (unset) |
|
39 |
|
40 For non-static table values (dynamic strings), the remaining bits |
|
41 are interpreted as a pointer to a CStringPoolNode (which is assumed |
|
42 to be word aligned). |
|
43 |
|
44 Bits 2-20 represent the table index. |
|
45 Bits 21-31 represent the table uid (that is the address of the table). |
|
46 */ |
|
47 |
|
48 /** |
|
49 Bit 1 is used in tokens to indicate case sensitivity. So mask it |
|
50 out to get the node. |
|
51 @internalComponent |
|
52 */ |
|
53 const TUint KTokenToNode = 0xfffffffd; |
|
54 |
|
55 /** |
|
56 Determine if this id corresponds to a table. |
|
57 @internalComponent |
|
58 */ |
|
59 #define IS_TABLE_ENTRY(tableId)(tableId & 0x01) |
|
60 |
|
61 /** |
|
62 Obtain the Table Index. |
|
63 @internalComponent |
|
64 */ |
|
65 #define TABLE_INDEX(val)((val & 0xffffc)>>2) |
|
66 |
|
67 /** |
|
68 Obtain the Table UID. |
|
69 @internalComponent |
|
70 */ |
|
71 #define TABLE_UID(val)(val>>20) |
|
72 |
|
73 /** |
|
74 This is used to mark the reference count of a node so that is will not be deleted when closed |
|
75 @internalComponent |
|
76 */ |
|
77 const TUint KMarkedForNoDeleted = 0xffff; |
|
78 |
|
79 |
|
80 |
|
81 class RStringTokenEither; |
|
82 |
|
83 /** |
|
84 @internalComponent |
|
85 */ |
|
86 struct TStringIdMap |
|
87 { |
|
88 TInt32 iSourceTableVal; |
|
89 TInt32 iTargetTableVal; |
|
90 }; |
|
91 |
|
92 |
|
93 /** |
|
94 Internal node class |
|
95 @internalComponent |
|
96 */ |
|
97 NONSHARABLE_CLASS(CStringPoolNode) : public CBase |
|
98 { |
|
99 public: |
|
100 ~CStringPoolNode(); |
|
101 |
|
102 public: |
|
103 HBufC8* iDes; |
|
104 TUint16 iRefcount; |
|
105 TUint8 iHash; |
|
106 }; |
|
107 |
|
108 /** |
|
109 @internalComponent |
|
110 */ |
|
111 NONSHARABLE_CLASS(CStringPoolImplementation) : public CBase |
|
112 { |
|
113 public: |
|
114 CStringPoolImplementation(); |
|
115 /// Destructor |
|
116 ~CStringPoolImplementation(); |
|
117 |
|
118 /// Constructs a string pool |
|
119 static CStringPoolImplementation* NewL(); |
|
120 |
|
121 // USed for cleaning up when a OpenTableL leaves |
|
122 static void CleanupHashCS(TAny* aImplementation); |
|
123 static void CleanupHashCI(TAny* aImplementation); |
|
124 static void CleanupIdMap(TAny* aImplementation); |
|
125 static void CleanUpHash(RPointerArray <RStringTokenEither>* aHashCleanup, CArrayFixSeg<RStringTokenEither>* hash[KHashModulo]); |
|
126 |
|
127 /// Adds a table to the pool. (Note this currently only works once) |
|
128 void AddTableL(const TStringTable& aTable); |
|
129 void AddCallBackL( MStringPoolCloseCallBack& aCallBack); |
|
130 |
|
131 |
|
132 // Find FirstVal given duplicate val |
|
133 TInt32 FindFirstValFromDuplicate(TInt32 aDuplicateVal) const; |
|
134 |
|
135 // Find table index Val given first val & table UID |
|
136 TInt FindTableIndexFromFirstVal(TInt32 aDuplicateVal, TInt aTableUid) const; |
|
137 |
|
138 |
|
139 TInt16 TableUid(const TStringTable& aTable) const; |
|
140 |
|
141 const TStringTable& TableRef(TInt32 aVal) const; |
|
142 |
|
143 /// Looks up a particular index in the pre-loaded tables |
|
144 const TDesC8& TableLookup(TInt aIndex, TInt aTableUid) const; |
|
145 |
|
146 /// Finds or creates a string. Increments the reference count if needed. |
|
147 RStringTokenEither OpenL( const TDesC8& aString, TBool aCaseInsensitive); |
|
148 |
|
149 /// Closes a string (decrements the reference count and deletes if 0 |
|
150 void Close(RStringTokenEither aString); |
|
151 |
|
152 /// Increments the reference count on a string |
|
153 void IncrementCount(RStringTokenEither aString); |
|
154 |
|
155 inline RStringPool Handle(); |
|
156 |
|
157 private: |
|
158 |
|
159 // Check for any undeletable string and delete them now |
|
160 void DeleteUndeletableStrings(CArrayFixSeg<RStringTokenEither>* aArray[KHashModulo], TInt i); |
|
161 |
|
162 private: |
|
163 |
|
164 /// Finds a string in the pool. |
|
165 RStringTokenEither FindDes( const TDesC8& aString, TBool aCaseInsensitive); |
|
166 |
|
167 /// Calculates a hash for a descriptor |
|
168 TUint Hash( const TDesC8& ) const; |
|
169 |
|
170 static TBool CompareCS(const TDesC8& s1, const TDesC8& s2); |
|
171 static TBool CompareCI(const TDesC8& s1, const TDesC8& s2); |
|
172 |
|
173 private: |
|
174 /// The table. |
|
175 CArrayFixSeg<RStringTokenEither>* iCSHashTable[KHashModulo]; |
|
176 CArrayFixSeg<RStringTokenEither>* iCIHashTable[KHashModulo]; |
|
177 RPointerArray<TStringTable> iTablePtrs; // Stores array of tables, where the index is the table UID |
|
178 RArray <TStringIdMap> iStringMapList; |
|
179 RArray <TStringIdMap> iStringMapListReverse; |
|
180 |
|
181 // For rolling back when a leave occurs during CreateTableL |
|
182 RPointerArray <TStringIdMap> iRollbackMapList; |
|
183 RPointerArray <RStringTokenEither> iRollbackHashListCS; |
|
184 RPointerArray <RStringTokenEither> iRollbackHashListCI; |
|
185 RPointerArray<MStringPoolCloseCallBack> iCallBacks; |
|
186 }; |
|
187 |
|
188 /** |
|
189 An internal version of the string token class. This class can hold |
|
190 either folding or non-folding versions, and it is up to the user |
|
191 to get it right. |
|
192 @internalComponent |
|
193 */ |
|
194 class RStringTokenEither : public RStringTokenBase |
|
195 { |
|
196 public: |
|
197 inline RStringTokenEither(); |
|
198 |
|
199 inline RStringTokenEither(TUint32 aVal); |
|
200 |
|
201 /** Comparison operator |
|
202 @param aVal The string to compare. */ |
|
203 inline TBool operator==(RStringTokenEither aVal) const; |
|
204 |
|
205 /** Comparison operator |
|
206 @param aVal The string to compare. */ |
|
207 inline TBool operator!=(RStringTokenEither aVal) const; |
|
208 |
|
209 /** Assignment operator; makes a string token from a string. |
|
210 @param aVal The string to copy */ |
|
211 inline RStringTokenEither operator=(RStringBase aVal); |
|
212 |
|
213 friend class RStringPool; |
|
214 friend class RStringEither; |
|
215 friend class CStringPoolImplementation; |
|
216 }; |
|
217 |
|
218 class RStringEither : public RStringBase |
|
219 /** |
|
220 @internalComponent |
|
221 */ |
|
222 { |
|
223 public: |
|
224 RStringEither(CStringPoolImplementation* aPool, RStringTokenEither aVal); |
|
225 }; |
|
226 |
|
227 class StringUtils |
|
228 /** |
|
229 @internalComponent |
|
230 */ |
|
231 { |
|
232 public: |
|
233 static inline TBool IsTableEntry(TInt aVal); |
|
234 static inline TInt TableIndex(TInt aVal); |
|
235 static inline TInt16 TableUid(TInt aVal); |
|
236 static inline CStringPoolNode* NodePtr(TInt aVal); |
|
237 static TInt ValFromIndex(TInt aIndex, TUint16 aTableId); |
|
238 static TInt ValFromIndexF(TInt aIndex, TUint16 aTableId); |
|
239 static TInt ValFromIndex(TInt aIndex, TUint16 aTableId, TBool aCaseSensitive); |
|
240 |
|
241 static void LogIt(TRefByValue<const TDesC8> aFmt, ...); |
|
242 static void LogIt1(TRefByValue<const TDesC8> aFmt); |
|
243 }; |
|
244 |
|
245 #ifndef __TOOLS2__ |
|
246 #define _LOGGING |
|
247 #endif |
|
248 |
|
249 #if defined (_DEBUG) && defined (_LOGGING) |
|
250 |
|
251 /** |
|
252 HTTP Logging macros |
|
253 @internalComponent |
|
254 */ |
|
255 #define __LOG(C) StringUtils::LogIt1(C); |
|
256 #define __LOG1(C, X) StringUtils::LogIt(C, X); |
|
257 #define __LOG2(C, X, Y) StringUtils::LogIt(C, X, Y); |
|
258 #define __LOG3(C, X, Y, Z) StringUtils::LogIt(C, X, Y, Z); |
|
259 |
|
260 #else |
|
261 |
|
262 /** |
|
263 NULL macros |
|
264 @internalComponent |
|
265 */ |
|
266 #define __LOG(C) |
|
267 #define __LOG1(C, X) |
|
268 #define __LOG2(C, X, Y) |
|
269 #define __LOG3(C, X, Y, Z) |
|
270 #endif // !_DEBUG |
|
271 |
|
272 |
|
273 inline TBool StringUtils::IsTableEntry(TInt aVal) |
|
274 { |
|
275 return IS_TABLE_ENTRY(aVal); |
|
276 } |
|
277 |
|
278 inline TInt StringUtils::TableIndex(TInt aVal) |
|
279 { |
|
280 return TABLE_INDEX(aVal); |
|
281 } |
|
282 |
|
283 inline TInt16 StringUtils::TableUid(TInt aVal) |
|
284 { |
|
285 return (TInt16) TABLE_UID(aVal); |
|
286 } |
|
287 |
|
288 inline CStringPoolNode* StringUtils::NodePtr(TInt aVal) |
|
289 { |
|
290 return reinterpret_cast<CStringPoolNode*>(aVal & KTokenToNode); |
|
291 } |
|
292 |
|
293 inline RStringEither::RStringEither(CStringPoolImplementation* aPool, |
|
294 RStringTokenEither aVal) |
|
295 { |
|
296 iPool = aPool->Handle(); |
|
297 iVal = aVal.iVal; |
|
298 } |
|
299 |
|
300 inline RStringPool CStringPoolImplementation::Handle() |
|
301 { |
|
302 RStringPool p; |
|
303 p.iImplementation = this; |
|
304 return p; |
|
305 } |
|
306 |
|
307 inline RStringTokenEither::RStringTokenEither() |
|
308 { |
|
309 } |
|
310 |
|
311 inline RStringTokenEither::RStringTokenEither(TUint32 aVal) |
|
312 { |
|
313 iVal = aVal; |
|
314 } |
|
315 |
|
316 inline TBool RStringTokenEither::operator==(RStringTokenEither aVal) const |
|
317 { |
|
318 return iVal == aVal.iVal; |
|
319 } |
|
320 |
|
321 inline TBool RStringTokenEither::operator!=(RStringTokenEither aVal) const |
|
322 { |
|
323 return iVal != aVal.iVal; |
|
324 } |
|
325 |
|
326 inline RStringTokenEither RStringTokenEither::operator=(RStringBase aVal) |
|
327 { |
|
328 RStringTokenBase b = aVal; |
|
329 iVal = b.iVal; |
|
330 return *this; |
|
331 } |
|
332 |
|
333 |
|
334 #endif // __STRINGPOOLIMPLEMENTATION_H__ |