sl@0
|
1 |
// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
//
|
sl@0
|
15 |
|
sl@0
|
16 |
#include <e32base.h>
|
sl@0
|
17 |
#include <stringpool.h>
|
sl@0
|
18 |
#include <wspdecoder.h>
|
sl@0
|
19 |
|
sl@0
|
20 |
// Constants
|
sl@0
|
21 |
const TUint8 KWapQuote = 0x7F;
|
sl@0
|
22 |
const TUint8 KCarryBitMask = 0x80;
|
sl@0
|
23 |
#define KTopBitMask KCarryBitMask
|
sl@0
|
24 |
const TUint8 KTop3BitSet = 0x70;
|
sl@0
|
25 |
const TUint8 KQuoteChar = '\"';
|
sl@0
|
26 |
|
sl@0
|
27 |
// Panic category
|
sl@0
|
28 |
_LIT(KUriPanicCategory,"WSPDECODER");
|
sl@0
|
29 |
|
sl@0
|
30 |
|
sl@0
|
31 |
//***********************************************************************
|
sl@0
|
32 |
// TWspHeaderSegmenter
|
sl@0
|
33 |
//**********************************************************************/
|
sl@0
|
34 |
|
sl@0
|
35 |
|
sl@0
|
36 |
/**
|
sl@0
|
37 |
NextL iterates through the buffer. Each call returns a TWspField in the paramater.
|
sl@0
|
38 |
|
sl@0
|
39 |
@param aHeader Out - a TWspField containing the header <name,value> pair.
|
sl@0
|
40 |
@warning The TWspField::iHdrName will be opened internally.
|
sl@0
|
41 |
It must be closed by the caller before this class is destroyed.
|
sl@0
|
42 |
@return KErrNone if next field is returned
|
sl@0
|
43 |
KErrNotFound at the end of the buffer - no TWspField param returned
|
sl@0
|
44 |
KErrCorrupt if segmenting does not parse correctly
|
sl@0
|
45 |
@leave RStringPool::OpenFStringL StringPool leave code if opening string fails.
|
sl@0
|
46 |
*/
|
sl@0
|
47 |
EXPORT_C TInt TWspHeaderSegmenter::NextL(TWspField& aHeader)
|
sl@0
|
48 |
{
|
sl@0
|
49 |
// have we run out of buffer?
|
sl@0
|
50 |
if (iOffset >= iBuffer.Length())
|
sl@0
|
51 |
return KErrNotFound;
|
sl@0
|
52 |
|
sl@0
|
53 |
// Set decoder to current buffer
|
sl@0
|
54 |
TWspPrimitiveDecoder decoder(iBuffer.Mid(iOffset));
|
sl@0
|
55 |
TInt bufLen = 0;
|
sl@0
|
56 |
|
sl@0
|
57 |
|
sl@0
|
58 |
// Get the Field Name
|
sl@0
|
59 |
switch(decoder.VarType())
|
sl@0
|
60 |
{
|
sl@0
|
61 |
case TWspPrimitiveDecoder::EString:
|
sl@0
|
62 |
{
|
sl@0
|
63 |
TPtrC8 name;
|
sl@0
|
64 |
bufLen = decoder.String(name);
|
sl@0
|
65 |
if (bufLen < KErrNone) return bufLen;
|
sl@0
|
66 |
aHeader.iHdrName = iPool.OpenFStringL(name);
|
sl@0
|
67 |
}
|
sl@0
|
68 |
break;
|
sl@0
|
69 |
|
sl@0
|
70 |
case TWspPrimitiveDecoder::E7BitVal:
|
sl@0
|
71 |
{
|
sl@0
|
72 |
TUint8 name;
|
sl@0
|
73 |
bufLen = decoder.Val7Bit(name);
|
sl@0
|
74 |
if (bufLen < KErrNone) return bufLen;
|
sl@0
|
75 |
|
sl@0
|
76 |
aHeader.iHdrName = iPool.StringF(name, iStringTable);
|
sl@0
|
77 |
}
|
sl@0
|
78 |
break;
|
sl@0
|
79 |
|
sl@0
|
80 |
default: // header name can't be anything else
|
sl@0
|
81 |
return KErrCorrupt;
|
sl@0
|
82 |
}
|
sl@0
|
83 |
|
sl@0
|
84 |
// move our pointer past header name
|
sl@0
|
85 |
iOffset += bufLen;
|
sl@0
|
86 |
|
sl@0
|
87 |
|
sl@0
|
88 |
// Get the value buffer by figuring out the type, then set the pointer to span the entire
|
sl@0
|
89 |
// value. Note - further parsing will happen later to pull out specific value data.
|
sl@0
|
90 |
switch(decoder.VarType())
|
sl@0
|
91 |
{
|
sl@0
|
92 |
case TWspPrimitiveDecoder::ELengthVal:
|
sl@0
|
93 |
{
|
sl@0
|
94 |
TInt len;
|
sl@0
|
95 |
bufLen = decoder.LengthVal(len);
|
sl@0
|
96 |
bufLen += len;
|
sl@0
|
97 |
}
|
sl@0
|
98 |
break;
|
sl@0
|
99 |
case TWspPrimitiveDecoder::EQuotedString:
|
sl@0
|
100 |
case TWspPrimitiveDecoder::EString:
|
sl@0
|
101 |
{
|
sl@0
|
102 |
TPtrC8 strBuf;
|
sl@0
|
103 |
bufLen = decoder.String(strBuf);
|
sl@0
|
104 |
}
|
sl@0
|
105 |
break;
|
sl@0
|
106 |
case TWspPrimitiveDecoder::E7BitVal:
|
sl@0
|
107 |
bufLen = 1;
|
sl@0
|
108 |
break;
|
sl@0
|
109 |
default:
|
sl@0
|
110 |
return KErrCorrupt;
|
sl@0
|
111 |
}
|
sl@0
|
112 |
|
sl@0
|
113 |
if (bufLen < 0)
|
sl@0
|
114 |
return bufLen;
|
sl@0
|
115 |
|
sl@0
|
116 |
if (iOffset + bufLen > iBuffer.Length())
|
sl@0
|
117 |
return KErrCorrupt;
|
sl@0
|
118 |
|
sl@0
|
119 |
aHeader.iValBuffer.Set(iBuffer.Mid(iOffset, bufLen));
|
sl@0
|
120 |
iOffset += bufLen;
|
sl@0
|
121 |
return KErrNone;
|
sl@0
|
122 |
}
|
sl@0
|
123 |
|
sl@0
|
124 |
|
sl@0
|
125 |
//
|
sl@0
|
126 |
// WAP-WSP 8.4.1.2
|
sl@0
|
127 |
//
|
sl@0
|
128 |
|
sl@0
|
129 |
/**
|
sl@0
|
130 |
Looks at the byte currently pointed at in this buffer and returns the type.
|
sl@0
|
131 |
|
sl@0
|
132 |
@return TWspHeaderType - the type of this data octet
|
sl@0
|
133 |
*/
|
sl@0
|
134 |
EXPORT_C TWspPrimitiveDecoder::TWspHeaderType TWspPrimitiveDecoder::VarType() const
|
sl@0
|
135 |
{
|
sl@0
|
136 |
TWspHeaderType type = ENotSet;
|
sl@0
|
137 |
|
sl@0
|
138 |
// Check that the offset has not overflowed the buffer
|
sl@0
|
139 |
if( iOffset >= iBuffer.Length() )
|
sl@0
|
140 |
return type;
|
sl@0
|
141 |
|
sl@0
|
142 |
TInt octet = iBuffer[iOffset];
|
sl@0
|
143 |
|
sl@0
|
144 |
if (octet >= 0 && octet <= 31)
|
sl@0
|
145 |
type = ELengthVal;
|
sl@0
|
146 |
else if (octet == 34)
|
sl@0
|
147 |
type = EQuotedString;
|
sl@0
|
148 |
else if (octet >= 32 && octet <= 127)
|
sl@0
|
149 |
type = EString;
|
sl@0
|
150 |
else if (octet >= 128 && octet <= 255)
|
sl@0
|
151 |
type = E7BitVal;
|
sl@0
|
152 |
|
sl@0
|
153 |
return type;
|
sl@0
|
154 |
}
|
sl@0
|
155 |
|
sl@0
|
156 |
|
sl@0
|
157 |
/**
|
sl@0
|
158 |
Returns length of the data following this byte.
|
sl@0
|
159 |
|
sl@0
|
160 |
@pre iBuffer[iOffset] must be valid, VarType() == TWspHeaderType::ELengthVal
|
sl@0
|
161 |
@post internal offset gets updated to move past this primitive
|
sl@0
|
162 |
@param aVal Out - the length encoded in this byte that indicates the size of the
|
sl@0
|
163 |
data that follows.
|
sl@0
|
164 |
@return postive number indicating the number of bytes read from the buffer
|
sl@0
|
165 |
KErrCorrupt if data is not formatted correctly.
|
sl@0
|
166 |
*/
|
sl@0
|
167 |
EXPORT_C TInt TWspPrimitiveDecoder::LengthVal(TInt& aVal)
|
sl@0
|
168 |
{
|
sl@0
|
169 |
// have we run out of buffer?
|
sl@0
|
170 |
if (iOffset >= iBuffer.Length())
|
sl@0
|
171 |
return KErrCorrupt;
|
sl@0
|
172 |
|
sl@0
|
173 |
TInt bufLen = 0;
|
sl@0
|
174 |
aVal = iBuffer[iOffset++];
|
sl@0
|
175 |
|
sl@0
|
176 |
if (aVal == 31)
|
sl@0
|
177 |
{
|
sl@0
|
178 |
TUint32 uintVarLen = 0;
|
sl@0
|
179 |
bufLen = UintVar(uintVarLen);
|
sl@0
|
180 |
if (bufLen < KErrNone) return bufLen;
|
sl@0
|
181 |
aVal = (TInt)uintVarLen;
|
sl@0
|
182 |
}
|
sl@0
|
183 |
|
sl@0
|
184 |
// add the 1 byte read at to get first aVal
|
sl@0
|
185 |
++bufLen;
|
sl@0
|
186 |
return bufLen;
|
sl@0
|
187 |
}
|
sl@0
|
188 |
|
sl@0
|
189 |
|
sl@0
|
190 |
/**
|
sl@0
|
191 |
Returns a TPtrC holding the string the buffer currently points at without the NULL
|
sl@0
|
192 |
termination. If the String type is a quoted string then the quotes are not included
|
sl@0
|
193 |
in the returned buffer.
|
sl@0
|
194 |
|
sl@0
|
195 |
@pre iBuffer[iOffset] must be valid, VarType() == TWspType::EString
|
sl@0
|
196 |
@post internal offset gets updated to move past this primitive
|
sl@0
|
197 |
@param aString Out - the string
|
sl@0
|
198 |
@return postive number indicating the number of bytes read from the buffer
|
sl@0
|
199 |
KErrCorrupt if data is not formatted correctly.
|
sl@0
|
200 |
*/
|
sl@0
|
201 |
EXPORT_C TInt TWspPrimitiveDecoder::String(TPtrC8& aString)
|
sl@0
|
202 |
{
|
sl@0
|
203 |
TWspHeaderType type = VarType();
|
sl@0
|
204 |
if( type != EString && type != EQuotedString)
|
sl@0
|
205 |
return KErrCorrupt;
|
sl@0
|
206 |
|
sl@0
|
207 |
TInt nullIndex = iBuffer.Mid(iOffset).Locate('\0');
|
sl@0
|
208 |
if( nullIndex == KErrNotFound )
|
sl@0
|
209 |
return KErrCorrupt;
|
sl@0
|
210 |
|
sl@0
|
211 |
// Set buffer to data not including the NULL terminator
|
sl@0
|
212 |
TPtrC8 buf = iBuffer.Mid(iOffset, nullIndex);
|
sl@0
|
213 |
|
sl@0
|
214 |
// is there a WAP Quote (0x7F) or a " at the start - step over it
|
sl@0
|
215 |
TInt bufferOffset = 0;
|
sl@0
|
216 |
const TUint8 firstByte = iBuffer[iOffset];
|
sl@0
|
217 |
if( firstByte == KQuoteChar || firstByte == KWapQuote )
|
sl@0
|
218 |
++bufferOffset;
|
sl@0
|
219 |
|
sl@0
|
220 |
// Set the descriptor with the correct buffer segment
|
sl@0
|
221 |
aString.Set(buf.Mid(bufferOffset));
|
sl@0
|
222 |
|
sl@0
|
223 |
// Step over the NULL
|
sl@0
|
224 |
++nullIndex;
|
sl@0
|
225 |
|
sl@0
|
226 |
// update the offset
|
sl@0
|
227 |
iOffset += nullIndex;
|
sl@0
|
228 |
|
sl@0
|
229 |
return nullIndex;
|
sl@0
|
230 |
}
|
sl@0
|
231 |
|
sl@0
|
232 |
/**
|
sl@0
|
233 |
Returns a token, a short int or an octet value with the top bit cleared
|
sl@0
|
234 |
|
sl@0
|
235 |
@pre iBuffer[iOffset] must be valid, VarType() == TWspHeaderType::E7BitVal
|
sl@0
|
236 |
@post internal offset gets updated to move past this primitive
|
sl@0
|
237 |
@param aVal Out - the 7 bit value with top bit cleared
|
sl@0
|
238 |
@return postive number indicating the number of bytes read from the buffer
|
sl@0
|
239 |
KErrCorrupt if data is not formatted correctly.
|
sl@0
|
240 |
*/
|
sl@0
|
241 |
EXPORT_C TInt TWspPrimitiveDecoder::Val7Bit(TUint8& aVal)
|
sl@0
|
242 |
{
|
sl@0
|
243 |
// have we run out of buffer?
|
sl@0
|
244 |
if (iOffset >= iBuffer.Length())
|
sl@0
|
245 |
return KErrCorrupt;
|
sl@0
|
246 |
|
sl@0
|
247 |
aVal = (TUint8)(iBuffer[iOffset] & KWapQuote);
|
sl@0
|
248 |
++iOffset;
|
sl@0
|
249 |
|
sl@0
|
250 |
// 1 byte read
|
sl@0
|
251 |
return 1;
|
sl@0
|
252 |
}
|
sl@0
|
253 |
|
sl@0
|
254 |
|
sl@0
|
255 |
/**
|
sl@0
|
256 |
Returns an Integer - could be short or long.
|
sl@0
|
257 |
|
sl@0
|
258 |
@pre iBuffer[iOffset] must be valid, VarType() == TWspHeaderType::ELengthVal or
|
sl@0
|
259 |
VarType() == TWspHeaderType::E7BitVal
|
sl@0
|
260 |
@post internal offset gets updated to move past this primitive
|
sl@0
|
261 |
@param aVal Out - the long int
|
sl@0
|
262 |
@return postive number indicating the number of bytes read from the buffer
|
sl@0
|
263 |
KErrCorrupt if data is not formatted correctly.
|
sl@0
|
264 |
*/
|
sl@0
|
265 |
EXPORT_C TInt TWspPrimitiveDecoder::Integer(TUint32& aVal)
|
sl@0
|
266 |
{
|
sl@0
|
267 |
// have we run out of buffer?
|
sl@0
|
268 |
if (iOffset >= iBuffer.Length())
|
sl@0
|
269 |
return KErrCorrupt;
|
sl@0
|
270 |
|
sl@0
|
271 |
TInt bufLen = 0;
|
sl@0
|
272 |
|
sl@0
|
273 |
// read the first byte
|
sl@0
|
274 |
aVal = iBuffer[iOffset];
|
sl@0
|
275 |
|
sl@0
|
276 |
// short integers have the top bit set
|
sl@0
|
277 |
if (aVal & KTopBitMask)
|
sl@0
|
278 |
{
|
sl@0
|
279 |
aVal &= KWapQuote;
|
sl@0
|
280 |
++iOffset;
|
sl@0
|
281 |
++bufLen;
|
sl@0
|
282 |
}
|
sl@0
|
283 |
else
|
sl@0
|
284 |
{
|
sl@0
|
285 |
bufLen = LongInt(aVal);
|
sl@0
|
286 |
}
|
sl@0
|
287 |
|
sl@0
|
288 |
return bufLen;
|
sl@0
|
289 |
}
|
sl@0
|
290 |
|
sl@0
|
291 |
/**
|
sl@0
|
292 |
Returns a long int the buffer is currently pointing at.
|
sl@0
|
293 |
|
sl@0
|
294 |
@pre iBuffer[iOffset] must be valid, VarType() == TWspHeaderType::ELengthVal
|
sl@0
|
295 |
@post internal offset gets updated to move past this primitive
|
sl@0
|
296 |
@param aVal Out - the long int
|
sl@0
|
297 |
@return postive number indicating the number of bytes read from the buffer
|
sl@0
|
298 |
KErrCorrupt if data is not formatted correctly.
|
sl@0
|
299 |
*/
|
sl@0
|
300 |
EXPORT_C TInt TWspPrimitiveDecoder::LongInt(TUint32& aVal)
|
sl@0
|
301 |
{
|
sl@0
|
302 |
// have we run out of buffer?
|
sl@0
|
303 |
if (iOffset >= iBuffer.Length())
|
sl@0
|
304 |
return KErrCorrupt;
|
sl@0
|
305 |
|
sl@0
|
306 |
__ASSERT_DEBUG(aVal <= KMaxTUint, User::Panic(KUriPanicCategory, EWspDecoderLongIntOverflow));
|
sl@0
|
307 |
// initialize
|
sl@0
|
308 |
aVal = 0;
|
sl@0
|
309 |
|
sl@0
|
310 |
// Get num bytes encoding [len] [byte1] ... [byten]
|
sl@0
|
311 |
// we are positioned at that location in the source descriptor
|
sl@0
|
312 |
TUint8 numBytes = 0;
|
sl@0
|
313 |
TInt bufLen = Val7Bit(numBytes);
|
sl@0
|
314 |
if (bufLen < KErrNone) return bufLen;
|
sl@0
|
315 |
|
sl@0
|
316 |
// len can be up to 30 and verify we have enough buffer
|
sl@0
|
317 |
if (numBytes > 30 || numBytes > iBuffer.Mid(iOffset).Length())
|
sl@0
|
318 |
return KErrCorrupt;
|
sl@0
|
319 |
|
sl@0
|
320 |
// Loop over the buffer, taking each byte and shifting it in count times.
|
sl@0
|
321 |
for (TInt count = 0; count < numBytes ; ++count)
|
sl@0
|
322 |
aVal = (aVal << 8) + iBuffer[iOffset++];
|
sl@0
|
323 |
|
sl@0
|
324 |
return (bufLen + numBytes);
|
sl@0
|
325 |
}
|
sl@0
|
326 |
|
sl@0
|
327 |
/**
|
sl@0
|
328 |
Returns a TUint32
|
sl@0
|
329 |
|
sl@0
|
330 |
@pre iBuffer[iOffset] must be valid, VarType() == TWspHeaderType::ELengthVal or
|
sl@0
|
331 |
VarType() == TWspHeaderType::E7BitVal
|
sl@0
|
332 |
@post internal offset gets updated to move past this primitive
|
sl@0
|
333 |
@param aVal Out - the TUint32 decoded
|
sl@0
|
334 |
@return postive number indicating the number of bytes read from the buffer
|
sl@0
|
335 |
KErrCorrupt if data is not formatted correctly.
|
sl@0
|
336 |
*/
|
sl@0
|
337 |
EXPORT_C TInt TWspPrimitiveDecoder::UintVar(TUint32& aVal)
|
sl@0
|
338 |
{
|
sl@0
|
339 |
// have we run out of buffer?
|
sl@0
|
340 |
if (iOffset >= iBuffer.Length())
|
sl@0
|
341 |
return KErrCorrupt;
|
sl@0
|
342 |
|
sl@0
|
343 |
// initialize return val
|
sl@0
|
344 |
aVal = 0;
|
sl@0
|
345 |
|
sl@0
|
346 |
// maximum length for a uintvar is 5
|
sl@0
|
347 |
TInt lenLeft = Min(iBuffer.Mid(iOffset).Length(), 5);
|
sl@0
|
348 |
|
sl@0
|
349 |
// get the first octet
|
sl@0
|
350 |
TUint8 byte = iBuffer[iOffset++];
|
sl@0
|
351 |
TInt numBytes = 1;
|
sl@0
|
352 |
|
sl@0
|
353 |
--lenLeft;
|
sl@0
|
354 |
|
sl@0
|
355 |
// Check if any of the top 3 bits, ignoring the very top 'continue' bit, are set.
|
sl@0
|
356 |
// Later if we see that this is a 5 byte number - we'll know it is corrupt.
|
sl@0
|
357 |
// Encoding uses 7 bits/number 7x5=35 and we only support a maxiumum number
|
sl@0
|
358 |
// of 32 bits.
|
sl@0
|
359 |
TBool topThreeBitsSet = byte & KTop3BitSet;
|
sl@0
|
360 |
|
sl@0
|
361 |
// copy over data from the byte into our return value (the top bit is a carry bit)
|
sl@0
|
362 |
aVal = byte & KWapQuote;
|
sl@0
|
363 |
|
sl@0
|
364 |
// while the 'continue' bit is set and we have more data
|
sl@0
|
365 |
while ((byte & KCarryBitMask) && (lenLeft > 0))
|
sl@0
|
366 |
{
|
sl@0
|
367 |
// shift our last value up
|
sl@0
|
368 |
aVal <<= 7;
|
sl@0
|
369 |
// get the next byte
|
sl@0
|
370 |
byte = iBuffer[iOffset++];
|
sl@0
|
371 |
// copy it over to the lowest byte
|
sl@0
|
372 |
aVal |= byte & KWapQuote;
|
sl@0
|
373 |
--lenLeft;
|
sl@0
|
374 |
++numBytes;
|
sl@0
|
375 |
}
|
sl@0
|
376 |
|
sl@0
|
377 |
// last octet has continue bit set ... NOT allowed Or
|
sl@0
|
378 |
// this was encoded wrong - can't have a number bigger than 32 bits
|
sl@0
|
379 |
if ((byte & KCarryBitMask) || (numBytes == 5 && topThreeBitsSet))
|
sl@0
|
380 |
return KErrCorrupt;
|
sl@0
|
381 |
|
sl@0
|
382 |
// number of bytes read
|
sl@0
|
383 |
return numBytes;
|
sl@0
|
384 |
}
|
sl@0
|
385 |
|
sl@0
|
386 |
|
sl@0
|
387 |
/**
|
sl@0
|
388 |
Returns a formatted version string
|
sl@0
|
389 |
|
sl@0
|
390 |
@pre iBuffer[iOffset] must be valid, VarType() == TWspHeaderType::ELengthVal
|
sl@0
|
391 |
@post internal offset gets updated to move past this primitive
|
sl@0
|
392 |
@param aPool In - an opened string pool
|
sl@0
|
393 |
@param aVer Out - a formatted version string. Caller must close this string.
|
sl@0
|
394 |
@return postive number indicating the number of bytes read from the buffer
|
sl@0
|
395 |
KErrCorrupt if data is not formatted correctly.
|
sl@0
|
396 |
*/
|
sl@0
|
397 |
EXPORT_C TInt TWspPrimitiveDecoder::VersionL(RStringPool aPool, RStringF& aVer)
|
sl@0
|
398 |
{
|
sl@0
|
399 |
const TInt KMaxBufLength=5;
|
sl@0
|
400 |
TInt bufLen = 0;
|
sl@0
|
401 |
TInt byte = iBuffer[iOffset];
|
sl@0
|
402 |
if (!(byte & KTopBitMask))
|
sl@0
|
403 |
{
|
sl@0
|
404 |
TPtrC8 str;
|
sl@0
|
405 |
bufLen = String(str);
|
sl@0
|
406 |
if (bufLen < KErrNone) return KErrCorrupt;
|
sl@0
|
407 |
aVer = aPool.OpenFStringL(str);
|
sl@0
|
408 |
}
|
sl@0
|
409 |
else
|
sl@0
|
410 |
{
|
sl@0
|
411 |
// Major 0-7 , Minor 0-15 [xxx][yyyy]
|
sl@0
|
412 |
TUint8 val;
|
sl@0
|
413 |
bufLen = Val7Bit(val);
|
sl@0
|
414 |
if (bufLen < KErrNone) return KErrCorrupt;
|
sl@0
|
415 |
|
sl@0
|
416 |
|
sl@0
|
417 |
TInt minVer = val & 0x0F;
|
sl@0
|
418 |
TInt majVer = val & 0xF0;
|
sl@0
|
419 |
majVer >>= 4;
|
sl@0
|
420 |
|
sl@0
|
421 |
if (majVer < 0 || majVer > 7)
|
sl@0
|
422 |
return KErrCorrupt;
|
sl@0
|
423 |
|
sl@0
|
424 |
TBuf8<KMaxBufLength> buf;
|
sl@0
|
425 |
if (minVer == 0x0F)
|
sl@0
|
426 |
{
|
sl@0
|
427 |
_LIT8(KVersionFormat, "%D");
|
sl@0
|
428 |
buf.Format(KVersionFormat, majVer);
|
sl@0
|
429 |
}
|
sl@0
|
430 |
else
|
sl@0
|
431 |
{
|
sl@0
|
432 |
_LIT8(KVersionFormat, "%D.%D");
|
sl@0
|
433 |
buf.Format(KVersionFormat, majVer, minVer);
|
sl@0
|
434 |
}
|
sl@0
|
435 |
aVer = aPool.OpenFStringL(buf);
|
sl@0
|
436 |
}
|
sl@0
|
437 |
|
sl@0
|
438 |
return bufLen;
|
sl@0
|
439 |
}
|
sl@0
|
440 |
|
sl@0
|
441 |
/**
|
sl@0
|
442 |
Returns a TDateTime offset from January 1, 1970 - WAP WSP Section 8.4.2.3 Panics if
|
sl@0
|
443 |
the time val is greater then the maximum allowable integer size (32 bits).
|
sl@0
|
444 |
|
sl@0
|
445 |
@pre iBuffer[iOffset] must be valid, VarType() == TWspHeaderType::ELengthVal
|
sl@0
|
446 |
@post internal offset gets updated to move past this primitive
|
sl@0
|
447 |
@param aDateTime Out - a WAP Date
|
sl@0
|
448 |
@return postive number indicating the number of bytes read from the buffer
|
sl@0
|
449 |
KErrCorrupt if data is not formatted correctly.
|
sl@0
|
450 |
*/
|
sl@0
|
451 |
EXPORT_C TInt TWspPrimitiveDecoder::Date(TDateTime& aDateTime)
|
sl@0
|
452 |
{
|
sl@0
|
453 |
TUint32 secVal;
|
sl@0
|
454 |
TInt bufLen = LongInt(secVal);
|
sl@0
|
455 |
__ASSERT_ALWAYS(bufLen <= KMaxTInt, User::Panic(KUriPanicCategory, EWspDecoderDateOverflow));
|
sl@0
|
456 |
if (bufLen < KErrNone) return bufLen;
|
sl@0
|
457 |
|
sl@0
|
458 |
TDateTime dt(1970,EJanuary,0,0,0,0,0);
|
sl@0
|
459 |
TTime time(dt);
|
sl@0
|
460 |
|
sl@0
|
461 |
TInt sec = STATIC_CAST(TInt, secVal);
|
sl@0
|
462 |
time += TTimeIntervalSeconds(sec);
|
sl@0
|
463 |
aDateTime = time.DateTime();
|
sl@0
|
464 |
|
sl@0
|
465 |
return bufLen;
|
sl@0
|
466 |
}
|