|
1 // Copyright (c) 1997-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 <etelmm.h> // for RMobilePhoneBookStore |
|
17 #include "mpbutil.h" |
|
18 |
|
19 const TUint8 KTagPadZeroValue = 0x00; |
|
20 |
|
21 EXPORT_C CPhoneBookBuffer::CPhoneBookBuffer() : iMonitor(NULL,0,0) |
|
22 /** The CPhoneBookBuffer library class is constructed using a simple, one-phase |
|
23 constructor because the CPhoneBookBuffer class does not allocate any member |
|
24 data on the heap. */ |
|
25 { |
|
26 } |
|
27 |
|
28 EXPORT_C void CPhoneBookBuffer::Set(TDes8* aBuf) |
|
29 /** This member function sets the buffer's internal attribute iPtr to point to |
|
30 the supplied 8-bit buffer, which is owned by the caller of this function member. |
|
31 |
|
32 @param aData A pointer to the buffer |
|
33 @capability None |
|
34 */ |
|
35 { |
|
36 iPtr = aBuf; |
|
37 } |
|
38 |
|
39 EXPORT_C TInt CPhoneBookBuffer::AddNewEntryTag() |
|
40 /** This function member puts a new entry tag byte (ETagPBNewEntry) into the buffer |
|
41 and sets iMonitor to point to the beginning of each new entry. |
|
42 |
|
43 @return KErrNone if successful, or KErrOverflow if there is not enough space |
|
44 in the buffer. |
|
45 @see RMobilePhoneBookStore::TMobilePBFieldTags |
|
46 @capability None |
|
47 */ |
|
48 { |
|
49 // First check whether there is enough space to fit new entry tag |
|
50 if( (iPtr->MaxLength() - iPtr->Length()) > 1 ) |
|
51 { |
|
52 AppendInt8(RMobilePhoneBookStore::ETagPBNewEntry); |
|
53 const TInt len = iPtr->Length(); |
|
54 // Make sure iMonitor has been updated and it points to the beggining of the new entry |
|
55 iMonitor.Set(&(*iPtr)[len-1], iPtr->MaxLength() - len + 1, iPtr->MaxLength() - len + 1); |
|
56 return KErrNone; |
|
57 } |
|
58 else |
|
59 { |
|
60 return KErrOverflow; |
|
61 } |
|
62 } |
|
63 |
|
64 EXPORT_C TInt CPhoneBookBuffer::AddNewNumberTag() |
|
65 /** This function member puts a new number tag byte (ETagPBAnrStart) into the buffer. |
|
66 |
|
67 |
|
68 @return KErrNone if successful, or KErrOverflow if there is not enough space |
|
69 in the buffer. |
|
70 @see RMobilePhoneBookStore::TMobilePBFieldTags |
|
71 @capability None |
|
72 */ |
|
73 { |
|
74 // First check whether there is enough space to fit new entry tag |
|
75 if( (iPtr->MaxLength() - iPtr->Length()) > 1 ) |
|
76 { |
|
77 AppendInt8(RMobilePhoneBookStore::ETagPBAnrStart); |
|
78 return KErrNone; |
|
79 } |
|
80 else |
|
81 { |
|
82 return KErrOverflow; |
|
83 } |
|
84 } |
|
85 |
|
86 |
|
87 /** |
|
88 * Puts a 8-bit integer value into buffer. |
|
89 * |
|
90 * The valid tags for use with 8-bit integers are: |
|
91 * |
|
92 * @li RMobilePhoneBookStore::ETagPBBearerCap |
|
93 * @li RMobilePhoneBookStore::ETagPBEntryControl |
|
94 * @li RMobilePhoneBookStore::ETagPBHiddenInfo |
|
95 * @li RMobilePhoneBookStore::ETagPBTonNpi |
|
96 * @li RMobilePhoneBookStore::ETagPBUniqueId |
|
97 * @li RMobilePhoneBookStore::ETagPBEntryStatus |
|
98 * |
|
99 * @param aTagValue Tag byte to use. |
|
100 * @param aInteger Value to put in the buffer. |
|
101 * |
|
102 * @return KErrNone if successful, KErrOverflow if there is not enough |
|
103 * space in the buffer or KErrArgument if the parameter is invalid. |
|
104 * |
|
105 * @capability None |
|
106 */ |
|
107 EXPORT_C TInt CPhoneBookBuffer::PutTagAndValue(TUint8 aTagValue, TUint8 aInteger) |
|
108 { |
|
109 // |
|
110 // Check that the tag type is valid for this type of value... |
|
111 // |
|
112 if (aTagValue != RMobilePhoneBookStore::ETagPBBearerCap && |
|
113 aTagValue != RMobilePhoneBookStore::ETagPBEntryControl && |
|
114 aTagValue != RMobilePhoneBookStore::ETagPBHiddenInfo && |
|
115 aTagValue != RMobilePhoneBookStore::ETagPBTonNpi && |
|
116 aTagValue != RMobilePhoneBookStore::ETagPBUniqueId && |
|
117 aTagValue != RMobilePhoneBookStore::ETagPBEntryStatus) |
|
118 { |
|
119 return KErrArgument; |
|
120 } |
|
121 |
|
122 // First need to ensure that aInteger can fit into the supplied buffer |
|
123 if((iPtr->MaxLength()-iPtr->Length()) > 2) |
|
124 { |
|
125 AppendInt8(aTagValue); |
|
126 AppendInt8(aInteger); |
|
127 return KErrNone; |
|
128 } |
|
129 else |
|
130 { |
|
131 return KErrOverflow; |
|
132 } |
|
133 } |
|
134 |
|
135 |
|
136 /** |
|
137 * Puts a 16-bit integer value into buffer. |
|
138 * |
|
139 * The valid tags for use with 16-bit integers are: |
|
140 * |
|
141 * @li RMobilePhoneBookStore::ETagPBAdnIndex |
|
142 * |
|
143 * @param aTagValue Tag byte to use. |
|
144 * @param aInteger Value to put in the buffer. |
|
145 * |
|
146 * @return KErrNone if successful, KErrOverflow if there is not enough |
|
147 * space in the buffer or KErrArgument if the parameter is invalid. |
|
148 * |
|
149 * @capability None |
|
150 */ |
|
151 EXPORT_C TInt CPhoneBookBuffer::PutTagAndValue(TUint8 aTagValue, TUint16 aInteger) |
|
152 { |
|
153 // |
|
154 // Check that the tag type is valid for this type of value... |
|
155 // |
|
156 if (aTagValue != RMobilePhoneBookStore::ETagPBAdnIndex) |
|
157 { |
|
158 return KErrArgument; |
|
159 } |
|
160 |
|
161 // First need to ensure that aInteger can fit into the supplied buffer |
|
162 if((iPtr->MaxLength()-iPtr->Length()) > 3) |
|
163 { |
|
164 AppendInt8(aTagValue); |
|
165 AppendInt16(aInteger); |
|
166 return KErrNone; |
|
167 } |
|
168 else |
|
169 { |
|
170 return KErrOverflow; |
|
171 } |
|
172 } |
|
173 |
|
174 |
|
175 /** |
|
176 * Puts a 32-bit integer value into buffer. |
|
177 * |
|
178 * The valid tags for use with 32-bit integers are: |
|
179 * |
|
180 * @li None. |
|
181 * |
|
182 * @param aTagValue Tag byte to use. |
|
183 * @param aInteger Value to put in the buffer. |
|
184 * |
|
185 * @return KErrNone if successful, KErrOverflow if there is not enough |
|
186 * space in the buffer or KErrArgument if the parameter is invalid. |
|
187 * |
|
188 * @capability None |
|
189 */ |
|
190 EXPORT_C TInt CPhoneBookBuffer::PutTagAndValue(TUint8 aTagValue, TUint32 aInteger) |
|
191 { |
|
192 // |
|
193 // No Tags support 32bit integers... |
|
194 // |
|
195 (void) aTagValue; |
|
196 (void) aInteger; |
|
197 |
|
198 return KErrArgument; |
|
199 |
|
200 // // First need to ensure that aInteger can fit into the supplied buffer |
|
201 // if((iPtr->MaxLength()-iPtr->Length()) > 5) |
|
202 // { |
|
203 // AppendInt8(aTagValue); |
|
204 // AppendInt32(aInteger); |
|
205 // return KErrNone; |
|
206 // } |
|
207 // else |
|
208 // { |
|
209 // return KErrOverflow; |
|
210 // } |
|
211 } |
|
212 |
|
213 |
|
214 /** |
|
215 * Puts a 16-bit descriptor value into buffer. |
|
216 * |
|
217 * The valid tags for use with 16-bit descriptors are: |
|
218 * |
|
219 * @li RMobilePhoneBookStore::ETagPBSecondName |
|
220 * @li RMobilePhoneBookStore::ETagPBGroupName |
|
221 * @li RMobilePhoneBookStore::ETagPBEmailAddress |
|
222 * @li RMobilePhoneBookStore::ETagPBText |
|
223 * @li RMobilePhoneBookStore::ETagPBNumber |
|
224 * |
|
225 * @param aTagValue Tag byte to use. |
|
226 * @param aData Value to put in the buffer. |
|
227 * |
|
228 * @return KErrNone if successful, KErrOverflow if there is not enough |
|
229 * space in the buffer or KErrArgument if the parameter is invalid. |
|
230 * |
|
231 * @capability None |
|
232 */ |
|
233 EXPORT_C TInt CPhoneBookBuffer::PutTagAndValue(TUint8 aTagValue, const TDesC16 &aData) |
|
234 { |
|
235 // |
|
236 // Check that the tag type is valid for this type of value... |
|
237 // |
|
238 if (aTagValue != RMobilePhoneBookStore::ETagPBSecondName && |
|
239 aTagValue != RMobilePhoneBookStore::ETagPBGroupName && |
|
240 aTagValue != RMobilePhoneBookStore::ETagPBEmailAddress && |
|
241 aTagValue != RMobilePhoneBookStore::ETagPBText && |
|
242 aTagValue != RMobilePhoneBookStore::ETagPBNumber) |
|
243 { |
|
244 return KErrArgument; |
|
245 } |
|
246 |
|
247 // First need to ensure that aData can fit into the supplied buffer |
|
248 // Need to use Size() because this is Unicode data and we want to know number of bytes not number of characters |
|
249 // Also allow for the 1-byte tag and up to 3 zero padding bytes |
|
250 if((aData.Size()+3 <= KMaxUint16Val) && ((iPtr->MaxLength()-iPtr->Length()) > (aData.Size()+4))) |
|
251 { |
|
252 // Make sure buffer is word aligned after adding 3 bytes for tag and length |
|
253 switch(iPtr->Size()%4) |
|
254 { |
|
255 case 0: |
|
256 AppendInt8(KTagPadZeroValue); |
|
257 break; |
|
258 case 1: |
|
259 break; |
|
260 case 2: |
|
261 AppendInt8(KTagPadZeroValue); |
|
262 AppendInt8(KTagPadZeroValue); |
|
263 AppendInt8(KTagPadZeroValue); |
|
264 break; |
|
265 case 3: |
|
266 AppendInt8(KTagPadZeroValue); |
|
267 AppendInt8(KTagPadZeroValue); |
|
268 break; |
|
269 default: |
|
270 break; |
|
271 } |
|
272 |
|
273 AppendInt8(aTagValue); |
|
274 TUint16 len=(TUint16) aData.Size(); |
|
275 iPtr->Append((const TUint8*)&len,2); |
|
276 TUint8* dataPtr=reinterpret_cast<TUint8*>(const_cast<TUint16*>(aData.Ptr())); |
|
277 iPtr->Append(dataPtr,len); |
|
278 return KErrNone; |
|
279 } |
|
280 else |
|
281 { |
|
282 return KErrOverflow; |
|
283 } |
|
284 } |
|
285 |
|
286 |
|
287 /** |
|
288 * Puts a 8-bit descriptor value into buffer. |
|
289 * |
|
290 * The valid tags for use with 8-bit descriptors are: |
|
291 * |
|
292 * @li None. |
|
293 * |
|
294 * @param aTagValue Tag byte to use. |
|
295 * @param aData Value to put in the buffer. |
|
296 * |
|
297 * @return KErrNone if successful, KErrOverflow if there is not enough |
|
298 * space in the buffer or KErrArgument if the parameter is invalid. |
|
299 * |
|
300 * @capability None |
|
301 */ |
|
302 EXPORT_C TInt CPhoneBookBuffer::PutTagAndValue(TUint8 aTagValue, const TDesC8 &aData) |
|
303 { |
|
304 // |
|
305 // No Tags support 8bit text... |
|
306 // |
|
307 (void) aTagValue; |
|
308 (void) aData; |
|
309 |
|
310 return KErrArgument; |
|
311 |
|
312 // // First need to ensure that aData can fit into the supplied buffer |
|
313 // if((aData.Size() <= KMaxUint16Val) && ((iPtr->MaxLength()-iPtr->Length()) > (aData.Size()+1))) |
|
314 // { |
|
315 // AppendInt8(aTagValue); |
|
316 // TUint16 len=(TUint16) aData.Length(); |
|
317 // iPtr->Append((const TUint8*)&len,2); |
|
318 // iPtr->Append(aData); |
|
319 // return KErrNone; |
|
320 // } |
|
321 // else |
|
322 // { |
|
323 // return KErrOverflow; |
|
324 // } |
|
325 } |
|
326 |
|
327 EXPORT_C TInt CPhoneBookBuffer::RemovePartialEntry() |
|
328 /**This function will rollback the buffer to the end of the last complete |
|
329 phonebook entry and remove any data after this. |
|
330 |
|
331 @return KErrNone if successful. |
|
332 @capability None |
|
333 */ |
|
334 { |
|
335 iPtr->SetLength(iPtr->MaxLength() - iMonitor.Length()); |
|
336 iMonitor.FillZ(); |
|
337 return KErrNone; |
|
338 } |
|
339 |
|
340 EXPORT_C void CPhoneBookBuffer::StartRead() |
|
341 /** This function member sets the CPhoneBookBuffer class' iRead member data to |
|
342 point to the start of the populated TLV buffer, ready to start data extraction |
|
343 from the buffer. |
|
344 @capability None |
|
345 */ |
|
346 { |
|
347 iRead.Set(*iPtr); |
|
348 } |
|
349 |
|
350 EXPORT_C TInt CPhoneBookBuffer::GetTagAndType(TUint8 &aTagValue, TPhBkTagType &aDataType) |
|
351 /** This function member reads the next tag value from the buffer. |
|
352 |
|
353 @param aTagValue On completion, the next Tag type from the buffer. |
|
354 @param aDataType On completion, the data type associated with the tag value. |
|
355 @return KErrNone if successful, or KErrNotFound if there are no more tags in |
|
356 the buffer. |
|
357 @capability None |
|
358 */ |
|
359 { |
|
360 // Check we've not reached end of buffer - if we have then return |
|
361 TInt length = iRead.Length(); |
|
362 |
|
363 if (length<=0) |
|
364 return KErrNotFound; |
|
365 |
|
366 // Extract all padding zero bytes until tag is found |
|
367 TInt i=0; |
|
368 do |
|
369 { |
|
370 aTagValue=iRead[i++]; |
|
371 } |
|
372 while ((aTagValue==KTagPadZeroValue) && i<length); |
|
373 |
|
374 if (i < length) |
|
375 iRead.Set(iRead.Mid(i)); |
|
376 else |
|
377 return KErrNotFound; |
|
378 |
|
379 switch(aTagValue) // set tag type according to the tag value |
|
380 { |
|
381 case RMobilePhoneBookStore::ETagPBNewEntry: |
|
382 case RMobilePhoneBookStore::ETagPBAnrStart: |
|
383 aDataType = EPhBkTypeNoData; |
|
384 break; |
|
385 |
|
386 case RMobilePhoneBookStore::ETagPBBearerCap: |
|
387 case RMobilePhoneBookStore::ETagPBEntryControl: |
|
388 case RMobilePhoneBookStore::ETagPBHiddenInfo: |
|
389 case RMobilePhoneBookStore::ETagPBTonNpi: |
|
390 case RMobilePhoneBookStore::ETagPBUniqueId: |
|
391 case RMobilePhoneBookStore::ETagPBEntryStatus: |
|
392 aDataType = EPhBkTypeInt8; |
|
393 break; |
|
394 |
|
395 case RMobilePhoneBookStore::ETagPBAdnIndex: |
|
396 aDataType = EPhBkTypeInt16; |
|
397 break; |
|
398 |
|
399 case RMobilePhoneBookStore::ETagPBSecondName: |
|
400 case RMobilePhoneBookStore::ETagPBGroupName: |
|
401 case RMobilePhoneBookStore::ETagPBEmailAddress: |
|
402 case RMobilePhoneBookStore::ETagPBText: |
|
403 case RMobilePhoneBookStore::ETagPBNumber: |
|
404 aDataType = EPhBkTypeDes16; |
|
405 break; |
|
406 |
|
407 default: |
|
408 return KErrNotFound; |
|
409 } |
|
410 return KErrNone; |
|
411 } |
|
412 |
|
413 EXPORT_C TInt CPhoneBookBuffer::GetValue(TUint16 &aInteger) |
|
414 /** Gets a 16-bit integer value from the buffer. |
|
415 |
|
416 @param aInteger On completion, the 16-bit value from the buffer. |
|
417 @return KErrNone if successful. |
|
418 @capability None |
|
419 */ |
|
420 { |
|
421 aInteger=(TUint16)((iRead[1]<<8)+iRead[0]); // Dependant upon endianess |
|
422 iRead.Set(iRead.Mid(2)); |
|
423 return KErrNone; |
|
424 } |
|
425 |
|
426 EXPORT_C TInt CPhoneBookBuffer::GetValue(TUint8 &aInteger) |
|
427 /** Gets a 8-bit integer value from the buffer. |
|
428 |
|
429 @param aInteger On completion, the 8-bit value from the buffer. |
|
430 @return KErrNone if successful. |
|
431 @capability None |
|
432 */ |
|
433 { |
|
434 aInteger=(TUint8)(iRead[0]); |
|
435 iRead.Set(iRead.Mid(1)); |
|
436 return KErrNone; |
|
437 } |
|
438 |
|
439 EXPORT_C TInt CPhoneBookBuffer::GetValue(TUint32 &aInteger) |
|
440 /** Gets a 32-bit integer value from the buffer. |
|
441 |
|
442 @param aInteger On completion, the 32-bit value from the buffer. |
|
443 @return KErrNone if successful. |
|
444 @capability None |
|
445 */ |
|
446 { |
|
447 TUint16 aMSW(0), aLSW(0); |
|
448 GetValue(aLSW); |
|
449 GetValue(aMSW); |
|
450 aInteger=(TUint32)((aMSW<<16)+aLSW); // Dependant upon endianess |
|
451 return KErrNone; |
|
452 } |
|
453 |
|
454 EXPORT_C TInt CPhoneBookBuffer::GetValue(TPtrC8 &aData) |
|
455 /** Gets a 8-bit descriptor from the buffer. The read pointer is then incremented past the read value. |
|
456 |
|
457 @param aData On completion, the 8-bit descriptor from the buffer. |
|
458 @return KErrNone if successful. |
|
459 @capability None |
|
460 */ |
|
461 { |
|
462 TUint16 len; |
|
463 len=(TUint16)((iRead[1]<<8)+iRead[0]); // Dependant upon endianess |
|
464 aData.Set(iRead.Mid(2,len)); |
|
465 iRead.Set(iRead.Mid(len+2)); |
|
466 return KErrNone; |
|
467 } |
|
468 |
|
469 EXPORT_C TInt CPhoneBookBuffer::GetValue(TPtrC16 &aData) |
|
470 /** Gets a 16-bit descriptor from the buffer. |
|
471 |
|
472 @param aData On completion, the 16-bit descriptor from the buffer. |
|
473 The read pointer is then incremented past the read value. |
|
474 @return KErrNone if successful. |
|
475 @capability None |
|
476 */ |
|
477 { |
|
478 TUint16 size=(TUint16)((iRead[1]<<8)+iRead[0]); // Dependant upon endianess |
|
479 TUint16 len=(TUint16)(size/2); |
|
480 |
|
481 iRead.Set(iRead.Mid(2)); |
|
482 |
|
483 TUint16* dataPtr=reinterpret_cast<TUint16*>(const_cast<TUint8*>(iRead.Ptr())); |
|
484 |
|
485 aData.Set(dataPtr,len); |
|
486 |
|
487 iRead.Set(iRead.Mid(size)); |
|
488 return KErrNone; |
|
489 } |
|
490 |
|
491 EXPORT_C TInt CPhoneBookBuffer::BufferLength() |
|
492 /** This function member returns the length of the populated buffer. |
|
493 |
|
494 @return The buffer length. |
|
495 @capability None |
|
496 */ |
|
497 { |
|
498 return iPtr->Length(); |
|
499 } |
|
500 |
|
501 EXPORT_C TInt CPhoneBookBuffer::RemainingReadLength() |
|
502 /** This function member returns the length of the remaining data to read in the |
|
503 populated buffer. |
|
504 |
|
505 @return The length of the remaining data. |
|
506 @capability None |
|
507 */ |
|
508 { |
|
509 return iRead.Length(); |
|
510 } |
|
511 |
|
512 EXPORT_C void CPhoneBookBuffer::SkipValue(TPhBkTagType aDataType) |
|
513 /** This function member skips the next value in the buffer that is waiting to |
|
514 be read. Clients would use this function member if they do not support the |
|
515 field contained in the next data value. |
|
516 |
|
517 @param aDataType The data type of the value to skip |
|
518 @capability None |
|
519 */ |
|
520 { |
|
521 TUint16 size=0; |
|
522 switch (aDataType) |
|
523 { |
|
524 case EPhBkTypeInt8: |
|
525 iRead.Set(iRead.Mid(1)); |
|
526 break; |
|
527 case EPhBkTypeInt16: |
|
528 iRead.Set(iRead.Mid(2)); |
|
529 break; |
|
530 case EPhBkTypeInt32: |
|
531 iRead.Set(iRead.Mid(4)); |
|
532 break; |
|
533 case EPhBkTypeDes8: |
|
534 case EPhBkTypeDes16: |
|
535 size=(TUint16)((iRead[1]<<8)+iRead[0]); // Dependant upon endianess |
|
536 iRead.Set(iRead.Mid(2+size)); |
|
537 break; |
|
538 default: |
|
539 // EPhBkTypeNoData caught here - no data to skip, so do nothing |
|
540 break; |
|
541 } |
|
542 } |
|
543 |
|
544 TInt CPhoneBookBuffer::AppendInt8(TUint8 aInteger) |
|
545 { |
|
546 const TUint8* intAddr=(const TUint8*)&aInteger; |
|
547 iPtr->Append(intAddr,1); |
|
548 return KErrNone; |
|
549 } |
|
550 |
|
551 TInt CPhoneBookBuffer::AppendInt16(TUint16 aInteger) |
|
552 { |
|
553 const TUint8* intAddr=(const TUint8*)&aInteger; |
|
554 iPtr->Append(intAddr,2); |
|
555 return KErrNone; |
|
556 } |
|
557 |
|
558 TInt CPhoneBookBuffer::AppendInt32(TUint32 aInteger) |
|
559 { |
|
560 const TUint8* intAddr=(const TUint8*)&aInteger; |
|
561 iPtr->Append(intAddr,4); |
|
562 return KErrNone; |
|
563 } |