|
1 // character_converter.cpp |
|
2 // |
|
3 // Copyright (c) 2005 - 2010 Accenture. All rights reserved. |
|
4 // This component and the accompanying materials are made available |
|
5 // under the terms of the "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 // Accenture - Initial contribution |
|
11 // |
|
12 |
|
13 |
|
14 #include "character_converter.h" |
|
15 |
|
16 const TInt KSlack = 20; |
|
17 |
|
18 |
|
19 CCharacterConverter* CCharacterConverter::NewL(TInt aMaxBlockSize, RFs& aFs, TUint aCharset) |
|
20 { |
|
21 CCharacterConverter* self = new(ELeave) CCharacterConverter(aMaxBlockSize, aFs, aCharset); |
|
22 CleanupStack::PushL(self); |
|
23 self->ConstructL(); |
|
24 CleanupStack::Pop(self); |
|
25 return self; |
|
26 } |
|
27 |
|
28 CCharacterConverter::~CCharacterConverter() |
|
29 { |
|
30 delete iCharSets; |
|
31 delete iConverter; |
|
32 delete iNarrowBuf; |
|
33 delete iWideBuf; |
|
34 } |
|
35 |
|
36 const TDesC& CCharacterConverter::ConvertChunkL(const TDesC8& aNarrowBuf, TChunkType aType) |
|
37 { |
|
38 ASSERT(aNarrowBuf.Length() <= iMaxBlockSize); |
|
39 |
|
40 switch (aType) |
|
41 { |
|
42 case EFirst: |
|
43 { |
|
44 iCharConvState = CCnvCharacterSetConverter::KStateDefault; |
|
45 iNarrowPtr = aNarrowBuf; |
|
46 if (iCharset == 0) |
|
47 { |
|
48 // Only spend time autodetecting if we haven't been told the charset to use |
|
49 const TUint16* p = (const TUint16*)aNarrowBuf.Ptr(); |
|
50 if ((*p == 0xFEFF) || (*p == 0xFFFE)) |
|
51 { |
|
52 iNarrowPtr.Delete(0, 2); |
|
53 iCharset = (*p == 0xFEFF) ? KCharacterSetIdentifierUnicodeLittle : KCharacterSetIdentifierUnicodeBig; |
|
54 } |
|
55 else |
|
56 { |
|
57 iCharSets = CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL(iFs); |
|
58 TInt confidenceLevel; |
|
59 CCnvCharacterSetConverter::AutoDetectCharacterSetL(confidenceLevel, iCharset, *iCharSets, iNarrowPtr.Left(32)); |
|
60 } |
|
61 } |
|
62 iConverter->PrepareToConvertToOrFromL(iCharset, iFs); |
|
63 } // Deliberate fall through. |
|
64 case EMiddle: |
|
65 { |
|
66 if (aType == EMiddle) |
|
67 { |
|
68 iNarrowPtr += aNarrowBuf; |
|
69 } |
|
70 TInt numUnconvertibleChars; |
|
71 const TInt ret = iConverter->ConvertToUnicode(iWidePtr, iNarrowPtr, iCharConvState, numUnconvertibleChars); |
|
72 iNumUnconvertibleChars += numUnconvertibleChars; |
|
73 if (ret < 0) |
|
74 { |
|
75 User::Leave(ret); |
|
76 } |
|
77 else if (ret > KSlack) |
|
78 { |
|
79 User::Leave(KErrCorrupt); |
|
80 } |
|
81 else if (ret > 0) |
|
82 { |
|
83 iNarrowPtr = iNarrowPtr.Right(ret); |
|
84 } |
|
85 else |
|
86 { |
|
87 iNarrowPtr.Zero(); |
|
88 } |
|
89 break; |
|
90 } |
|
91 case ELast: |
|
92 { |
|
93 iNarrowPtr += aNarrowBuf; |
|
94 TInt numUnconvertibleChars; |
|
95 const TInt ret = iConverter->ConvertToUnicode(iWidePtr, iNarrowPtr, iCharConvState, numUnconvertibleChars); |
|
96 iNumUnconvertibleChars += numUnconvertibleChars; |
|
97 if (ret < 0) |
|
98 { |
|
99 User::Leave(ret); |
|
100 } |
|
101 else if (ret > 0) |
|
102 { |
|
103 User::Leave(KErrCorrupt); |
|
104 } |
|
105 iNarrowPtr.Zero(); |
|
106 break; |
|
107 } |
|
108 default: |
|
109 { |
|
110 ASSERT(EFalse); |
|
111 } |
|
112 } |
|
113 |
|
114 return iWidePtr; |
|
115 } |
|
116 |
|
117 CCharacterConverter::CCharacterConverter(TInt aMaxBlockSize, RFs& aFs, TUint aCharset) |
|
118 : iFs(aFs), iMaxBlockSize(aMaxBlockSize), iNarrowPtr(NULL, 0), iWidePtr(NULL, 0), iCharset(aCharset) |
|
119 { |
|
120 } |
|
121 |
|
122 void CCharacterConverter::ConstructL() |
|
123 { |
|
124 iNarrowBuf = HBufC8::NewL(iMaxBlockSize + KSlack); |
|
125 iWideBuf = HBufC16::NewL(iMaxBlockSize + KSlack); |
|
126 iNarrowPtr.Set(iNarrowBuf->Des()); |
|
127 iWidePtr.Set(iWideBuf->Des()); |
|
128 iConverter = CCnvCharacterSetConverter::NewL(); |
|
129 } |