1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/lowlevellibsandfws/apputils/src/StringPoolAPI.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,292 @@
1.4 +// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <e32std.h>
1.20 +#include "StringPoolImplementation.h"
1.21 +
1.22 +
1.23 +
1.24 +EXPORT_C void RStringBase::Close()
1.25 +/** Closes a string.
1.26 +
1.27 +You must close every string you open. In other words, every call to RStringBase::Copy(),
1.28 +RStringPool::OpenStringL() and RStringPool::OpenFStringL() must be matched
1.29 +by a close.
1.30 +
1.31 +Strings created through RStringPool::String() or RStringPool::StringF() with
1.32 +an integer argument need not be closed (but closing is harmless).
1.33 +
1.34 +Strings created through RStringPool::String() or RStringPool::StringF() with
1.35 +a StringToken or StringTokenF argument must not be closed, as they're just
1.36 +changing the external representation. */
1.37 + {
1.38 + if (iVal)
1.39 + //harmless for empty strings
1.40 + iPool.iImplementation->Close(RStringTokenEither(iVal));
1.41 + // invalidate the string if it's a dinamic one otherwise do nothing
1.42 + if(!StringUtils::IsTableEntry(this->iVal))
1.43 + iVal=NULL;
1.44 + }
1.45 +
1.46 +
1.47 +EXPORT_C RStringBase RStringBase::Copy()
1.48 +/** Copies a string.
1.49 +
1.50 +Both the original and the copy string must be separately closed.
1.51 +
1.52 +@return The string base. */
1.53 + {
1.54 + if (iVal)
1.55 + iPool.iImplementation->IncrementCount(RStringTokenEither(iVal));
1.56 + return *this;
1.57 + }
1.58 +
1.59 +
1.60 +/** Returns the content of the string
1.61 + */
1.62 +EXPORT_C const TDesC8& RStringBase::DesC() const
1.63 +/** Gets the content of the string.
1.64 +
1.65 +@return Descriptor containing the content of the string. */
1.66 + {
1.67 + // check for empty string
1.68 + if (iVal == 0)
1.69 + return KNullDesC8();
1.70 + if (StringUtils::IsTableEntry(iVal))
1.71 + {
1.72 + TInt index = StringUtils::TableIndex(iVal);
1.73 + TInt tableUid= StringUtils::TableUid(iVal);
1.74 + return iPool.iImplementation->TableLookup(index, tableUid);
1.75 + }
1.76 + else
1.77 + return *StringUtils::NodePtr(iVal)->iDes;
1.78 + }
1.79 +
1.80 +
1.81 +EXPORT_C TInt RStringBase::Index(const TStringTable& aTable) const
1.82 +/** Gets the enumeration value corresponding to this string.
1.83 +
1.84 +@param aTable String table to look in
1.85 +@return The string's enumeration value, or -1 if there is no such value
1.86 +@panic EStringTableNotFound If the table supplied is not found. This panic is raised in debug builds only, in release mode the behaviour is undefined*/
1.87 + {
1.88 + //return an error for empty strings(i.e. with iVal=0 )
1.89 + if(!this->iVal)
1.90 + return KErrNotFound;
1.91 + TInt tableId=iPool.iImplementation->TableUid(aTable);
1.92 + __ASSERT_DEBUG(tableId!=KErrNotFound,StringPoolPanic::Panic(StringPoolPanic::EStringTableNotFound));
1.93 + // First check the iVal is part of the same table
1.94 + if (StringUtils::IsTableEntry(iVal))
1.95 + {
1.96 + if (tableId==StringUtils::TableUid(iVal))
1.97 + return StringUtils::TableIndex(iVal);
1.98 + }
1.99 + // Then check if the iVal is in the reverse duplicate list
1.100 + TInt index=iPool.iImplementation->FindTableIndexFromFirstVal(iVal, tableId);
1.101 + return index;
1.102 + }
1.103 +
1.104 +
1.105 +EXPORT_C const TStringTable* RStringBase::OriginalTableRef() const
1.106 +/** Gets the table (if any) that first added the current string to the pool.
1.107 +
1.108 +Note there multiple tables can contain the same string.
1.109 +
1.110 +@return The table or NULL if the string was created dynamically (not from
1.111 +a table) */
1.112 + {
1.113 + if(StringUtils::IsTableEntry(iVal))
1.114 + return &iPool.iImplementation->TableRef(iVal);
1.115 + else
1.116 + return NULL;
1.117 + }
1.118 +
1.119 +/** Implementation of RStringPool class*/
1.120 +
1.121 +EXPORT_C void RStringPool::OpenL()
1.122 +/** Creates an initialised string pool with no pre-loaded string tables.
1.123 +
1.124 +@leave KErrNoMemory Not enough memory to open the pool */
1.125 + {
1.126 + iImplementation = new (ELeave) CStringPoolImplementation;
1.127 + }
1.128 +
1.129 +EXPORT_C void RStringPool::OpenL(const TStringTable& aTable,MStringPoolCloseCallBack& aCallBack)
1.130 +/** Creates an initialised string pool with a pre-loaded string table, and a string-pool-closing
1.131 +callback.
1.132 +
1.133 +@param aTable The pre-loaded string table.
1.134 +@param aCallBack Callback interface that is called when the string pool closes
1.135 +@leave KErrNoMemory Not enough memory to open the pool */
1.136 + {
1.137 + if (!iImplementation)
1.138 + {
1.139 + iImplementation = new (ELeave) CStringPoolImplementation;
1.140 + CleanupClosePushL(*this);
1.141 + iImplementation->AddTableL(aTable);
1.142 + iImplementation->AddCallBackL(aCallBack);
1.143 + CleanupStack::Pop(); //this
1.144 + }
1.145 + else
1.146 + {
1.147 + iImplementation->AddTableL(aTable);
1.148 + iImplementation->AddCallBackL(aCallBack);
1.149 + }
1.150 + }
1.151 +
1.152 +EXPORT_C void RStringPool::OpenL(const TStringTable& aTable)
1.153 +/** Creates an initialised string pool with a pre-loaded string table.
1.154 +
1.155 +@param aTable The pre-loaded string table.
1.156 +@leave KErrNoMemory Not enough memory to open the pool */
1.157 + {
1.158 + if (!iImplementation)
1.159 + {
1.160 + iImplementation = new (ELeave) CStringPoolImplementation;
1.161 + CleanupClosePushL(*this);
1.162 + iImplementation->AddTableL(aTable);
1.163 + CleanupStack::Pop(); //this
1.164 + }
1.165 + else
1.166 + {
1.167 + iImplementation->AddTableL(aTable);
1.168 + }
1.169 + }
1.170 +
1.171 +
1.172 +EXPORT_C void RStringPool::Close()
1.173 +/** Closes the string pool table.
1.174 +
1.175 +This invalidates all other handles to the table. */
1.176 + {
1.177 + delete iImplementation;
1.178 + iImplementation = NULL;
1.179 + }
1.180 +
1.181 +EXPORT_C RStringF RStringPool::OpenFStringL(const TDesC8& aString) const
1.182 +/** Creates an RStringF using the current string pool.
1.183 +
1.184 +The string is opened as case-insensitive.
1.185 +
1.186 +@param aString The value of the string.
1.187 +@leave KErrNoMemory Not enough memory to open the string
1.188 +@return Initialised RStringF object */
1.189 + {
1.190 + RStringTokenEither newString = iImplementation->OpenL(aString, ETrue);
1.191 + RStringF r;
1.192 + r.iPool = *this;
1.193 + r.iVal = newString.iVal;
1.194 + return r;
1.195 + }
1.196 +
1.197 +EXPORT_C RString RStringPool::OpenStringL(const TDesC8& aString) const
1.198 +/** Creates an RString using the current string pool.
1.199 +
1.200 +The string is opened as case-sensitive.
1.201 +
1.202 +@param aString The value of the string.
1.203 +@leave KErrNoMemory Not enough memory to open the string
1.204 +@return Initialised RString object */
1.205 + {
1.206 + RStringTokenEither newString = iImplementation->OpenL(aString, EFalse);
1.207 + RString r;
1.208 + r.iPool = *this;
1.209 + r.iVal = newString.iVal;
1.210 + return r;
1.211 + }
1.212 +
1.213 +EXPORT_C RString RStringPool::String(RStringToken aString) const
1.214 +/** Creates an RString from the supplied RStringToken.
1.215 +
1.216 +@param aString The string token
1.217 +@return Initialised RString object */
1.218 + {
1.219 + RString r;
1.220 + r.iPool = *this;
1.221 + r.iVal = aString.iVal;
1.222 + return r;
1.223 + }
1.224 +
1.225 +EXPORT_C RString RStringPool::String(TInt aIndex,const TStringTable& aTable) const
1.226 +/** Gets a case-sensitive string specified by a string table enumeration value.
1.227 +
1.228 +aIndex is interpreted as an offset into the handle's pre-loaded string table.
1.229 +
1.230 +@param aIndex The string table enumeration value
1.231 +@param aTable The string table from which to read the string
1.232 +@return Initialised RString object
1.233 +@panic EStringTableNotFound If the table supplied is not found. This panic is raised in debug builds only, in release mode the behaviour is undefined*/
1.234 + {
1.235 + __ASSERT_DEBUG(aTable.iCaseSensitive==1,StringPoolPanic::Panic(StringPoolPanic::ECreatingStringWithWrongCase));
1.236 + if(aIndex <(TInt)aTable.iCount)
1.237 + {//the index is in valid range the index
1.238 + RString r;
1.239 + r.iPool = *this;
1.240 + TInt16 tableUid = iImplementation->TableUid(aTable);
1.241 + __ASSERT_DEBUG(tableUid!=KErrNotFound,StringPoolPanic::Panic(StringPoolPanic::EStringTableNotFound));
1.242 + r.iVal = StringUtils::ValFromIndex(aIndex, tableUid);
1.243 + TInt originalVal;
1.244 + if (KErrNotFound!=(originalVal=iImplementation->FindFirstValFromDuplicate(r.iVal)))
1.245 + {
1.246 + r.iVal=originalVal;
1.247 + }
1.248 + return r;
1.249 + }
1.250 + else // the index is out of range
1.251 + return RString();
1.252 + }
1.253 +
1.254 +EXPORT_C RStringF RStringPool::StringF(RStringTokenF aString) const
1.255 +/** Creates a RStringF from the supplied RStringToken.
1.256 +
1.257 +@param aString The value of the string
1.258 +@return Initialised RStringF object */
1.259 + {
1.260 + RStringF r;
1.261 + r.iPool = *this;
1.262 + r.iVal = aString.iVal;
1.263 + return r;
1.264 + }
1.265 +
1.266 +EXPORT_C RStringF RStringPool::StringF(TInt aIndex,const TStringTable& aTable) const
1.267 +/** Gets a case-insensitive string specified by a string table enumeration value.
1.268 +
1.269 +Creates an RStringF from a string table enumeration value.
1.270 +
1.271 +aIndex is interpreted as an offset into the handle's pre-loaded string table.
1.272 +
1.273 +@param aIndex The string table enumeration value
1.274 +@param aTable The string table from which to read the string
1.275 +@return Initialised RStringF object
1.276 +@panic EStringTableNotFound If the table supplied is not found. This panic is raised in debug builds only, in release mode the behaviour is undefined*/
1.277 + {
1.278 + __ASSERT_DEBUG(aTable.iCaseSensitive==0,StringPoolPanic::Panic(StringPoolPanic::ECreatingStringWithWrongCase));
1.279 + if(aIndex <(TInt)aTable.iCount)
1.280 + {//the index is in valid range the index
1.281 + RStringF r;
1.282 + r.iPool = *this;
1.283 + TInt16 tableUid = iImplementation->TableUid(aTable);
1.284 + __ASSERT_DEBUG(tableUid!=KErrNotFound,StringPoolPanic::Panic(StringPoolPanic::EStringTableNotFound));
1.285 + r.iVal = StringUtils::ValFromIndexF(aIndex, tableUid);
1.286 + TInt originalVal;
1.287 + if (KErrNotFound!=(originalVal=iImplementation->FindFirstValFromDuplicate(r.iVal)))
1.288 + {
1.289 + r.iVal=originalVal;
1.290 + }
1.291 + return r;
1.292 + }
1.293 + else // the index is out of range so return an empty string
1.294 + return RStringF();
1.295 + }