telephonyserver/etelmultimode/CETEL/mm_pbutil.cpp
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyserver/etelmultimode/CETEL/mm_pbutil.cpp	Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,563 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <etelmm.h>		// for RMobilePhoneBookStore
+#include "mpbutil.h"
+
+const TUint8 KTagPadZeroValue = 0x00;
+
+EXPORT_C CPhoneBookBuffer::CPhoneBookBuffer() : iMonitor(NULL,0,0)
+/** The CPhoneBookBuffer library class is constructed using a simple, one-phase 
+constructor because the CPhoneBookBuffer class does not allocate any member 
+data on the heap. */
+	{
+	}
+
+EXPORT_C void CPhoneBookBuffer::Set(TDes8* aBuf)
+/** This member function sets the buffer's internal attribute iPtr to point to 
+the supplied 8-bit buffer, which is owned by the caller of this function member.
+	
+@param aData A pointer to the buffer 
+@capability None
+*/
+	{
+	iPtr = aBuf;
+	}
+
+EXPORT_C TInt CPhoneBookBuffer::AddNewEntryTag()
+/** This function member puts a new entry tag byte (ETagPBNewEntry) into the buffer 
+ and sets iMonitor to point to the beginning of each new entry.
+
+@return KErrNone if successful, or KErrOverflow if there is not enough space 
+in the buffer.
+@see RMobilePhoneBookStore::TMobilePBFieldTags 
+@capability None
+*/
+	{
+	// First check whether there is enough space to fit new entry tag
+	if( (iPtr->MaxLength() - iPtr->Length()) > 1 )
+		{
+		AppendInt8(RMobilePhoneBookStore::ETagPBNewEntry);
+		const TInt len = iPtr->Length();
+		// Make sure iMonitor has been updated and it points to the beggining of the new entry
+		iMonitor.Set(&(*iPtr)[len-1], iPtr->MaxLength() - len + 1, iPtr->MaxLength() - len + 1);
+		return KErrNone;
+		}
+	else
+		{
+		return KErrOverflow;
+		}
+	}
+
+EXPORT_C TInt CPhoneBookBuffer::AddNewNumberTag()
+/** This function member puts a new number tag byte (ETagPBAnrStart) into the buffer. 
+
+
+@return KErrNone if successful, or KErrOverflow if there is not enough space 
+in the buffer.
+@see RMobilePhoneBookStore::TMobilePBFieldTags 
+@capability None
+*/
+	{
+	// First check whether there is enough space to fit new entry tag
+	if( (iPtr->MaxLength() - iPtr->Length()) > 1 )
+		{
+		AppendInt8(RMobilePhoneBookStore::ETagPBAnrStart);
+		return KErrNone;
+		}
+	else
+		{
+		return KErrOverflow;
+		}
+	}
+
+
+/**
+ *  Puts a 8-bit integer value into buffer.
+ *
+ *  The valid tags for use with 8-bit integers are:
+ *
+ *  @li  RMobilePhoneBookStore::ETagPBBearerCap
+ *  @li  RMobilePhoneBookStore::ETagPBEntryControl
+ *  @li  RMobilePhoneBookStore::ETagPBHiddenInfo
+ *  @li  RMobilePhoneBookStore::ETagPBTonNpi
+ *  @li  RMobilePhoneBookStore::ETagPBUniqueId
+ *  @li  RMobilePhoneBookStore::ETagPBEntryStatus
+ *
+ *  @param aTagValue  Tag byte to use.
+ *  @param aInteger   Value to put in the buffer.
+ *
+ *  @return KErrNone if successful, KErrOverflow if there is not enough
+ *          space in the buffer or KErrArgument if the parameter is invalid.
+ *
+ *  @capability None
+ */
+EXPORT_C TInt CPhoneBookBuffer::PutTagAndValue(TUint8 aTagValue, TUint8 aInteger)
+	{
+	//
+	// Check that the tag type is valid for this type of value...
+	//
+	if (aTagValue != RMobilePhoneBookStore::ETagPBBearerCap  &&
+		aTagValue != RMobilePhoneBookStore::ETagPBEntryControl  &&
+		aTagValue != RMobilePhoneBookStore::ETagPBHiddenInfo  &&
+		aTagValue != RMobilePhoneBookStore::ETagPBTonNpi  &&
+		aTagValue != RMobilePhoneBookStore::ETagPBUniqueId  &&
+		aTagValue != RMobilePhoneBookStore::ETagPBEntryStatus)
+		{
+		return KErrArgument;
+		}
+
+	// First need to ensure that aInteger can fit into the supplied buffer
+	if((iPtr->MaxLength()-iPtr->Length()) > 2)
+		{
+		AppendInt8(aTagValue);
+		AppendInt8(aInteger);
+		return KErrNone;
+		}
+	else
+		{
+		return KErrOverflow;
+		}
+	}
+
+
+/**
+ *  Puts a 16-bit integer value into buffer.
+ *
+ *  The valid tags for use with 16-bit integers are:
+ *
+ *  @li  RMobilePhoneBookStore::ETagPBAdnIndex
+ *
+ *  @param aTagValue  Tag byte to use.
+ *  @param aInteger   Value to put in the buffer.
+ *
+ *  @return KErrNone if successful, KErrOverflow if there is not enough
+ *          space in the buffer or KErrArgument if the parameter is invalid.
+ *
+ *  @capability None
+ */
+EXPORT_C TInt CPhoneBookBuffer::PutTagAndValue(TUint8 aTagValue, TUint16 aInteger)
+	{
+	//
+	// Check that the tag type is valid for this type of value...
+	//
+	if (aTagValue != RMobilePhoneBookStore::ETagPBAdnIndex)
+		{
+		return KErrArgument;
+		}
+
+	// First need to ensure that aInteger can fit into the supplied buffer
+	if((iPtr->MaxLength()-iPtr->Length()) > 3)
+		{
+		AppendInt8(aTagValue);
+		AppendInt16(aInteger);
+		return KErrNone;
+		}
+	else
+		{
+		return KErrOverflow;
+		}
+	}
+
+
+/**
+ *  Puts a 32-bit integer value into buffer.
+ *
+ *  The valid tags for use with 32-bit integers are:
+ *
+ *  @li  None.
+ *
+ *  @param aTagValue  Tag byte to use.
+ *  @param aInteger   Value to put in the buffer.
+ *
+ *  @return KErrNone if successful, KErrOverflow if there is not enough
+ *          space in the buffer or KErrArgument if the parameter is invalid.
+ *
+ *  @capability None
+ */
+EXPORT_C TInt CPhoneBookBuffer::PutTagAndValue(TUint8 aTagValue, TUint32 aInteger)
+	{
+	//
+	// No Tags support 32bit integers...
+	//
+	(void) aTagValue;
+	(void) aInteger;
+	
+	return KErrArgument;
+
+//	// First need to ensure that aInteger can fit into the supplied buffer
+//	if((iPtr->MaxLength()-iPtr->Length()) > 5)
+//		{
+//		AppendInt8(aTagValue);
+//		AppendInt32(aInteger);
+//		return KErrNone;
+//		}
+//	else
+//		{
+//		return KErrOverflow;
+//		}
+	}
+
+
+/**
+ *  Puts a 16-bit descriptor value into buffer.
+ *
+ *  The valid tags for use with 16-bit descriptors are:
+ *
+ *  @li  RMobilePhoneBookStore::ETagPBSecondName
+ *  @li  RMobilePhoneBookStore::ETagPBGroupName
+ *  @li  RMobilePhoneBookStore::ETagPBEmailAddress
+ *  @li  RMobilePhoneBookStore::ETagPBText
+ *  @li  RMobilePhoneBookStore::ETagPBNumber
+ *
+ *  @param aTagValue  Tag byte to use.
+ *  @param aData      Value to put in the buffer.
+ *
+ *  @return KErrNone if successful, KErrOverflow if there is not enough
+ *          space in the buffer or KErrArgument if the parameter is invalid.
+ *
+ *  @capability None
+ */
+EXPORT_C TInt CPhoneBookBuffer::PutTagAndValue(TUint8 aTagValue, const TDesC16 &aData)
+	{
+	//
+	// Check that the tag type is valid for this type of value...
+	//
+	if (aTagValue != RMobilePhoneBookStore::ETagPBSecondName  &&
+		aTagValue != RMobilePhoneBookStore::ETagPBGroupName  &&
+		aTagValue != RMobilePhoneBookStore::ETagPBEmailAddress  &&
+		aTagValue != RMobilePhoneBookStore::ETagPBText  &&
+		aTagValue != RMobilePhoneBookStore::ETagPBNumber)
+		{
+		return KErrArgument;
+		}
+
+	// First need to ensure that aData can fit into the supplied buffer
+	// Need to use Size() because this is Unicode data and we want to know number of bytes not number of characters
+	// Also allow for the 1-byte tag and up to 3 zero padding bytes
+	if((aData.Size()+3 <= KMaxUint16Val) && ((iPtr->MaxLength()-iPtr->Length()) > (aData.Size()+4)))
+		{
+		// Make sure buffer is word aligned after adding 3 bytes for tag and length
+		switch(iPtr->Size()%4)
+			{
+		case 0:
+			AppendInt8(KTagPadZeroValue);
+			break;
+		case 1:
+			break;
+		case 2:
+			AppendInt8(KTagPadZeroValue);
+			AppendInt8(KTagPadZeroValue);
+			AppendInt8(KTagPadZeroValue);
+			break;
+		case 3:
+			AppendInt8(KTagPadZeroValue);
+			AppendInt8(KTagPadZeroValue);
+			break;
+		default:
+			break;
+			}
+
+		AppendInt8(aTagValue);
+		TUint16 len=(TUint16) aData.Size();
+		iPtr->Append((const TUint8*)&len,2);
+		TUint8* dataPtr=reinterpret_cast<TUint8*>(const_cast<TUint16*>(aData.Ptr()));
+		iPtr->Append(dataPtr,len);
+		return KErrNone;
+		}
+	else 
+		{
+		return KErrOverflow;
+		}	
+	}
+
+
+/**
+ *  Puts a 8-bit descriptor value into buffer.
+ *
+ *  The valid tags for use with 8-bit descriptors are:
+ *
+ *  @li  None.
+ *
+ *  @param aTagValue  Tag byte to use.
+ *  @param aData      Value to put in the buffer.
+ *
+ *  @return KErrNone if successful, KErrOverflow if there is not enough
+ *          space in the buffer or KErrArgument if the parameter is invalid.
+ *
+ *  @capability None
+ */
+EXPORT_C TInt CPhoneBookBuffer::PutTagAndValue(TUint8 aTagValue, const TDesC8 &aData)
+	{
+	//
+	// No Tags support 8bit text...
+	//
+	(void) aTagValue;
+	(void) aData;
+	
+	return KErrArgument;
+
+//	// First need to ensure that aData can fit into the supplied buffer
+//	if((aData.Size() <= KMaxUint16Val) && ((iPtr->MaxLength()-iPtr->Length()) > (aData.Size()+1)))
+//		{
+//		AppendInt8(aTagValue);
+//		TUint16 len=(TUint16) aData.Length();
+//		iPtr->Append((const TUint8*)&len,2);
+//		iPtr->Append(aData);
+//		return KErrNone;
+//		}
+//	else 
+//		{
+//		return KErrOverflow;
+//		}	
+	}
+
+EXPORT_C TInt CPhoneBookBuffer::RemovePartialEntry()
+/**This function will rollback the buffer to the end of the last complete 
+phonebook entry and remove any data after this.
+
+@return KErrNone if successful. 
+@capability None
+*/
+	{
+	iPtr->SetLength(iPtr->MaxLength() - iMonitor.Length());
+	iMonitor.FillZ();
+	return KErrNone;
+	}
+
+EXPORT_C void CPhoneBookBuffer::StartRead()
+/** This function member sets the CPhoneBookBuffer class' iRead member data to 
+point to the start of the populated TLV buffer, ready to start data extraction 
+from the buffer. 
+@capability None
+*/
+	{
+	iRead.Set(*iPtr);
+	}
+
+EXPORT_C TInt CPhoneBookBuffer::GetTagAndType(TUint8 &aTagValue, TPhBkTagType &aDataType)
+/** This function member reads the next tag value from the buffer.
+
+@param aTagValue On completion, the next Tag type from the buffer.
+@param aDataType On completion, the data type associated with the tag value.
+@return KErrNone if successful, or KErrNotFound if there are no more tags in 
+the buffer. 
+@capability None
+*/
+	{
+	// Check we've not reached end of buffer - if we have then return
+	TInt length = iRead.Length();
+	
+	if (length<=0)
+		return KErrNotFound;
+
+	// Extract all padding zero bytes until tag is found
+	TInt i=0;
+	do
+		{
+		aTagValue=iRead[i++];
+		}
+	while ((aTagValue==KTagPadZeroValue) && i<length);
+
+	if (i < length)
+		iRead.Set(iRead.Mid(i));
+	else
+		return KErrNotFound;
+
+	switch(aTagValue) // set tag type according to the tag value
+		{
+		case RMobilePhoneBookStore::ETagPBNewEntry:
+		case RMobilePhoneBookStore::ETagPBAnrStart:
+			aDataType = EPhBkTypeNoData;
+			break;
+
+		case RMobilePhoneBookStore::ETagPBBearerCap:
+		case RMobilePhoneBookStore::ETagPBEntryControl:
+		case RMobilePhoneBookStore::ETagPBHiddenInfo:
+		case RMobilePhoneBookStore::ETagPBTonNpi:
+		case RMobilePhoneBookStore::ETagPBUniqueId:
+		case RMobilePhoneBookStore::ETagPBEntryStatus:
+			aDataType = EPhBkTypeInt8;
+			break;
+
+		case RMobilePhoneBookStore::ETagPBAdnIndex: 
+			aDataType = EPhBkTypeInt16; 
+			break;
+
+		case RMobilePhoneBookStore::ETagPBSecondName:
+		case RMobilePhoneBookStore::ETagPBGroupName:
+		case RMobilePhoneBookStore::ETagPBEmailAddress:
+		case RMobilePhoneBookStore::ETagPBText:
+		case RMobilePhoneBookStore::ETagPBNumber:
+			aDataType = EPhBkTypeDes16; 
+			break;
+
+		default:
+			return KErrNotFound;
+		}
+	return KErrNone;
+	}
+
+EXPORT_C TInt CPhoneBookBuffer::GetValue(TUint16 &aInteger)
+/** Gets a 16-bit integer value from the buffer.
+
+@param aInteger On completion, the 16-bit value from the buffer.
+@return KErrNone if successful. 
+@capability None
+*/
+	{
+	aInteger=(TUint16)((iRead[1]<<8)+iRead[0]);		// Dependant upon endianess
+	iRead.Set(iRead.Mid(2));
+	return KErrNone;
+	}
+
+EXPORT_C TInt CPhoneBookBuffer::GetValue(TUint8 &aInteger)
+/** Gets a 8-bit integer value from the buffer.
+
+@param aInteger On completion, the 8-bit value from the buffer.
+@return KErrNone if successful. 
+@capability None
+*/
+	{
+	aInteger=(TUint8)(iRead[0]);		
+	iRead.Set(iRead.Mid(1));
+	return KErrNone;
+	}
+
+EXPORT_C TInt CPhoneBookBuffer::GetValue(TUint32 &aInteger)
+/** Gets a 32-bit integer value from the buffer.
+
+@param aInteger On completion, the 32-bit value from the buffer.
+@return KErrNone if successful. 
+@capability None
+*/
+	{
+	TUint16 aMSW(0), aLSW(0);
+	GetValue(aLSW);
+	GetValue(aMSW);
+	aInteger=(TUint32)((aMSW<<16)+aLSW);		// Dependant upon endianess
+	return KErrNone;
+	}
+
+EXPORT_C TInt CPhoneBookBuffer::GetValue(TPtrC8 &aData)
+/** Gets a 8-bit descriptor from the buffer. The read pointer is then incremented past the read value.
+
+@param aData On completion, the 8-bit descriptor from the buffer.
+@return KErrNone if successful. 
+@capability None
+*/
+	{
+	TUint16 len;
+	len=(TUint16)((iRead[1]<<8)+iRead[0]);		// Dependant upon endianess
+	aData.Set(iRead.Mid(2,len));
+	iRead.Set(iRead.Mid(len+2));
+	return KErrNone;
+	}
+
+EXPORT_C TInt CPhoneBookBuffer::GetValue(TPtrC16 &aData)
+/** Gets a 16-bit descriptor from the buffer.
+
+@param aData On completion, the 16-bit descriptor from the buffer. 
+The read pointer is then incremented past the read value.
+@return KErrNone if successful. 
+@capability None
+*/
+	{
+	TUint16 size=(TUint16)((iRead[1]<<8)+iRead[0]);		// Dependant upon endianess
+	TUint16 len=(TUint16)(size/2);
+
+	iRead.Set(iRead.Mid(2));
+
+	TUint16* dataPtr=reinterpret_cast<TUint16*>(const_cast<TUint8*>(iRead.Ptr()));
+
+	aData.Set(dataPtr,len);
+	
+	iRead.Set(iRead.Mid(size));
+	return KErrNone;
+	}
+
+EXPORT_C TInt CPhoneBookBuffer::BufferLength()
+/** This function member returns the length of the populated buffer.
+
+@return The buffer length. 
+@capability None
+*/
+	{
+	return iPtr->Length();
+	}
+
+EXPORT_C TInt CPhoneBookBuffer::RemainingReadLength()
+/** This function member returns the length of the remaining data to read in the 
+populated buffer.
+
+@return The length of the remaining data. 
+@capability None
+*/
+	{
+	return iRead.Length();
+	}
+
+EXPORT_C void CPhoneBookBuffer::SkipValue(TPhBkTagType aDataType)
+/** This function member skips the next value in the buffer that is waiting to 
+be read. Clients would use this function member if they do not support the 
+field contained in the next data value.
+
+@param aDataType The data type of the value to skip 
+@capability None
+*/
+	{
+	TUint16 size=0;
+	switch (aDataType)
+		{
+	case EPhBkTypeInt8:
+		iRead.Set(iRead.Mid(1));
+		break;
+	case EPhBkTypeInt16:
+		iRead.Set(iRead.Mid(2));
+		break;
+	case EPhBkTypeInt32:
+		iRead.Set(iRead.Mid(4));
+		break;
+	case EPhBkTypeDes8:
+	case EPhBkTypeDes16:
+		size=(TUint16)((iRead[1]<<8)+iRead[0]);		// Dependant upon endianess
+		iRead.Set(iRead.Mid(2+size));
+		break;
+	default:
+		// EPhBkTypeNoData caught here - no data to skip, so do nothing
+		break;
+		}
+	}
+
+TInt CPhoneBookBuffer::AppendInt8(TUint8 aInteger)
+	{
+	const TUint8* intAddr=(const TUint8*)&aInteger;
+	iPtr->Append(intAddr,1);
+	return KErrNone;
+	}
+
+TInt CPhoneBookBuffer::AppendInt16(TUint16 aInteger)
+	{
+	const TUint8* intAddr=(const TUint8*)&aInteger;
+	iPtr->Append(intAddr,2);
+	return KErrNone;
+	}
+
+TInt CPhoneBookBuffer::AppendInt32(TUint32 aInteger)
+	{
+	const TUint8* intAddr=(const TUint8*)&aInteger;
+	iPtr->Append(intAddr,4);
+	return KErrNone;
+	}