|
1 /* |
|
2 * Copyright (c) 2004-2006 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: Utils for IM modules. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "CAUtils.h" |
|
20 #include "CCAStorageManagerFactory.h" |
|
21 #include "MCAStoredContacts.h" |
|
22 #include "ChatDebugPrint.h" |
|
23 #include "impsbuilddefinitions.h" |
|
24 |
|
25 #include <EscapeUtils.h> |
|
26 #include <collate.h> |
|
27 |
|
28 // needed to skip prefixes in domain-neutral comparison (TUint version) |
|
29 const TUint KColonUInt( ':' ); |
|
30 |
|
31 // needed to skip domains in domain-neutral comparison (TUint version) |
|
32 const TUint KAtUInt( '@' ); |
|
33 // general colon needed in various places |
|
34 _LIT( KColon, ":" ); |
|
35 |
|
36 // general slash needed in various places |
|
37 _LIT( KSlash, "/" ); |
|
38 |
|
39 // needed to skip domains in domain-neutral comparison |
|
40 _LIT( KAt, "@" ); |
|
41 |
|
42 // "test character identity and accents, ignore case" |
|
43 const TInt KCollationLevel = 1; |
|
44 |
|
45 // max number to store any values |
|
46 const TInt KMAX_NUMBER = 12; |
|
47 |
|
48 // max number to fit |
|
49 const TInt KMAX_LIMIT = 255; |
|
50 |
|
51 // max number base |
|
52 const TInt KMAX_NUMBERBASE = 10; |
|
53 |
|
54 // some character value constants |
|
55 //const TUint K7LSBMask = 0x7f // bitmask for 7 lsb bits |
|
56 const TUint K8BitMask = 0xff; // full bitmask |
|
57 //const TUint KCharCodeZero = 0x30 // '0' |
|
58 //const TUint KCharCodeSmallZ = 0x7a // 'z' |
|
59 //const TUint KCharCodeSpace = 0x20 // ' ' |
|
60 const TUint KCharToArea = 0x030; |
|
61 |
|
62 // Unused areas (2) in ISO 8859-1 specification |
|
63 //const TUint KUnused8859start1 = 0x00 |
|
64 const TUint KUnused8859end1 = 0x1F; |
|
65 const TUint KUnused8859start2 = 0x7F; |
|
66 const TUint KUnused8859end2 = 0x9F; |
|
67 |
|
68 // forbidden characters that cannot appear in Wireless Village Ids |
|
69 _LIT( KWVForbiddenCharacters, "/@+ \t:" ); |
|
70 |
|
71 /** |
|
72 * Constants to use in validation. |
|
73 * |
|
74 */ |
|
75 _LIT( KCUImpsId_WhiteSpace, " " ); |
|
76 _LIT( KCUImpsId_At, "@" ); |
|
77 _LIT( KCUImpsId_Dot, "." ); |
|
78 _LIT( KCUImpsId_TwoDots, ".." ); |
|
79 _LIT( KCUImpsId_Slash, "/" ); |
|
80 _LIT( KCUImpsId_Plus, "+" ); |
|
81 _LIT( KCUImpsId_Tabulator, "\t" ); |
|
82 _LIT( KCUImpsId_WVPrefix, "wv:" ); |
|
83 |
|
84 _LIT( KCUImpsId_AtEnc, "%40" ); |
|
85 _LIT( KCUImpsId_SlashEnc, "%2F" ); |
|
86 _LIT( KCUImpsId_PlusEnc, "%2B" ); |
|
87 _LIT( KCUImpsId_TabulatorEnc, "%09" ); |
|
88 _LIT( KCUImpsId_WhiteSpaceEnc, "%20" ); |
|
89 |
|
90 // length of "wv:" prefix |
|
91 const TInt KCUImpsId_WVPrefixLength = 3; |
|
92 |
|
93 // maximum length of user id |
|
94 const TInt KServerWVUserIdMaxLength = 50; |
|
95 |
|
96 // defines how far we are going to search for the protocol part in user id |
|
97 const TInt KMaxLengthSearchProtPart = 4; |
|
98 |
|
99 // maximum numerical value to append to generated WVID. |
|
100 const TInt KMaxAppendNumber = 9999; |
|
101 |
|
102 // ----------------------------------------------------------------------------- |
|
103 // CAUtils::NeutralCompare |
|
104 // ----------------------------------------------------------------------------- |
|
105 // |
|
106 TInt CAUtils::NeutralCompare( const TDesC& aId1, |
|
107 const TDesC& aId2, TBool aDomainNeutral ) |
|
108 { |
|
109 // points to user part of id |
|
110 TPtrC ptrId1( aId1 ); |
|
111 TPtrC ptrId2( aId2 ); |
|
112 |
|
113 // Reduce looking for protocol part only to beginning of the WVID and |
|
114 // skip protocol part ("anything:") in the beginning of the WVID |
|
115 TInt colonPos1 = aId1.Left( KMaxLengthSearchProtPart ).Locate( KColonUInt ); |
|
116 |
|
117 // first id |
|
118 if ( ( KErrNotFound != colonPos1 ) && ( aId1.Length() - 1 != colonPos1 ) ) |
|
119 { |
|
120 // contains ":", and it is not the last char |
|
121 ptrId1.Set( aId1.Mid( colonPos1 + 1 ) ); |
|
122 } |
|
123 |
|
124 TInt colonPos2 = aId2.Left( KMaxLengthSearchProtPart ).Locate( KColonUInt ); |
|
125 |
|
126 // second id |
|
127 if ( ( KErrNotFound != colonPos2 ) && ( aId2.Length() - 1 != colonPos2 ) ) |
|
128 { |
|
129 // contains ":", and it is not the last char |
|
130 ptrId2.Set( aId2.Mid( colonPos2 + 1 ) ); |
|
131 } |
|
132 |
|
133 // find out if we have domains in the ids |
|
134 TInt domainPos1( ptrId1.Locate( KAtUInt ) ); |
|
135 TInt domainPos2( ptrId2.Locate( KAtUInt ) ); |
|
136 |
|
137 TBool domainIn1( KErrNotFound != domainPos1 ); |
|
138 TBool domainIn2( KErrNotFound != domainPos2 ); |
|
139 |
|
140 // points to domains in the neutral id |
|
141 TPtrC ptrDom1( KNullDesC ); |
|
142 TPtrC ptrDom2( KNullDesC ); |
|
143 |
|
144 // points to user parts in the neutral id |
|
145 TPtrC ptrUid1( ptrId1 ); |
|
146 TPtrC ptrUid2( ptrId2 ); |
|
147 |
|
148 // separate user id parts and domain parts |
|
149 if ( domainIn1 ) |
|
150 { |
|
151 ptrDom1.Set( ptrId1.Mid( domainPos1 + 1 ) ); |
|
152 ptrUid1.Set( ptrId1.Mid( 0, domainPos1 ) ); |
|
153 } |
|
154 |
|
155 if ( domainIn2 ) |
|
156 { |
|
157 ptrDom2.Set( ptrId2.Mid( domainPos2 + 1 ) ); |
|
158 ptrUid2.Set( ptrId2.Mid( 0, domainPos2 ) ); |
|
159 } |
|
160 |
|
161 // Create custom collation method to ignore punctuations |
|
162 // index 0 gets the default method |
|
163 TCollationMethod collation = |
|
164 *Mem::CollationMethodByIndex( 0 ); |
|
165 collation.iFlags |= TCollationMethod::EIgnoreNone; |
|
166 |
|
167 // domains are compared only when it is really needed |
|
168 // check if userid part is the same in both ids |
|
169 TInt idResult = ptrUid1.CompareC( ptrUid2, KCollationLevel, &collation ); |
|
170 |
|
171 if ( idResult != 0 ) |
|
172 { |
|
173 return idResult; |
|
174 } |
|
175 |
|
176 // id part is same, we have to compare domain |
|
177 |
|
178 // If domain comparison is neutral and one id is without domain |
|
179 // -> Domains are same. Other situation domainResult stays valid. |
|
180 if ( aDomainNeutral && ( domainIn1 ^ domainIn2 ) ) |
|
181 { |
|
182 return 0; |
|
183 } |
|
184 else |
|
185 { |
|
186 return ptrDom1.CompareC( ptrDom2, KCollationLevel, &collation ); |
|
187 } |
|
188 } |
|
189 |
|
190 // ----------------------------------------------------------------------------- |
|
191 // CAUtils::DisplayId |
|
192 // ----------------------------------------------------------------------------- |
|
193 // |
|
194 TPtrC CAUtils::DisplayId( const TDesC& aId, TBool aListHiding ) |
|
195 { |
|
196 TPtrC ret( aId ); |
|
197 |
|
198 MCAStoredContacts* contacts = NULL; |
|
199 TRAPD( err, contacts = CCAStorageManagerFactory::ContactListInterfaceL() ); |
|
200 if ( err != KErrNone || !contacts ) |
|
201 { |
|
202 // some error, don't modify |
|
203 CHAT_DP_FUNC_DP( "DisplayId", "Got some error, not hiding" ); |
|
204 return ret; |
|
205 } |
|
206 |
|
207 // if we've branded the feature out, don't modify anything |
|
208 // UI CR : 101-39728: Check for prefix hiding or Wv hiding. |
|
209 if ( contacts->WVHiding() || contacts->WVHidingPrefixOnly() ) |
|
210 { |
|
211 // locate ":" for userid, groupid. |
|
212 // locate "/" for list id. |
|
213 TInt pos = aId.FindC( aListHiding ? KSlash : KColon ); |
|
214 |
|
215 if ( ( pos != KErrNotFound ) && ( pos != aId.Length() - 1 ) ) |
|
216 { |
|
217 // contains the special character, and it is not the last char |
|
218 // remove everything before the special char (including the char) |
|
219 ret.Set( aId.Mid( pos + 1 ) ); |
|
220 } |
|
221 if ( contacts->WVHiding() || aListHiding ) |
|
222 { |
|
223 // remove also the domain part |
|
224 TInt domainPos = ret.FindC( KAt ); |
|
225 if ( ( domainPos != KErrNotFound ) && ( domainPos != 0 ) ) |
|
226 { |
|
227 ret.Set( ret.Mid( 0, domainPos ) ); |
|
228 } |
|
229 |
|
230 } |
|
231 } |
|
232 |
|
233 return ret; |
|
234 } |
|
235 // ----------------------------------------------------------------------------- |
|
236 // CAUtils::GenerateIdLC |
|
237 // ----------------------------------------------------------------------------- |
|
238 // |
|
239 HBufC* CAUtils::GenerateIdLC( const TDesC& aId, TInt aNum ) |
|
240 { |
|
241 // copy ID |
|
242 HBufC* result = HBufC::NewLC( KServerWVUserIdMaxLength ); |
|
243 TPtr resultPtr( result->Des() ); |
|
244 resultPtr.Copy( aId ); |
|
245 |
|
246 TInt len( resultPtr.Length() ); |
|
247 |
|
248 // Start from end of data |
|
249 for ( TInt i( len - 1 ); i >= 0; --i ) |
|
250 { |
|
251 // Do quick and dirty UNICODE to ISO-8859-1 conversion |
|
252 // and modify all non-ISO-8859-1 characters |
|
253 // to be in valid ranges |
|
254 const TInt& currentChar = resultPtr[ i ]; |
|
255 TUint ch = currentChar & K8BitMask; |
|
256 |
|
257 // is ch in first unused area |
|
258 if ( ch <= KUnused8859end1 ) |
|
259 { |
|
260 ch += KUnused8859end1 + 1; |
|
261 } |
|
262 |
|
263 // is ch in second unused area |
|
264 if ( ch >= KUnused8859start2 && ch <= KUnused8859end2 ) |
|
265 { |
|
266 TInt difference = ch - KUnused8859start2; |
|
267 ch = KUnused8859end2 + difference + 1; |
|
268 } |
|
269 |
|
270 TChar isoFixedChar = TChar( ch ); |
|
271 // put it into the string |
|
272 HBufC* isoFixed = HBufC::NewLC( 1 ); |
|
273 isoFixed->Des().Append( isoFixedChar ); |
|
274 |
|
275 resultPtr.Replace( i, 1, *isoFixed ); |
|
276 CleanupStack::PopAndDestroy( isoFixed ); |
|
277 |
|
278 // now all the specials get removed |
|
279 TPtrC c = resultPtr.Mid( i, 1 ); // next character |
|
280 TInt position = KWVForbiddenCharacters().FindF( c ); |
|
281 |
|
282 if ( position != KErrNotFound ) |
|
283 { |
|
284 // the current character is a FORBIDDEN CHARACTER, |
|
285 // remove it |
|
286 resultPtr.Delete( i, 1 ); |
|
287 } |
|
288 } |
|
289 |
|
290 CHAT_DP( D_CHAT_LIT( "CAUtils::GenerateIdLC conversion '%S' -> '%S'" ), &aId, &resultPtr ); |
|
291 |
|
292 // "Append" number |
|
293 if ( aNum > 0 && aNum <= KMaxAppendNumber ) |
|
294 { |
|
295 TBuf<KMAX_NUMBER> number; // 12, enough space to store a very large number |
|
296 number.AppendNum( aNum ); |
|
297 |
|
298 TInt numLength = number.Length(); |
|
299 TInt resultLength = resultPtr.Length(); |
|
300 if ( numLength + resultLength > KServerWVUserIdMaxLength ) |
|
301 { |
|
302 // can't append directly because we would exceed the space. |
|
303 // use replace instead |
|
304 TInt usableSpace = KServerWVUserIdMaxLength - resultLength; |
|
305 TInt startPos = resultLength - numLength + usableSpace; |
|
306 TInt replaceAmount = numLength - usableSpace; |
|
307 |
|
308 resultPtr.Replace( startPos, replaceAmount, number ); |
|
309 } |
|
310 else |
|
311 { |
|
312 // enough space in the end, just append |
|
313 resultPtr.AppendNum( aNum ); |
|
314 } |
|
315 } |
|
316 |
|
317 CHAT_DP( D_CHAT_LIT( "CAUtils::GenerateIdLC returning '%S'" ), &resultPtr ); |
|
318 return result; |
|
319 } |
|
320 |
|
321 // ----------------------------------------------------------------------------- |
|
322 // CAUtils::ExternalizeBufferToStreamL |
|
323 // Helper method for externalize the buffer |
|
324 // ----------------------------------------------------------------------------- |
|
325 // |
|
326 void CAUtils::ExternalizeBufferToStreamL( const TDesC& aBuffer, RWriteStream& aStream ) |
|
327 { |
|
328 aStream.WriteInt32L( aBuffer.Length() ); |
|
329 aStream.WriteL( aBuffer ); |
|
330 } |
|
331 |
|
332 // ----------------------------------------------------------------------------- |
|
333 // CAUtils::ExternalizeBufferToStreamL |
|
334 // Helper method for externalize the buffer |
|
335 // ----------------------------------------------------------------------------- |
|
336 // |
|
337 void CAUtils::ExternalizeBufferToStreamL( const TDesC8& aBuffer, RWriteStream& aStream ) |
|
338 { |
|
339 aStream.WriteInt32L( aBuffer.Length() ); |
|
340 aStream.WriteL( aBuffer ); |
|
341 } |
|
342 |
|
343 // ----------------------------------------------------------------------------- |
|
344 // CAUtils::InternalizeBufferFromStreamL |
|
345 // Helper method for internalize the buffer |
|
346 // ----------------------------------------------------------------------------- |
|
347 // |
|
348 HBufC* CAUtils::InternalizeBufferFromStreamLC( RReadStream& aStream ) |
|
349 { |
|
350 HBufC* buffer = NULL; |
|
351 |
|
352 TInt length = aStream.ReadInt32L(); |
|
353 |
|
354 if ( length == 0 ) |
|
355 { |
|
356 buffer = KNullDesC().AllocLC(); |
|
357 } |
|
358 else |
|
359 { |
|
360 buffer = HBufC::NewLC( length ); |
|
361 TPtr ptr( buffer->Des() ); |
|
362 aStream.ReadL( ptr, length ); |
|
363 } |
|
364 |
|
365 return buffer; |
|
366 } |
|
367 |
|
368 // ----------------------------------------------------------------------------- |
|
369 // CAUtils::InternalizeBufferFromStreamL |
|
370 // Helper method for internalize the buffer |
|
371 // ----------------------------------------------------------------------------- |
|
372 // |
|
373 HBufC8* CAUtils::InternalizeBuffer8FromStreamLC( RReadStream& aStream ) |
|
374 { |
|
375 HBufC8* buffer = NULL; |
|
376 |
|
377 TInt length = aStream.ReadInt32L(); |
|
378 |
|
379 if ( length == 0 ) |
|
380 { |
|
381 buffer = KNullDesC8().AllocLC(); |
|
382 } |
|
383 else |
|
384 { |
|
385 buffer = HBufC8::NewLC( length ); |
|
386 TPtr8 ptr( buffer->Des() ); |
|
387 aStream.ReadL( ptr, length ); |
|
388 } |
|
389 |
|
390 return buffer; |
|
391 } |
|
392 |
|
393 // ----------------------------------------------------------------------------- |
|
394 // CAUtils::InternalizeBufferFromStreamL |
|
395 // Helper method for internalize the buffer |
|
396 // ----------------------------------------------------------------------------- |
|
397 // |
|
398 HBufC* CAUtils::InternalizeBufferFromStreamL( RReadStream& aStream ) |
|
399 { |
|
400 HBufC* buffer = InternalizeBufferFromStreamLC( aStream ); |
|
401 CleanupStack::Pop( buffer ); |
|
402 return buffer; |
|
403 } |
|
404 |
|
405 // ----------------------------------------------------------------------------- |
|
406 // CAUtils::InternalizeBufferFromStreamL |
|
407 // Helper method for internalize the buffer |
|
408 // ----------------------------------------------------------------------------- |
|
409 // |
|
410 HBufC8* CAUtils::InternalizeBuffer8FromStreamL( RReadStream& aStream ) |
|
411 { |
|
412 HBufC8* buffer = InternalizeBuffer8FromStreamLC( aStream ); |
|
413 CleanupStack::Pop( buffer ); |
|
414 return buffer; |
|
415 } |
|
416 |
|
417 // ----------------------------------------------------------------------------- |
|
418 // CAUtils::ValidLoginIdL() |
|
419 // ----------------------------------------------------------------------------- |
|
420 // |
|
421 TBool CAUtils::ValidLoginIdL( const TDesC& aPresenceId ) |
|
422 { |
|
423 TBool incorrectDomain ( EFalse ); |
|
424 TBool forbiddenChars ( EFalse ); |
|
425 TBool incorrectUserPart ( EFalse ); |
|
426 |
|
427 HBufC* wvId = aPresenceId.AllocLC(); |
|
428 TPtr wvIdPtr = wvId->Des(); |
|
429 |
|
430 TInt maxLength ( KServerWVUserIdMaxLength ); |
|
431 |
|
432 // let's take out the "wv:" from beginning of user id |
|
433 TInt position( KErrNotFound ); |
|
434 if ( KCUImpsId_WVPrefix().CompareF( wvId->Left( KCUImpsId_WVPrefix().Length() ) ) == 0 ) |
|
435 { |
|
436 wvIdPtr.Delete( 0, KCUImpsId_WVPrefix().Length() ); |
|
437 position = KErrNotFound; |
|
438 // we just took out 3 characters from the id, we have to adjust the max length |
|
439 maxLength = maxLength - KCUImpsId_WVPrefixLength; |
|
440 } |
|
441 |
|
442 // where is "@" ? |
|
443 TInt atIndex( wvId->Find( KCUImpsId_At ) ); |
|
444 // we want the domain part without the '@' |
|
445 TPtrC domainPart( wvId->Mid( atIndex + 1 ) ); |
|
446 |
|
447 if ( atIndex > 0 ) |
|
448 { |
|
449 // check if the domain part is empty |
|
450 if ( domainPart.Length() == 0 ) |
|
451 { |
|
452 incorrectDomain = ETrue; |
|
453 } |
|
454 } |
|
455 else if ( atIndex == 0 ) |
|
456 { |
|
457 // the '@' is the first character |
|
458 incorrectUserPart = ETrue; |
|
459 } |
|
460 |
|
461 TInt returnValue = domainPart.Find( KCUImpsId_At() ); |
|
462 // check the correctness of the domain part |
|
463 if ( returnValue != KErrNotFound ) |
|
464 { |
|
465 // extra @-mark found in the domain part |
|
466 incorrectDomain = ETrue; |
|
467 } |
|
468 |
|
469 returnValue = domainPart.Find( KCUImpsId_Dot() ); |
|
470 if ( returnValue != KErrNotFound ) |
|
471 { |
|
472 // the part after the '.' |
|
473 TPtrC partAfterDot ( domainPart.Mid( returnValue + 1 ) ); |
|
474 // the part before the '.' |
|
475 TPtrC partBeforeDot ( domainPart.Left( returnValue ) ); |
|
476 // if the '.' is the last character or the first character after the '@' |
|
477 // the domain part is wrong |
|
478 if ( ( 0 == partAfterDot.Length() ) || ( 0 == partBeforeDot.Length() ) ) |
|
479 { |
|
480 // the '.' is the last character |
|
481 incorrectDomain = ETrue; |
|
482 } |
|
483 } |
|
484 |
|
485 returnValue = domainPart.Find( KCUImpsId_TwoDots() ); |
|
486 if ( returnValue != KErrNotFound ) |
|
487 { |
|
488 // there are two sequential dots in the domain part |
|
489 incorrectDomain = ETrue; |
|
490 } |
|
491 |
|
492 |
|
493 // check the wvid for forbidden chars |
|
494 |
|
495 // first we must delete one '@' char if existing |
|
496 position = wvIdPtr.Find( KCUImpsId_At ); |
|
497 if ( position != KErrNotFound ) |
|
498 { |
|
499 wvIdPtr.Delete( position, KCUImpsId_At().Length() ); |
|
500 } |
|
501 |
|
502 returnValue = wvIdPtr.Find( KCUImpsId_WhiteSpace() ); |
|
503 // no empty chars allowed in the user part |
|
504 if ( returnValue != KErrNotFound ) |
|
505 { |
|
506 forbiddenChars = ETrue; |
|
507 } |
|
508 // no encoded empty chars allowed in the user part |
|
509 returnValue = wvIdPtr.Find( KCUImpsId_WhiteSpaceEnc() ); |
|
510 if ( returnValue != KErrNotFound ) |
|
511 { |
|
512 forbiddenChars = ETrue; |
|
513 } |
|
514 |
|
515 // no '+' allowed in the user part |
|
516 returnValue = wvIdPtr.Find( KCUImpsId_Plus() ); |
|
517 if ( returnValue != KErrNotFound ) |
|
518 { |
|
519 forbiddenChars = ETrue; |
|
520 } |
|
521 // no encoded '+' allowed in the user part |
|
522 returnValue = wvIdPtr.Find( KCUImpsId_PlusEnc() ); |
|
523 if ( returnValue != KErrNotFound ) |
|
524 { |
|
525 forbiddenChars = ETrue; |
|
526 } |
|
527 |
|
528 |
|
529 // no '\t' allowed in the user part |
|
530 returnValue = wvIdPtr.Find( KCUImpsId_Tabulator() ); |
|
531 if ( returnValue != KErrNotFound ) |
|
532 { |
|
533 forbiddenChars = ETrue; |
|
534 } |
|
535 // no encoded tabulator allowed in the user part |
|
536 returnValue = wvIdPtr.Find( KCUImpsId_TabulatorEnc() ); |
|
537 if ( returnValue != KErrNotFound ) |
|
538 { |
|
539 forbiddenChars = ETrue; |
|
540 } |
|
541 |
|
542 // no '/' allowed in the user part |
|
543 returnValue = wvIdPtr.Find( KCUImpsId_Slash() ); |
|
544 if ( returnValue != KErrNotFound ) |
|
545 { |
|
546 forbiddenChars = ETrue; |
|
547 } |
|
548 // no encoded '/' allowed in the user part |
|
549 returnValue = wvIdPtr.Find( KCUImpsId_SlashEnc() ); |
|
550 if ( returnValue != KErrNotFound ) |
|
551 { |
|
552 forbiddenChars = ETrue; |
|
553 } |
|
554 |
|
555 // no encoded '@' chars allowed in the user part |
|
556 returnValue = wvIdPtr.Find( KCUImpsId_AtEnc() ); |
|
557 if ( returnValue != KErrNotFound ) |
|
558 { |
|
559 forbiddenChars = ETrue; |
|
560 } |
|
561 |
|
562 TPtr userId = wvId->Des(); |
|
563 |
|
564 // no 16bit Unicode chars characters allowed in the user part |
|
565 for ( TInt index = 0; index < wvIdPtr.Length(); index++ ) |
|
566 { |
|
567 TUint value = userId[index]; |
|
568 // if the character does not fit into 8 bits, it's forbidden 255 |
|
569 if ( value > KMAX_LIMIT ) |
|
570 { |
|
571 forbiddenChars = ETrue; |
|
572 } |
|
573 } |
|
574 |
|
575 TBool tooLongId ( EFalse ); |
|
576 |
|
577 // check if the user id is too long when encoded, but only if there are no forbidden chars |
|
578 if ( !forbiddenChars ) |
|
579 { |
|
580 HBufC* encodedUserId = EscapeUtils::EscapeEncodeL( *wvId, EscapeUtils::EEscapeUrlEncoded ); |
|
581 |
|
582 if ( atIndex != KErrNotFound ) |
|
583 { |
|
584 // @-character was removed from the ID, since it should not be encoded |
|
585 // so the maxlength has to be decreased by it's length |
|
586 maxLength = maxLength - KCUImpsId_At().Length(); |
|
587 } |
|
588 |
|
589 if ( encodedUserId->Length() > maxLength ) |
|
590 { |
|
591 tooLongId = ETrue; |
|
592 } |
|
593 delete encodedUserId; |
|
594 } |
|
595 |
|
596 CleanupStack::PopAndDestroy( wvId ); |
|
597 |
|
598 if ( forbiddenChars ) |
|
599 { |
|
600 return EFalse; |
|
601 } |
|
602 else if ( incorrectDomain ) |
|
603 { |
|
604 return EFalse; |
|
605 } |
|
606 else if ( tooLongId ) |
|
607 { |
|
608 return EFalse; |
|
609 } |
|
610 else if ( incorrectUserPart ) |
|
611 { |
|
612 return EFalse; |
|
613 } |
|
614 |
|
615 return ETrue; |
|
616 } |
|
617 |
|
618 |
|
619 // --------------------------------------------------------- |
|
620 // CAUtils::ReconstructIdL |
|
621 // (other items were commented in a header). |
|
622 // --------------------------------------------------------- |
|
623 // |
|
624 HBufC* CAUtils::ReconstructIdL( const TDesC& aOrigId, const TDesC& aUserId ) |
|
625 { |
|
626 CHAT_DP( D_CHAT_LIT( "** ReconstructIdL, the original id: %S" ), &aOrigId ); |
|
627 CHAT_DP( D_CHAT_LIT( "** ReconstructIdL, user entered id: %S" ), &aUserId ); |
|
628 |
|
629 // we got user id, add the removed parts ("wv:" and "@something" ) |
|
630 TInt colonPos( aOrigId.Locate( KColonUInt ) ); |
|
631 TInt domainPos( aOrigId.Locate( KAtUInt ) ); |
|
632 TInt userColonPos( aUserId.Locate( KColonUInt ) ); |
|
633 TInt userDomainPos( aUserId.Locate( KAtUInt ) ); |
|
634 |
|
635 // calculate the new length and determine what additions are needed |
|
636 TInt newLength( aUserId.Length() ); |
|
637 TBool addPrefix( EFalse ); |
|
638 TBool addDomain( EFalse ); |
|
639 |
|
640 if ( colonPos != KErrNotFound && |
|
641 ( colonPos + 1 ) != aOrigId.Length() && |
|
642 userColonPos == KErrNotFound ) |
|
643 { |
|
644 // the original id had ":" (not last character) and the current one doesn't |
|
645 // => we'll be adding "wv:" |
|
646 newLength += colonPos + 1; |
|
647 addPrefix = ETrue; |
|
648 } |
|
649 |
|
650 if ( domainPos != KErrNotFound && userDomainPos == KErrNotFound ) |
|
651 { |
|
652 // the original id had domain and the current one doesn't |
|
653 // => we'll be adding "@something" |
|
654 newLength += aOrigId.Length() - domainPos; |
|
655 addDomain = ETrue; |
|
656 } |
|
657 |
|
658 HBufC* newId = HBufC::NewL( newLength ); |
|
659 // NOTE: NO LEAVING METHODS ALLOWED AFTER THIS! |
|
660 |
|
661 TPtr newIdPtr( newId->Des() ); |
|
662 newIdPtr.Zero(); |
|
663 |
|
664 if ( addPrefix ) |
|
665 { |
|
666 // add removed "wv:" prefix |
|
667 newIdPtr.Append( aOrigId.Left( colonPos + 1 ) ); |
|
668 } |
|
669 newIdPtr.Append( aUserId ); |
|
670 if ( addDomain ) |
|
671 { |
|
672 // add removed domain part |
|
673 newIdPtr.Append( aOrigId.Right( aOrigId.Length() - domainPos ) ); |
|
674 } |
|
675 |
|
676 CHAT_DP( D_CHAT_LIT( "** ReconstructIdL, reconstructed id: %S" ), &newIdPtr ); |
|
677 return newId; |
|
678 } |
|
679 |
|
680 // --------------------------------------------------------- |
|
681 // CAUtils::NeutralFind |
|
682 // --------------------------------------------------------- |
|
683 // |
|
684 TInt CAUtils::NeutralFind( const MDesCArray& aUserList, const TDesC& aUserId ) |
|
685 { |
|
686 TInt count( aUserList.MdcaCount() ); |
|
687 for ( TInt i( 0 ); i < count; ++i ) |
|
688 { |
|
689 if ( CAUtils::NeutralCompare( aUserList.MdcaPoint( i ), |
|
690 aUserId ) == 0 ) |
|
691 { |
|
692 return i; |
|
693 } |
|
694 } |
|
695 return KErrNotFound; |
|
696 } |
|
697 |
|
698 // --------------------------------------------------------- |
|
699 // Static helper method used in |
|
700 // LanguageSpecificNumberConversion. |
|
701 // --------------------------------------------------------- |
|
702 // |
|
703 static TChar NumberToBase( TChar ch ) |
|
704 { |
|
705 TDigitType d[] = { EDigitTypeWestern, |
|
706 EDigitTypeArabicIndic, |
|
707 EDigitTypeEasternArabicIndic, |
|
708 EDigitTypeDevanagari, |
|
709 EDigitTypeThai |
|
710 }; |
|
711 TInt i = 0; |
|
712 TInt num = sizeof( d ) / sizeof( d[0] ); |
|
713 // code scanner warning can be ignored |
|
714 while ( i < num ) |
|
715 { |
|
716 if ( ch > TChar( d[i] ) && ch < TChar( d[i] + KMAX_NUMBERBASE ) ) |
|
717 { |
|
718 return d[i]; |
|
719 } |
|
720 i++; |
|
721 } |
|
722 |
|
723 return ch; |
|
724 } |
|
725 |
|
726 // --------------------------------------------------------- |
|
727 // CAUtils::LanguageSpecificNumberConversion |
|
728 // --------------------------------------------------------- |
|
729 // |
|
730 void CAUtils::LanguageSpecificNumberConversion( TDes& aDes ) |
|
731 { |
|
732 // Get current locale and digit type |
|
733 TLocale locale; |
|
734 locale.Refresh(); |
|
735 TDigitType digitType = locale.DigitType(); |
|
736 |
|
737 // Check if conversion is needed |
|
738 TBool conversion = ( digitType == EDigitTypeArabicIndic ) |
|
739 || ( digitType == EDigitTypeEasternArabicIndic ) |
|
740 || ( digitType == EDigitTypeDevanagari ); |
|
741 |
|
742 if ( !conversion ) |
|
743 { |
|
744 // Don't do anything |
|
745 return; |
|
746 } |
|
747 |
|
748 // Do conversion, logic for this conversion |
|
749 // comes from AknTextUtils::LanguageSpecificNumberConversion. |
|
750 // Logic is copied here to avoid using Avkon in engine side. |
|
751 TChar toArea = KCharToArea; |
|
752 |
|
753 switch ( digitType ) |
|
754 { |
|
755 case EDigitTypeWestern: |
|
756 case EDigitTypeArabicIndic: |
|
757 case EDigitTypeEasternArabicIndic: |
|
758 case EDigitTypeDevanagari: |
|
759 case EDigitTypeThai: // Flowthrough |
|
760 { |
|
761 toArea = digitType; |
|
762 break; |
|
763 } |
|
764 case EDigitTypeUnknown: |
|
765 case EDigitTypeAllTypes: |
|
766 default: // Flowthrough |
|
767 { |
|
768 return; |
|
769 } |
|
770 } |
|
771 |
|
772 TInt length = aDes.Length(); |
|
773 |
|
774 for ( TInt i = 0; i < length; i++ ) |
|
775 { |
|
776 TChar ch = aDes[i]; |
|
777 TChar fromArea = NumberToBase( ch ); |
|
778 TChar::TBdCategory cat = ch.GetBdCategory(); |
|
779 switch ( cat ) |
|
780 { |
|
781 case TChar::EArabicNumber: |
|
782 case TChar::EEuropeanNumber: // Flowthrough |
|
783 { |
|
784 ch += toArea; |
|
785 ch -= fromArea; |
|
786 aDes[i] = TUint16( ch ); |
|
787 break; |
|
788 } |
|
789 default: |
|
790 { |
|
791 break; |
|
792 } |
|
793 } |
|
794 } |
|
795 } |
|
796 // --------------------------------------------------------- |
|
797 // CAUtils::CapitalizeListNameL : UI CR : 101-39727 |
|
798 // --------------------------------------------------------- |
|
799 // |
|
800 HBufC* CAUtils::CapitalizeListNameL( const TDesC& aListname ) |
|
801 { |
|
802 MCAStoredContacts* contacts = NULL; |
|
803 TRAPD( err, contacts = CCAStorageManagerFactory::ContactListInterfaceL() ); |
|
804 |
|
805 if ( err == KErrNone && contacts |
|
806 && contacts->CapitalizingEnabled() |
|
807 && ( aListname.Length() ) ) |
|
808 { |
|
809 HBufC* capitalPartBuf = HBufC::NewL( KServerWVUserIdMaxLength ); |
|
810 TPtr capitalPartptr( capitalPartBuf->Des() ); |
|
811 |
|
812 if ( aListname.Length() == 1 ) |
|
813 { |
|
814 capitalPartptr.CopyUC( aListname ); |
|
815 return capitalPartBuf; |
|
816 } |
|
817 capitalPartptr.CopyUC( aListname.Left( 1 ) );// copy and capitalize first letter |
|
818 capitalPartptr.Append( aListname.Right( ( aListname.Length() - 1 ) ) );// append the remaining |
|
819 return capitalPartBuf; |
|
820 } |
|
821 |
|
822 // some error, don't modify |
|
823 CHAT_DP_FUNC_DP( "CapitalizeListNameL", "Got some error, not Capitalizing" ); |
|
824 HBufC* capitalPartBuf = aListname.AllocL(); |
|
825 return capitalPartBuf; |
|
826 } |
|
827 |
|
828 |
|
829 // --------------------------------------------------------- |
|
830 // CAUtils::CapitalizingEnabled UI CR : 101-39727 |
|
831 // --------------------------------------------------------- |
|
832 // |
|
833 TBool CAUtils::CapitalizingEnabled() |
|
834 { |
|
835 MCAStoredContacts* contacts = NULL; |
|
836 TRAPD( err, contacts = CCAStorageManagerFactory::ContactListInterfaceL() ); |
|
837 if ( err != KErrNone || !contacts ) |
|
838 { |
|
839 // some error, return Efalse |
|
840 return EFalse; |
|
841 } |
|
842 return ( contacts->CapitalizingEnabled() ); |
|
843 } |
|
844 |
|
845 |
|
846 // --------------------------------------------------------- |
|
847 // CAUtils::CapitalizeListNameL UI CR : 101-39727 |
|
848 // --------------------------------------------------------- |
|
849 // |
|
850 |
|
851 HBufC* CAUtils::CapitalizeListIdL( const TDesC& aId ) |
|
852 { |
|
853 TPtrC ret( aId ); |
|
854 TBool slashfound( EFalse ); |
|
855 TBool domainfound( EFalse ); |
|
856 // locate "/" for list id. |
|
857 TInt pos = aId.FindC( KSlash ); |
|
858 |
|
859 if ( ( pos != KErrNotFound ) && ( pos != aId.Length() - 1 ) ) |
|
860 { |
|
861 // make it true if slash found and it should not be at the last position |
|
862 slashfound = ETrue; |
|
863 } |
|
864 |
|
865 // locate for the domain part |
|
866 |
|
867 TInt domainPos = ret.FindC( KAt ); |
|
868 if ( ( domainPos != KErrNotFound ) && ( domainPos != 0 ) ) |
|
869 { |
|
870 // make it true if domain part is found and itshould not be at the first position |
|
871 domainfound = ETrue; |
|
872 } |
|
873 |
|
874 MCAStoredContacts* contacts = NULL; |
|
875 TRAPD( err, contacts = CCAStorageManagerFactory::ContactListInterfaceL() ); |
|
876 |
|
877 if ( err == KErrNone && contacts // extrachecking here bcoz |
|
878 && contacts->CapitalizingEnabled()// it has to return NULL |
|
879 && aId.Length() ) // (not the list id) |
|
880 { // if error occurs |
|
881 if ( slashfound && !domainfound ) |
|
882 { |
|
883 //remove upto '/' and capitalize |
|
884 return CAUtils::CapitalizeListNameL( aId.Right( ( aId.Length() - ( pos + 1 ) ) ) ); |
|
885 } |
|
886 else if ( slashfound && domainfound ) |
|
887 { |
|
888 // remove upto '/' and after domain part and capitalize |
|
889 return CAUtils::CapitalizeListNameL( aId.Mid( pos + 1, ( domainPos - pos - 1 ) ) ); |
|
890 } |
|
891 else |
|
892 { |
|
893 // if only domain part found or both part not found just capitalize listId |
|
894 return CAUtils::CapitalizeListNameL( aId ); |
|
895 } |
|
896 |
|
897 } |
|
898 |
|
899 // some error,return null |
|
900 return NULL; |
|
901 } |
|
902 |
|
903 // End of file |