1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericservices/httputils/wspcodec/WSPEncoder.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,630 @@
1.4 +// Copyright (c) 2001-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 <wspencoder.h>
1.20 +
1.21 +//constants
1.22 +//
1.23 +const TUint8 KWSPQuoteCharacter = 0x7F; // QUOTE character as specified in the WSP BNF.
1.24 +const TUint8 KWSPQuote = 0x22; // The regular quote character ".
1.25 +const TUint8 KCarryBitMask = 0x80; // Continue bit set
1.26 +#define KTopBitMask KCarryBitMask // Mask for checking top bit
1.27 +const TUint KUintVarIndicator = 31; // Byte value indicating a UIntVar follows.
1.28 +const TUint KUIntVarOctetShift = 7; // Octet shift required processing a UnIntVar
1.29 +const TUint KLongIntOctetShift = 8; // Octet shift required processing a LongInt
1.30 +const TInt KDesArrayGranularity = 6; // Granularity of descriptor array
1.31 +_LIT8(KWspStringTerminator, "\0");
1.32 +_LIT8(KTxtSeparators, "()<>@,;:\\\"/[]?={} "); // Separator characters as defined in RFC2616
1.33 +
1.34 +// Panic category
1.35 +//
1.36 +_LIT(KWspCodecPanicCategory,"WSPCODEC");
1.37 +
1.38 +/**
1.39 + Static factory constructor.
1.40 +
1.41 + @leave KErrNoMemory
1.42 + @return returns a Pointer to fully constructed CWspHeaderEncoder object.
1.43 +*/
1.44 +EXPORT_C CWspHeaderEncoder* CWspHeaderEncoder::NewL()
1.45 + {
1.46 + CWspHeaderEncoder* self = CWspHeaderEncoder::NewLC();
1.47 + CleanupStack::Pop(self);
1.48 + return self;
1.49 + }
1.50 +
1.51 +/**
1.52 + Static factory constructor.
1.53 +
1.54 + @leave KErrNoMemory
1.55 + @return returns a Pointer to fully constructed CWspHeaderEncoder object on the Heap.
1.56 +*/
1.57 +EXPORT_C CWspHeaderEncoder* CWspHeaderEncoder::NewLC()
1.58 + {
1.59 + CWspHeaderEncoder* self = new (ELeave) CWspHeaderEncoder();
1.60 + CleanupStack::PushL(self);
1.61 + self->ConstructL();
1.62 + return self;
1.63 + }
1.64 +
1.65 +/**
1.66 + Default constructor.
1.67 +*/
1.68 +CWspHeaderEncoder::CWspHeaderEncoder()
1.69 + {
1.70 + }
1.71 +
1.72 +/**
1.73 + Default destructor
1.74 +*/
1.75 +EXPORT_C CWspHeaderEncoder::~CWspHeaderEncoder()
1.76 + {
1.77 + iArray.ResetAndDestroy();
1.78 + }
1.79 +
1.80 +/**
1.81 + Standard second phase construction.
1.82 +*/
1.83 +void CWspHeaderEncoder::ConstructL()
1.84 + {
1.85 + // Create new buffer;
1.86 + CDesC8Array* buffer = new (ELeave) CDesC8ArrayFlat(KDesArrayGranularity);
1.87 + CleanupStack::PushL(buffer);
1.88 + User::LeaveIfError(iArray.Append(buffer));
1.89 + CleanupStack::Pop(buffer);
1.90 + }
1.91 +
1.92 +/**
1.93 + Starts a new encoded header.
1.94 +
1.95 + @param aToken field name being encoded as a Token value.
1.96 + @leave KErrNoMemory
1.97 +*/
1.98 +EXPORT_C void CWspHeaderEncoder::StartHeaderL(TUint8 aToken)
1.99 + {
1.100 + __ASSERT_DEBUG(iTotalLength==0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderCalledTwice));
1.101 + AddShortIntL(aToken);
1.102 + }
1.103 +
1.104 +/**
1.105 + Starts a new encoded header.
1.106 +
1.107 + @param aString Fieldname parameter is encoded as a TextString.
1.108 + @leave KErrNoMemory
1.109 +*/
1.110 +EXPORT_C void CWspHeaderEncoder::StartHeaderL(const TDesC8& aString)
1.111 + {
1.112 + __ASSERT_DEBUG(iTotalLength==0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderCalledTwice));
1.113 + AddTextStringL(aString);
1.114 + }
1.115 +
1.116 +/**
1.117 + Starts a new encoded header.
1.118 +
1.119 + @param aString Fieldname parameter is encoded as a TextString.
1.120 + @leave KErrNotSupported
1.121 +*/
1.122 +EXPORT_C void CWspHeaderEncoder::StartHeaderL(const RStringF /* aString */ )
1.123 + {
1.124 + __ASSERT_DEBUG(iTotalLength==0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderCalledTwice));
1.125 + User::Leave(KErrNotSupported);
1.126 + }
1.127 +
1.128 +
1.129 +/**
1.130 + Completes and returns encoded field 8 bit buffer. This method will panic if an
1.131 + EndValueLengthL() is not called after a StartValueLength().
1.132 +
1.133 + Note:
1.134 + The final buffer containing the entire encoded header is constructed.
1.135 + Returns buffer containing the encoded field constructed
1.136 + from the first call to StartHeaderL.
1.137 +
1.138 + @return Pointer to buffer containing the entire encoded field.
1.139 + Responsibility for deallocating the memory is also passed.
1.140 + @pre The function StartHeaderL should have been called.
1.141 + @post Encoder is reset ready to be used again.
1.142 + @leave HBufC8::NewL leaves, if the new 8 bit heap descriptor cannot be created.
1.143 +
1.144 +*/
1.145 +EXPORT_C HBufC8* CWspHeaderEncoder::EndHeaderL()
1.146 + {
1.147 + __ASSERT_DEBUG(iArray.Count()==1,User::Panic(KWspCodecPanicCategory, EWspCodecPanicEndValueLengthNotCalled));
1.148 + // concatenate array elements and return.
1.149 +
1.150 + HBufC8* outputBuffer = HBufC8::NewL(iTotalLength);
1.151 +
1.152 + CDesC8Array* desc = iArray[0];
1.153 + TInt count = desc->Count();
1.154 + for (TInt jj=0; jj<count; ++jj)
1.155 + {
1.156 + (outputBuffer->Des()).Append((*desc)[jj]);
1.157 + }
1.158 +
1.159 + desc->Reset();
1.160 + iTotalLength=0;
1.161 + return outputBuffer;
1.162 + }
1.163 +
1.164 +/**
1.165 + Encodes input Integer value and adds it to the encoded field. Choice of encoded
1.166 + form dependent on the size of the input.Either ShortInt or LongInt method chosen.
1.167 +
1.168 + @param aInt Integer value to be encoded.
1.169 + @pre StartHeaderL needs to have been called.
1.170 + @leave KErrNoMemory
1.171 +*/
1.172 +EXPORT_C void CWspHeaderEncoder::AddIntegerL(const TUint aInt)
1.173 + {
1.174 + // Determine if its a short or longInt we want
1.175 + (aInt < KTopBitMask) ? AddShortIntL((TUint8) aInt) : AddLongIntL(aInt);
1.176 + }
1.177 +
1.178 +/**
1.179 + Encodes input and adds it to the encoded field. Encodes parameter value using WSP
1.180 + ShortInt method.
1.181 +
1.182 + @param aValue value to be encoded.
1.183 + @pre StartHeaderL needs to have been called.
1.184 + @leave KErrNoMemory
1.185 +*/
1.186 +EXPORT_C void CWspHeaderEncoder::AddShortIntL(const TUint8 aValue)
1.187 + {
1.188 + const TInt arrayCount=iArray.Count();
1.189 + __ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
1.190 + CDesC8Array* desc=iArray[arrayCount-1];
1.191 +
1.192 +
1.193 + // ShortInt shoud be a character 127 or less. With highest bit set to 1.
1.194 + TUint8 shortInt = TWspPrimitiveEncoder::ShortInt(aValue);
1.195 +
1.196 + desc->AppendL(TPtrC8(&shortInt, 1));
1.197 + ++iTotalLength;
1.198 + }
1.199 +
1.200 +
1.201 +/**
1.202 + Encodes input and adds it to the encoded field. For short length the value must
1.203 + be between octet 0 - 31.
1.204 +
1.205 + @param aValue value to be encoded.
1.206 + @pre StartHeaderL needs to have been called.
1.207 + @leave KErrNoMemory, KErrOverflow if the value is greater than 31
1.208 +*/
1.209 +EXPORT_C void CWspHeaderEncoder::AddShortLengthL(const TUint8 aValue)
1.210 + {
1.211 + const TInt arrayCount=iArray.Count();
1.212 + __ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
1.213 + CDesC8Array* desc=iArray[arrayCount-1];
1.214 +
1.215 + // Check if the value is in the correct range ie octet 0-31
1.216 + if(aValue > KUintVarIndicator)
1.217 + User::Leave(KErrOverflow);
1.218 +
1.219 + desc->AppendL(TPtrC8(&aValue, 1));
1.220 + ++iTotalLength;
1.221 + }
1.222 +
1.223 +/**
1.224 + Encodes input and adds it to the encoded field. Encodes parameter value using WSP
1.225 + LongInt method.
1.226 +
1.227 + @param aValue value to be encoded.
1.228 + @pre StartHeaderL needs to have been called.
1.229 + @leave KErrNoMemory
1.230 +*/
1.231 +EXPORT_C void CWspHeaderEncoder::AddLongIntL(const TUint32 aValue)
1.232 + {
1.233 + const TInt arrayCount=iArray.Count();
1.234 + __ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
1.235 + CDesC8Array* desc=iArray[arrayCount-1];
1.236 +
1.237 + HBufC8* buf = TWspPrimitiveEncoder::LongIntL(aValue);
1.238 + CleanupStack::PushL(buf);
1.239 +
1.240 + desc->AppendL(*buf);
1.241 + iTotalLength+=buf->Length();
1.242 +
1.243 + CleanupStack::PopAndDestroy(buf);
1.244 + }
1.245 +
1.246 +/**
1.247 + Encodes input and adds it to the encoded field. Encodes parameter value using WSP
1.248 + UIntVar method.
1.249 +
1.250 + @param aInt value to be encoded.
1.251 + @pre StartHeaderL needs to have been called.
1.252 + @leave KErrNoMemory
1.253 +*/
1.254 +EXPORT_C void CWspHeaderEncoder::AddUintVarL(const TUint aInt)
1.255 + {
1.256 + const TInt arrayCount=iArray.Count();
1.257 + __ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
1.258 + CDesC8Array* desc=iArray[arrayCount-1];
1.259 +
1.260 + HBufC8* buf = TWspPrimitiveEncoder::UintVarL(aInt);
1.261 + CleanupStack::PushL(buf);
1.262 +
1.263 + desc->AppendL(*buf);
1.264 + iTotalLength+=buf->Length();
1.265 +
1.266 + CleanupStack::PopAndDestroy(buf);
1.267 + }
1.268 +
1.269 +/**
1.270 + Encodes input and adds it to the encoded field. Encodes parameter value using WSP
1.271 + TextString method.
1.272 +
1.273 + @param aText value to be encoded.
1.274 + @pre StartHeaderL needs to have been called.
1.275 + @leave KErrNoMemory
1.276 +*/
1.277 +EXPORT_C void CWspHeaderEncoder::AddTextStringL(const TDesC8& aText)
1.278 + {
1.279 + const TInt arrayCount=iArray.Count();
1.280 + __ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
1.281 + CDesC8Array* desc=iArray[arrayCount-1];
1.282 +
1.283 + HBufC8* buf = TWspPrimitiveEncoder::TextStringL(aText);
1.284 + CleanupStack::PushL(buf);
1.285 + desc->AppendL(*buf);
1.286 + iTotalLength+=buf->Length();
1.287 + CleanupStack::PopAndDestroy(buf);
1.288 + }
1.289 +
1.290 +/**
1.291 + Encodes input and adds it to the encoded field. Encodes parameter value using WSP
1.292 + TextString method.
1.293 +
1.294 + @param aText value to be encoded.
1.295 + @pre StartHeaderL needs to have been called.
1.296 + @leave KErrNoMemory
1.297 +*/
1.298 +EXPORT_C void CWspHeaderEncoder::AddTextStringL(const RString& /* aText */)
1.299 + {
1.300 + User::Leave(KErrNotSupported);
1.301 + }
1.302 +
1.303 +/**
1.304 + Encodes input and adds it to the encoded field.Encodes parameter value using WSP
1.305 + Date method.
1.306 +
1.307 + @param aDate value to be encoded.
1.308 + @pre StartHeaderL needs to have been called.
1.309 + @leave KErrNoMemory
1.310 +*/
1.311 +EXPORT_C void CWspHeaderEncoder::AddDateL(const TDateTime aDate)
1.312 + {
1.313 + const TInt arrayCount=iArray.Count();
1.314 + __ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
1.315 + CDesC8Array* desc=iArray[arrayCount-1];
1.316 +
1.317 + HBufC8* buf = TWspPrimitiveEncoder::DateL(aDate);
1.318 + CleanupStack::PushL(buf);
1.319 + desc->AppendL(*buf);
1.320 + iTotalLength+=buf->Length();
1.321 + CleanupStack::PopAndDestroy(buf);
1.322 + }
1.323 +
1.324 +/**
1.325 + Encodes input and adds it to the encoded field. Adds value as-is to the encoded field.
1.326 +
1.327 + @param aToken parameter added without encodeing. Should be a valid WSP token,
1.328 + a 8 bit number > 0x7F (i.e. top bit set).
1.329 + @pre StartHeaderL and StartValueLengthL should have been called.
1.330 + @post EndValueLengthL needs to be called subsequently.
1.331 +*/
1.332 +EXPORT_C void CWspHeaderEncoder::AddTokenL(const TUint8 aToken)
1.333 + {
1.334 + const TInt arrayCount=iArray.Count();
1.335 + __ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
1.336 + CDesC8Array* desc=iArray[arrayCount-1];
1.337 +
1.338 + TUint8 shortInt = (TUint8) (aToken);
1.339 + desc->AppendL(TPtrC8(&shortInt, 1));
1.340 + ++iTotalLength;
1.341 + }
1.342 +
1.343 +/**
1.344 + Encodes input and adds it to the encoded field. Encodes parameter value using WSP
1.345 + TokenText method.
1.346 +
1.347 + @param aTokenText value to be encoded.
1.348 + @leave KErrNoMemory
1.349 +*/
1.350 +EXPORT_C void CWspHeaderEncoder::AddTokenTextL(const TDesC8& aTokenText)
1.351 + {
1.352 + const TInt arrayCount=iArray.Count();
1.353 + __ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
1.354 +
1.355 + // Step through token text passed in and ensure there are no invalid characters
1.356 + const TInt tokenTextLength = aTokenText.Length();
1.357 + for( TInt ii = 0; ii<tokenTextLength; ++ii)
1.358 + {
1.359 + TUint8 currentChar = aTokenText[ii];
1.360 + if( KTxtSeparators().Locate(currentChar) != KErrNotFound )
1.361 + User::Leave(KErrCorrupt);
1.362 + }
1.363 + // Token text does not contain any invalid characters
1.364 + HBufC8* buf = TWspPrimitiveEncoder::TextStringL(aTokenText);
1.365 + CleanupStack::PushL(buf);
1.366 + CDesC8Array* desc=iArray[arrayCount-1];
1.367 + desc->AppendL(*buf);
1.368 + iTotalLength += buf->Length();
1.369 + CleanupStack::PopAndDestroy(buf);
1.370 + }
1.371 +
1.372 +/**
1.373 + Encodes input and adds it to the encoded field. Adds value as-is to the encoded field.
1.374 +
1.375 + @param aData value to be encoded.
1.376 + @leave KErrNoMemory
1.377 +*/
1.378 +EXPORT_C void CWspHeaderEncoder::AddDataL(const TDesC8& aData)
1.379 + {
1.380 + const TInt arrayCount=iArray.Count();
1.381 + __ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
1.382 + CDesC8Array* desc=iArray[arrayCount-1];
1.383 + desc->AppendL(aData);
1.384 + iTotalLength += aData.Length();
1.385 + }
1.386 +
1.387 +/**
1.388 + From calling this function, the length in bytes of all encodings added subsequently will
1.389 + be calculated and stored as part of the encoded string, as specified in WSP spec.Can be nested. i.e.
1.390 + @code
1.391 + encoder->StartHeaderL();
1.392 + encoder->StartValueLengthL();
1.393 + encoder->StartValueLengthL();
1.394 + encoder->AddLongIntL();
1.395 + encoder->EndValueLengthL();
1.396 + encoder->AddTextStringL();
1.397 + encoder->EndValueLengthL();
1.398 + HBufC8* output = encoder->EndHeaderL();
1.399 + @endcode
1.400 +
1.401 + @pre StartHeaderL should have been called.
1.402 + @post EndValueLengthL needs to be called subsequently.
1.403 + @leave KErrNoMemory
1.404 +*/
1.405 +EXPORT_C void CWspHeaderEncoder::StartValueLengthL()
1.406 + {
1.407 + // Create new buffer;
1.408 + CDesC8Array* buffer = new (ELeave) CDesC8ArrayFlat(KDesArrayGranularity);
1.409 + CleanupStack::PushL(buffer);
1.410 + User::LeaveIfError(iArray.Append(buffer));
1.411 + CleanupStack::Pop(buffer);
1.412 + }
1.413 +
1.414 +/**
1.415 + Needs to be called at the point in the construction of a header when ValueLength
1.416 + can be calculated.
1.417 +
1.418 + @pre StartHeaderL and StartValueLengthL should have been called.
1.419 + @post ValueLength has been calculated and added, together with the
1.420 + encoded header, to the internal representation of the header buffer.
1.421 + @leave KErrNoMemory
1.422 +*/
1.423 +EXPORT_C void CWspHeaderEncoder::EndValueLengthL()
1.424 + {
1.425 + const TInt arrayCount=iArray.Count();
1.426 + __ASSERT_ALWAYS(arrayCount>1,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartValueLengthNotCalled));
1.427 +
1.428 + // Calculate the length of the current buffer.
1.429 + // and append it onto the previous buffer. [length value, then data]
1.430 + TUint32 valueLength=0;
1.431 +
1.432 +
1.433 + CDesC8Array* desc=iArray[arrayCount-1]; // current descriptor being dealt with
1.434 + CDesC8Array* parentDesc=iArray[arrayCount-2]; // parent descriptor to which it must be added.
1.435 +
1.436 + TInt buffersToAdd=desc->Count();
1.437 + TInt ii=buffersToAdd;
1.438 +
1.439 + // Check the length of all parameters (not the first element in tha array, the field name)
1.440 + while (ii)
1.441 + valueLength+=(*desc)[--ii].Length();
1.442 +
1.443 + // Remove desc from array. Will have to delete also.
1.444 + iArray.Remove(arrayCount-1);
1.445 + CleanupStack::PushL(desc);
1.446 +
1.447 + // Depending of size of the length save as number or UintVar
1.448 + if (valueLength < KUintVarIndicator)
1.449 + {
1.450 + // Value length represented by an 8 bit number.
1.451 + AddShortLengthL( (TUint8) valueLength);
1.452 + }
1.453 + else
1.454 + {
1.455 + // Value length represented by an 8bit value indicating a UIntVar follows,
1.456 + // followed by a UIntVar
1.457 + AddShortLengthL( (TUint8) KUintVarIndicator);
1.458 + AddUintVarL(valueLength);
1.459 + }
1.460 +
1.461 + // Add field value, parameters etc.
1.462 + ii=0;
1.463 + while (ii<buffersToAdd)
1.464 + parentDesc->AppendL((*desc)[ii++]);
1.465 +
1.466 + CleanupStack::PopAndDestroy(desc);
1.467 + }
1.468 +
1.469 +
1.470 +
1.471 +
1.472 +//**********************************************************************************
1.473 +
1.474 +/**
1.475 + Takes a TUint8 parameter, and sets the top bit. As specified for the WSP ShortInt
1.476 + encoding method.
1.477 +
1.478 + @param aValue number to be encoded.
1.479 + @return Output, encoded as a TUint8, representation of the header buffer.
1.480 + If input greater that 127 (invalid input), returns 0
1.481 +*/
1.482 +EXPORT_C TUint8 TWspPrimitiveEncoder::ShortInt(const TUint8 aValue)
1.483 + {
1.484 + // ShortInt should be a character 127 or less. With highest bit set to 1.
1.485 + return (aValue > KWSPQuoteCharacter) ? (TUint8) 0: (TUint8) (aValue | KTopBitMask);
1.486 + }
1.487 +
1.488 +/**
1.489 + Takes a TUint32 parameter and encodes it using the WSP specified LongInt method.
1.490 +
1.491 + @param aValue number to be encoded.
1.492 + @return Output, encoded HBufC8 buffer.
1.493 + @leave KErrNoMemory
1.494 +*/
1.495 +EXPORT_C HBufC8* TWspPrimitiveEncoder::LongIntL(const TUint32 aValue)
1.496 + {
1.497 + // Consists of size and up to number of 30 bytes.
1.498 + // for a TInt32 the maximum is 4 bytes long.
1.499 + // Check size of number, to determine number of bytes needed to store it.
1.500 +
1.501 + TUint8 size = 0; // maximum value is 4 with a 32bit integer
1.502 + TUint32 value=aValue;
1.503 + do {
1.504 + ++size;
1.505 + value >>=KLongIntOctetShift; ; // shift by 8 bits.
1.506 + } while (value>0);
1.507 +
1.508 + HBufC8* output = HBufC8::NewL(size+1);
1.509 + TPtr8 outPtr(output->Des());
1.510 +
1.511 + outPtr.Append(size);
1.512 + TInt ii = size;
1.513 + while (ii-- >0)
1.514 + {
1.515 + outPtr.Append( (TUint8) (aValue>>ii*KLongIntOctetShift) );
1.516 + }
1.517 +
1.518 + return output;
1.519 + }
1.520 +
1.521 +/**
1.522 + Takes a TUint32 parameter and encodes it using the WSP specified UintVar method.
1.523 +
1.524 + @param aInt number to be encoded.
1.525 + @return Output, encoded HBufC8 buffer.
1.526 + @leave KErrNoMemory
1.527 +*/
1.528 +EXPORT_C HBufC8* TWspPrimitiveEncoder::UintVarL(const TUint32 aInt)
1.529 + {
1.530 + TUint8 size = 0; // maximum value is 5 with a 32bit integer
1.531 + TUint32 value=aInt;
1.532 + do {
1.533 + ++size;
1.534 + value >>=KUIntVarOctetShift; ; // shift by 7 bits.
1.535 + } while (value>0);
1.536 +
1.537 + HBufC8* output = HBufC8::NewL(size);
1.538 + TPtr8 outPtr(output->Des());
1.539 +
1.540 + TInt ii = size;
1.541 + while (--ii > 0)
1.542 + {
1.543 + outPtr.Append( (TUint8)(aInt>>(KUIntVarOctetShift*(ii)) & KWSPQuoteCharacter) | KCarryBitMask);
1.544 + }
1.545 +
1.546 + // Finally the first 7 bits, last octet, do not set first bit.
1.547 + outPtr.Append( (TUint8)(aInt & KWSPQuoteCharacter) ); // Add even if 0 value.
1.548 +
1.549 + return output;
1.550 + }
1.551 +
1.552 +/**
1.553 + Takes a RString parameter and encodes it using the WSP specified TextString method.
1.554 +
1.555 + @param aText string to be encoded.
1.556 + @return Output, encoded HBufC8 buffer.
1.557 + @leave KErrNoMemory
1.558 +*/
1.559 +EXPORT_C HBufC8* TWspPrimitiveEncoder::TextStringL(const RString /* aText*/ )
1.560 + {
1.561 + User::Leave(KErrNotSupported);
1.562 + return NULL;
1.563 + }
1.564 +
1.565 +/**
1.566 + Takes a TDesC8 parameter and encodes it using the WSP specified TextString method.
1.567 +
1.568 + @param aText string to be encoded.
1.569 + @return Output, encoded HBufC8 buffer.
1.570 + @leave KErrNoMemory
1.571 +*/
1.572 +EXPORT_C HBufC8* TWspPrimitiveEncoder::TextStringL(const TDesC8& aText)
1.573 + {
1.574 + HBufC8* output=NULL;
1.575 + TInt stringLength = aText.Length();
1.576 + TUint8 firstChar = 0;
1.577 + TUint8 lastChar = 0;
1.578 + if(stringLength>0)
1.579 + {
1.580 + firstChar = aText[0];
1.581 + lastChar = aText[stringLength-1];
1.582 + }
1.583 +
1.584 + TPtr8 outPtr(NULL,0);
1.585 + if (firstChar > KWSPQuoteCharacter)
1.586 + {
1.587 + // Apply WSP rule: first character of the string not 7bit add QuoteCharacter.
1.588 + // Add the quote character and include space for the NULL character
1.589 + stringLength+=2;
1.590 + output = HBufC8::NewL(stringLength);
1.591 + outPtr.Set(output->Des());
1.592 +
1.593 + outPtr.Append(KWSPQuoteCharacter);
1.594 + outPtr.Append(aText);
1.595 + }
1.596 + else if (firstChar==KWSPQuote && lastChar==KWSPQuote)
1.597 + {
1.598 + // Apply WSP rule: if quoted string, remove the closing quote
1.599 + output = HBufC8::NewL(stringLength);
1.600 + outPtr.Set(output->Des());
1.601 + outPtr.Append(aText);
1.602 + outPtr.SetLength(stringLength-1);
1.603 + }
1.604 + else
1.605 + {
1.606 + stringLength+=1; // terminating NULL char
1.607 + output = HBufC8::NewL(stringLength);
1.608 + outPtr.Set(output->Des());
1.609 + outPtr.Append(aText);
1.610 + }
1.611 +
1.612 + // Terminate string with 0x00
1.613 + outPtr.Append(KWspStringTerminator);
1.614 + return output;
1.615 + }
1.616 +
1.617 +/**
1.618 + Takes a TDateTime parameter and encodes it using the WSP specified Date encoding method.
1.619 +
1.620 + @param aDate value to be encoded.
1.621 + @return Output, encoded HBufC8 buffer.
1.622 + @leave KErrNoMemory
1.623 +*/
1.624 +EXPORT_C HBufC8* TWspPrimitiveEncoder::DateL(const TDateTime aDate)
1.625 + {
1.626 + TTime baseTime(TDateTime(1970,EJanuary,0,0,0,0,0));
1.627 + TTime dateTime(aDate);
1.628 + TTimeIntervalSeconds interval;
1.629 + dateTime.SecondsFrom(baseTime, interval);
1.630 +
1.631 + return LongIntL(interval.Int());
1.632 + }
1.633 +