symport/bafl/src/stringpoolimplementation.h
changeset 1 0a7b44b10206
child 2 806186ab5e14
equal deleted inserted replaced
0:c55016431358 1:0a7b44b10206
       
     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__