|
1 /* |
|
2 * Copyright (c) 1997-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 * |
|
16 */ |
|
17 |
|
18 #include "PictographObserver.h" |
|
19 |
|
20 #include <e32std.h> |
|
21 #include <charconv.h> |
|
22 #include <convutils.h> |
|
23 #include "jisx0201.h" |
|
24 #include "jisx0208.h" |
|
25 #include "jisx0212.h" |
|
26 #include <ecom/implementationproxy.h> |
|
27 #include "charactersetconverter.h" |
|
28 #include "featmgr/featmgr.h" |
|
29 |
|
30 const TUint KSingleShift2=0x8e; |
|
31 const TUint KSingleShift3=0x8f; |
|
32 |
|
33 // SecureID for Brower app |
|
34 const TUint32 KBrowserSecureId = 0x10008D39; |
|
35 // Define for converting from YenSign to BackSlash |
|
36 const TUint KCharacterCodeForYenSign = 0x00A5; |
|
37 const TUint KCharacterCodeForBackSlash = 0x005C; |
|
38 |
|
39 _LIT8(KLit8EucJpPackedReplacementForUnconvertibleUnicodeCharacters, "\xa1\xa9"); // fullwidth question mark |
|
40 |
|
41 #if defined(_DEBUG) |
|
42 |
|
43 _LIT(KLitPanicText, "EUCJP_PACKED"); |
|
44 |
|
45 enum TPanic |
|
46 { |
|
47 EPanicNothingToConvert1=1, |
|
48 EPanicNothingToConvert2, |
|
49 EPanicNothingToConvert3, |
|
50 EPanicNothingToConvert4, |
|
51 EPanicNothingToConvert5, |
|
52 EPanicNothingToConvert6, |
|
53 EPanicOddNumberOfBytes1, |
|
54 EPanicOddNumberOfBytes2, |
|
55 EPanicOddNumberOfBytes3, |
|
56 EPanicOddNumberOfBytes4, |
|
57 EPanicOddNumberOfBytes5, |
|
58 EPanicOddNumberOfBytes6, |
|
59 EPanicBadHighBit1, |
|
60 EPanicBadHighBit2, |
|
61 EPanicBadHighBit3, |
|
62 EPanicBadHighBit4, |
|
63 EPanicBadHighBit5, |
|
64 EPanicBadHighBit6, |
|
65 EPanicBadHighBit7, |
|
66 EPanicBadPointers1, |
|
67 EPanicBadPointers2, |
|
68 EPanicBadPointers3, |
|
69 EPanicBadPointers4, |
|
70 EPanicBadPointers5, |
|
71 EPanicBadPointers6, |
|
72 EPanicBadPointers7, |
|
73 EPanicBadPointers8, |
|
74 EPanicBadPointers9, |
|
75 EPanicBadPointers10, |
|
76 EPanicBadPointers11, |
|
77 EPanicBadPointers12, |
|
78 EPanicBadPointers13, |
|
79 EPanicBadPointers14, |
|
80 EPanicBadPointers15, |
|
81 EPanicBadPointers16, |
|
82 EPanicBadPointers17, |
|
83 EPanicBadPointers18, |
|
84 EPanicBadPointers19, |
|
85 EPanicBadPointers20, |
|
86 EPanicBadPointers21, |
|
87 EPanicBadPointers22, |
|
88 EPanicBadPointers23, |
|
89 EPanicBadPointers24, |
|
90 EPanicBadPointers25, |
|
91 EPanicBadPointers26, |
|
92 EPanicBadPointers27, |
|
93 EPanicBadPointers28, |
|
94 EPanicBadPointers29, |
|
95 EPanicBadPointers30, |
|
96 EPanicBadPointers31, |
|
97 EPanicBadPointers32, |
|
98 EPanicBadPointers33, |
|
99 EPanicBadPointers34, |
|
100 EPanicBadPointers35, |
|
101 EPanicBadPointers36, |
|
102 EPanicBadCalculation1, |
|
103 EPanicBadCalculation2, |
|
104 EPanicNumberOfBytesIsNotMultipleOfThree1, |
|
105 EPanicNumberOfBytesIsNotMultipleOfThree2, |
|
106 EPanicSingleShift2Expected, |
|
107 EPanicSingleShift3Expected |
|
108 }; |
|
109 |
|
110 LOCAL_C void Panic(TPanic aPanic) |
|
111 { |
|
112 User::Panic(KLitPanicText, aPanic); |
|
113 } |
|
114 |
|
115 #endif |
|
116 |
|
117 |
|
118 class CEucjpPackedConverterImpl : public CCharacterSetConverterPluginInterface |
|
119 { |
|
120 |
|
121 public: |
|
122 virtual const TDesC8& ReplacementForUnconvertibleUnicodeCharacters(); |
|
123 |
|
124 virtual TInt ConvertFromUnicode( |
|
125 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, |
|
126 const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, |
|
127 TDes8& aForeign, |
|
128 const TDesC16& aUnicode, |
|
129 CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters); |
|
130 |
|
131 virtual TInt ConvertToUnicode( |
|
132 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, |
|
133 TDes16& aUnicode, |
|
134 const TDesC8& aForeign, |
|
135 TInt& aState, |
|
136 TInt& aNumberOfUnconvertibleCharacters, |
|
137 TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter); |
|
138 |
|
139 virtual TBool IsInThisCharacterSetL( |
|
140 TBool& aSetToTrue, |
|
141 TInt& aConfidenceLevel, |
|
142 const TDesC8& aSample); |
|
143 |
|
144 static CEucjpPackedConverterImpl* NewL(); |
|
145 virtual ~CEucjpPackedConverterImpl(); |
|
146 |
|
147 private: |
|
148 CEucjpPackedConverterImpl(); |
|
149 void ConstructL(); |
|
150 |
|
151 }; |
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 const TDesC8& CEucjpPackedConverterImpl::ReplacementForUnconvertibleUnicodeCharacters() |
|
158 { |
|
159 return KLit8EucJpPackedReplacementForUnconvertibleUnicodeCharacters; |
|
160 } |
|
161 |
|
162 LOCAL_C void DummyConvertFromIntermediateBufferInPlace(TInt, TDes8&, TInt& aNumberOfCharactersThatDroppedOut) |
|
163 { |
|
164 aNumberOfCharactersThatDroppedOut=0; |
|
165 } |
|
166 |
|
167 LOCAL_C void ConvertFromJisX0208ToEucJpPackedInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut) |
|
168 { |
|
169 aNumberOfCharactersThatDroppedOut=0; |
|
170 const TInt descriptorLength=aDescriptor.Length(); |
|
171 __ASSERT_DEBUG(descriptorLength>aStartPositionInDescriptor, Panic(EPanicNothingToConvert1)); |
|
172 __ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%2==0, Panic(EPanicOddNumberOfBytes1)); |
|
173 TUint8* pointerToCurrentByte=CONST_CAST(TUint8*, aDescriptor.Ptr()); |
|
174 const TUint8* const pointerToLastByte=pointerToCurrentByte+(descriptorLength-1); |
|
175 pointerToCurrentByte+=aStartPositionInDescriptor; |
|
176 FOREVER |
|
177 { |
|
178 const TUint currentByte=*pointerToCurrentByte; |
|
179 __ASSERT_DEBUG((currentByte&0x80)==0, Panic(EPanicBadHighBit1)); |
|
180 *pointerToCurrentByte=STATIC_CAST(TUint8, currentByte|0x80); |
|
181 __ASSERT_DEBUG(pointerToCurrentByte<=pointerToLastByte, Panic(EPanicBadPointers1)); |
|
182 if (pointerToCurrentByte>=pointerToLastByte) |
|
183 { |
|
184 break; |
|
185 } |
|
186 ++pointerToCurrentByte; |
|
187 } |
|
188 } |
|
189 |
|
190 LOCAL_C void ConvertFromHalfWidthKatakana8ToEucJpPackedInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut) |
|
191 { |
|
192 TInt descriptorLength=aDescriptor.Length(); |
|
193 __ASSERT_DEBUG(descriptorLength>aStartPositionInDescriptor, Panic(EPanicNothingToConvert2)); |
|
194 aNumberOfCharactersThatDroppedOut=Max(0, (descriptorLength-aStartPositionInDescriptor)-((aDescriptor.MaxLength()-aStartPositionInDescriptor)/2)); |
|
195 descriptorLength-=aNumberOfCharactersThatDroppedOut; |
|
196 __ASSERT_DEBUG(descriptorLength>=aStartPositionInDescriptor, Panic(EPanicBadCalculation1)); |
|
197 if (descriptorLength<=aStartPositionInDescriptor) |
|
198 { |
|
199 aDescriptor.SetLength(descriptorLength); |
|
200 } |
|
201 else |
|
202 { |
|
203 TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr()); // pointerToTargetByte is initialized properly when descriptorLength has been offset to the actual final length of aDescriptor |
|
204 const TUint8* const pointerToFirstByte=pointerToTargetByte+aStartPositionInDescriptor; |
|
205 const TUint8* pointerToSourceByte=pointerToTargetByte+(descriptorLength-1); |
|
206 descriptorLength=((descriptorLength-aStartPositionInDescriptor)*2)+aStartPositionInDescriptor; |
|
207 __ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%2==0, Panic(EPanicOddNumberOfBytes2)); |
|
208 aDescriptor.SetLength(descriptorLength); |
|
209 pointerToTargetByte+=descriptorLength-1; // pointerToTargetByte is is initialized properly here |
|
210 FOREVER |
|
211 { |
|
212 *pointerToTargetByte=*pointerToSourceByte; |
|
213 __ASSERT_DEBUG(pointerToTargetByte>pointerToFirstByte, Panic(EPanicBadPointers2)); |
|
214 --pointerToTargetByte; |
|
215 *pointerToTargetByte=KSingleShift2; |
|
216 __ASSERT_DEBUG(pointerToTargetByte>=pointerToFirstByte, Panic(EPanicBadPointers3)); |
|
217 if (pointerToTargetByte<=pointerToFirstByte) |
|
218 { |
|
219 break; |
|
220 } |
|
221 --pointerToTargetByte; |
|
222 __ASSERT_DEBUG(pointerToSourceByte>pointerToFirstByte, Panic(EPanicBadPointers4)); |
|
223 --pointerToSourceByte; |
|
224 } |
|
225 __ASSERT_DEBUG(pointerToTargetByte==pointerToFirstByte, Panic(EPanicBadPointers5)); |
|
226 __ASSERT_DEBUG(pointerToSourceByte==pointerToFirstByte, Panic(EPanicBadPointers6)); |
|
227 } |
|
228 } |
|
229 |
|
230 LOCAL_C void ConvertFromJisX0212ToEucJpPackedInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut) |
|
231 { |
|
232 TInt descriptorLength=aDescriptor.Length(); |
|
233 __ASSERT_DEBUG(descriptorLength>aStartPositionInDescriptor, Panic(EPanicNothingToConvert3)); |
|
234 __ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%2==0, Panic(EPanicOddNumberOfBytes3)); |
|
235 aNumberOfCharactersThatDroppedOut=Max(0, ((descriptorLength-aStartPositionInDescriptor)/2)-((aDescriptor.MaxLength()-aStartPositionInDescriptor)/3)); |
|
236 descriptorLength-=aNumberOfCharactersThatDroppedOut*2; |
|
237 __ASSERT_DEBUG(descriptorLength>=aStartPositionInDescriptor, Panic(EPanicBadCalculation2)); |
|
238 if (descriptorLength<=aStartPositionInDescriptor) |
|
239 { |
|
240 aDescriptor.SetLength(descriptorLength); |
|
241 } |
|
242 else |
|
243 { |
|
244 __ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%2==0, Panic(EPanicOddNumberOfBytes4)); |
|
245 TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr()); // pointerToTargetByte is initialized properly when descriptorLength has been offset to the actual final length of aDescriptor |
|
246 const TUint8* const pointerToFirstByte=pointerToTargetByte+aStartPositionInDescriptor; |
|
247 const TUint8* pointerToSourceByte=pointerToTargetByte+(descriptorLength-1); |
|
248 descriptorLength=(((descriptorLength-aStartPositionInDescriptor)*3)/2)+aStartPositionInDescriptor; |
|
249 __ASSERT_DEBUG((descriptorLength-aStartPositionInDescriptor)%3==0, Panic(EPanicNumberOfBytesIsNotMultipleOfThree1)); |
|
250 aDescriptor.SetLength(descriptorLength); |
|
251 pointerToTargetByte+=descriptorLength-1; // pointerToTargetByte is is initialized properly here |
|
252 FOREVER |
|
253 { |
|
254 __ASSERT_DEBUG((*pointerToSourceByte&0x80)==0, Panic(EPanicBadHighBit2)); |
|
255 *pointerToTargetByte=STATIC_CAST(TUint8, *pointerToSourceByte|0x80); |
|
256 __ASSERT_DEBUG(pointerToTargetByte>pointerToFirstByte, Panic(EPanicBadPointers7)); |
|
257 --pointerToTargetByte; |
|
258 __ASSERT_DEBUG(pointerToSourceByte>pointerToFirstByte, Panic(EPanicBadPointers8)); |
|
259 --pointerToSourceByte; |
|
260 __ASSERT_DEBUG((*pointerToSourceByte&0x80)==0, Panic(EPanicBadHighBit3)); |
|
261 *pointerToTargetByte=STATIC_CAST(TUint8, *pointerToSourceByte|0x80); |
|
262 __ASSERT_DEBUG(pointerToTargetByte>pointerToFirstByte, Panic(EPanicBadPointers9)); |
|
263 --pointerToTargetByte; |
|
264 *pointerToTargetByte=KSingleShift3; |
|
265 __ASSERT_DEBUG(pointerToTargetByte>=pointerToFirstByte, Panic(EPanicBadPointers10)); |
|
266 if (pointerToTargetByte<=pointerToFirstByte) |
|
267 { |
|
268 break; |
|
269 } |
|
270 --pointerToTargetByte; |
|
271 __ASSERT_DEBUG(pointerToSourceByte>pointerToFirstByte, Panic(EPanicBadPointers11)); |
|
272 --pointerToSourceByte; |
|
273 } |
|
274 __ASSERT_DEBUG(pointerToTargetByte==pointerToFirstByte, Panic(EPanicBadPointers12)); |
|
275 __ASSERT_DEBUG(pointerToSourceByte==pointerToFirstByte, Panic(EPanicBadPointers13)); |
|
276 } |
|
277 } |
|
278 |
|
279 TInt CEucjpPackedConverterImpl::ConvertFromUnicode( |
|
280 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, |
|
281 const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, |
|
282 TDes8& aForeign, |
|
283 const TDesC16& aUnicode, |
|
284 CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters) |
|
285 { |
|
286 RArray<CnvUtilities::SCharacterSet> characterSets; |
|
287 if ( FeatureManager::FeatureSupported(KFeatureIdJapanesePicto) ) |
|
288 { |
|
289 CnvUtilities::SCharacterSet characterSet; |
|
290 |
|
291 characterSet.iConversionData=&CnvJisRoman::ConversionData(); |
|
292 characterSet.iConvertFromIntermediateBufferInPlace=DummyConvertFromIntermediateBufferInPlace; |
|
293 characterSet.iEscapeSequence=&KNullDesC8; |
|
294 characterSets.Append(characterSet); |
|
295 characterSet.iConversionData=&CnvJisX0208::ConversionData(); |
|
296 characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromJisX0208ToEucJpPackedInPlace; |
|
297 characterSet.iEscapeSequence=&KNullDesC8; |
|
298 characterSets.Append(characterSet); |
|
299 characterSet.iConversionData=&CnvHalfWidthKatakana8::ConversionData(); |
|
300 characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromHalfWidthKatakana8ToEucJpPackedInPlace; |
|
301 characterSet.iEscapeSequence=&KNullDesC8; |
|
302 characterSets.Append(characterSet); |
|
303 characterSet.iConversionData=&CnvJisX0212::ConversionData(); |
|
304 characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromJisX0212ToEucJpPackedInPlace; |
|
305 characterSet.iEscapeSequence=&KNullDesC8; |
|
306 characterSets.Append(characterSet); |
|
307 |
|
308 SetCharacterSetsForPictograph(characterSets, ECharsetEucJp); |
|
309 } |
|
310 else |
|
311 { |
|
312 CnvUtilities::SCharacterSet characterSet; |
|
313 characterSet.iConversionData=&CnvJisRoman::ConversionData(); |
|
314 characterSet.iConvertFromIntermediateBufferInPlace=DummyConvertFromIntermediateBufferInPlace; |
|
315 characterSet.iEscapeSequence=&KNullDesC8; |
|
316 characterSets.Append(characterSet); |
|
317 characterSet.iConversionData=&CnvJisX0208::ConversionData(); |
|
318 characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromJisX0208ToEucJpPackedInPlace; |
|
319 characterSet.iEscapeSequence=&KNullDesC8; |
|
320 characterSets.Append(characterSet); |
|
321 characterSet.iConversionData=&CnvHalfWidthKatakana8::ConversionData(); |
|
322 characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromHalfWidthKatakana8ToEucJpPackedInPlace; |
|
323 characterSet.iEscapeSequence=&KNullDesC8; |
|
324 characterSets.Append(characterSet); |
|
325 characterSet.iConversionData=&CnvJisX0212::ConversionData(); |
|
326 characterSet.iConvertFromIntermediateBufferInPlace=ConvertFromJisX0212ToEucJpPackedInPlace; |
|
327 characterSet.iEscapeSequence=&KNullDesC8; |
|
328 characterSets.Append(characterSet); |
|
329 } |
|
330 TInt unconvert = CnvUtilities::ConvertFromUnicode(aDefaultEndiannessOfForeignCharacters, aReplacementForUnconvertibleUnicodeCharacters, aForeign, aUnicode, aIndicesOfUnconvertibleCharacters, characterSets.Array()); |
|
331 |
|
332 characterSets.Close(); |
|
333 return unconvert; |
|
334 } |
|
335 |
|
336 LOCAL_C TInt NumberOfBytesAbleToConvertToJisRoman(const TDesC8& aDescriptor) |
|
337 { |
|
338 const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1; |
|
339 const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length(); |
|
340 if (pointerToPreviousByte==pointerToLastByte) |
|
341 { |
|
342 return 0; |
|
343 } |
|
344 FOREVER |
|
345 { |
|
346 __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers14)); |
|
347 const TUint currentByte=*(pointerToPreviousByte+1); |
|
348 if (currentByte&0x80) |
|
349 { |
|
350 break; |
|
351 } |
|
352 __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers15)); |
|
353 ++pointerToPreviousByte; |
|
354 __ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers16)); |
|
355 if (pointerToPreviousByte>=pointerToLastByte) |
|
356 { |
|
357 break; |
|
358 } |
|
359 } |
|
360 return (pointerToPreviousByte+1)-aDescriptor.Ptr(); |
|
361 } |
|
362 |
|
363 LOCAL_C TInt NumberOfBytesAbleToConvertToJisX0208(const TDesC8& aDescriptor) |
|
364 { |
|
365 const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1; |
|
366 const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length(); |
|
367 if (pointerToPreviousByte==pointerToLastByte) |
|
368 { |
|
369 return 0; |
|
370 } |
|
371 FOREVER |
|
372 { |
|
373 __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers17)); |
|
374 TUint currentByte=*(pointerToPreviousByte+1); |
|
375 if (currentByte<0xa0) |
|
376 { |
|
377 break; |
|
378 } |
|
379 __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers18)); |
|
380 if (pointerToLastByte-pointerToPreviousByte<2) |
|
381 { |
|
382 break; |
|
383 } |
|
384 ++pointerToPreviousByte; |
|
385 currentByte=*(pointerToPreviousByte+1); |
|
386 if (currentByte<0xa0) |
|
387 { |
|
388 return CCnvCharacterSetConverter::EErrorIllFormedInput; |
|
389 } |
|
390 __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers19)); |
|
391 ++pointerToPreviousByte; |
|
392 __ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers20)); |
|
393 if (pointerToPreviousByte>=pointerToLastByte) |
|
394 { |
|
395 break; |
|
396 } |
|
397 } |
|
398 return (pointerToPreviousByte+1)-aDescriptor.Ptr(); |
|
399 } |
|
400 |
|
401 LOCAL_C TInt NumberOfBytesAbleToConvertToHalfWidthKatakana8(const TDesC8& aDescriptor) |
|
402 { |
|
403 const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1; |
|
404 const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length(); |
|
405 if (pointerToPreviousByte==pointerToLastByte) |
|
406 { |
|
407 return 0; |
|
408 } |
|
409 FOREVER |
|
410 { |
|
411 __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers21)); |
|
412 TUint currentByte=*(pointerToPreviousByte+1); |
|
413 if (currentByte!=KSingleShift2) |
|
414 { |
|
415 break; |
|
416 } |
|
417 __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers22)); |
|
418 if (pointerToLastByte-pointerToPreviousByte<2) |
|
419 { |
|
420 break; |
|
421 } |
|
422 ++pointerToPreviousByte; |
|
423 currentByte=*(pointerToPreviousByte+1); |
|
424 if (currentByte<0xa0) |
|
425 { |
|
426 return CCnvCharacterSetConverter::EErrorIllFormedInput; |
|
427 } |
|
428 __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers23)); |
|
429 ++pointerToPreviousByte; |
|
430 __ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers24)); |
|
431 if (pointerToPreviousByte>=pointerToLastByte) |
|
432 { |
|
433 break; |
|
434 } |
|
435 } |
|
436 return (pointerToPreviousByte+1)-aDescriptor.Ptr(); |
|
437 } |
|
438 |
|
439 LOCAL_C TInt NumberOfBytesAbleToConvertToJisX0212(const TDesC8& aDescriptor) |
|
440 { |
|
441 const TUint8* pointerToPreviousByte=aDescriptor.Ptr()-1; |
|
442 const TUint8* const pointerToLastByte=pointerToPreviousByte+aDescriptor.Length(); |
|
443 if (pointerToPreviousByte==pointerToLastByte) |
|
444 { |
|
445 return 0; |
|
446 } |
|
447 FOREVER |
|
448 { |
|
449 __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers25)); |
|
450 TUint currentByte=*(pointerToPreviousByte+1); |
|
451 if (currentByte!=KSingleShift3) |
|
452 { |
|
453 break; |
|
454 } |
|
455 __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers26)); |
|
456 if (pointerToLastByte-pointerToPreviousByte<3) |
|
457 { |
|
458 break; |
|
459 } |
|
460 ++pointerToPreviousByte; |
|
461 currentByte=*(pointerToPreviousByte+1); |
|
462 if (currentByte<0xa0) |
|
463 { |
|
464 return CCnvCharacterSetConverter::EErrorIllFormedInput; |
|
465 } |
|
466 __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers27)); |
|
467 ++pointerToPreviousByte; |
|
468 currentByte=*(pointerToPreviousByte+1); |
|
469 if (currentByte<0xa0) |
|
470 { |
|
471 return CCnvCharacterSetConverter::EErrorIllFormedInput; |
|
472 } |
|
473 __ASSERT_DEBUG(pointerToPreviousByte<pointerToLastByte, Panic(EPanicBadPointers28)); |
|
474 ++pointerToPreviousByte; |
|
475 __ASSERT_DEBUG(pointerToPreviousByte<=pointerToLastByte, Panic(EPanicBadPointers29)); |
|
476 if (pointerToPreviousByte>=pointerToLastByte) |
|
477 { |
|
478 break; |
|
479 } |
|
480 } |
|
481 return (pointerToPreviousByte+1)-aDescriptor.Ptr(); |
|
482 } |
|
483 |
|
484 LOCAL_C void DummyConvertToIntermediateBufferInPlace(TDes8&) |
|
485 { |
|
486 } |
|
487 |
|
488 LOCAL_C void ConvertToJisX0208FromEucJpPackedInPlace(TDes8& aDescriptor) |
|
489 { |
|
490 const TInt descriptorLength=aDescriptor.Length(); |
|
491 __ASSERT_DEBUG(descriptorLength>0, Panic(EPanicNothingToConvert4)); |
|
492 __ASSERT_DEBUG(descriptorLength%2==0, Panic(EPanicOddNumberOfBytes5)); |
|
493 TUint8* pointerToCurrentByte=CONST_CAST(TUint8*, aDescriptor.Ptr()); |
|
494 const TUint8* const pointerToLastByte=pointerToCurrentByte+(descriptorLength-1); |
|
495 FOREVER |
|
496 { |
|
497 const TUint currentByte=*pointerToCurrentByte; |
|
498 __ASSERT_DEBUG(currentByte&0x80, Panic(EPanicBadHighBit4)); |
|
499 *pointerToCurrentByte=STATIC_CAST(TUint8, currentByte&~0x80); |
|
500 __ASSERT_DEBUG(pointerToCurrentByte<=pointerToLastByte, Panic(EPanicBadPointers30)); |
|
501 if (pointerToCurrentByte>=pointerToLastByte) |
|
502 { |
|
503 break; |
|
504 } |
|
505 ++pointerToCurrentByte; |
|
506 } |
|
507 } |
|
508 |
|
509 LOCAL_C void ConvertToHalfWidthKatakana8FromEucJpPackedInPlace(TDes8& aDescriptor) |
|
510 { |
|
511 const TInt descriptorLength=aDescriptor.Length(); |
|
512 __ASSERT_DEBUG(descriptorLength>0, Panic(EPanicNothingToConvert5)); |
|
513 __ASSERT_DEBUG(descriptorLength%2==0, Panic(EPanicOddNumberOfBytes6)); |
|
514 TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr()); |
|
515 const TUint8* pointerToSourceByte=pointerToTargetByte; |
|
516 const TUint8* const pointerToLastByte=pointerToSourceByte+(descriptorLength-1); |
|
517 FOREVER |
|
518 { |
|
519 __ASSERT_DEBUG(*pointerToSourceByte==KSingleShift2, Panic(EPanicSingleShift2Expected)); |
|
520 __ASSERT_DEBUG(pointerToSourceByte<pointerToLastByte, Panic(EPanicBadPointers31)); |
|
521 ++pointerToSourceByte; |
|
522 const TUint sourceByte=*pointerToSourceByte; |
|
523 __ASSERT_DEBUG(sourceByte&0x80, Panic(EPanicBadHighBit5)); |
|
524 *pointerToTargetByte=STATIC_CAST(TUint8, sourceByte); |
|
525 __ASSERT_DEBUG(pointerToSourceByte<=pointerToLastByte, Panic(EPanicBadPointers32)); |
|
526 if (pointerToSourceByte>=pointerToLastByte) |
|
527 { |
|
528 break; |
|
529 } |
|
530 ++pointerToSourceByte; |
|
531 ++pointerToTargetByte; |
|
532 } |
|
533 aDescriptor.SetLength(descriptorLength/2); |
|
534 } |
|
535 |
|
536 LOCAL_C void ConvertToJisX0212FromEucJpPackedInPlace(TDes8& aDescriptor) |
|
537 { |
|
538 const TInt descriptorLength=aDescriptor.Length(); |
|
539 __ASSERT_DEBUG(descriptorLength>0, Panic(EPanicNothingToConvert6)); |
|
540 __ASSERT_DEBUG(descriptorLength%3==0, Panic(EPanicNumberOfBytesIsNotMultipleOfThree2)); |
|
541 TUint8* pointerToTargetByte=CONST_CAST(TUint8*, aDescriptor.Ptr()); |
|
542 const TUint8* pointerToSourceByte=pointerToTargetByte; |
|
543 const TUint8* const pointerToLastByte=pointerToSourceByte+(descriptorLength-1); |
|
544 FOREVER |
|
545 { |
|
546 __ASSERT_DEBUG(*pointerToSourceByte==KSingleShift3, Panic(EPanicSingleShift3Expected)); |
|
547 __ASSERT_DEBUG(pointerToSourceByte<pointerToLastByte, Panic(EPanicBadPointers33)); |
|
548 ++pointerToSourceByte; |
|
549 TUint sourceByte=*pointerToSourceByte; |
|
550 __ASSERT_DEBUG(sourceByte&0x80, Panic(EPanicBadHighBit6)); |
|
551 *pointerToTargetByte=STATIC_CAST(TUint8, sourceByte&~0x80); |
|
552 __ASSERT_DEBUG(pointerToSourceByte<pointerToLastByte, Panic(EPanicBadPointers34)); |
|
553 ++pointerToSourceByte; |
|
554 sourceByte=*pointerToSourceByte; |
|
555 __ASSERT_DEBUG(sourceByte&0x80, Panic(EPanicBadHighBit7)); |
|
556 __ASSERT_DEBUG(pointerToTargetByte<pointerToLastByte, Panic(EPanicBadPointers35)); |
|
557 ++pointerToTargetByte; |
|
558 *pointerToTargetByte=STATIC_CAST(TUint8, sourceByte&~0x80); |
|
559 __ASSERT_DEBUG(pointerToSourceByte<=pointerToLastByte, Panic(EPanicBadPointers36)); |
|
560 if (pointerToSourceByte>=pointerToLastByte) |
|
561 { |
|
562 break; |
|
563 } |
|
564 ++pointerToSourceByte; |
|
565 ++pointerToTargetByte; |
|
566 } |
|
567 aDescriptor.SetLength((descriptorLength/3)*2); |
|
568 } |
|
569 |
|
570 TInt CEucjpPackedConverterImpl::ConvertToUnicode( |
|
571 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, |
|
572 TDes16& aUnicode, |
|
573 const TDesC8& aForeign, |
|
574 TInt& /*aState*/, |
|
575 TInt& aNumberOfUnconvertibleCharacters, |
|
576 TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter) |
|
577 { |
|
578 RArray<CnvUtilities::SMethod> methods; |
|
579 if ( FeatureManager::FeatureSupported(KFeatureIdJapanesePicto) ) |
|
580 { |
|
581 CnvUtilities::SMethod method; |
|
582 SetMethodsForPictograph(methods, ECharsetEucJp); |
|
583 method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisRoman; |
|
584 method.iConvertToIntermediateBufferInPlace=DummyConvertToIntermediateBufferInPlace; |
|
585 method.iConversionData=&CnvJisRoman::ConversionData(); |
|
586 method.iNumberOfBytesPerCharacter=1; |
|
587 method.iNumberOfCoreBytesPerCharacter=1; |
|
588 methods.Append(method); |
|
589 method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisX0208; |
|
590 method.iConvertToIntermediateBufferInPlace=ConvertToJisX0208FromEucJpPackedInPlace; |
|
591 method.iConversionData=&CnvJisX0208::ConversionData(); |
|
592 method.iNumberOfBytesPerCharacter=2; |
|
593 method.iNumberOfCoreBytesPerCharacter=2; |
|
594 methods.Append(method); |
|
595 method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToHalfWidthKatakana8; |
|
596 method.iConvertToIntermediateBufferInPlace=ConvertToHalfWidthKatakana8FromEucJpPackedInPlace; |
|
597 method.iConversionData=&CnvHalfWidthKatakana8::ConversionData(); |
|
598 method.iNumberOfBytesPerCharacter=2; |
|
599 method.iNumberOfCoreBytesPerCharacter=1; |
|
600 methods.Append(method); |
|
601 method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisX0212; |
|
602 method.iConvertToIntermediateBufferInPlace=ConvertToJisX0212FromEucJpPackedInPlace; |
|
603 method.iConversionData=&CnvJisX0212::ConversionData(); |
|
604 method.iNumberOfBytesPerCharacter=3; |
|
605 method.iNumberOfCoreBytesPerCharacter=2; |
|
606 methods.Append(method); |
|
607 } |
|
608 else |
|
609 { |
|
610 CnvUtilities::SMethod method; |
|
611 method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisRoman; |
|
612 method.iConvertToIntermediateBufferInPlace=DummyConvertToIntermediateBufferInPlace; |
|
613 method.iConversionData=&CnvJisRoman::ConversionData(); |
|
614 method.iNumberOfBytesPerCharacter=1; |
|
615 method.iNumberOfCoreBytesPerCharacter=1; |
|
616 methods.Append(method); |
|
617 method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisX0208; |
|
618 method.iConvertToIntermediateBufferInPlace=ConvertToJisX0208FromEucJpPackedInPlace; |
|
619 method.iConversionData=&CnvJisX0208::ConversionData(); |
|
620 method.iNumberOfBytesPerCharacter=2; |
|
621 method.iNumberOfCoreBytesPerCharacter=2; |
|
622 methods.Append(method); |
|
623 method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToHalfWidthKatakana8; |
|
624 method.iConvertToIntermediateBufferInPlace=ConvertToHalfWidthKatakana8FromEucJpPackedInPlace; |
|
625 method.iConversionData=&CnvHalfWidthKatakana8::ConversionData(); |
|
626 method.iNumberOfBytesPerCharacter=2; |
|
627 method.iNumberOfCoreBytesPerCharacter=1; |
|
628 methods.Append(method); |
|
629 method.iNumberOfBytesAbleToConvert=NumberOfBytesAbleToConvertToJisX0212; |
|
630 method.iConvertToIntermediateBufferInPlace=ConvertToJisX0212FromEucJpPackedInPlace; |
|
631 method.iConversionData=&CnvJisX0212::ConversionData(); |
|
632 method.iNumberOfBytesPerCharacter=3; |
|
633 method.iNumberOfCoreBytesPerCharacter=2; |
|
634 methods.Append(method); |
|
635 } |
|
636 TInt unconvert = CnvUtilities::ConvertToUnicodeFromHeterogeneousForeign(aDefaultEndiannessOfForeignCharacters, aUnicode, aForeign, aNumberOfUnconvertibleCharacters, aIndexOfFirstByteOfFirstUnconvertibleCharacter, methods.Array()); |
|
637 |
|
638 // The following is specific impelementation for brower. |
|
639 // If brower app calls this API, the yen sign code(0xA5) |
|
640 // must be converted to backslash code(0x5C). |
|
641 // Becasue Javascript supports backslash code ony. |
|
642 TBool browserProcess = (RProcess().SecureId().iId == KBrowserSecureId); |
|
643 if (browserProcess && aUnicode.Length() > 0) |
|
644 { |
|
645 const TUint16* pB = aUnicode.Ptr(); |
|
646 const TUint16* pbase = pB; |
|
647 const TUint16* pE = pB + aUnicode.Length() -1; |
|
648 while (pE>=pbase) |
|
649 { |
|
650 if (*pbase == KCharacterCodeForYenSign) |
|
651 { |
|
652 aUnicode[pbase - pB] = KCharacterCodeForBackSlash; |
|
653 } |
|
654 pbase++; |
|
655 } |
|
656 } |
|
657 |
|
658 methods.Close(); |
|
659 return unconvert; |
|
660 } |
|
661 |
|
662 TBool CEucjpPackedConverterImpl::IsInThisCharacterSetL( |
|
663 TBool& aSetToTrue, |
|
664 TInt& aConfidenceLevel, |
|
665 const TDesC8& aSample) |
|
666 { |
|
667 aSetToTrue=ETrue; |
|
668 // check for the SS2 and SS3 which specifies Code Set 2 & 3 respectively from the Code space |
|
669 // between 00-7f only... then ambiguous |
|
670 aSetToTrue = ETrue; |
|
671 TInt sampleLength = aSample.Length(); |
|
672 TInt eucjpPacked = 0; |
|
673 aConfidenceLevel = 0; |
|
674 |
|
675 for (TInt i = 0; i < sampleLength; ++i) |
|
676 { |
|
677 // Code set 1 JISX 0208 support |
|
678 TInt increment1 = i+1; |
|
679 if (increment1 >= sampleLength) |
|
680 break; |
|
681 if (((aSample[i] >= 0xa1) && (aSample[i] <= 0xfe)) && |
|
682 ((aSample[increment1] >= 0xa1) && (aSample[increment1] <= 0xfe))) |
|
683 { |
|
684 eucjpPacked = eucjpPacked +2; |
|
685 i++; |
|
686 } |
|
687 // Single Shift 2 (SS2) sequence - Code Set 2 |
|
688 if (aSample[i]==0x8e) |
|
689 { |
|
690 TInt increment1 = i+1; |
|
691 if (increment1 >= sampleLength) |
|
692 break; |
|
693 if ((aSample[increment1] >= 0xa1) && (aSample[increment1] <= 0xdf)) |
|
694 { |
|
695 eucjpPacked = eucjpPacked+2; |
|
696 i++; |
|
697 } |
|
698 else |
|
699 { |
|
700 eucjpPacked = 0; |
|
701 break; |
|
702 } |
|
703 } |
|
704 // Single Shift 3 (SS3) sequence - Code Set 3 |
|
705 if (aSample[i]==0x8f) |
|
706 { |
|
707 TInt increment1 = i+1; |
|
708 TInt increment2 = i+2; |
|
709 if ((increment1 >= sampleLength) || (increment2 >= sampleLength)) |
|
710 break; |
|
711 if (((aSample[increment1] >= 0xa1) && (aSample[increment1] <= 0xfe)) && |
|
712 ((aSample[increment2] >= 0xa1) && (aSample[increment2] <= 0xfe))) |
|
713 { |
|
714 eucjpPacked = eucjpPacked +3; |
|
715 i+=2; |
|
716 } |
|
717 else |
|
718 { |
|
719 eucjpPacked =0; |
|
720 break; |
|
721 } |
|
722 } |
|
723 } |
|
724 if (eucjpPacked) |
|
725 aConfidenceLevel = (eucjpPacked*100)/sampleLength; |
|
726 else |
|
727 aConfidenceLevel = 0; |
|
728 aConfidenceLevel=(aConfidenceLevel >100)?100:aConfidenceLevel; |
|
729 return ETrue; |
|
730 } |
|
731 |
|
732 CEucjpPackedConverterImpl* CEucjpPackedConverterImpl::NewL() |
|
733 { |
|
734 CEucjpPackedConverterImpl* self = new(ELeave) CEucjpPackedConverterImpl(); |
|
735 CleanupStack::PushL(self); |
|
736 self->ConstructL(); |
|
737 CleanupStack::Pop(self); |
|
738 return self; |
|
739 } |
|
740 |
|
741 CEucjpPackedConverterImpl::~CEucjpPackedConverterImpl() |
|
742 { |
|
743 FeatureManager::UnInitializeLib(); |
|
744 } |
|
745 |
|
746 CEucjpPackedConverterImpl::CEucjpPackedConverterImpl() |
|
747 { |
|
748 } |
|
749 |
|
750 void CEucjpPackedConverterImpl::ConstructL() |
|
751 { |
|
752 FeatureManager::InitializeLibL(); |
|
753 } |
|
754 |
|
755 const TImplementationProxy ImplementationTable[] = |
|
756 { |
|
757 #ifdef S60_TEST |
|
758 IMPLEMENTATION_PROXY_ENTRY(0x01000005,CEucjpPackedConverterImpl::NewL) |
|
759 #else |
|
760 IMPLEMENTATION_PROXY_ENTRY(0x10006067,CEucjpPackedConverterImpl::NewL) |
|
761 #endif |
|
762 }; |
|
763 |
|
764 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) |
|
765 { |
|
766 aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); |
|
767 |
|
768 return ImplementationTable; |
|
769 } |
|
770 |