symport/bafl/src/stringpoolapi.cpp
changeset 1 0a7b44b10206
child 2 806186ab5e14
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/symport/bafl/src/stringpoolapi.cpp	Thu Jun 25 15:59:54 2009 +0100
@@ -0,0 +1,292 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Symbian Foundation License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <e32std.h>
+#include "stringpoolimplementation.h"
+
+
+
+EXPORT_C void RStringBase::Close()
+/** Closes a string.
+
+You must close every string you open. In other words, every call to RStringBase::Copy(),
+RStringPool::OpenStringL() and RStringPool::OpenFStringL() must be matched
+by a close.
+
+Strings created through RStringPool::String() or RStringPool::StringF() with
+an integer argument need not be closed (but closing is harmless).
+
+Strings created through RStringPool::String() or RStringPool::StringF() with
+a StringToken or StringTokenF argument must not be closed, as they're just
+changing the external representation. */
+	{
+	if (iVal)
+		//harmless for empty strings
+		iPool.iImplementation->Close(RStringTokenEither(iVal));
+	// invalidate the string if it's a dinamic one	otherwise do nothing
+	if(!StringUtils::IsTableEntry(this->iVal))
+		iVal=0U;
+	}
+
+
+EXPORT_C RStringBase RStringBase::Copy()
+/** Copies a string.
+
+Both the original and the copy string must be separately closed.
+
+@return The string base. */
+	{
+	if (iVal)
+		iPool.iImplementation->IncrementCount(RStringTokenEither(iVal));
+	return *this;
+	}
+
+
+/** Returns the content of the string
+ */
+EXPORT_C const TDesC8& RStringBase::DesC() const
+/** Gets the content of the string.
+
+@return Descriptor containing the content of the string. */
+	{
+	// check for empty string
+	if (iVal == 0)
+		return KNullDesC8();
+	if (StringUtils::IsTableEntry(iVal))
+		{
+		TInt index = StringUtils::TableIndex(iVal);
+		TInt tableUid= StringUtils::TableUid(iVal);
+		return iPool.iImplementation->TableLookup(index, tableUid);
+		}
+	else
+		return *StringUtils::NodePtr(iVal)->iDes;
+	}
+
+
+EXPORT_C TInt RStringBase::Index(const TStringTable& aTable) const
+/** Gets the enumeration value corresponding to this string.
+
+@param	aTable String table to look in
+@return	The string's enumeration value, or -1 if there is no such value
+@panic	EStringTableNotFound If the table supplied is not found. This panic is raised in debug builds only, in release mode the behaviour is undefined*/
+	{
+	//return an error for empty strings(i.e. with iVal=0 )
+	if(!this->iVal)
+	   return KErrNotFound;
+	TInt tableId=iPool.iImplementation->TableUid(aTable);
+	__ASSERT_DEBUG(tableId!=KErrNotFound,StringPoolPanic::Panic(StringPoolPanic::EStringTableNotFound));
+	// First check the iVal is part of the same table
+	if (StringUtils::IsTableEntry(iVal))
+	   {
+	   if (tableId==StringUtils::TableUid(iVal))
+		   return StringUtils::TableIndex(iVal);
+	   }
+	// Then check if the iVal is in the reverse duplicate list
+	TInt index=iPool.iImplementation->FindTableIndexFromFirstVal(iVal, tableId);
+	return index;
+	}
+
+
+EXPORT_C const TStringTable* RStringBase::OriginalTableRef() const
+/** Gets the table (if any) that first added the current string to the pool.
+
+Note there multiple tables can contain the same string.
+
+@return The table or NULL if the string was created dynamically (not from
+a table) */
+	{
+	if(StringUtils::IsTableEntry(iVal))
+		return &iPool.iImplementation->TableRef(iVal);
+	else
+		return NULL;
+	}
+
+/** Implementation of RStringPool class*/
+
+EXPORT_C void RStringPool::OpenL()
+/** Creates an initialised string pool with no pre-loaded string tables.
+
+@leave KErrNoMemory Not enough memory to open the pool */
+	{
+	iImplementation = new (ELeave) CStringPoolImplementation;
+	}
+
+EXPORT_C void RStringPool::OpenL(const TStringTable& aTable,MStringPoolCloseCallBack& aCallBack)
+/** Creates an initialised string pool with a pre-loaded string table, and a string-pool-closing
+callback.
+
+@param aTable The pre-loaded string table.
+@param aCallBack Callback interface that is called when the string pool closes
+@leave KErrNoMemory Not enough memory to open the pool */
+	{
+	if (!iImplementation)
+		{
+		iImplementation = new (ELeave) CStringPoolImplementation;
+		CleanupClosePushL(*this);
+		iImplementation->AddTableL(aTable);
+		iImplementation->AddCallBackL(aCallBack);
+		CleanupStack::Pop(); //this
+		}
+	else
+		{
+		iImplementation->AddTableL(aTable);
+		iImplementation->AddCallBackL(aCallBack);
+		}
+	}
+
+EXPORT_C void RStringPool::OpenL(const TStringTable& aTable)
+/** Creates an initialised string pool with a pre-loaded string table.
+
+@param aTable The pre-loaded string table.
+@leave KErrNoMemory Not enough memory to open the pool */
+	{
+	if (!iImplementation)
+		{
+		iImplementation = new (ELeave) CStringPoolImplementation;
+		CleanupClosePushL(*this);
+		iImplementation->AddTableL(aTable);
+		CleanupStack::Pop(); //this
+		}
+	else
+		{
+		iImplementation->AddTableL(aTable);
+		}
+	}
+
+
+EXPORT_C void RStringPool::Close()
+/** Closes the string pool table.
+
+This invalidates all other handles to the table. */
+	{
+	delete iImplementation;
+	iImplementation = NULL;
+	}
+
+EXPORT_C RStringF RStringPool::OpenFStringL(const TDesC8& aString) const
+/** Creates an RStringF using the current string pool.
+
+The string is opened as case-insensitive.
+
+@param aString The value of the string.
+@leave KErrNoMemory Not enough memory to open the string
+@return Initialised RStringF object */
+	{
+	RStringTokenEither newString = iImplementation->OpenL(aString, ETrue);
+	RStringF r;
+	r.iPool = *this;
+	r.iVal = newString.iVal;
+	return r;
+	}
+
+EXPORT_C RString RStringPool::OpenStringL(const TDesC8& aString) const
+/** Creates an RString using the current string pool.
+
+The string is opened as case-sensitive.
+
+@param aString The value of the string.
+@leave KErrNoMemory Not enough memory to open the string
+@return Initialised RString object */
+	{
+	RStringTokenEither newString = iImplementation->OpenL(aString, EFalse);
+	RString r;
+	r.iPool = *this;
+	r.iVal = newString.iVal;
+	return r;
+	}
+
+EXPORT_C RString RStringPool::String(RStringToken aString) const
+/** Creates an RString from the supplied RStringToken.
+
+@param aString The string token
+@return Initialised RString object */
+	{
+	RString r;
+	r.iPool = *this;
+	r.iVal = aString.iVal;
+	return r;
+	}
+
+EXPORT_C RString RStringPool::String(TInt aIndex,const TStringTable& aTable) const
+/** Gets a case-sensitive string specified by a string table enumeration value.
+
+aIndex is interpreted as an offset into the handle's pre-loaded string table.
+
+@param	aIndex The string table enumeration value
+@param	aTable The string table from which to read the string
+@return	Initialised RString object
+@panic	EStringTableNotFound If the table supplied is not found. This panic is raised in debug builds only, in release mode the behaviour is undefined*/
+	{
+	__ASSERT_DEBUG(aTable.iCaseSensitive==1,StringPoolPanic::Panic(StringPoolPanic::ECreatingStringWithWrongCase));
+	if(aIndex <(TInt)aTable.iCount)
+		{//the index is in valid range the index
+		RString r;
+		r.iPool = *this;
+		TInt16 tableUid = iImplementation->TableUid(aTable);
+		__ASSERT_DEBUG(tableUid!=KErrNotFound,StringPoolPanic::Panic(StringPoolPanic::EStringTableNotFound));
+		r.iVal = StringUtils::ValFromIndex(aIndex, tableUid);
+		TInt originalVal;
+		if (KErrNotFound!=(originalVal=iImplementation->FindFirstValFromDuplicate(r.iVal)))
+			{
+			r.iVal=originalVal;
+			}
+		return r;
+		}
+	else // the index is out of range
+	return RString();
+	}
+
+EXPORT_C RStringF RStringPool::StringF(RStringTokenF aString) const
+/** Creates a RStringF from the supplied RStringToken.
+
+@param aString The value of the string
+@return Initialised RStringF object */
+	{
+	RStringF r;
+	r.iPool = *this;
+	r.iVal = aString.iVal;
+	return r;
+	}
+
+EXPORT_C RStringF RStringPool::StringF(TInt aIndex,const TStringTable& aTable) const
+/** Gets a case-insensitive string specified by a string table enumeration value.
+
+Creates an RStringF from a string table enumeration value.
+
+aIndex is interpreted as an offset into the handle's pre-loaded string table.
+
+@param	aIndex The string table enumeration value
+@param	aTable The string table from which to read the string
+@return	Initialised RStringF object
+@panic	EStringTableNotFound If the table supplied is not found. This panic is raised in debug builds only, in release mode the behaviour is undefined*/
+	{
+	__ASSERT_DEBUG(aTable.iCaseSensitive==0,StringPoolPanic::Panic(StringPoolPanic::ECreatingStringWithWrongCase));
+	if(aIndex <(TInt)aTable.iCount)
+		{//the index is in valid range the index
+		RStringF r;
+		r.iPool = *this;
+		TInt16 tableUid = iImplementation->TableUid(aTable);
+		__ASSERT_DEBUG(tableUid!=KErrNotFound,StringPoolPanic::Panic(StringPoolPanic::EStringTableNotFound));
+		r.iVal = StringUtils::ValFromIndexF(aIndex, tableUid);
+		TInt originalVal;
+		if (KErrNotFound!=(originalVal=iImplementation->FindFirstValFromDuplicate(r.iVal)))
+			{
+			r.iVal=originalVal;
+			}
+		return r;
+		}
+	else // the index is out of range so return an empty string
+	return RStringF();
+	}