bluetooth/btsdp/database/DataEncoder.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2000-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 "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <bluetooth/logger.h>
       
    17 #include <es_sock.h>
       
    18 #include "DataEncoder.h"
       
    19 #include "sdputil.h"
       
    20 
       
    21 #ifdef __FLOG_ACTIVE
       
    22 _LIT8(KLogComponent, LOG_COMPONENT_SDPDATABASE);
       
    23 #endif
       
    24 
       
    25 #ifdef _DEBUG
       
    26 PANICCATEGORY("dataenc");
       
    27 #endif
       
    28 
       
    29 EXPORT_C TElementEncoder::TElementEncoder(TDes8& aWriteBuffer)
       
    30 : iWriteBuf(aWriteBuffer)
       
    31 	{
       
    32 	}
       
    33 
       
    34 EXPORT_C TInt TElementEncoder::WriteNil()
       
    35 	{
       
    36 	return WriteHeader(ETypeNil, 0);
       
    37 	}
       
    38 
       
    39 EXPORT_C TInt TElementEncoder::WriteUint(const TDesC8& aUint)
       
    40 	{
       
    41 	return WriteElement(ETypeUint, aUint);
       
    42 	}
       
    43 
       
    44 EXPORT_C TInt TElementEncoder::WriteUint(TUint aVal, TInt aNumberOfBytes)
       
    45 	{
       
    46 	TBuf8<sizeof(aVal)> val(aNumberOfBytes);
       
    47 	PutUint(&val[0], aVal, aNumberOfBytes);
       
    48 	return WriteUint(val);
       
    49 	}
       
    50 
       
    51 EXPORT_C TInt TElementEncoder::WriteInt(const TDesC8& aInt)
       
    52 	{
       
    53 	return WriteElement(ETypeInt, aInt);
       
    54 	}
       
    55 
       
    56 EXPORT_C TInt TElementEncoder::WriteInt(TInt aVal, TInt aNumberOfBytes)
       
    57 	{
       
    58 	TBuf8<sizeof(aVal)> val(aNumberOfBytes);
       
    59 	PutUint(&val[0], static_cast<TInt>(aVal), aNumberOfBytes);
       
    60 	return WriteInt(val);
       
    61 	}
       
    62 
       
    63 EXPORT_C TInt TElementEncoder::WriteUUID(const TUUID& aUUID)
       
    64 	{
       
    65 	return WriteElement(ETypeUUID, aUUID.Des());
       
    66 	}
       
    67 
       
    68 EXPORT_C TInt TElementEncoder::WriteString(const TDesC8& aString)
       
    69 	{
       
    70 	return WriteElement(ETypeString, aString);
       
    71 	}
       
    72 
       
    73 EXPORT_C TInt TElementEncoder::WriteBoolean(TBool aBoolean)
       
    74 	{
       
    75 	TBuf8<1> val(1);
       
    76 	val[0] = TUint8(aBoolean ? 1 : 0);
       
    77 	return WriteElement(ETypeBoolean, val);
       
    78 	}
       
    79 
       
    80 EXPORT_C TInt TElementEncoder::WriteDES(TUint aDataSize)
       
    81 	{
       
    82 	return WriteHeader(ETypeDES, aDataSize);
       
    83 	}
       
    84 
       
    85 EXPORT_C TInt TElementEncoder::WriteDEA(TUint aDataSize)
       
    86 	{
       
    87 	return WriteHeader(ETypeDEA, aDataSize);
       
    88 	}
       
    89 
       
    90 EXPORT_C TInt TElementEncoder::WriteURL(const TDesC8 &aUrl)
       
    91 	{
       
    92 	return WriteElement(ETypeURL, aUrl);
       
    93 	}
       
    94 
       
    95 EXPORT_C TInt TElementEncoder::WriteElement(TSdpElementType aType, const TDesC8 &aData)
       
    96 	{
       
    97 	TInt n = WriteHeader(aType, aData.Length());
       
    98 	return n + WriteDesc(aData);
       
    99 	}
       
   100 
       
   101 EXPORT_C TInt TElementEncoder::WriteHeader(TSdpElementType aType, TUint aDataSize)
       
   102 	{
       
   103 	TUint headLen = HeaderSize(aType, aDataSize);
       
   104 	ASSERT_DEBUG(headLen < 6);
       
   105 	TBuf8<5> header(headLen);
       
   106 	header[0] = TUint8(aType << 3 | SizeDescriptor(aType, aDataSize));
       
   107 
       
   108 	if (headLen > 1)
       
   109 		{// Write out the additional size bytes
       
   110 		PutUint(&header[1], aDataSize, headLen-1);
       
   111 		}
       
   112 
       
   113 	return WriteDesc(header);
       
   114 	}
       
   115 
       
   116 EXPORT_C TInt TElementEncoder::WriteDesc(const TDesC8 &aDesc)
       
   117 /**
       
   118 	Append descriptor onto the write buffer.
       
   119 	returns the number of bytes that did NOT fit into the write buffer.
       
   120 **/
       
   121 	{
       
   122 	TInt remSpace = iWriteBuf.MaxLength() - iWriteBuf.Length();
       
   123 	TInt writeLen = Min(aDesc.Length(), remSpace);
       
   124 	iWriteBuf.Append(aDesc.Left(writeLen));
       
   125 	return aDesc.Length() - writeLen;
       
   126 	}
       
   127 
       
   128 EXPORT_C void TElementEncoder::PutUint(TUint8* aPtr, TUint aUint, TInt aNumberOfBytes)
       
   129 	{
       
   130 	TUint test = aNumberOfBytes == 4 ? 1 : !(aUint & (0xffffffff << (aNumberOfBytes * 8)));
       
   131 	 
       
   132 	__ASSERT_ALWAYS(test,
       
   133 					DbPanic(ESdpAttrValueBadSize));
       
   134 	switch(aNumberOfBytes)
       
   135 		{
       
   136 	case 4:
       
   137 		*aPtr++ = TUint8(aUint>>24);
       
   138 	case 3:
       
   139 		*aPtr++ = TUint8(aUint>>16);
       
   140 	case 2:
       
   141 		*aPtr++ = TUint8(aUint>>8);
       
   142 	case 1:
       
   143 		*aPtr = TUint8(aUint);
       
   144 		break;
       
   145 	default:
       
   146 		DbPanic(ESdpAttrValueBadSize);
       
   147 		}
       
   148 	}
       
   149 
       
   150 EXPORT_C TSdpElementSizeDesc TElementEncoder::SizeDescriptor(TSdpElementType aType, TUint aDataSize)
       
   151 	{
       
   152 	__ASSERT_ALWAYS(aType < TInt(sizeof(KSdpElementValidSizes)), DbPanic(ESdpAttrValueBadSize));
       
   153 	if (aType == ETypeBoolean && aDataSize == 1)
       
   154 		return ESizeOneByte;
       
   155 	if (aType == ETypeNil && aDataSize == 0)
       
   156 		return ESizeOneByte;
       
   157 	
       
   158 
       
   159 	TUint8 validSizes = KSdpElementValidSizes[aType];
       
   160 	if (validSizes&0x1f)
       
   161 		{
       
   162 		//if size is in range [0,4] and aType is not Nil
       
   163 		//then aDataSize should be non-zero.
       
   164 		//Indeed the logic in the loop below the "__ASSERT"
       
   165 		//fails for aDataSize = 0...
       
   166 		__ASSERT_DEBUG(aDataSize, DbPanic(ESdpAttrValueBadSize)); 
       
   167 		for (TInt i=0; i <= ESizeSixteenBytes; ++i)
       
   168 			{
       
   169 			if (TUint((1<<i)&validSizes) == aDataSize)
       
   170 				return TSdpElementSizeDesc(i);
       
   171 			}
       
   172 		}
       
   173 
       
   174 	if (validSizes&0xe0)
       
   175 		{
       
   176 		for (TInt i=ESizeOneAdditional; i <= ESizeFourAdditional; ++i)
       
   177 			{
       
   178 			if ((aDataSize >> (8*(i-(ESizeOneAdditional-1))) == 0) && TUint((1<<i)&validSizes))
       
   179 				return TSdpElementSizeDesc(i);
       
   180 			}
       
   181 		}
       
   182 	DbPanic(ESdpAttrValueBadSize);
       
   183 	return ESizeOneByte;
       
   184 	}
       
   185 
       
   186 EXPORT_C TInt TElementEncoder::HeaderSize(TSdpElementType aType, TUint aDataSize)
       
   187 	{
       
   188 	TInt sizeDesc = SizeDescriptor(aType, aDataSize);
       
   189 	return 1 + (sizeDesc >= 5 ? 1<<(sizeDesc-5) : 0);
       
   190 	}
       
   191 
       
   192 EXPORT_C TInt TElementEncoder::EncodedSize(TSdpElementType aType, TUint aDataSize)
       
   193 	{
       
   194 	return HeaderSize(aType, aDataSize) + aDataSize;
       
   195 	}