|
1 // Copyright (c) 2003-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 // Character conversion class definitions |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file Schconv.cpp |
|
20 */ |
|
21 |
|
22 #include "SCHCONV.H" |
|
23 #include <utf.h> |
|
24 #include "ND_STD.H" |
|
25 |
|
26 _LIT(KUnicodeType1,"ISO-10646-UCS-2"); //< 3 names for UNICODE |
|
27 _LIT(KUnicodeType2,"csUnicode"); |
|
28 _LIT(KUnicodeType3,"UNICODE-1-1"); |
|
29 _LIT(KIso88591Type1,"ISO-8859-1"); //< 3 name for ISO-8859-1 |
|
30 |
|
31 /* |
|
32 _LIT(KIso88591Type2,"ISO_8859-1"); |
|
33 _LIT(KIso88591Type3,"latin1"); |
|
34 */ |
|
35 |
|
36 // CScriptCharacterConverter definitions |
|
37 |
|
38 CScriptCharacterConverter* CScriptCharacterConverter::NewL() |
|
39 /** |
|
40 2 phased constructor for CScriptCharacterConverter, first phase. |
|
41 |
|
42 @exception Leaves if ConstructL() leaves, or not enough memory is available. |
|
43 @return a new CScriptCharacterConverter object. |
|
44 */ |
|
45 { |
|
46 CScriptCharacterConverter* r=new(ELeave) CScriptCharacterConverter(); |
|
47 CleanupStack::PushL(r); |
|
48 r->ConstructL(); |
|
49 CleanupStack::Pop(); |
|
50 return r; |
|
51 } |
|
52 |
|
53 CScriptCharacterConverter::CScriptCharacterConverter() |
|
54 : iDefaultCharSet(KIso88591Type1) |
|
55 /** |
|
56 Private constructor for CScriptCharacterConverter, used in the first phase of construction. |
|
57 */ |
|
58 {} |
|
59 |
|
60 void CScriptCharacterConverter::ConstructL() |
|
61 /** |
|
62 Instantiates member variables. |
|
63 |
|
64 @exception Leaves if file server Connect() fails or CCnvCharacterSetConverter::NewL() leaves. |
|
65 */ |
|
66 { |
|
67 User::LeaveIfError(iFs.Connect()); |
|
68 iConverter=CCnvCharacterSetConverter::NewL(); |
|
69 } |
|
70 |
|
71 CScriptCharacterConverter::~CScriptCharacterConverter() |
|
72 /** |
|
73 Destructor. |
|
74 Closes file server. |
|
75 Deletes iConverter. |
|
76 */ |
|
77 { |
|
78 iFs.Close(); |
|
79 delete iConverter; |
|
80 } |
|
81 |
|
82 HBufC8* CScriptCharacterConverter::ConvertL(const TDesC8& aString, const TDesC& aCharSet) |
|
83 /** |
|
84 Calls ConvertLC. |
|
85 */ |
|
86 { |
|
87 HBufC8* buf; |
|
88 buf=ConvertLC(aString,aCharSet); |
|
89 CleanupStack::Pop(); //buf |
|
90 return buf; |
|
91 } |
|
92 |
|
93 HBufC8* CScriptCharacterConverter::ConvertL(const TDesC16& aString, const TDesC& aCharSet) |
|
94 /** |
|
95 Calls ConvertLC. |
|
96 */ |
|
97 { |
|
98 HBufC8* buf; |
|
99 buf=ConvertLC(aString,aCharSet); |
|
100 CleanupStack::Pop(); //buf |
|
101 return buf; |
|
102 } |
|
103 |
|
104 HBufC8* CScriptCharacterConverter::ConvertLC(const TDesC8& aString, const TDesC& aCharSet) |
|
105 /** |
|
106 Converts from ISO-8859-1 to aCharSet or if aCharSet is empty to the default |
|
107 character set. Returns the result in the form of an 8-bit buffer ready for sending |
|
108 to comm port. Leaves with KErrCharacterConversionError if there is an error in |
|
109 conversion. |
|
110 */ |
|
111 { |
|
112 TBuf<KMaxCharacterTypeLength> type=aCharSet; |
|
113 if (type.Length()==0) |
|
114 type.Copy(iDefaultCharSet); |
|
115 |
|
116 HBufC8* buf=HBufC8::NewLC(aString.Length()); // must put this on the cleanup stack first as we're leaving it there |
|
117 |
|
118 // first convert to unicode |
|
119 if (iConverter->PrepareToConvertToOrFromL(KCharacterSetIdentifierIso88591,iFs)!=CCnvCharacterSetConverter::EAvailable) |
|
120 User::Leave(KErrCharacterSetDoesNotExist); |
|
121 HBufC16* buf16=HBufC16::NewLC(aString.Length()); |
|
122 TPtr16 unicode(buf16->Des()); |
|
123 TInt state=CCnvCharacterSetConverter::KStateDefault; |
|
124 TInt ret=iConverter->ConvertToUnicode(unicode,aString,state); |
|
125 if (ret!=KErrNone) // this conversion is from ISO-8859-1 to unicode, so we know the length |
|
126 User::Leave(KErrCharacterConversionError); |
|
127 |
|
128 if (IsUnicode(type)) |
|
129 { |
|
130 TPtr8 resString(buf->Des()); |
|
131 CopyToEightBitDataL(resString,unicode); |
|
132 } |
|
133 else |
|
134 { |
|
135 PrepareToConvertL(type); |
|
136 TPtrC16 remainingUnicode(unicode); |
|
137 TInt state=CCnvCharacterSetConverter::KStateDefault; |
|
138 FOREVER |
|
139 { |
|
140 TPtr8 resString(buf->Des()); |
|
141 ret=iConverter->ConvertFromUnicode(resString,remainingUnicode,state); |
|
142 if (ret<KErrNone) |
|
143 { |
|
144 User::Leave(KErrCharacterConversionError); |
|
145 break; |
|
146 } |
|
147 else |
|
148 { |
|
149 if (ret==KErrNone) |
|
150 break; |
|
151 buf->ReAllocL(buf->Length()+ret); |
|
152 } |
|
153 remainingUnicode.Set(remainingUnicode.Right(ret)); |
|
154 } |
|
155 } |
|
156 |
|
157 CleanupStack::PopAndDestroy(); // buf16 |
|
158 return buf; |
|
159 } |
|
160 |
|
161 HBufC8* CScriptCharacterConverter::ConvertLC(const TDesC16& aString, const TDesC& aCharSet) |
|
162 /** |
|
163 Converts from UNICODE to aCharSet or if aCharSet is empty to the default |
|
164 character set. Returns the result in th form of an 8-bit buffer ready for sending |
|
165 to comm port. Leaves with KErrCharacterConversionError if there is an error in |
|
166 conversion. |
|
167 */ |
|
168 { |
|
169 TBuf<KMaxCharacterTypeLength> type=aCharSet; |
|
170 if (type.Length()==0) |
|
171 type.Copy(iDefaultCharSet); |
|
172 |
|
173 HBufC8* buf=HBufC8::NewLC(aString.Length());; |
|
174 TPtrC16 remainingUnicode(aString); |
|
175 TInt ret=KErrNone; |
|
176 |
|
177 if (IsUnicode(type)) |
|
178 { |
|
179 TPtr8 resString(buf->Des()); |
|
180 CopyToEightBitDataL(resString,aString); |
|
181 } |
|
182 else // other types |
|
183 { |
|
184 PrepareToConvertL(type); |
|
185 TInt state=CCnvCharacterSetConverter::KStateDefault; |
|
186 FOREVER |
|
187 { |
|
188 TPtr8 resString(buf->Des()); |
|
189 ret=iConverter->ConvertFromUnicode(resString,remainingUnicode,state); |
|
190 if (ret<KErrNone) |
|
191 { |
|
192 User::Leave(KErrCharacterConversionError); |
|
193 break; |
|
194 } |
|
195 else |
|
196 { |
|
197 if (ret==KErrNone) |
|
198 break; |
|
199 buf->ReAllocL(buf->Length()+ret); |
|
200 } |
|
201 remainingUnicode.Set(remainingUnicode.Right(ret)); |
|
202 } |
|
203 } |
|
204 |
|
205 return buf; |
|
206 } |
|
207 |
|
208 void CScriptCharacterConverter::ConvertFromDefaultL(const TDesC8& aSrc,TDes16& aTrg) |
|
209 /** |
|
210 Converts aString from the default character to set to Unicode |
|
211 Should have been passed a big enough buffer for the conversion to happen in one go |
|
212 so leaves if the return value from the conversion is not 0 |
|
213 */ |
|
214 { |
|
215 DoConvertFromDefaultToUnicodeL(aSrc,aTrg); |
|
216 } |
|
217 |
|
218 void CScriptCharacterConverter::SetDefaultCharSet(const TDesC& aCharSet) |
|
219 /** |
|
220 Sets default character set. |
|
221 */ |
|
222 { |
|
223 iDefaultCharSet=aCharSet; |
|
224 } |
|
225 |
|
226 void CScriptCharacterConverter::PrepareToConvertL(const TDesC& aNameToMatch) |
|
227 /** |
|
228 Prepares to convert. |
|
229 */ |
|
230 { |
|
231 TBuf8<KMaxCharacterTypeLength> type; |
|
232 type.Copy(aNameToMatch); |
|
233 const TInt charSetId=iConverter->ConvertStandardNameOfCharacterSetToIdentifierL(type,iFs); |
|
234 if ((charSetId==0) || (iConverter->PrepareToConvertToOrFromL(charSetId,iFs)!=CCnvCharacterSetConverter::EAvailable)) |
|
235 User::Leave(KErrCharacterSetDoesNotExist); |
|
236 } |
|
237 |
|
238 void CScriptCharacterConverter::CopyToEightBitDataL(TDes8& aTrg, const TDesC16& aSrc) |
|
239 /** |
|
240 Copies to eight bit. |
|
241 */ |
|
242 { |
|
243 TInt len=aSrc.Length()*2; |
|
244 if (len>aTrg.MaxLength()) |
|
245 User::Leave(KErrOverflow); |
|
246 TUint8* ptrToBuf=(TUint8*)aSrc.Ptr(); |
|
247 aTrg.Copy(ptrToBuf,len); |
|
248 } |
|
249 |
|
250 void CScriptCharacterConverter::CopyFromEightBitDataL(TDes16& aTrg, const TDesC8& aSrc) |
|
251 |
|
252 { |
|
253 TInt len=aSrc.Length()/2; // if source length is odd then we can't use the last 8 bits anyway |
|
254 if (len>aTrg.MaxLength()) |
|
255 User::Leave(KErrOverflow); |
|
256 TUint16* ptrToBuf=(TUint16*)aSrc.Ptr(); |
|
257 aTrg.Copy(ptrToBuf,len); |
|
258 } |
|
259 |
|
260 void CScriptCharacterConverter::DoConvertFromDefaultToUnicodeL(const TDesC8& aSrc,TDes16& aTrg) |
|
261 /** |
|
262 Converts aString from the default character to set to unicode |
|
263 */ |
|
264 { |
|
265 __ASSERT_DEBUG(aSrc.Length()<=KRxBufferSize, User::Invariant()); |
|
266 __ASSERT_DEBUG(aTrg.MaxLength()>=KRxBufferSize, User::Invariant()); |
|
267 |
|
268 TInt state=CnvUtfConverter::KStateDefault; |
|
269 TInt ret=KErrNone; |
|
270 aTrg.SetLength(0); |
|
271 |
|
272 if (IsUnicode(iDefaultCharSet)) |
|
273 CopyFromEightBitDataL(aTrg,aSrc); |
|
274 else |
|
275 { |
|
276 PrepareToConvertL(iDefaultCharSet); |
|
277 ret=iConverter->ConvertToUnicode(aTrg,aSrc,state); |
|
278 } |
|
279 |
|
280 if (ret!=KErrNone) |
|
281 User::Leave(KErrCharacterConversionError); |
|
282 } |
|
283 |
|
284 TBool CScriptCharacterConverter::IsUnicode(const TDesC& aType) const |
|
285 /** |
|
286 Checks if type is unicode. |
|
287 */ |
|
288 { |
|
289 if ((aType.CompareF(KUnicodeType1)==KErrNone) |
|
290 || (aType.CompareF(KUnicodeType2)==KErrNone) |
|
291 || (aType.CompareF(KUnicodeType3)==KErrNone)) |
|
292 return ETrue; |
|
293 return EFalse; |
|
294 } |