|
1 /* |
|
2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * Utility methods for UI and engine modules. Provides help for address |
|
16 * string parsing, resource files and contact database access. |
|
17 * General address format is either |
|
18 * alias<real-address> |
|
19 * or |
|
20 * <real-address> |
|
21 * as used in the Client MTM API. |
|
22 * |
|
23 */ |
|
24 |
|
25 |
|
26 |
|
27 // INCLUDE FILES |
|
28 #include <barsc.h> // resource file |
|
29 #include <bautils.h> |
|
30 #include <miutpars.h> // e-mail utilities |
|
31 |
|
32 #include <miutconv.h> // CharConv |
|
33 #include <flogger.h> |
|
34 #include <e32svr.h> |
|
35 #include <e32base.h> |
|
36 #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
37 #include <imcvcodc.h> |
|
38 #else |
|
39 #include <imcvcodc.h> |
|
40 #include <cimconvertheader.h> |
|
41 #endif |
|
42 #include <f32file.h> |
|
43 #include <UiklafInternalCRKeys.h> |
|
44 #include <telconfigcrkeys.h> |
|
45 #include <centralrepository.h> |
|
46 #include <CoreApplicationUIsSDKCRKeys.h> |
|
47 #include <data_caging_path_literals.hrh> |
|
48 |
|
49 #include <MVPbkContactStore.h> |
|
50 #include <MVPbkContactStoreProperties.h> |
|
51 #include <MVPbkContactLink.h> |
|
52 #include <CPbk2StoreConfiguration.h> // Contact store configuration |
|
53 #include <contactmatcher.h> // contact match wrapper |
|
54 #include <CVPbkPhoneNumberMatchStrategy.h> |
|
55 #include <CVPbkContactLinkArray.h> |
|
56 #include <CVPbkFieldTypeRefsList.h> |
|
57 #include <TVPbkFieldVersitProperty.h> |
|
58 #include <VPbkFieldType.hrh> |
|
59 #include <MVPbkStoreContactFieldCollection.h> |
|
60 #include <MVPbkStoreContact.h> |
|
61 #include <CVPbkContactStoreUriArray.h> |
|
62 #include <VPbkContactStoreUris.h> |
|
63 #include <TVPbkContactStoreUriPtr.h> |
|
64 #include "mmsgenutils.h" |
|
65 #include "MmsEnginePrivateCRKeys.h" |
|
66 |
|
67 // EXTERNAL DATA STRUCTURES |
|
68 |
|
69 // EXTERNAL FUNCTION PROTOTYPES |
|
70 |
|
71 // CONSTANTS |
|
72 const TInt KLogBufferLength = 256; |
|
73 #ifdef _DEBUG |
|
74 _LIT( KLogDir, "mmsc" ); |
|
75 _LIT( KLogFile, "mmsc.txt" ); |
|
76 #endif |
|
77 const TUint KMinAliasMaxLength = 14; |
|
78 const TUint KExtraSpaceForConversion10 = 10; |
|
79 const TUint KExtraSpaceForConversion30 = 30; |
|
80 |
|
81 const TInt KErrMultipleMatchFound = KErrGeneral; |
|
82 // MACROS |
|
83 |
|
84 // LOCAL CONSTANTS AND MACROS |
|
85 |
|
86 // MODULE DATA STRUCTURES |
|
87 |
|
88 // LOCAL FUNCTION PROTOTYPES |
|
89 |
|
90 // ==================== LOCAL FUNCTIONS ==================== |
|
91 |
|
92 // ================= MEMBER FUNCTIONS ======================= |
|
93 |
|
94 // Constructor |
|
95 // |
|
96 EXPORT_C TMmsGenUtils::TMmsGenUtils() |
|
97 { |
|
98 } |
|
99 |
|
100 // Destructor |
|
101 // |
|
102 // THERE SHOULD NOT BE DESTRUCTOR IN T-CLASS. |
|
103 // MUST BE REMOVED |
|
104 EXPORT_C TMmsGenUtils::~TMmsGenUtils() |
|
105 { |
|
106 } |
|
107 |
|
108 |
|
109 // --------------------------------------------------------- |
|
110 // TMmsGenUtils::AddressTypeAndRealAddress |
|
111 // --------------------------------------------------------- |
|
112 // |
|
113 EXPORT_C TInt TMmsGenUtils::AddressTypeAndRealAddress( |
|
114 const TDesC& aAddress, |
|
115 TMmsAddressType& aType, |
|
116 TDes& aRealAddress, |
|
117 TInt aMaxLength, |
|
118 const TDesC& aOpen, |
|
119 const TDesC& aClose ) |
|
120 { |
|
121 aRealAddress.Zero(); |
|
122 aType = EMmsAddressTypeUnknown; |
|
123 |
|
124 TPtrC realAddress; |
|
125 realAddress.Set( PureAddress( aAddress, aOpen, aClose ) ); |
|
126 |
|
127 if ( realAddress.Length() > aMaxLength ) |
|
128 { |
|
129 return KErrTooBig; |
|
130 } |
|
131 |
|
132 if ( IsValidMMSPhoneAddress( realAddress ) ) |
|
133 { |
|
134 aType = EMmsAddressTypeMobile; |
|
135 } |
|
136 else if ( IsValidEmailAddress( realAddress ) ) |
|
137 { |
|
138 aType = EMmsAddressTypeEmail; |
|
139 } |
|
140 else |
|
141 { |
|
142 |
|
143 } |
|
144 |
|
145 // we returned earlier if address was too big. |
|
146 if ( aType != EMmsAddressTypeUnknown ) |
|
147 { |
|
148 aRealAddress.Copy( realAddress ); |
|
149 } |
|
150 |
|
151 return KErrNone; |
|
152 } |
|
153 |
|
154 // --------------------------------------------------------- |
|
155 // TMmsGenUtils::IsValidAddress |
|
156 // --------------------------------------------------------- |
|
157 // |
|
158 EXPORT_C TBool TMmsGenUtils::IsValidAddress( |
|
159 const TDesC& aAddress, |
|
160 TBool aReal, |
|
161 const TDesC& aOpen, |
|
162 const TDesC& aClose ) |
|
163 { |
|
164 TPtrC realAddress; |
|
165 |
|
166 if ( !aReal) |
|
167 { |
|
168 realAddress.Set( PureAddress( aAddress, aOpen, aClose ) ); |
|
169 } |
|
170 else |
|
171 { |
|
172 realAddress.Set ( aAddress ); |
|
173 } |
|
174 |
|
175 if ( !IsValidMMSPhoneAddress( realAddress ) ) |
|
176 { |
|
177 return IsValidEmailAddress( realAddress ); |
|
178 } |
|
179 |
|
180 return ETrue; |
|
181 } |
|
182 |
|
183 // --------------------------------------------------------- |
|
184 // TMmsGenUtils::IsValidEmailAddress |
|
185 // --------------------------------------------------------- |
|
186 // |
|
187 EXPORT_C TBool TMmsGenUtils::IsValidEmailAddress( |
|
188 const TDesC& aAddress, |
|
189 TBool aReal, |
|
190 const TDesC& aOpen, |
|
191 const TDesC& aClose ) |
|
192 { |
|
193 // Strip off alias part if necessary |
|
194 TPtrC realAddress; |
|
195 if ( aReal ) |
|
196 { |
|
197 realAddress.Set( aAddress ); |
|
198 } |
|
199 else |
|
200 { |
|
201 realAddress.Set( PureAddress( aAddress, aOpen, aClose ) ); |
|
202 } |
|
203 TImMessageField email; |
|
204 return email.ValidInternetEmailAddress( realAddress ); |
|
205 } |
|
206 |
|
207 // --------------------------------------------------------- |
|
208 // TMmsGenUtils::IsValidMMSPhoneAddress |
|
209 // --------------------------------------------------------- |
|
210 // |
|
211 EXPORT_C TBool TMmsGenUtils::IsValidMMSPhoneAddress( |
|
212 const TDesC& aAddress, |
|
213 TBool aReal, |
|
214 const TDesC& aOpen, |
|
215 const TDesC& aClose ) |
|
216 { |
|
217 // global_phone_number = [+] 1*(DIGIT, written-sep) |
|
218 // written_sep = ('-') |
|
219 |
|
220 // Strip off alias part if necessary |
|
221 TPtrC realAddress; |
|
222 if ( aReal ) |
|
223 { |
|
224 realAddress.Set( aAddress ); |
|
225 } |
|
226 else |
|
227 { |
|
228 realAddress.Set( PureAddress( aAddress, aOpen, aClose ) ); |
|
229 } |
|
230 |
|
231 TInt length = realAddress.Length(); |
|
232 |
|
233 if ( length == 0 ) |
|
234 { |
|
235 return EFalse; |
|
236 } |
|
237 |
|
238 TInt pos = 0; |
|
239 TInt ich = realAddress[0]; |
|
240 TChar ch = ich; |
|
241 if ( ch == '+' ) |
|
242 { |
|
243 pos++; |
|
244 } |
|
245 |
|
246 if ( pos == length ) |
|
247 { |
|
248 return EFalse; |
|
249 } |
|
250 |
|
251 while ( pos < length ) |
|
252 { |
|
253 ich = realAddress[pos]; |
|
254 ch = ich; |
|
255 ch.Fold(); |
|
256 TInt fch = ch; |
|
257 // do not check for fch == '.' |
|
258 //Even # and * are valid characters now |
|
259 if ( !( ch.IsDigit() || fch == '-' || fch == '#' || fch == '*' ) ) |
|
260 { |
|
261 return EFalse; |
|
262 } |
|
263 pos++; |
|
264 } |
|
265 |
|
266 return ETrue; |
|
267 } |
|
268 |
|
269 |
|
270 // --------------------------------------------------------- |
|
271 // TMmsGenUtils::Alias |
|
272 // --------------------------------------------------------- |
|
273 // |
|
274 EXPORT_C TPtrC TMmsGenUtils::Alias( |
|
275 const TDesC& aAddress, |
|
276 const TDesC& aOpen, |
|
277 const TDesC& aClose ) |
|
278 { |
|
279 |
|
280 // syntax is : |
|
281 // <alias><separator1><pure_address><separator2> | |
|
282 // <pure_address> |
|
283 TInt firstPos = 0; |
|
284 TInt lastPos = 0; |
|
285 TInt length = aAddress.Length(); |
|
286 TInt sepaLen1 = aOpen.Length(); |
|
287 TInt sepaLen2 = aClose.Length(); |
|
288 TInt firstSeparatorPosition = 0; |
|
289 |
|
290 while( firstSeparatorPosition >= 0 ) |
|
291 { |
|
292 firstSeparatorPosition = aAddress.Mid( firstPos ).Find( aOpen ); |
|
293 if ( firstSeparatorPosition >= 0 ) |
|
294 { |
|
295 firstPos += firstSeparatorPosition + sepaLen1; |
|
296 } |
|
297 } |
|
298 if ( firstPos <= 0 ) |
|
299 { |
|
300 // No alias |
|
301 return TPtrC(); |
|
302 } |
|
303 |
|
304 // Search another separator after the first separator from |
|
305 lastPos = aAddress.Mid( firstPos ).Find( aClose ); |
|
306 if ( lastPos == KErrNotFound ) |
|
307 { |
|
308 return TPtrC(); |
|
309 } |
|
310 firstPos -= sepaLen1; // point to first separator |
|
311 if ( lastPos == length - firstPos - sepaLen1 - sepaLen2 ) |
|
312 { |
|
313 // Alias part found |
|
314 // remove trailing and leading spaces |
|
315 lastPos = firstPos; |
|
316 firstPos = 0; |
|
317 while ( firstPos < aAddress.Length() && |
|
318 aAddress.Mid( firstPos, 1 ).Compare( KSpace16 ) == 0 ) |
|
319 { |
|
320 // remove leading spaces |
|
321 firstPos++; |
|
322 } |
|
323 while ( lastPos > 0 && aAddress.Mid( lastPos - 1, 1 ).Compare( KSpace16 ) == 0 ) |
|
324 { |
|
325 lastPos--; |
|
326 } |
|
327 if ( lastPos > firstPos ) |
|
328 { |
|
329 return aAddress.Mid( firstPos, lastPos - firstPos ); |
|
330 } |
|
331 } |
|
332 // No alias defined - spaces alone do not count as alias. |
|
333 return TPtrC(); |
|
334 } |
|
335 |
|
336 // --------------------------------------------------------- |
|
337 // TMmsGenUtils::PureAddress |
|
338 // --------------------------------------------------------- |
|
339 // |
|
340 EXPORT_C TPtrC TMmsGenUtils::PureAddress( |
|
341 const TDesC& aAddress, |
|
342 const TDesC& aOpen, |
|
343 const TDesC& aClose ) |
|
344 { |
|
345 // syntax is : |
|
346 // <alias><separator1><pure_address><separator2> | |
|
347 // <pure_address> |
|
348 TInt firstPos = 0; |
|
349 TInt lastPos = 0; |
|
350 TInt length = aAddress.Length(); |
|
351 TInt sepaLen1 = aOpen.Length(); |
|
352 TInt sepaLen2 = aClose.Length(); |
|
353 TInt firstSeparatorPosition = 0; |
|
354 |
|
355 while( firstSeparatorPosition >= 0 ) |
|
356 { |
|
357 firstSeparatorPosition = aAddress.Mid( firstPos ).Find( aOpen ); |
|
358 if ( firstSeparatorPosition >= 0 ) |
|
359 { |
|
360 firstPos += firstSeparatorPosition + sepaLen1; |
|
361 } |
|
362 } |
|
363 if ( firstPos <= 0 ) |
|
364 { |
|
365 // No alias |
|
366 return aAddress; |
|
367 } |
|
368 |
|
369 // Check if the second separator ends the address |
|
370 TPtrC last = aAddress.Right( sepaLen2 ); |
|
371 lastPos = length - sepaLen2; |
|
372 |
|
373 if ( !last.Compare( aClose ) ) |
|
374 { |
|
375 // Alias part found |
|
376 if ( lastPos > firstPos ) |
|
377 { |
|
378 return aAddress.Mid( firstPos, lastPos - firstPos ); |
|
379 } |
|
380 } |
|
381 // No alias defined - return the original string as pure address |
|
382 // If syntax is weird, namely |
|
383 // alias <> |
|
384 // with nothing between the separators, we return the original string as is |
|
385 return aAddress; |
|
386 } |
|
387 |
|
388 // --------------------------------------------------------- |
|
389 // TMmsGenUtils::GenerateDetails |
|
390 // --------------------------------------------------------- |
|
391 // |
|
392 EXPORT_C TInt TMmsGenUtils::GenerateDetails( |
|
393 const TDesC& aAddress, |
|
394 TDes& aAlias, |
|
395 TInt aMaxLength, |
|
396 RFs& aFs ) |
|
397 { |
|
398 |
|
399 TInt err = KErrNone; |
|
400 |
|
401 // alias search order: Local alias, remote alias, none |
|
402 |
|
403 TPtrC realAddress; |
|
404 realAddress.Set( PureAddress( aAddress, KSepaOpen, KSepaClose ) ); |
|
405 |
|
406 TRAP( err, DoGetAliasL( aFs, realAddress, aAlias, aMaxLength ) ); |
|
407 if ( err != KErrNone || aAlias.Length() == 0 ) |
|
408 { |
|
409 // No alias found from Contact db, see if there is a local alias |
|
410 TPtrC myAddress = Alias( aAddress, KSepaOpen, KSepaClose ); |
|
411 if ( myAddress.Length() > 0 ) |
|
412 { |
|
413 // Alias was found from the address |
|
414 aAlias.Copy( myAddress.Left( aMaxLength ) ); |
|
415 return KErrNone; |
|
416 } |
|
417 else |
|
418 { |
|
419 if ( err == KErrNotFound ) |
|
420 { |
|
421 err = KErrNone; |
|
422 } |
|
423 // just keep the original address |
|
424 aAlias.Copy( aAddress.Left( aMaxLength ) ); |
|
425 } |
|
426 } |
|
427 |
|
428 return err; |
|
429 |
|
430 } |
|
431 |
|
432 |
|
433 // --------------------------------------------------------- |
|
434 // TMmsGenUtils::GetAlias |
|
435 // --------------------------------------------------------- |
|
436 // |
|
437 EXPORT_C TInt TMmsGenUtils::GetAlias( |
|
438 const TDesC& aAddress, |
|
439 TDes& aAlias, |
|
440 TInt aMaxLength, |
|
441 RFs& aFs ) |
|
442 { |
|
443 TInt err = KErrNone; |
|
444 TRAP( err, DoGetAliasL( aFs, aAddress, aAlias, aMaxLength ) ); |
|
445 if ( err == KErrNotFound ) |
|
446 { |
|
447 err = KErrNone; |
|
448 } |
|
449 return err; |
|
450 } |
|
451 |
|
452 |
|
453 // --------------------------------------------------------- |
|
454 // TMmsGenUtils::GetAliasForAllL |
|
455 // This function searches aliases for all addresses in a |
|
456 // address field by opening the contact db only once for all |
|
457 // addresses. This significantly reduces processing time |
|
458 // when executing "Create Reply to all" with a lot of addresses |
|
459 // --------------------------------------------------------- |
|
460 // |
|
461 EXPORT_C void TMmsGenUtils::GetAliasForAllL( |
|
462 const CDesCArray& aAddress, |
|
463 CDesCArray& aAlias, |
|
464 TInt aMaxLength, |
|
465 RFs& aFs ) |
|
466 { |
|
467 |
|
468 if ( aMaxLength <= 0 ) |
|
469 { |
|
470 User::Leave( KErrArgument ); |
|
471 } |
|
472 |
|
473 TUint stack = 0; |
|
474 |
|
475 //Let's find the number of digits to match |
|
476 TInt digitsToMatch = DigitsToMatch(); |
|
477 TInt err = KErrNone; |
|
478 |
|
479 // Use contact wrapper to open all databases |
|
480 CContactMatcher* contactMatcher = OpenAllStoresL( aFs ); |
|
481 CleanupStack::PushL( contactMatcher ); |
|
482 stack++; |
|
483 |
|
484 HBufC* helpBuffer = HBufC::NewL( aMaxLength ); |
|
485 CleanupStack::PushL( helpBuffer ); |
|
486 stack++; |
|
487 |
|
488 TPtr pHelpBuffer = helpBuffer->Des(); |
|
489 |
|
490 for ( TInt i = 0; i < aAddress.MdcaCount(); i++ ) |
|
491 { |
|
492 // We trap these one by one in order to be able |
|
493 // to continue to next match in case of error (not found) |
|
494 |
|
495 // make sure the alias is empty if nothing found |
|
496 pHelpBuffer.Zero(); |
|
497 |
|
498 TRAP( err, DoGetAliasL( |
|
499 aAddress.MdcaPoint(i), |
|
500 pHelpBuffer, |
|
501 aMaxLength, |
|
502 *contactMatcher, |
|
503 digitsToMatch ) ); |
|
504 |
|
505 // if alias is not found, we'll have an empty buffer |
|
506 // We have to insert it anyway to keep the indexes correct |
|
507 // as we have two parallel arrays |
|
508 aAlias.InsertL( i, pHelpBuffer ); |
|
509 } |
|
510 |
|
511 // closing is best effort only. |
|
512 TRAP_IGNORE( contactMatcher->CloseStoresL() ); |
|
513 CleanupStack::PopAndDestroy( stack, contactMatcher ); //contactMatcher, helpBuffer |
|
514 |
|
515 } |
|
516 |
|
517 // --------------------------------------------------------- |
|
518 // TMmsGenUtils::GenerateAddress |
|
519 // --------------------------------------------------------- |
|
520 // |
|
521 EXPORT_C HBufC* TMmsGenUtils::GenerateAddressL( |
|
522 const TDesC& aRealAddress, |
|
523 const TDesC& aAlias, |
|
524 const TDesC& aOpen, |
|
525 const TDesC& aClose ) |
|
526 { |
|
527 TInt sepaLen1 = aOpen.Length(); |
|
528 TInt sepaLen2 = aClose.Length(); |
|
529 TInt length = aRealAddress.Length() + aAlias.Length() + sepaLen1 + sepaLen2; |
|
530 HBufC* buf = HBufC::NewL( length ); |
|
531 buf->Des().Copy( aAlias ); |
|
532 buf->Des().Append( aOpen ); |
|
533 buf->Des().Append( aRealAddress ); |
|
534 buf->Des().Append( aClose ); |
|
535 return buf; |
|
536 } |
|
537 |
|
538 // --------------------------------------------------------- |
|
539 // TMmsGenUtils::GetDescriptionL |
|
540 // --------------------------------------------------------- |
|
541 // |
|
542 EXPORT_C void TMmsGenUtils::GetDescriptionL( |
|
543 RFs& aFs, |
|
544 const TDesC& aPath, |
|
545 TInt aFileSize, |
|
546 TPtrC8 aMimetype, |
|
547 TInt aCharSet, |
|
548 TDes& aDescription ) |
|
549 { |
|
550 TInt fileSize = aFileSize; // file size in characters |
|
551 TInt error = KErrNone; |
|
552 // set empty description if we cannot get anything |
|
553 aDescription = TPtrC(); |
|
554 |
|
555 // No subject set, so we have to |
|
556 // find the first text/plain attachment. |
|
557 |
|
558 // Update iDescription if necessary |
|
559 |
|
560 if ( aMimetype.CompareF( KMmsTextPlain )) |
|
561 { |
|
562 // no description available |
|
563 return; |
|
564 } |
|
565 |
|
566 TInt outLength = aDescription.MaxLength(); |
|
567 |
|
568 // Open the attachment file |
|
569 RFileReadStream reader; |
|
570 reader.PushL(); |
|
571 error = reader.Open( aFs, |
|
572 aPath, |
|
573 EFileShareReadersOnly ); |
|
574 if ( error != KErrNone ) |
|
575 { |
|
576 CleanupStack::PopAndDestroy( &reader ); //reader |
|
577 // cannot open file, cannot get description |
|
578 return; |
|
579 } |
|
580 |
|
581 TInt firstSize = 0; |
|
582 if ( TUint( aCharSet ) == KMmsIso10646Ucs2 ) |
|
583 { |
|
584 // Read the content |
|
585 TUint16 word = 0; |
|
586 TBool bom = EFalse; |
|
587 TBool nativeEndian = EFalse; |
|
588 |
|
589 // Check if first character is BOM and if so, then what kind it is. |
|
590 TRAP ( error, {word = reader.ReadUint16L();}); |
|
591 if ( error != KErrNone ) |
|
592 { |
|
593 CleanupStack::PopAndDestroy( &reader ); //reader |
|
594 return; // no description available |
|
595 } |
|
596 |
|
597 // reserve extra space for conversion |
|
598 firstSize = outLength + KExtraSpaceForConversion10; |
|
599 HBufC* buf1 = HBufC::NewLC( firstSize ); |
|
600 TPtr tp = buf1->Des(); |
|
601 |
|
602 if ( word == KMmsByteOrderMark ) |
|
603 { |
|
604 bom = ETrue; |
|
605 nativeEndian = ETrue; |
|
606 } |
|
607 else if ( word == KMmsReversedByteOrderMark ) |
|
608 { |
|
609 bom = ETrue; |
|
610 } |
|
611 else |
|
612 { |
|
613 } |
|
614 |
|
615 if ( bom ) |
|
616 { |
|
617 fileSize -= 2; |
|
618 } |
|
619 |
|
620 fileSize = fileSize / 2; |
|
621 |
|
622 // Read the rest of the characters |
|
623 if ( nativeEndian ) |
|
624 { |
|
625 // No need for byte order changes |
|
626 reader.ReadL( tp, Min( firstSize, fileSize )); |
|
627 } |
|
628 else if ( bom ) |
|
629 { |
|
630 // Change byte order. |
|
631 TUint8 byte1 = 0; |
|
632 TUint16 byte2 = 0; |
|
633 TUint16 word1 = 0; |
|
634 TInt numChars = Min( firstSize, fileSize ); |
|
635 for ( TInt i = 0; i < numChars; i++ ) |
|
636 { |
|
637 byte1 = reader.ReadUint8L(); |
|
638 byte2 = reader.ReadUint8L(); |
|
639 word1 = byte1; |
|
640 const TInt KMmsBitsInByte = 8; |
|
641 word1 <<= KMmsBitsInByte; |
|
642 word1 |= byte2; |
|
643 tp.Append( word1 ); |
|
644 } |
|
645 } |
|
646 |
|
647 else // no bom |
|
648 { |
|
649 // Return the first character if it was not BOM. |
|
650 // should not happen regularly |
|
651 // Read the characters |
|
652 reader.ReadL( tp, Min( firstSize, fileSize - 2 )); |
|
653 TBuf<2> auxBuf; |
|
654 auxBuf.Append(word); |
|
655 tp.Insert(0, auxBuf); |
|
656 } |
|
657 |
|
658 // Replace CR and LF with SPACE. |
|
659 ReplaceCRLFAndTrim( tp ); |
|
660 |
|
661 // Set output parameter |
|
662 aDescription = tp.Left( Min( outLength, tp.Length()) ); |
|
663 CleanupStack::PopAndDestroy( buf1 ); |
|
664 } |
|
665 |
|
666 else if ( aCharSet == KMmsUsAscii ) |
|
667 { |
|
668 // reserve extra space for conversion |
|
669 firstSize = outLength + KExtraSpaceForConversion10; |
|
670 HBufC8* buf8 = HBufC8::NewLC( firstSize ); |
|
671 TPtr8 tp8 = buf8->Des(); |
|
672 |
|
673 // Read the characters |
|
674 reader.ReadL( tp8, Min( firstSize, fileSize )); |
|
675 |
|
676 // Replace CR and LF with SPACE |
|
677 ReplaceCRLFAndTrim( tp8 ); |
|
678 |
|
679 // Copy 8 bit data to 16 bit description |
|
680 HBufC* buf16 = NULL; |
|
681 buf16 = HBufC::NewLC( tp8.Length() ); |
|
682 TPtr tp16 = buf16->Des(); |
|
683 tp16.Copy( tp8 ); |
|
684 |
|
685 // Set output parameter |
|
686 aDescription = tp16.Left( Min( outLength, tp16.Length()) ); |
|
687 CleanupStack::PopAndDestroy( buf16 ); |
|
688 CleanupStack::PopAndDestroy( buf8 ); |
|
689 } |
|
690 else if ( aCharSet == KMmsUtf8 ) |
|
691 { |
|
692 |
|
693 if ( fileSize > KMmsMaxDescription ) |
|
694 { |
|
695 fileSize = KMmsMaxDescription; |
|
696 } |
|
697 |
|
698 // reserve extra space for conversion |
|
699 firstSize = outLength + KExtraSpaceForConversion30; |
|
700 HBufC8* buf8 = HBufC8::NewLC( firstSize ); |
|
701 TPtr8 tp8 = buf8->Des(); |
|
702 |
|
703 // Read the characters |
|
704 TRAP( error, reader.ReadL( tp8, Min( firstSize, fileSize ))); |
|
705 |
|
706 if ( error == KErrNone ) |
|
707 { |
|
708 // Convert 8-bit UTF to Unicode |
|
709 HBufC* buf16 = HBufC::NewLC( tp8.Length() ); |
|
710 TPtr tp16 = buf16->Des(); |
|
711 CnvUtfConverter::ConvertToUnicodeFromUtf8( tp16, tp8 ); |
|
712 |
|
713 // Replace CR and LF with SPACE |
|
714 ReplaceCRLFAndTrim( tp16 ); |
|
715 |
|
716 // Set output parameter |
|
717 aDescription = tp16.Left( Min( outLength, tp16.Length()) ); |
|
718 CleanupStack::PopAndDestroy( buf16 ); |
|
719 } |
|
720 CleanupStack::PopAndDestroy( buf8 ); |
|
721 } |
|
722 else |
|
723 { |
|
724 |
|
725 } |
|
726 |
|
727 // Free memory |
|
728 CleanupStack::PopAndDestroy( &reader ); //reader |
|
729 } |
|
730 |
|
731 // --------------------------------------------------------- |
|
732 // TMmsGenUtils::ReplaceCRLFAndTrim |
|
733 // --------------------------------------------------------- |
|
734 // |
|
735 EXPORT_C void TMmsGenUtils::ReplaceCRLFAndTrim( TDes16& aDes ) |
|
736 { |
|
737 TInt position = -1; |
|
738 |
|
739 // Find all <CR> and <LF> characters and replace them with spaces |
|
740 |
|
741 for ( position = 0; position < aDes.Length(); position++ ) |
|
742 { |
|
743 if ( aDes.Mid( position, 1 ) < KSpace16 || |
|
744 aDes.Mid( position, 1 ) == KMmsUnicodeLineSeparator || |
|
745 aDes.Mid( position, 1 ) == KMmsUnicodeParagraphSeparator || |
|
746 aDes.Mid( position, 1 ) == KMmsIdeographicSpace || |
|
747 ((TChar)aDes[position]).IsControl() ) |
|
748 { |
|
749 aDes.Replace( position, 1, KSpace16 ); |
|
750 } |
|
751 } |
|
752 |
|
753 // Delete leading and trailing space characters from the descriptor’s |
|
754 // data and replace each contiguous set of space characters within |
|
755 // the data by one space character. |
|
756 aDes.TrimAll(); |
|
757 } |
|
758 |
|
759 |
|
760 // --------------------------------------------------------- |
|
761 // TMmsGenUtils::ReplaceCRLFAndTrim |
|
762 // --------------------------------------------------------- |
|
763 // |
|
764 EXPORT_C void TMmsGenUtils::ReplaceCRLFAndTrim( TDes8& aDes ) |
|
765 { |
|
766 // This function should be used for US-ASCII only |
|
767 TInt position = -1; |
|
768 |
|
769 for ( position = 0; position < aDes.Length(); position++ ) |
|
770 { |
|
771 if ( aDes.Mid( position, 1 ) < KSpace8 ) |
|
772 { |
|
773 aDes.Replace( position, 1, KSpace8 ); |
|
774 } |
|
775 } |
|
776 |
|
777 // Delete leading and trailing space characters from the descriptor’s |
|
778 // data and replace each contiguous set of space characters within |
|
779 // the data by one space character. |
|
780 aDes.TrimAll(); |
|
781 } |
|
782 |
|
783 // --------------------------------------------------------- |
|
784 // TMmsGenUtils::Log |
|
785 // --------------------------------------------------------- |
|
786 // |
|
787 EXPORT_C void TMmsGenUtils::Log( TRefByValue<const TDesC> aFmt,...) |
|
788 { |
|
789 #ifdef _DEBUG |
|
790 VA_LIST list; |
|
791 VA_START( list, aFmt ); |
|
792 |
|
793 // Print to log file |
|
794 TBuf<KLogBufferLength> buf; |
|
795 buf.FormatList( aFmt, list ); |
|
796 |
|
797 // Write to log file |
|
798 RFileLogger::Write( KLogDir, KLogFile, EFileLoggingModeAppend, buf ); |
|
799 #endif |
|
800 } |
|
801 |
|
802 // --------------------------------------------------------- |
|
803 // TMmsGenUtils::DoGetAliasL |
|
804 // --------------------------------------------------------- |
|
805 // |
|
806 void TMmsGenUtils::DoGetAliasL( |
|
807 RFs& aFs, |
|
808 const TDesC& aAddress, |
|
809 TDes& aAlias, |
|
810 TInt aMaxLength ) |
|
811 { |
|
812 |
|
813 //Let's find the number of digits to match |
|
814 TInt digitsToMatch = DigitsToMatch(); |
|
815 |
|
816 // We have only one address and one alias to put into the array |
|
817 CDesCArray* aliasArray = new ( ELeave )CDesCArrayFlat( 1 ); |
|
818 CleanupStack::PushL( aliasArray ); |
|
819 |
|
820 CDesCArray* realAddressArray = new ( ELeave )CDesCArrayFlat( 1 ); |
|
821 CleanupStack::PushL( realAddressArray ); |
|
822 |
|
823 realAddressArray->InsertL( 0, aAddress ); |
|
824 |
|
825 // GetAliasForAllL opens contact matcher |
|
826 GetAliasForAllL( *realAddressArray, *aliasArray, aMaxLength, aFs ); |
|
827 |
|
828 TInt size = aliasArray->MdcaCount(); |
|
829 |
|
830 if ( size > 0 ) |
|
831 { |
|
832 // only one item in our array |
|
833 aAlias.Copy( aliasArray->MdcaPoint( 0 ).Left( Min( aMaxLength, aAlias.MaxLength() ) ) ); |
|
834 } |
|
835 |
|
836 CleanupStack::PopAndDestroy( realAddressArray ); |
|
837 CleanupStack::PopAndDestroy( aliasArray ); |
|
838 |
|
839 return; |
|
840 |
|
841 } |
|
842 |
|
843 |
|
844 // --------------------------------------------------------- |
|
845 // TMmsGenUtils::DoGetAliasL |
|
846 // --------------------------------------------------------- |
|
847 // |
|
848 void TMmsGenUtils::DoGetAliasL( |
|
849 const TDesC& aAddress, |
|
850 TDes& aAlias, |
|
851 TInt aMaxLength, |
|
852 CContactMatcher& aContactMatcher, |
|
853 TInt aDigitsToMatch ) |
|
854 { |
|
855 // It appears that with the new phonebook system with multiple phonebooks, |
|
856 // TContactItemId type id cannot be extracted. |
|
857 // The result contains MVPbkContactLink type objects. |
|
858 |
|
859 // The given descriptor has to be at least 14 in length |
|
860 // (otherwise this method would leave later) |
|
861 if( aAlias.MaxLength() < KMinAliasMaxLength ) |
|
862 { |
|
863 User::Leave( KErrBadDescriptor ); |
|
864 } |
|
865 |
|
866 // These should be inline with each other, but if necessary, |
|
867 // size down aMaxLength. |
|
868 // aMaxLength, however, can be smaller than the buffer |
|
869 if ( aMaxLength > aAlias.MaxLength() ) |
|
870 { |
|
871 aMaxLength = aAlias.MaxLength(); |
|
872 } |
|
873 |
|
874 if ( aMaxLength > 0 ) |
|
875 { |
|
876 // set length of alias to 0 |
|
877 // this can be used to determine if alias was found |
|
878 // contact id not needed or used |
|
879 aAlias.Zero(); |
|
880 } |
|
881 |
|
882 // Convert to real address just in case. The address should be pure already, |
|
883 // but we are just being paranoid... |
|
884 |
|
885 TPtrC realAddress; |
|
886 realAddress.Set( PureAddress( aAddress, KSepaOpen, KSepaClose ) ); |
|
887 CVPbkContactLinkArray* linkArray = CVPbkContactLinkArray::NewL(); |
|
888 CleanupStack::PushL( linkArray ); |
|
889 |
|
890 // Check if the address is phone number or EMail address |
|
891 if ( IsValidMMSPhoneAddress( realAddress, ETrue ) ) |
|
892 { |
|
893 // Lookup the telephone number in the contact database |
|
894 // For numbers shorter than 7 digits, only exact matches are returned |
|
895 |
|
896 aContactMatcher.MatchPhoneNumberL( realAddress, aDigitsToMatch, |
|
897 CVPbkPhoneNumberMatchStrategy::EVPbkMatchFlagsNone, *linkArray ); |
|
898 |
|
899 // If more than one matches have been found, |
|
900 // the first one will be used. |
|
901 } |
|
902 else if ( IsValidEmailAddress( realAddress ) ) |
|
903 { |
|
904 // Try to match with EMail address |
|
905 |
|
906 TVPbkFieldVersitProperty prop; |
|
907 CVPbkFieldTypeRefsList* fieldTypes = CVPbkFieldTypeRefsList::NewL(); |
|
908 CleanupStack::PushL( fieldTypes ); |
|
909 |
|
910 const MVPbkFieldTypeList& fieldTypeList = aContactMatcher.FieldTypes(); |
|
911 const MVPbkFieldType* foundType = NULL; |
|
912 |
|
913 prop.SetName( EVPbkVersitNameEMAIL ); |
|
914 /* |
|
915 // Remove code because matching matches properies, too. |
|
916 // We don't care about properties. |
|
917 |
|
918 // The phonebook should provide a function that allows mathcing name only |
|
919 foundType = fieldTypeList.FindMatch( prop, 0 ); |
|
920 |
|
921 if ( foundType ) |
|
922 { |
|
923 fieldTypes->AppendL( *foundType ); |
|
924 } |
|
925 */ |
|
926 |
|
927 // The field type matching does not work because it tries to match |
|
928 // parameters we are not interested in. |
|
929 // We try to generate a list that has all entries with versit type EMAIL |
|
930 |
|
931 TInt i; |
|
932 for ( i = 0; i < fieldTypeList.FieldTypeCount(); i++ ) |
|
933 { |
|
934 foundType = &(fieldTypeList.FieldTypeAt( i )); |
|
935 if ( foundType->VersitProperties().Count() > 0 |
|
936 && foundType->VersitProperties()[0].Name() == prop.Name() ) |
|
937 { |
|
938 fieldTypes->AppendL( *foundType ); |
|
939 } |
|
940 } |
|
941 |
|
942 |
|
943 // Here we stop at first match - email addresses should be unique |
|
944 aContactMatcher.MatchDataL( realAddress, *fieldTypes, *linkArray ); |
|
945 CleanupStack::PopAndDestroy( fieldTypes ); |
|
946 } |
|
947 else |
|
948 { |
|
949 User::Leave( KErrNotFound ); |
|
950 } |
|
951 |
|
952 TInt nameIndex = 0; //correct index if only one match is found |
|
953 if( linkArray->Count() == 0 ) |
|
954 { |
|
955 Log( _L( "No match found" ) ); |
|
956 User::Leave( KErrNotFound ); |
|
957 } |
|
958 else if( linkArray->Count() > 1 ) |
|
959 { |
|
960 //Multiple matches found. Get the current store single match index if any. |
|
961 nameIndex = GetCurrentStoreIndexL( *linkArray ); |
|
962 if( nameIndex == KErrMultipleMatchFound ) |
|
963 { |
|
964 /* No unique match in current store, Hence show the name only if all the matches have |
|
965 * identical names |
|
966 */ |
|
967 if( ShowContactNameL( linkArray, nameIndex, aContactMatcher) == EFalse) |
|
968 { |
|
969 Log( _L( "No (Perfect) match found" ) ); |
|
970 User::Leave( KErrMultipleMatchFound ); |
|
971 } |
|
972 } |
|
973 } |
|
974 |
|
975 // if not interested in alias, skip this |
|
976 if ( aMaxLength > 0 ) |
|
977 { |
|
978 HBufC* alias = GetContactNameL( linkArray->At(nameIndex), aContactMatcher ); |
|
979 if ( alias && alias->Des().Length() > 0 ) |
|
980 { |
|
981 aAlias.Copy( alias->Des().Left( aMaxLength ) ); |
|
982 } |
|
983 else |
|
984 { |
|
985 aAlias.Copy( TPtrC() ); |
|
986 } |
|
987 delete alias; |
|
988 alias = NULL; |
|
989 // end of part skipped if not interested in alias |
|
990 } |
|
991 |
|
992 linkArray->ResetAndDestroy(); |
|
993 CleanupStack::PopAndDestroy( linkArray ); |
|
994 } |
|
995 |
|
996 // --------------------------------------------------------- |
|
997 // TMmsGenUtils::ConvertEscapesFromUri |
|
998 // --------------------------------------------------------- |
|
999 // |
|
1000 /*TInt TMmsGenUtils::ConvertEscapesFromUri( |
|
1001 const TDesC8& aInput, |
|
1002 TDes8& aOutput ) |
|
1003 { |
|
1004 TInt retval = KErrNone; |
|
1005 |
|
1006 // Checkings |
|
1007 if( aOutput.MaxLength() < aInput.Length() ) |
|
1008 { |
|
1009 retval = KErrArgument; |
|
1010 return retval; |
|
1011 } |
|
1012 |
|
1013 // Loop through aInput and find the number of '%' chars |
|
1014 for( TUint8 i = 0; i < aInput.Length(); i++ ) |
|
1015 { |
|
1016 if( aInput[i] == 0x25 ) // '%' found |
|
1017 { |
|
1018 // Store the chars representing the hexvalue |
|
1019 TUint8 highbyte = aInput[i+1]; |
|
1020 TUint8 lowbyte = aInput[i+2]; |
|
1021 |
|
1022 // Check the bytes |
|
1023 TUint8 result = 0; |
|
1024 |
|
1025 // Map the highbyte to correct upperbits of result |
|
1026 // (In order to save code lines and keep code readable, |
|
1027 // the following does not follow the coding convention.) |
|
1028 if(highbyte == 0x30) result = 0x0; |
|
1029 if(highbyte == 0x31) result = 0x1; |
|
1030 if(highbyte == 0x32) result = 0x2; |
|
1031 if(highbyte == 0x33) result = 0x3; |
|
1032 if(highbyte == 0x34) result = 0x4; |
|
1033 if(highbyte == 0x35) result = 0x5; |
|
1034 if(highbyte == 0x36) result = 0x6; |
|
1035 if(highbyte == 0x37) result = 0x7; |
|
1036 if(highbyte == 0x38) result = 0x8; |
|
1037 if(highbyte == 0x39) result = 0x9; |
|
1038 if(highbyte == 0x41 || highbyte == 0x61) result = 0xA; |
|
1039 if(highbyte == 0x42 || highbyte == 0x62) result = 0xB; |
|
1040 if(highbyte == 0x43 || highbyte == 0x63) result = 0xC; |
|
1041 if(highbyte == 0x44 || highbyte == 0x64) result = 0xD; |
|
1042 if(highbyte == 0x45 || highbyte == 0x65) result = 0xE; |
|
1043 if(highbyte == 0x46 || highbyte == 0x66) result = 0xF; |
|
1044 |
|
1045 if( ( result == 0 ) && ( highbyte != 0x30 ) ) |
|
1046 { |
|
1047 retval = KErrArgument; |
|
1048 } |
|
1049 result <<= 4; |
|
1050 |
|
1051 // Map the lowbyte to correct lowerbits of result |
|
1052 // (In order to save code lines and keep code readable, |
|
1053 // the following does not follow the coding convention.) |
|
1054 if(lowbyte == 0x30) result += 0x0; |
|
1055 if(lowbyte == 0x31) result += 0x1; |
|
1056 if(lowbyte == 0x32) result += 0x2; |
|
1057 if(lowbyte == 0x33) result += 0x3; |
|
1058 if(lowbyte == 0x34) result += 0x4; |
|
1059 if(lowbyte == 0x35) result += 0x5; |
|
1060 if(lowbyte == 0x36) result += 0x6; |
|
1061 if(lowbyte == 0x37) result += 0x7; |
|
1062 if(lowbyte == 0x38) result += 0x8; |
|
1063 if(lowbyte == 0x39) result += 0x9; |
|
1064 if(lowbyte == 0x41 || lowbyte == 0x61) result += 0xA; |
|
1065 if(lowbyte == 0x42 || lowbyte == 0x62) result += 0xB; |
|
1066 if(lowbyte == 0x43 || lowbyte == 0x63) result += 0xC; |
|
1067 if(lowbyte == 0x44 || lowbyte == 0x64) result += 0xD; |
|
1068 if(lowbyte == 0x45 || lowbyte == 0x65) result += 0xE; |
|
1069 if(lowbyte == 0x46 || lowbyte == 0x66) result += 0xF; |
|
1070 |
|
1071 if( ( ( result & 0xF ) == 0 ) && ( lowbyte != 0x30 ) ) |
|
1072 { |
|
1073 retval = KErrArgument; |
|
1074 } |
|
1075 |
|
1076 // Abort if error has occurred |
|
1077 if( retval != KErrNone ) |
|
1078 { |
|
1079 return retval; |
|
1080 } |
|
1081 |
|
1082 // Insert the value to output parameter |
|
1083 aOutput.Append( result ); |
|
1084 i += 2; // Jumping over the two chars already handled |
|
1085 } |
|
1086 else |
|
1087 { |
|
1088 aOutput.Append( aInput[i] ); |
|
1089 } |
|
1090 } // for |
|
1091 return retval; |
|
1092 }*/ |
|
1093 |
|
1094 // --------------------------------------------------------- |
|
1095 // TMmsGenUtils::DecodeMessageHeader |
|
1096 // --------------------------------------------------------- |
|
1097 // |
|
1098 EXPORT_C void TMmsGenUtils::DecodeAndConvertMessageHeaderL( |
|
1099 const TDesC8& aInput, |
|
1100 TDes16& aOutput, |
|
1101 RFs& aFs |
|
1102 ) |
|
1103 { |
|
1104 // Create CCnvCharacterSetConverter |
|
1105 CCnvCharacterSetConverter* characterSetConverter |
|
1106 = CCnvCharacterSetConverter::NewL(); |
|
1107 CleanupStack::PushL( characterSetConverter ); |
|
1108 |
|
1109 // Create CImConvertCharconv |
|
1110 // (this is a wrapper for the actual char converter) |
|
1111 CImConvertCharconv* converter |
|
1112 = CImConvertCharconv::NewL( *characterSetConverter, aFs ); |
|
1113 CleanupStack::PushL( converter ); |
|
1114 |
|
1115 // Create CImConvertHeader that actually does the task |
|
1116 CImConvertHeader* headerConverter = CImConvertHeader::NewL( *converter ); |
|
1117 CleanupStack::PushL( headerConverter ); |
|
1118 |
|
1119 // Perform the decoding and charset conversion |
|
1120 headerConverter->DecodeHeaderFieldL( aInput, aOutput ); |
|
1121 |
|
1122 // Clean up and return |
|
1123 CleanupStack::PopAndDestroy( headerConverter ); |
|
1124 CleanupStack::PopAndDestroy( converter ); |
|
1125 CleanupStack::PopAndDestroy( characterSetConverter ); |
|
1126 } |
|
1127 |
|
1128 |
|
1129 // --------------------------------------------------------- |
|
1130 // |
|
1131 // Return the free space in a drive identified by the aDrive parameter |
|
1132 // and the media type of the drive. |
|
1133 // |
|
1134 // --------------------------------------------------------- |
|
1135 static TInt64 FreeSpaceL(RFs* aFs, TInt aDrive, TMediaType& aMediaType) |
|
1136 { |
|
1137 RFs fs; |
|
1138 TInt err = KErrNone; |
|
1139 |
|
1140 if ( !aFs ) |
|
1141 User::LeaveIfError(fs.Connect()); // Create temp session |
|
1142 else |
|
1143 fs = *aFs; |
|
1144 |
|
1145 TVolumeInfo vinfo; |
|
1146 err = fs.Volume(vinfo, aDrive); |
|
1147 |
|
1148 TDriveInfo driveInfo; |
|
1149 TInt errorCode = fs.Drive( driveInfo, aDrive ); |
|
1150 if ( errorCode == KErrNone ) |
|
1151 { |
|
1152 aMediaType = driveInfo.iType; |
|
1153 } |
|
1154 else |
|
1155 { |
|
1156 aMediaType = EMediaUnknown; |
|
1157 } |
|
1158 |
|
1159 if ( !aFs ) |
|
1160 fs.Close(); // Close temp. session |
|
1161 |
|
1162 if (err != KErrNone) |
|
1163 { |
|
1164 User::LeaveIfError(err); |
|
1165 } |
|
1166 |
|
1167 return TInt64(vinfo.iFree); |
|
1168 } |
|
1169 |
|
1170 // --------------------------------------------------------- |
|
1171 // TMmsGenUtils::DiskSpaceBelowCriticalLevelL |
|
1172 // --------------------------------------------------------- |
|
1173 // |
|
1174 EXPORT_C TBool TMmsGenUtils::DiskSpaceBelowCriticalLevelL( |
|
1175 RFs* aFs, TInt aBytesToWrite, TInt aDrive) |
|
1176 { |
|
1177 TInt64 free; |
|
1178 TInt64 criticalLevel; |
|
1179 CRepository* repository = NULL; |
|
1180 TMediaType mediaType = EMediaNotPresent; |
|
1181 free = FreeSpaceL(aFs, aDrive, mediaType); |
|
1182 |
|
1183 TInt64 newFree = free - (TInt64)aBytesToWrite; |
|
1184 |
|
1185 // Querying Critical Level from CenRep |
|
1186 TInt error = KErrNone; |
|
1187 TInt level = 0; |
|
1188 TRAP( error, repository = CRepository::NewL( KCRUidUiklaf ) ); |
|
1189 if ( error == KErrNone) |
|
1190 { |
|
1191 error = repository->Get( KUikOODDiskCriticalThreshold, level ); |
|
1192 delete repository; |
|
1193 if( error != KErrNone ) |
|
1194 { |
|
1195 // Default value 0 means "anything goes" |
|
1196 level = 0; |
|
1197 } |
|
1198 } |
|
1199 |
|
1200 #ifdef _DEBUG |
|
1201 if ( error != KErrNone ) |
|
1202 { |
|
1203 _LIT( KMmsCriticalSpaceError, "- Get critical disk space threshold returned error %d" ); |
|
1204 Log( KMmsCriticalSpaceError, error ); |
|
1205 } |
|
1206 else |
|
1207 { |
|
1208 _LIT( KMmsCriticalSpaceLog, "- Critical level: %d, free space: %d" ); |
|
1209 Log( KMmsCriticalSpaceLog, level, newFree ); |
|
1210 } |
|
1211 #endif |
|
1212 |
|
1213 criticalLevel = level; |
|
1214 return newFree <= criticalLevel; |
|
1215 } |
|
1216 |
|
1217 // --------------------------------------------------------- |
|
1218 // TMmsGenUtils::NetworkOperationsAllowed() |
|
1219 // |
|
1220 // --------------------------------------------------------- |
|
1221 // |
|
1222 EXPORT_C TBool TMmsGenUtils::NetworkOperationsAllowed() |
|
1223 { |
|
1224 TBool networkAllowed = ETrue; // optimist |
|
1225 // If there is no such key, we will continue normally. |
|
1226 // This means that in a system where online/offline mode switching |
|
1227 // is not supported, we behave as we were always online |
|
1228 |
|
1229 CRepository* repository = NULL; |
|
1230 TInt error = KErrNone; |
|
1231 TInt value = ECoreAppUIsNetworkConnectionAllowed; |
|
1232 TRAP( error, repository = CRepository::NewL( KCRUidCoreApplicationUIs ) ); |
|
1233 if( error == KErrNone ) |
|
1234 { |
|
1235 repository->Get( KCoreAppUIsNetworkConnectionAllowed, value ); |
|
1236 delete repository; |
|
1237 repository = NULL; |
|
1238 if ( value == ECoreAppUIsNetworkConnectionNotAllowed ) |
|
1239 { |
|
1240 networkAllowed = EFalse; |
|
1241 } |
|
1242 } |
|
1243 |
|
1244 return networkAllowed; |
|
1245 } |
|
1246 |
|
1247 // --------------------------------------------------------- |
|
1248 // TMmsGenUtils::GetLoggingSettings |
|
1249 // --------------------------------------------------------- |
|
1250 // |
|
1251 EXPORT_C void TMmsGenUtils::GetLoggingSettings( TBool& aDecodeLoggingOn, TBool& aDumpOn ) |
|
1252 { |
|
1253 // Consult CenRep for decodelogging and binarydump settings |
|
1254 CRepository* repository = NULL; |
|
1255 // default values are false if not found in repository |
|
1256 aDecodeLoggingOn = EFalse; |
|
1257 aDumpOn = EFalse; |
|
1258 |
|
1259 TInt retval = KErrNone; |
|
1260 TRAP_IGNORE( |
|
1261 { |
|
1262 repository = CRepository::NewL( KUidMmsServerMtm ); |
|
1263 CleanupStack::PushL( repository ); |
|
1264 TInt temp = 0; |
|
1265 retval = repository->Get( KMmsEngineDecodeLog, temp ); |
|
1266 if( retval == KErrNone ) |
|
1267 { |
|
1268 aDecodeLoggingOn = ( temp != 0 ); |
|
1269 } |
|
1270 retval = repository->Get( KMmsEngineBinaryDump, temp ); |
|
1271 if( retval == KErrNone ) |
|
1272 { |
|
1273 aDumpOn = ( temp != 0 ); |
|
1274 } |
|
1275 CleanupStack::PopAndDestroy( repository ); |
|
1276 repository = NULL; |
|
1277 } |
|
1278 ); |
|
1279 #ifndef __WINS__ |
|
1280 // turn decode logging on in armv5 version |
|
1281 // Release versions never log anyway |
|
1282 aDecodeLoggingOn = ETrue; |
|
1283 #endif |
|
1284 } |
|
1285 |
|
1286 // --------------------------------------------------------- |
|
1287 // TMmsGenUtils::AddAttributeL |
|
1288 // |
|
1289 // --------------------------------------------------------- |
|
1290 // |
|
1291 EXPORT_C void TMmsGenUtils::AddAttributeL( |
|
1292 const TDesC& aName, |
|
1293 const TDesC& aValue, |
|
1294 CDesCArray& aAttributeList ) |
|
1295 { |
|
1296 TInt position = FindAttributePosition( aName, aAttributeList ); |
|
1297 TInt error = KErrNone; |
|
1298 |
|
1299 if ( position == KErrNotFound ) |
|
1300 { |
|
1301 // not found, append to end |
|
1302 aAttributeList.AppendL( aName ); |
|
1303 TRAP ( error, aAttributeList.AppendL( aValue ) ); |
|
1304 if ( error != KErrNone ) |
|
1305 { |
|
1306 // could not add value, delete name, too. |
|
1307 // It is the last item in the list |
|
1308 aAttributeList.Delete( aAttributeList.MdcaCount() - 1 ); |
|
1309 } |
|
1310 } |
|
1311 else |
|
1312 { |
|
1313 // delete old value and insert new one |
|
1314 aAttributeList.Delete( position + 1 ); |
|
1315 TRAP ( error, aAttributeList.InsertL( position + 1, aValue ) ); |
|
1316 if ( error != KErrNone ) |
|
1317 { |
|
1318 // could not add value, delete name, too. |
|
1319 aAttributeList.Delete( position ); |
|
1320 } |
|
1321 } |
|
1322 User::LeaveIfError( error ); |
|
1323 |
|
1324 } |
|
1325 |
|
1326 // --------------------------------------------------------- |
|
1327 // TMmsGenUtils::GetAttributeL |
|
1328 // |
|
1329 // --------------------------------------------------------- |
|
1330 // |
|
1331 EXPORT_C TPtrC TMmsGenUtils::GetAttributeL( |
|
1332 const TDesC& aName, |
|
1333 const CDesCArray& aAttributeList ) |
|
1334 { |
|
1335 TInt position = FindAttributePosition( aName, aAttributeList ); |
|
1336 |
|
1337 if ( position == KErrNotFound ) |
|
1338 { |
|
1339 User::Leave( KErrNotFound ); |
|
1340 } |
|
1341 return ( aAttributeList.MdcaPoint( position + 1 ) ); |
|
1342 } |
|
1343 |
|
1344 // --------------------------------------------------------- |
|
1345 // TMmsGenUtils::FindAttribute |
|
1346 // |
|
1347 // --------------------------------------------------------- |
|
1348 // |
|
1349 EXPORT_C TBool TMmsGenUtils::FindAttribute( |
|
1350 const TDesC& aName, |
|
1351 const CDesCArray& aAttributeList ) |
|
1352 { |
|
1353 if ( FindAttributePosition( aName, aAttributeList ) == KErrNotFound ) |
|
1354 { |
|
1355 return EFalse; |
|
1356 } |
|
1357 return ETrue; |
|
1358 } |
|
1359 |
|
1360 // --------------------------------------------------------- |
|
1361 // TMmsGenUtils::DeleteAttribute |
|
1362 // |
|
1363 // --------------------------------------------------------- |
|
1364 // |
|
1365 EXPORT_C void TMmsGenUtils::DeleteAttribute( |
|
1366 const TDesC& aName, |
|
1367 CDesCArray& aAttributeList ) |
|
1368 { |
|
1369 TInt position = FindAttributePosition( aName, aAttributeList ); |
|
1370 |
|
1371 if ( position == KErrNotFound ) |
|
1372 { |
|
1373 return; // not found, nothing to delete |
|
1374 } |
|
1375 // delete both name and value |
|
1376 aAttributeList.Delete( position, 2 ); |
|
1377 } |
|
1378 |
|
1379 // --------------------------------------------------------- |
|
1380 // TMmsGenUtils::FindAttributePosition |
|
1381 // |
|
1382 // --------------------------------------------------------- |
|
1383 // |
|
1384 TInt TMmsGenUtils::FindAttributePosition( |
|
1385 const TDesC& aName, |
|
1386 const CDesCArray& aAttributeList ) |
|
1387 { |
|
1388 TInt position = KErrNotFound; |
|
1389 |
|
1390 TInt i; |
|
1391 |
|
1392 for ( i = 0; i < aAttributeList.MdcaCount() - 1; i+=2 ) |
|
1393 { |
|
1394 //It is not possible to index out of bound (codescanner warning) |
|
1395 if ( aAttributeList[i].Compare( aName ) == 0 ) |
|
1396 { |
|
1397 position = i; |
|
1398 } |
|
1399 } |
|
1400 return position; |
|
1401 } |
|
1402 |
|
1403 |
|
1404 // --------------------------------------------------------- |
|
1405 // TMmsGenUtils::DigitsToMatch |
|
1406 // |
|
1407 // --------------------------------------------------------- |
|
1408 TInt TMmsGenUtils::DigitsToMatch() |
|
1409 { |
|
1410 // Find the number of digits to be used when matching phone numbers |
|
1411 TInt digitsToMatch( KMmsNumberOfDigitsToMatch ); |
|
1412 |
|
1413 CRepository* repository = NULL; |
|
1414 TRAPD( err, repository = CRepository::NewL( KCRUidTelConfiguration )); |
|
1415 if ( err == KErrNone ) |
|
1416 { |
|
1417 err = repository->Get( KTelMatchDigits , digitsToMatch ); |
|
1418 delete repository; |
|
1419 if( err != KErrNone ) |
|
1420 { |
|
1421 digitsToMatch=KMmsNumberOfDigitsToMatch; |
|
1422 } |
|
1423 } |
|
1424 return digitsToMatch; |
|
1425 } |
|
1426 |
|
1427 // --------------------------------------------------------- |
|
1428 // TMmsGenUtils::OpenAllStoresL |
|
1429 // |
|
1430 // --------------------------------------------------------- |
|
1431 CContactMatcher* TMmsGenUtils::OpenAllStoresL( RFs& aFs ) |
|
1432 { |
|
1433 // Use contact wrapper to open all databases |
|
1434 CContactMatcher* contactMatcher = CContactMatcher::NewL( &aFs ); |
|
1435 CleanupStack::PushL( contactMatcher ); |
|
1436 |
|
1437 contactMatcher->OpenDefaultMatchStoresL(); |
|
1438 |
|
1439 CleanupStack::Pop( contactMatcher ); |
|
1440 return contactMatcher; |
|
1441 } |
|
1442 |
|
1443 // ----------------------------------------------------------------------------- |
|
1444 // TMmsGenUtils::GetContactNameL |
|
1445 // ----------------------------------------------------------------------------- |
|
1446 // |
|
1447 HBufC* TMmsGenUtils::GetContactNameL( |
|
1448 const MVPbkContactLink& aContactLink, |
|
1449 CContactMatcher &aContactMatcher) |
|
1450 { |
|
1451 Log(_L( "- TMmsGenUtils::GetContactNameL -> start" ) ); |
|
1452 MVPbkStoreContact* tempContact; |
|
1453 aContactMatcher.GetStoreContactL(aContactLink, &tempContact); |
|
1454 tempContact->PushL(); |
|
1455 |
|
1456 MVPbkStoreContactFieldCollection& coll = tempContact->Fields(); |
|
1457 HBufC* nameBuff = aContactMatcher.GetNameL( coll ); |
|
1458 |
|
1459 CleanupStack::PopAndDestroy(tempContact); // tempContact |
|
1460 |
|
1461 Log( _L( "- TMmsGenUtils::GetContactNameL <- end" ) ); |
|
1462 return nameBuff; |
|
1463 } |
|
1464 |
|
1465 // ----------------------------------------------------------------------------- |
|
1466 // TMmsGenUtils::GetContactNameInLowerCaseL |
|
1467 // ----------------------------------------------------------------------------- |
|
1468 // |
|
1469 HBufC* TMmsGenUtils::GetContactNameInLowerCaseL( |
|
1470 const MVPbkContactLink& aContactLink, |
|
1471 CContactMatcher &aContactMatcher) |
|
1472 { |
|
1473 //get the name |
|
1474 HBufC* nameBuff = GetContactNameL( aContactLink, aContactMatcher ); |
|
1475 CleanupStack::PushL( nameBuff ); |
|
1476 |
|
1477 //Convert to lower case , since this name buffer is used to compare names. |
|
1478 HBufC* nameInLowerCase = HBufC::NewL( nameBuff->Length() + 2 ); |
|
1479 nameInLowerCase->Des().CopyLC( *nameBuff ); |
|
1480 |
|
1481 CleanupStack::PopAndDestroy( nameBuff ); // nameBuff |
|
1482 return nameInLowerCase; |
|
1483 } |
|
1484 |
|
1485 // ----------------------------------------------------------------------------- |
|
1486 // TMmsGenUtils::ShowContactNameL |
|
1487 // ----------------------------------------------------------------------------- |
|
1488 // |
|
1489 TBool TMmsGenUtils::ShowContactNameL( |
|
1490 CVPbkContactLinkArray* aLinkArray, |
|
1491 TInt &aNameIndex, |
|
1492 CContactMatcher &aContactMatcher) |
|
1493 { |
|
1494 Log( _L("- TMmsGenUtils::ShowContactName -> start") ); |
|
1495 Log( _L("Contact Match statistics to follow..." ) ); |
|
1496 Log( _L("Match count: %d"), aLinkArray->Count() ); |
|
1497 /* TODO:: compare the names upto standard |
|
1498 * 1. if all the names are same - display the name |
|
1499 * eg: "abcdef xyz" && "abcdef xyz" |
|
1500 * 2. find min name legth among all,(if ONLY Part-match is needed ) |
|
1501 * if this length is > standard length and matches upto standard length - display the larger name. |
|
1502 * eg: abcdef xyz123, abcdef xyz12, abcdef xyz and std length is 10, |
|
1503 * since match upto 10 chars is fine, display abcdef xyz123 |
|
1504 * 3. in any other case do not show name |
|
1505 * eg: abcdef xyz , abcde xyz |
|
1506 * abcdef xyz , abcdef xy |
|
1507 * abcdef xyz , abcde |
|
1508 */ |
|
1509 TInt i, minLength = 999, maxLength = 0, length = 0, maxLengthIndex = 0, stdLength = 14; |
|
1510 TBool retVal = ETrue ; |
|
1511 |
|
1512 for( i = 0 ; i < aLinkArray->Count(); i++ ) |
|
1513 { |
|
1514 HBufC* alias = GetContactNameL( aLinkArray->At(i), aContactMatcher ); |
|
1515 Log( _L(":-> %s" ), alias->Des().PtrZ()); |
|
1516 length = alias->Des().Length(); |
|
1517 if(minLength > length) |
|
1518 { |
|
1519 minLength = length; |
|
1520 } |
|
1521 if(maxLength < length) |
|
1522 { |
|
1523 maxLength = length; |
|
1524 maxLengthIndex = i; |
|
1525 } |
|
1526 delete alias; |
|
1527 alias = NULL; |
|
1528 } |
|
1529 |
|
1530 Log( _L( "Contact Lengths: Std Length : %d\n MinLength : %d\n MaxLength : %d\n MaxLen index: %d" ), |
|
1531 stdLength, |
|
1532 minLength, |
|
1533 maxLength, |
|
1534 maxLengthIndex); |
|
1535 |
|
1536 if(minLength != maxLength) |
|
1537 { |
|
1538 //complete length match not possible |
|
1539 retVal = EFalse; |
|
1540 |
|
1541 /* NOTE: |
|
1542 * Uncomment below code if partial length(upto stdLength) match is sufficient, |
|
1543 * ensure stdLength is correct |
|
1544 */ |
|
1545 /* |
|
1546 if(minLength < stdLength) |
|
1547 { |
|
1548 retVal = EFalse; |
|
1549 } |
|
1550 */ |
|
1551 } |
|
1552 |
|
1553 if( retVal ) |
|
1554 { |
|
1555 TInt ret; |
|
1556 HBufC* longestName = GetContactNameInLowerCaseL( aLinkArray->At(maxLengthIndex), aContactMatcher ); |
|
1557 Log( _L( "Longest name:-> %s" ), longestName->Des().PtrZ()); |
|
1558 for ( i = 0; i < aLinkArray->Count() && retVal; i++ ) |
|
1559 { |
|
1560 HBufC* nameI = GetContactNameInLowerCaseL( aLinkArray->At(i), aContactMatcher ); |
|
1561 Log( _L( "compared with -> %s" ), nameI->Des().PtrZ()); |
|
1562 ret = longestName->Find(nameI->Des()); |
|
1563 if(ret == KErrNotFound || ret != 0) |
|
1564 { |
|
1565 Log( _L( "Part/Full Match error/offset: %d" ), ret); |
|
1566 retVal = EFalse; |
|
1567 } |
|
1568 delete nameI; |
|
1569 nameI = NULL; |
|
1570 } |
|
1571 delete longestName; |
|
1572 longestName = NULL; |
|
1573 } |
|
1574 |
|
1575 aNameIndex = maxLengthIndex; |
|
1576 |
|
1577 Log( _L( "Final Match result : %d\n Final Match index : %d" ), retVal, maxLengthIndex); |
|
1578 Log( _L( "- TMmsGenUtils::ShowContactName <- end" ) ); |
|
1579 |
|
1580 return retVal; |
|
1581 } |
|
1582 |
|
1583 // ----------------------------------------------------------------------------- |
|
1584 // TMmsGenUtils::GetCurrentStoreIndexL |
|
1585 // ----------------------------------------------------------------------------- |
|
1586 // |
|
1587 TInt TMmsGenUtils::GetCurrentStoreIndexL( CVPbkContactLinkArray& aLinkArray ) |
|
1588 { |
|
1589 TInt curStoreIndex( KErrMultipleMatchFound ); |
|
1590 TInt curStoreMatchCount = 0; |
|
1591 RArray<TInt> otherStoreMatchIndices; |
|
1592 CleanupClosePushL( otherStoreMatchIndices ); |
|
1593 |
|
1594 //Get the current configured contact store array(s) |
|
1595 CPbk2StoreConfiguration* storeConfiguration = CPbk2StoreConfiguration::NewL(); |
|
1596 CleanupStack::PushL( storeConfiguration ); |
|
1597 CVPbkContactStoreUriArray* currStoreArray = storeConfiguration->CurrentConfigurationL(); |
|
1598 CleanupStack::PopAndDestroy(storeConfiguration); |
|
1599 |
|
1600 if ( currStoreArray ) |
|
1601 { |
|
1602 /* Contact's store is compared against user selected stores. |
|
1603 * If contact is from such store, found index is incremented |
|
1604 * else, other store contact indices are populated into array for further use |
|
1605 */ |
|
1606 for ( TInt i = 0; i < aLinkArray.Count(); i++ ) |
|
1607 { |
|
1608 TVPbkContactStoreUriPtr uri = aLinkArray.At(i).ContactStore().StoreProperties().Uri(); |
|
1609 if ( currStoreArray->IsIncluded( uri ) ) |
|
1610 { |
|
1611 // Set index to found contact and increment the count. |
|
1612 curStoreIndex = i; |
|
1613 curStoreMatchCount++; |
|
1614 } |
|
1615 else |
|
1616 { |
|
1617 otherStoreMatchIndices.AppendL(i); |
|
1618 } |
|
1619 } |
|
1620 |
|
1621 delete currStoreArray; |
|
1622 if ( curStoreMatchCount > 1) |
|
1623 { |
|
1624 /* Multiple matches found from current user selected store(s) |
|
1625 * Delete match from other stores in aLinkArray. New aLinkArray should only contain |
|
1626 * current store contact matches, so that next level pruning can be done(e.g, names can be |
|
1627 * compared and displayed if they are identical). |
|
1628 */ |
|
1629 for(TInt i = otherStoreMatchIndices.Count() - 1; i >= 0; i--) |
|
1630 { |
|
1631 aLinkArray.Delete( otherStoreMatchIndices[i] ); |
|
1632 } |
|
1633 curStoreIndex = KErrMultipleMatchFound; |
|
1634 } |
|
1635 } |
|
1636 CleanupStack::PopAndDestroy( &otherStoreMatchIndices ); |
|
1637 return curStoreIndex; |
|
1638 } |
|
1639 |
|
1640 // ================= OTHER EXPORTED FUNCTIONS ============== |
|
1641 |
|
1642 // End of File |