|
1 /* |
|
2 * Copyright (c) 2002 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: Implements the characterconversion plug-in |
|
15 * for ISCII characterset. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 #include <e32std.h> |
|
24 #include <charconv.h> |
|
25 #include <convgeneratedcpp.h> |
|
26 #include <convutils.h> |
|
27 |
|
28 //The maximum length of any intermediate buffer allocated for conversion. |
|
29 const TInt KMaximumLengthOfIntermediateBuffer=5; |
|
30 //The ISCII ATR code point, used for ISCII script switching mechanism. |
|
31 const TUint KControlCharacterEscape=0xef; |
|
32 //The number of Indic scripts supported by the plug-in. |
|
33 //ISCII in general addresses all the Indic character sets. |
|
34 const TUint KNumberOfIndicCharactersetsSupported = 1; |
|
35 //The common reason for panic for all panics raised by the iscii plug-in |
|
36 _LIT16(KPanicReason,"ISCII Plug-in Panic"); |
|
37 //The escape sequence for ISCII (ATR) is 0xEF and immidiate byte following |
|
38 //that is the script selection code for Devanagari. |
|
39 _LIT8(KEscapeSequenceDevanagari,"\xef\x42"); |
|
40 //The sequence for Explicit Halant, in unicode it gets converted to VIRAMA+ZWNJ |
|
41 _LIT8(KExplicitHalant,"\xe8\xe8"); |
|
42 //For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the |
|
43 //sequence is converted to intermediate unused iscii code point. |
|
44 _LIT8(KReplacementForExplicitHalant,"\xe8\xfc"); |
|
45 //The sequence for Soft Halant, in unicode it gets converted to VIRAMA+ZWJ |
|
46 _LIT8(KSoftHalant,"\xe8\xe9"); |
|
47 //For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the |
|
48 //sequence is converted to intermediate unused iscii code point. |
|
49 _LIT8(KReplacementForSoftHalant,"\xe8\xfd"); |
|
50 //Devanagari character Om |
|
51 _LIT8(KOm,"\xa1\xe9"); |
|
52 ////For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the |
|
53 //sequence is converted to intermediate unused iscii code point. |
|
54 _LIT8(KReplacementForOm,"\xfe"); |
|
55 //Devanagari character Avagraha |
|
56 _LIT8(KAvagraha,"\xea\xe9"); |
|
57 //For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the |
|
58 //sequence is converted to intermediate unused iscii code point. |
|
59 _LIT8(KReplacementForAvagraha,"\xff"); |
|
60 |
|
61 //Devanagari character VOCALIC RR |
|
62 _LIT8(KVocalicRr,"\xaa\xe9"); |
|
63 //For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the |
|
64 //sequence is converted to intermediate unused iscii code point. |
|
65 _LIT8(KReplacementForVocalicRr,"\x80"); |
|
66 //Devanagari character VOCALIC LL |
|
67 _LIT8(KVocalicLl,"\xa7\xe9"); |
|
68 //For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the |
|
69 //sequence is converted to intermediate unused iscii code point. |
|
70 _LIT8(KReplacementForVocalicLl,"\x81"); |
|
71 //Devanagari character VOCALIC L SIGN |
|
72 _LIT8(KVocalicLSign,"\xdb\xe9"); |
|
73 //For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the |
|
74 //sequence is converted to intermediate unused iscii code point. |
|
75 _LIT8(KReplacementForVocalicLSign,"\x82"); |
|
76 //Devanagari character VOCALIC LL SIGN |
|
77 _LIT8(KVocalicLlSign,"\xdc\xe9"); |
|
78 //For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the |
|
79 //sequence is converted to intermediate unused iscii code point. |
|
80 _LIT8(KReplacementForVocalicLlSign,"\x83"); |
|
81 //Devanagari character VOCALIC L |
|
82 _LIT8(KVocalicL,"\xa6\xe9"); |
|
83 //For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the |
|
84 //sequence is converted to intermediate unused iscii code point. |
|
85 _LIT8(KReplacementForVocalicL,"\x84"); |
|
86 //Devanagari character VOCALIC RR SIGN |
|
87 _LIT8(KVocalicRrSign,"\xdf\xe9"); |
|
88 //For supportiing ISCII to Unicode conversion of multi byte ISCII sequences, the |
|
89 //sequence is converted to intermediate unused iscii code point. |
|
90 _LIT8(KReplacementForVocalicRrSign,"\x85"); |
|
91 |
|
92 //Unconvertible ISCII character |
|
93 _LIT8(KIsciiUnconvertibleCharacter,"\xeb"); |
|
94 |
|
95 enum TPanic |
|
96 { |
|
97 //The panic raised by ConvertToUnicodeFromModalForeign_Internal() if the input |
|
98 //conversion flag is CCnvCharacterSetConverter::EInputConversionFlagStopAtFirstUnconvertibleCharacter |
|
99 EPanicBadInputConversionFlags=1, |
|
100 //Panic raised if the buffer does not start with the escape sequence 0xEF |
|
101 EPanicBadRemainderOfForeign, |
|
102 //Panic is raised if the length of the search buffer is greater than the length of the |
|
103 //replacement buffer |
|
104 EPanicBadReplacementBuffer, |
|
105 //If the offset of start of the escape sequence is not an unsigned number. |
|
106 EPanicBadStartOfNextEscapeSequence |
|
107 }; |
|
108 |
|
109 //The dummy datastructure for the dummy conversion data i.e. used for conversion if the |
|
110 //script selection code is not supported. |
|
111 #define ARRAY_LENGTH(aArray) (sizeof(aArray)/sizeof((aArray)[0])) |
|
112 |
|
113 LOCAL_D const SCnvConversionData::SOneDirectionData::SRange::UData::SKeyedTable1616::SEntry keyedTable1616_foreignToUnicode_1[]= |
|
114 { |
|
115 { |
|
116 0xa0, |
|
117 0xfffd |
|
118 } |
|
119 }; |
|
120 |
|
121 LOCAL_D const SCnvConversionData::SOneDirectionData::SRange::UData::SKeyedTable1616::SEntry keyedTable1616_unicodeToForeign_1[]= |
|
122 { |
|
123 { |
|
124 0xfffd, |
|
125 0xa0 |
|
126 } |
|
127 }; |
|
128 |
|
129 LOCAL_D const SCnvConversionData::SVariableByteData::SRange foreignVariableByteDataRanges[]= |
|
130 { |
|
131 { |
|
132 0x00, |
|
133 0xff, |
|
134 0, |
|
135 0 |
|
136 } |
|
137 }; |
|
138 |
|
139 LOCAL_D const SCnvConversionData::SOneDirectionData::SRange foreignToUnicodeDataRanges[]= |
|
140 { |
|
141 { |
|
142 0x00, |
|
143 0x7f, |
|
144 SCnvConversionData::SOneDirectionData::SRange::EDirect, |
|
145 0, |
|
146 0, |
|
147 { |
|
148 0 |
|
149 } |
|
150 }, |
|
151 { |
|
152 0xa0, |
|
153 0xff, |
|
154 SCnvConversionData::SOneDirectionData::SRange::EKeyedTable1616, |
|
155 0, |
|
156 0, |
|
157 { |
|
158 UData_SKeyedTable1616(keyedTable1616_foreignToUnicode_1) |
|
159 } |
|
160 } |
|
161 }; |
|
162 |
|
163 LOCAL_D const SCnvConversionData::SOneDirectionData::SRange unicodeToForeignDataRanges[]= |
|
164 { |
|
165 { |
|
166 0x0000, |
|
167 0x007f, |
|
168 SCnvConversionData::SOneDirectionData::SRange::EDirect, |
|
169 1, |
|
170 0, |
|
171 { |
|
172 0 |
|
173 } |
|
174 }, |
|
175 { |
|
176 0x00a0, |
|
177 0xffff, |
|
178 SCnvConversionData::SOneDirectionData::SRange::EKeyedTable1616, |
|
179 1, |
|
180 0, |
|
181 { |
|
182 UData_SKeyedTable1616(keyedTable1616_unicodeToForeign_1) |
|
183 } |
|
184 } |
|
185 }; |
|
186 |
|
187 //The dummy conversion data to be used for conversion if the iscii code sequence is not |
|
188 //Devanagari (i.e. the script selection code is not 0x42 and something else. |
|
189 //In this case the ISCII characters are converted to unconvertible characters. |
|
190 |
|
191 LOCAL_D const SCnvConversionData conversionDataDummy= |
|
192 { |
|
193 SCnvConversionData::EFixedBigEndian, |
|
194 { |
|
195 ARRAY_LENGTH(foreignVariableByteDataRanges), |
|
196 foreignVariableByteDataRanges |
|
197 }, |
|
198 { |
|
199 ARRAY_LENGTH(foreignToUnicodeDataRanges), |
|
200 foreignToUnicodeDataRanges |
|
201 }, |
|
202 { |
|
203 ARRAY_LENGTH(unicodeToForeignDataRanges), |
|
204 unicodeToForeignDataRanges |
|
205 }, |
|
206 NULL, |
|
207 NULL |
|
208 }; |
|
209 |
|
210 |
|
211 |
|
212 #ifdef EKA2 |
|
213 |
|
214 /////////////////////////////////////////////////////////////// |
|
215 // 3.1 Code |
|
216 |
|
217 // INCLUDES |
|
218 #include <ecom/implementationproxy.h> |
|
219 #include <charactersetconverter.h> |
|
220 |
|
221 |
|
222 /** |
|
223 * The character conversion plug-in implementation for Iscii. |
|
224 * |
|
225 * @lib ecom.lib |
|
226 * @since Series 60 3.1 |
|
227 */ |
|
228 |
|
229 class CIsciiImplementation : public CCharacterSetConverterPluginInterface |
|
230 { |
|
231 public: |
|
232 //From CCharacterSetConverterPluginInterface |
|
233 virtual const TDesC8& ReplacementForUnconvertibleUnicodeCharacters(); |
|
234 |
|
235 //From CCharacterSetConverterPluginInterface |
|
236 virtual TInt ConvertFromUnicode( |
|
237 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, |
|
238 const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, |
|
239 TDes8& aForeign, |
|
240 const TDesC16& aUnicode, |
|
241 CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters ); |
|
242 |
|
243 //From CCharacterSetConverterPluginInterface |
|
244 virtual TInt ConvertToUnicode( |
|
245 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, |
|
246 TDes16& aUnicode, |
|
247 const TDesC8& aForeign, |
|
248 TInt&, |
|
249 TInt& aNumberOfUnconvertibleCharacters, |
|
250 TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter ); |
|
251 |
|
252 //From CCharacterSetConverterPluginInterface |
|
253 virtual TBool IsInThisCharacterSetL( |
|
254 TBool& aSetToTrue, |
|
255 TInt& aConfidenceLevel, |
|
256 const TDesC8& ); |
|
257 |
|
258 static CIsciiImplementation* NewL(); |
|
259 |
|
260 virtual ~CIsciiImplementation(); |
|
261 private: |
|
262 CIsciiImplementation(); |
|
263 }; |
|
264 |
|
265 //Checks if a descriptor starts with another descriptor at the begining. |
|
266 LOCAL_C TBool IsStartOf(const TDesC8& aEscapeSequence, const TDesC8& aBuffer) |
|
267 { |
|
268 const TInt lengthOfStart=aEscapeSequence.Length(); |
|
269 return (aBuffer.Length()>=lengthOfStart) && (aBuffer.Left(lengthOfStart)==aEscapeSequence); |
|
270 } |
|
271 // ----------------------------------------------------------------------------- |
|
272 // MatchesEscapeSequence() |
|
273 //If the remainder of the foreign text starts with the passed escapesequence, modifies the remainder of the foreign text |
|
274 //and sets the homogeneous run buffer that uses the same conversion data. |
|
275 //The homogeneous run buffer is the buffer that will use a single conversion data, it doesn't contain the attribute code |
|
276 // neither it contains the script switching code. |
|
277 //The aRemainderOfForeign buffer |
|
278 |
|
279 // Returns: ETrue: If the sequence contains the escape sequence |
|
280 // EFalse: If the sequence does not contain the escape sequence |
|
281 // |
|
282 // ----------------------------------------------------------------------------- |
|
283 // |
|
284 LOCAL_C TBool MatchesEscapeSequence(TInt& aNumberOfForeignBytesConsumed, TPtrC8& aHomogeneousRun, |
|
285 TPtrC8& aRemainderOfForeign, const TDesC8& aEscapeSequence) |
|
286 { |
|
287 const TInt lengthOfEscapeSequence=aEscapeSequence.Length(); |
|
288 if (IsStartOf(aEscapeSequence, aRemainderOfForeign)) |
|
289 { |
|
290 aRemainderOfForeign.Set(aRemainderOfForeign.Mid(lengthOfEscapeSequence)); |
|
291 const TInt startOfNextEscapeSequence=aRemainderOfForeign.Locate(KControlCharacterEscape); |
|
292 if (startOfNextEscapeSequence==KErrNotFound) |
|
293 { |
|
294 aHomogeneousRun.Set(aRemainderOfForeign); |
|
295 aRemainderOfForeign.Set(NULL, 0); |
|
296 } |
|
297 else |
|
298 { |
|
299 aHomogeneousRun.Set(aRemainderOfForeign.Left(startOfNextEscapeSequence)); |
|
300 aRemainderOfForeign.Set(aRemainderOfForeign.Mid(startOfNextEscapeSequence)); |
|
301 } |
|
302 aNumberOfForeignBytesConsumed+=lengthOfEscapeSequence; |
|
303 return ETrue; |
|
304 } |
|
305 return EFalse; |
|
306 } |
|
307 |
|
308 // ----------------------------------------------------------------------------- |
|
309 // NextHomogeneousForeignRun() |
|
310 //Matches the escape sequence of each of the elements of the SState array with the remainder of |
|
311 //foreign text and if the escape sequence matches with the start of remainder of the foreign text, |
|
312 //then the conversion data is set to the conversion data corresponding to the escape sequence |
|
313 //Also the homogeneous foreign text for conversion with the same escape sequence is set. |
|
314 |
|
315 // Returns: ETrue: If length of the remainder of foreign buffer is nonzero. |
|
316 // EFalse: If length of the remainder of foreign buffer is zero. |
|
317 // |
|
318 // ----------------------------------------------------------------------------- |
|
319 // |
|
320 |
|
321 |
|
322 LOCAL_C TBool NextHomogeneousForeignRun(const SCnvConversionData*& aConversionData, TInt& aNumberOfForeignBytesConsumed, TPtrC8& aHomogeneousRun, TPtrC8& aRemainderOfForeign, const TArray<CnvUtilities::SState>& aArrayOfStates, TUint& aOutputConversionFlags) |
|
323 { |
|
324 TBool returnValue = EFalse; |
|
325 TBool foundState = EFalse; |
|
326 __ASSERT_DEBUG((aRemainderOfForeign.Length()==0) || (aRemainderOfForeign[0]==KControlCharacterEscape), User::Panic(KPanicReason,EPanicBadRemainderOfForeign)); |
|
327 if (aRemainderOfForeign.Length()==0) |
|
328 { |
|
329 return returnValue; |
|
330 } |
|
331 const TInt numberOfStates=aArrayOfStates.Count(); |
|
332 TInt i; |
|
333 for (i=0; i<numberOfStates; ++i) |
|
334 { |
|
335 const CnvUtilities::SState& state=aArrayOfStates[i]; |
|
336 if (MatchesEscapeSequence(aNumberOfForeignBytesConsumed, aHomogeneousRun, aRemainderOfForeign, *state.iEscapeSequence)) |
|
337 { |
|
338 aConversionData=state.iConversionData; |
|
339 foundState = ETrue; |
|
340 } |
|
341 } |
|
342 if(!foundState) |
|
343 { |
|
344 for (i=0; i<numberOfStates; ++i) |
|
345 { |
|
346 if (IsStartOf(aRemainderOfForeign, *aArrayOfStates[i].iEscapeSequence)) |
|
347 { |
|
348 // aRemainderOfForeign ends with a truncated escape sequence, so ConvertToUnicode cannot convert any more |
|
349 aOutputConversionFlags|=CCnvCharacterSetConverter::EOutputConversionFlagInputIsTruncated; |
|
350 break; |
|
351 } |
|
352 } |
|
353 |
|
354 MatchesEscapeSequence(aNumberOfForeignBytesConsumed,aHomogeneousRun,aRemainderOfForeign,aRemainderOfForeign.Left(2)); |
|
355 aConversionData = &conversionDataDummy; |
|
356 returnValue = ETrue; |
|
357 } |
|
358 if (aHomogeneousRun.Length()>0) |
|
359 { |
|
360 returnValue = ETrue; |
|
361 } |
|
362 return returnValue; |
|
363 } |
|
364 // ----------------------------------------------------------------------------- |
|
365 // ConvertFromUnicodeIntermediateBufferInPlace() |
|
366 //Default implementation for conversion to the intermediate buffer |
|
367 //It modifies the unicode buffer before it is converted back to iscii. |
|
368 //The current implementation of iscii plug-in doesn't require any |
|
369 //modification to the default implementation |
|
370 // Returns: Nothing |
|
371 // |
|
372 // ----------------------------------------------------------------------------- |
|
373 // |
|
374 |
|
375 |
|
376 LOCAL_C void ConvertFromUnicodeIntermediateBufferInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut) |
|
377 { |
|
378 CnvUtilities::ConvertFromIntermediateBufferInPlace(aStartPositionInDescriptor, aDescriptor, aNumberOfCharactersThatDroppedOut, KEscapeSequenceDevanagari, 1); |
|
379 } |
|
380 |
|
381 // ----------------------------------------------------------------------------- |
|
382 // DoFindAndModifyBuffer() |
|
383 //Modifies the iscii buffer by replacing the search buffer with the replacement buffer. |
|
384 //Introduced for handling multibyte iscii sequence. |
|
385 //Takes the search buffer array and the replacement buffer arrays as input to it and replaces all |
|
386 //the occurances of the search buffer with the corresponding replace buffer. |
|
387 // Returns: Nothing |
|
388 // |
|
389 // ----------------------------------------------------------------------------- |
|
390 // |
|
391 |
|
392 LOCAL_C void DoFindAndModifyBuffer(TDes8& aModifyBuffer,const TDesC8& aSearchBuffer,const TDesC8& aReplaceBuffer) |
|
393 { |
|
394 FOREVER |
|
395 { |
|
396 TInt offset; |
|
397 __ASSERT_ALWAYS((aSearchBuffer.Length()>= aReplaceBuffer.Length()),User::Panic(KPanicReason,EPanicBadReplacementBuffer)); |
|
398 if((offset = aModifyBuffer.Find(aSearchBuffer)) != KErrNotFound) |
|
399 { |
|
400 TUint8 *pointerToBuffer = const_cast<TUint8*> (aModifyBuffer.Ptr()); |
|
401 Mem::Copy(pointerToBuffer+offset,aReplaceBuffer.Ptr(),aReplaceBuffer.Length()); |
|
402 Mem::Copy(pointerToBuffer+offset+aReplaceBuffer.Length(),pointerToBuffer+offset+aSearchBuffer.Length(),aModifyBuffer.Length()-aSearchBuffer.Length()-offset); |
|
403 aModifyBuffer.SetLength(aModifyBuffer.Length() - aSearchBuffer.Length() + aReplaceBuffer.Length()); |
|
404 } |
|
405 else |
|
406 break; |
|
407 } |
|
408 |
|
409 } |
|
410 |
|
411 // ----------------------------------------------------------------------------- |
|
412 // FindAndModifyBuffer() |
|
413 //Modifies the iscii buffer by replacing the search buffer with the replacement buffer. |
|
414 //Calls DoFindAndModifyBuffer() and supplies the search buffer and replacement buffer. |
|
415 //Introduced for handling multibyte iscii sequence. |
|
416 // Returns: Nothing |
|
417 // |
|
418 // ----------------------------------------------------------------------------- |
|
419 // |
|
420 |
|
421 LOCAL_C void FindAndModifyBuffer(TDes8& aModifyBuffer) |
|
422 { |
|
423 RArray<TPtrC8> searchBuffer; |
|
424 RArray<TPtrC8> replaceBuffer; |
|
425 |
|
426 //If the passed buffer contains the replacement buffer, |
|
427 //Then it should not get converted to respective Unicode |
|
428 //buffer rather it should get converted to replacement for |
|
429 //unconvertible character. |
|
430 |
|
431 searchBuffer.Append(KReplacementForExplicitHalant().Right(1)); |
|
432 searchBuffer.Append(KReplacementForSoftHalant().Right(1)); |
|
433 searchBuffer.Append(KReplacementForOm().Right(1)); |
|
434 searchBuffer.Append(KReplacementForAvagraha().Right(1)); |
|
435 |
|
436 searchBuffer.Append(KReplacementForVocalicRr().Right(1)); |
|
437 searchBuffer.Append(KReplacementForVocalicLl().Right(1)); |
|
438 searchBuffer.Append(KReplacementForVocalicLSign().Right(1)); |
|
439 searchBuffer.Append(KReplacementForVocalicLlSign().Right(1)); |
|
440 searchBuffer.Append(KReplacementForVocalicL().Right(1)); |
|
441 searchBuffer.Append(KReplacementForVocalicRrSign().Right(1)); |
|
442 |
|
443 //All normal search buffers |
|
444 searchBuffer.Append(KExplicitHalant().Mid(0)); |
|
445 searchBuffer.Append(KSoftHalant().Mid(0)); |
|
446 searchBuffer.Append(KOm().Mid(0)); |
|
447 searchBuffer.Append(KAvagraha().Mid(0)); |
|
448 |
|
449 searchBuffer.Append(KVocalicRr().Mid(0)); |
|
450 searchBuffer.Append(KVocalicLl().Mid(0)); |
|
451 searchBuffer.Append(KVocalicLSign().Mid(0)); |
|
452 searchBuffer.Append(KVocalicLlSign().Mid(0)); |
|
453 searchBuffer.Append(KVocalicL().Mid(0)); |
|
454 searchBuffer.Append(KVocalicRrSign().Mid(0)); |
|
455 |
|
456 //The replacement buffer for the odd cases to restrict the |
|
457 //replacement buffers not to get converted to the corresponding |
|
458 //unicode buffer |
|
459 |
|
460 replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0)); |
|
461 replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0)); |
|
462 replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0)); |
|
463 replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0)); |
|
464 |
|
465 replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0)); |
|
466 replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0)); |
|
467 replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0)); |
|
468 replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0)); |
|
469 replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0)); |
|
470 replaceBuffer.Append(KIsciiUnconvertibleCharacter().Mid(0)); |
|
471 |
|
472 //All normal replace buffers |
|
473 replaceBuffer.Append(KReplacementForExplicitHalant().Mid(0)); |
|
474 replaceBuffer.Append(KReplacementForSoftHalant().Mid(0)); |
|
475 replaceBuffer.Append(KReplacementForOm().Mid(0)); |
|
476 replaceBuffer.Append(KReplacementForAvagraha().Mid(0)); |
|
477 |
|
478 |
|
479 replaceBuffer.Append(KReplacementForVocalicRr().Mid(0)); |
|
480 replaceBuffer.Append(KReplacementForVocalicLl().Mid(0)); |
|
481 replaceBuffer.Append(KReplacementForVocalicLSign().Mid(0)); |
|
482 replaceBuffer.Append(KReplacementForVocalicLlSign().Mid(0)); |
|
483 replaceBuffer.Append(KReplacementForVocalicL().Mid(0)); |
|
484 replaceBuffer.Append(KReplacementForVocalicRrSign().Mid(0)); |
|
485 |
|
486 |
|
487 for(TInt counter=0;counter<searchBuffer.Count();counter++) |
|
488 { |
|
489 DoFindAndModifyBuffer(aModifyBuffer,searchBuffer[counter],replaceBuffer[counter]); |
|
490 } |
|
491 searchBuffer.Reset(); |
|
492 replaceBuffer.Reset(); |
|
493 |
|
494 } |
|
495 |
|
496 // ----------------------------------------------------------------------------- |
|
497 // DoNormalizeReturnValue() |
|
498 //Modifies the return value(Number of bytes did not get converted) according to the modified |
|
499 //intermediate buffer. Takes the modified intermediate buffer, return value, search and replace |
|
500 //buffers. Searches for the replace buffer in the intermediate buffer and if found, it looks for |
|
501 //the actual buffer corresponding to the replace buffer and adds the difference of the lengths |
|
502 //of the actual to replace buffer to the return value. |
|
503 // Returns: Nothing |
|
504 // |
|
505 // ----------------------------------------------------------------------------- |
|
506 // |
|
507 |
|
508 LOCAL_C void DoNormalizeReturnValue(TUint& aReturnValue,const TDesC8& aBuffer,RArray<TPtrC8>& anArrayOfSearches,RArray<TPtrC8>& anArrayOfReplaces) |
|
509 { |
|
510 TPtr8 buffer(const_cast<TUint8*>(aBuffer.Ptr()),aBuffer.Length(),aBuffer.Length()); |
|
511 TUint count = anArrayOfSearches.Count(); |
|
512 FOREVER |
|
513 { |
|
514 TBool flag = EFalse; |
|
515 for(TUint i=0;i<count;i++) |
|
516 { |
|
517 TPtrC8 searchBufferForComparison(buffer.Right(anArrayOfReplaces[i].Length())); |
|
518 TInt returnCompare = searchBufferForComparison.Compare(anArrayOfReplaces[i]); |
|
519 if(returnCompare == 0) |
|
520 { |
|
521 flag =ETrue; |
|
522 aReturnValue += (anArrayOfSearches[i].Length() - anArrayOfReplaces[i].Length()); |
|
523 buffer=buffer.MidTPtr(0,buffer.Length()-anArrayOfReplaces[i].Length()); |
|
524 break; |
|
525 } |
|
526 } |
|
527 |
|
528 if(buffer.Length() == 0) |
|
529 { |
|
530 break; |
|
531 } |
|
532 |
|
533 if(!flag) |
|
534 { |
|
535 buffer=buffer.MidTPtr(0,buffer.Length()-1); |
|
536 } |
|
537 } |
|
538 |
|
539 } |
|
540 |
|
541 // ----------------------------------------------------------------------------- |
|
542 // NormalizeReturnValue() |
|
543 //Modifies the return value(Number of bytes did not get converted) according to the |
|
544 //replacements done to the iscii buffer before conversion. |
|
545 //Internally calls DoNormalizeReturnValue() by suppling the search and replacement |
|
546 //buffers. |
|
547 |
|
548 // Returns: Nothing |
|
549 // |
|
550 // ----------------------------------------------------------------------------- |
|
551 // |
|
552 |
|
553 LOCAL_C void NormalizeReturnValue(TUint& aReturnValue,const TDesC8& aBuffer) |
|
554 { |
|
555 RArray<TPtrC8> searchBuffer; |
|
556 RArray<TPtrC8> replaceBuffer; |
|
557 |
|
558 searchBuffer.Append(KExplicitHalant().Mid(0)); |
|
559 searchBuffer.Append(KSoftHalant().Mid(0)); |
|
560 searchBuffer.Append(KOm().Mid(0)); |
|
561 searchBuffer.Append(KAvagraha().Mid(0)); |
|
562 |
|
563 searchBuffer.Append(KVocalicRr().Mid(0)); |
|
564 searchBuffer.Append(KVocalicLl().Mid(0)); |
|
565 searchBuffer.Append(KVocalicLSign().Mid(0)); |
|
566 searchBuffer.Append(KVocalicLlSign().Mid(0)); |
|
567 searchBuffer.Append(KVocalicL().Mid(0)); |
|
568 searchBuffer.Append(KVocalicRrSign().Mid(0)); |
|
569 |
|
570 replaceBuffer.Append(KReplacementForExplicitHalant().Mid(0)); |
|
571 replaceBuffer.Append(KReplacementForSoftHalant().Mid(0)); |
|
572 replaceBuffer.Append(KReplacementForOm().Mid(0)); |
|
573 replaceBuffer.Append(KReplacementForAvagraha().Mid(0)); |
|
574 |
|
575 replaceBuffer.Append(KReplacementForVocalicRr().Mid(0)); |
|
576 replaceBuffer.Append(KReplacementForVocalicLl().Mid(0)); |
|
577 replaceBuffer.Append(KReplacementForVocalicLSign().Mid(0)); |
|
578 replaceBuffer.Append(KReplacementForVocalicLlSign().Mid(0)); |
|
579 replaceBuffer.Append(KReplacementForVocalicL().Mid(0)); |
|
580 replaceBuffer.Append(KReplacementForVocalicRrSign().Mid(0)); |
|
581 |
|
582 DoNormalizeReturnValue(aReturnValue,aBuffer,searchBuffer,replaceBuffer); |
|
583 searchBuffer.Reset(); |
|
584 replaceBuffer.Reset(); |
|
585 } |
|
586 |
|
587 // ----------------------------------------------------------------------------- |
|
588 // HandleHomogeneousRun() |
|
589 //Handles a homogeneous foreign buffer and converts the foreign buffer to unicode |
|
590 //On return the aUnicode argument contains the converted unicode data. |
|
591 //Also it sets the return value, returned from the conversion. The return value also |
|
592 //takes into account if there is any buffer modification done before passing it to |
|
593 //CCnvCharacterSetConverter::DoConvertToUnicode() |
|
594 //buffers. |
|
595 |
|
596 // Returns: Nothing |
|
597 // |
|
598 // ----------------------------------------------------------------------------- |
|
599 // |
|
600 |
|
601 LOCAL_C void HandleHomogeneousRun(const SCnvConversionData*& aConversionData, |
|
602 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, |
|
603 TDes16& aUnicode, |
|
604 const TDesC8& aHomogeneousForeign, |
|
605 TInt& aNumberOfUnconvertibleCharacters, |
|
606 TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter, |
|
607 TUint& aOutputConversionFlags, |
|
608 TUint aInputConversionFlags,TInt& aNumberOfForeignBytesConsumed, |
|
609 TInt& aReturnValue) |
|
610 { |
|
611 TInt numberOfUnconvertibleCharacters; |
|
612 TInt indexOfFirstByteOfFirstUnconvertibleCharacter; |
|
613 TUint noOfConsumedBytes = 0; |
|
614 if(aConversionData == NULL) |
|
615 { |
|
616 aReturnValue = CCnvCharacterSetConverter::EErrorIllFormedInput; |
|
617 return; |
|
618 } |
|
619 aReturnValue = CCnvCharacterSetConverter::DoConvertToUnicode(*aConversionData,aDefaultEndiannessOfForeignCharacters, |
|
620 aUnicode,aHomogeneousForeign,numberOfUnconvertibleCharacters, |
|
621 indexOfFirstByteOfFirstUnconvertibleCharacter,aOutputConversionFlags, |
|
622 |
|
623 //The numberOfUnconvertibleCharacters and indexOfFirstByteOfFirstUnconvertibleCharacter are the values with |
|
624 //respect to the intermediate iscii buffer and original values aIndexOfFirstByteOfFirstUnconvertibleCharacter and |
|
625 //aNumberOfUnconvertibleCharacters need to be adjusted accordingly. |
|
626 |
|
627 aInputConversionFlags); |
|
628 if(numberOfUnconvertibleCharacters>0) |
|
629 { |
|
630 if(aNumberOfUnconvertibleCharacters == 0) |
|
631 { |
|
632 aIndexOfFirstByteOfFirstUnconvertibleCharacter = aNumberOfForeignBytesConsumed + indexOfFirstByteOfFirstUnconvertibleCharacter; |
|
633 } |
|
634 aNumberOfUnconvertibleCharacters+=numberOfUnconvertibleCharacters; |
|
635 } |
|
636 noOfConsumedBytes = aHomogeneousForeign.Length(); |
|
637 //To Check whether it is really required. |
|
638 NormalizeReturnValue(noOfConsumedBytes,aHomogeneousForeign); |
|
639 aNumberOfForeignBytesConsumed+=noOfConsumedBytes; |
|
640 if(aReturnValue>0) |
|
641 { |
|
642 TUint normalizedReturnValue = aReturnValue; |
|
643 |
|
644 //There original iscii buffer copied to an intermediate iscii buffer and then modified |
|
645 //and is then passed for conversion. Now, after conversion, the return value needs to |
|
646 //be adjusted according to the original buffer. NormalizeReturnValue() does the |
|
647 //same thing. |
|
648 |
|
649 NormalizeReturnValue(normalizedReturnValue,aHomogeneousForeign); |
|
650 aNumberOfForeignBytesConsumed-=normalizedReturnValue; |
|
651 aReturnValue=normalizedReturnValue; |
|
652 } |
|
653 |
|
654 //The HandleHomogeneousRun() method is called in a loop and once there is some |
|
655 //iscii codes converted to unicode, the ConvertToUnicode() should not return |
|
656 //CCnvCharacterSetConverter::EErrorIllFormedInput even though the conversion |
|
657 //method does not convert any of the iscii codes ppassed. To ensure that once the |
|
658 //first non-zero number of iscii codes are converted, the internal input conversion |
|
659 //flag is set to EInputConversionFlagAllowTruncatedInputNotEvenPartlyConsumable. |
|
660 |
|
661 if(aNumberOfForeignBytesConsumed>0) |
|
662 { |
|
663 aInputConversionFlags|=CCnvCharacterSetConverter::EInputConversionFlagAllowTruncatedInputNotEvenPartlyConsumable; |
|
664 } |
|
665 return; |
|
666 } |
|
667 |
|
668 // ----------------------------------------------------------------------------- |
|
669 // IsTruncatedDoubleByteIsciiSequence() |
|
670 //Checks if anIsciiBuffer is a part of multi byte iscii sequence truncated in the middle. |
|
671 //If it is a truncated sequence, then returns ETrue else returns EFalse. |
|
672 // |
|
673 // Returns: ETrue: If the intermediate input iscii buffer is truncated |
|
674 // EFalse: If the intermediate input iscii buffer is not truncated |
|
675 // |
|
676 // ----------------------------------------------------------------------------- |
|
677 // |
|
678 |
|
679 LOCAL_C TBool IsTruncatedDoubleByteIsciiSequence(const TDesC8& anIsciiBuffer) |
|
680 { |
|
681 RArray<TPtrC8> searchBuffer; |
|
682 if(anIsciiBuffer.Length () == 0) |
|
683 return EFalse; |
|
684 if(anIsciiBuffer[anIsciiBuffer.Length()-1] == 0xEF) |
|
685 return ETrue; |
|
686 searchBuffer.Append(KSoftHalant().Mid(0)); |
|
687 searchBuffer.Append(KOm().Mid(0)); |
|
688 searchBuffer.Append(KAvagraha().Mid(0)); |
|
689 searchBuffer.Append(KExplicitHalant().Mid(0)); |
|
690 TBool ret = EFalse; |
|
691 TBool isNotTruncated =EFalse; |
|
692 |
|
693 //First check if the intermediate iscii buffer is ending with a complete multi byte sequence. |
|
694 //If it ends with a complete multi byte sequence, no need to check if the last character of |
|
695 //intermediate iscii is same as first character of multi byte iscii sequence. And return EFalse. |
|
696 for(TUint counter = 0;counter<searchBuffer.Count();counter++) |
|
697 { |
|
698 if(searchBuffer[counter].Compare(anIsciiBuffer.Right(searchBuffer[counter].Length())) == 0) |
|
699 { |
|
700 isNotTruncated = ETrue; |
|
701 break; |
|
702 } |
|
703 } |
|
704 //If the intermediate iscii buffer is not ending with a complete multi byte sequence, and the |
|
705 //last code of the iscii buffer is a part of the multibyte sequence, then the iscii buffer is a |
|
706 //truncated sequence and in that case return ETrue. |
|
707 |
|
708 for(TUint counter = 0;counter<searchBuffer.Count();counter++) |
|
709 { |
|
710 if(isNotTruncated) |
|
711 break; |
|
712 else if( (anIsciiBuffer[anIsciiBuffer.Length()-1] == searchBuffer[counter][0])) |
|
713 { |
|
714 ret =ETrue; |
|
715 break; |
|
716 } |
|
717 } |
|
718 searchBuffer.Reset(); |
|
719 return ret; |
|
720 } |
|
721 |
|
722 // ----------------------------------------------------------------------------- |
|
723 // ReplacementForUnconvertibleUnicodeCharacters() |
|
724 //Returns the replacement character for unconvertible unicode character. |
|
725 //In the current implementation it is 0x1a (ASCII Substitute character) |
|
726 //The default implementation calls ReplacementForUnconvertibleUnicodeCharacters_internal() |
|
727 //in turn which is generated by cnvtool. |
|
728 // |
|
729 // Returns: Replacemt for unconvertible unicode characters (0x1a) |
|
730 // |
|
731 // ----------------------------------------------------------------------------- |
|
732 // |
|
733 |
|
734 const TDesC8& CIsciiImplementation::ReplacementForUnconvertibleUnicodeCharacters() |
|
735 { |
|
736 return ReplacementForUnconvertibleUnicodeCharacters_internal(); |
|
737 } |
|
738 |
|
739 // ----------------------------------------------------------------------------- |
|
740 // ConvertFromUnicode() |
|
741 //The main conversion function for converting from unicode to iscii |
|
742 //Loaded and called by the character conversion framework. |
|
743 //In turn calls CnvUtilities::ConvertFromUnicode() which is Symbian provide |
|
744 //utility method for converting unicode to modal character codes. |
|
745 // |
|
746 // Returns: The numbet of unicode codes it could not convert. |
|
747 // |
|
748 // ----------------------------------------------------------------------------- |
|
749 // |
|
750 |
|
751 TInt CIsciiImplementation::ConvertFromUnicode( |
|
752 CCnvCharacterSetConverter::TEndianness |
|
753 aDefaultEndiannessOfForeignCharacters, |
|
754 const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, |
|
755 TDes8& aForeign, |
|
756 const TDesC16& aUnicode, |
|
757 CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters ) |
|
758 { |
|
759 TFixedArray<CnvUtilities::SCharacterSet,KNumberOfIndicCharactersetsSupported> aArrayOfCharacterSets; |
|
760 aArrayOfCharacterSets[0].iConversionData = &conversionData; |
|
761 aArrayOfCharacterSets[0].iConvertFromIntermediateBufferInPlace = ConvertFromUnicodeIntermediateBufferInPlace; |
|
762 aArrayOfCharacterSets[0].iEscapeSequence = &KEscapeSequenceDevanagari(); |
|
763 |
|
764 return CnvUtilities::ConvertFromUnicode( |
|
765 aDefaultEndiannessOfForeignCharacters, |
|
766 aReplacementForUnconvertibleUnicodeCharacters, |
|
767 aForeign, |
|
768 aUnicode, |
|
769 aIndicesOfUnconvertibleCharacters, |
|
770 aArrayOfCharacterSets.Array()); |
|
771 } |
|
772 |
|
773 // ----------------------------------------------------------------------------- |
|
774 // ConvertToUnicode() |
|
775 //The main conversion function for converting from iscii to unicode |
|
776 //Loaded and called by the character conversion framework. |
|
777 //To support some of the iscii characters, the input forign buffer is |
|
778 //copied to an intermediate buffer and then is then modified and |
|
779 //CCnvCharactersetConverter::DoConvertToUnicode() is called with |
|
780 //the modified buffer. For extensibility of iscii to other Indic languages |
|
781 //it uses CnvUtilities::SState datastructure. CnvUtilities::SState is a |
|
782 //Symbian defined class for modal charactersets. The escape sequence |
|
783 //is specified to ATR followed by the script selection code and the conversion |
|
784 //data is specified to be the conversion for the particular script. For the time |
|
785 //being only Devanagari with script selection code 0x42 is supported. If |
|
786 //any of the other script codes are used the conversion leads to unconvertible |
|
787 //character i.e. 0xFFFD. |
|
788 // Returns: The numbet of iscii codes it could not convert. |
|
789 // |
|
790 // ----------------------------------------------------------------------------- |
|
791 // |
|
792 |
|
793 TInt CIsciiImplementation::ConvertToUnicode( |
|
794 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, |
|
795 TDes16& aUnicode, |
|
796 const TDesC8& aForeign, |
|
797 TInt& aState, |
|
798 TInt& aNumberOfUnconvertibleCharacters, |
|
799 TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter ) |
|
800 { |
|
801 aNumberOfUnconvertibleCharacters = 0; |
|
802 TUint aOutputConversionFlags = CCnvCharacterSetConverter::KStateDefault; |
|
803 aIndexOfFirstByteOfFirstUnconvertibleCharacter=-1; |
|
804 TUint internalInputConversionFlags = 0; |
|
805 TInt numberOfForeignBytesConsumed=0; |
|
806 TPtrC8 remainderOfForeign(aForeign); |
|
807 TInt returnValue; |
|
808 TBool flag = EFalse; |
|
809 TBool isSkipMatchSequence = EFalse; |
|
810 const SCnvConversionData* convData; |
|
811 //Set the iscii conversion data and escape sequence for Devanagari. |
|
812 TFixedArray<CnvUtilities::SState,KNumberOfIndicCharactersetsSupported> modals; |
|
813 modals[0].iConversionData = &conversionData; |
|
814 modals[0].iEscapeSequence = &KEscapeSequenceDevanagari(); |
|
815 |
|
816 aUnicode.SetLength(0); |
|
817 |
|
818 //The internal input conversion flag for conversion is set to CCnvCharacterSetConverter::EInputConversionFlagAppend |
|
819 //so that for each conversion in the conversion loop, the generated conversion buffer is appened to the aUnicode buffer. |
|
820 internalInputConversionFlags |= CCnvCharacterSetConverter::EInputConversionFlagAppend; |
|
821 if (aForeign.Length()==0) |
|
822 { |
|
823 return 0; |
|
824 } |
|
825 //Get the conversion data from the previous call else the conversion data is set to the default |
|
826 //conversion data, i.e. Devanagari. |
|
827 convData=(aState!=CCnvCharacterSetConverter::KStateDefault)? REINTERPRET_CAST(const SCnvConversionData*, aState): modals[0].iConversionData; |
|
828 FOREVER |
|
829 { |
|
830 TBuf8<KMaximumLengthOfIntermediateBuffer> intermediateBuffer; |
|
831 TUint numberOfForeignBytesConsumedThisTime = 0; |
|
832 if((remainderOfForeign.Length() >=KMaximumLengthOfIntermediateBuffer) && (aUnicode.MaxLength()-aUnicode.Length() >=KMaximumLengthOfIntermediateBuffer)) |
|
833 { |
|
834 numberOfForeignBytesConsumedThisTime = KMaximumLengthOfIntermediateBuffer; |
|
835 intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime); |
|
836 //If the intermediate buffer is a part of truncated buffer sequence but the |
|
837 //actual input buffer is not truncated then truncated sequence is not converted. |
|
838 //The intermediate buffer is modified so as not to contain the truncated sequence. |
|
839 |
|
840 flag = IsTruncatedDoubleByteIsciiSequence(intermediateBuffer); |
|
841 if(flag) |
|
842 { |
|
843 numberOfForeignBytesConsumedThisTime --; |
|
844 intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime); |
|
845 } |
|
846 |
|
847 } |
|
848 else |
|
849 { |
|
850 flag = IsTruncatedDoubleByteIsciiSequence(remainderOfForeign.Left(aUnicode.MaxLength()-aUnicode.Length())); |
|
851 if(!flag) |
|
852 { |
|
853 numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length(); |
|
854 intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime); |
|
855 } |
|
856 else |
|
857 { |
|
858 if(aForeign.Length()>(numberOfForeignBytesConsumed+aUnicode.Length())) |
|
859 { |
|
860 numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length()-1; |
|
861 intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime); |
|
862 break; |
|
863 } |
|
864 else |
|
865 { |
|
866 numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length(); |
|
867 intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime); |
|
868 } |
|
869 } |
|
870 } |
|
871 |
|
872 //The input intermediate iscii buffer is modified with the search and replace |
|
873 //buffers. It is required for supporting multibyte iscii sequences. |
|
874 FindAndModifyBuffer(intermediateBuffer); |
|
875 TPtrC8 remainderOfForeignInternal(intermediateBuffer); |
|
876 TPtrC8 homogeneousRun; |
|
877 const TInt startOfNextEscapeSequence=intermediateBuffer.Locate(KControlCharacterEscape); |
|
878 if (startOfNextEscapeSequence!=0) |
|
879 { |
|
880 if (startOfNextEscapeSequence==KErrNotFound) |
|
881 { |
|
882 homogeneousRun.Set(remainderOfForeignInternal); |
|
883 remainderOfForeignInternal.Set(NULL, 0); |
|
884 } |
|
885 else |
|
886 { |
|
887 __ASSERT_DEBUG(startOfNextEscapeSequence>0, User::Panic(KPanicReason,EPanicBadStartOfNextEscapeSequence)); |
|
888 homogeneousRun.Set(remainderOfForeignInternal.Left(startOfNextEscapeSequence)); |
|
889 remainderOfForeignInternal.Set(remainderOfForeignInternal.Mid(startOfNextEscapeSequence)); |
|
890 } |
|
891 isSkipMatchSequence = ETrue; |
|
892 } |
|
893 FOREVER |
|
894 { |
|
895 if(!isSkipMatchSequence) |
|
896 { |
|
897 if (!NextHomogeneousForeignRun(convData, numberOfForeignBytesConsumed, homogeneousRun, |
|
898 remainderOfForeignInternal, modals.Array(), aOutputConversionFlags)) |
|
899 { |
|
900 break; |
|
901 } |
|
902 } |
|
903 HandleHomogeneousRun( convData, aDefaultEndiannessOfForeignCharacters, aUnicode, homogeneousRun, aNumberOfUnconvertibleCharacters, |
|
904 aIndexOfFirstByteOfFirstUnconvertibleCharacter,aOutputConversionFlags,internalInputConversionFlags, |
|
905 numberOfForeignBytesConsumed,returnValue); |
|
906 if(returnValue<0) |
|
907 { |
|
908 return returnValue; |
|
909 } |
|
910 isSkipMatchSequence = EFalse; |
|
911 } |
|
912 if(returnValue > 0) |
|
913 break; |
|
914 if ((!flag && (numberOfForeignBytesConsumedThisTime != KMaximumLengthOfIntermediateBuffer)) || (flag && (numberOfForeignBytesConsumedThisTime != (KMaximumLengthOfIntermediateBuffer-1) ))) |
|
915 break; |
|
916 remainderOfForeign.Set(aForeign.Mid(numberOfForeignBytesConsumed)); |
|
917 } |
|
918 //If the number of iscii bytes consumed by the conversion is zero also the output conversion |
|
919 //flag is not set to EOutputConversionFlagInputIsTruncated, then return EErrorIllFormedInput. |
|
920 if ((numberOfForeignBytesConsumed==0) && (aOutputConversionFlags&CCnvCharacterSetConverter::EOutputConversionFlagInputIsTruncated)) |
|
921 { |
|
922 return CCnvCharacterSetConverter::EErrorIllFormedInput; |
|
923 } |
|
924 //Set the conversion data sothat next time when ConvertToUnicode() is called, |
|
925 //will use the previous conversion data. |
|
926 aState=REINTERPRET_CAST(TInt, convData); |
|
927 return aForeign.Length()-numberOfForeignBytesConsumed; |
|
928 } |
|
929 |
|
930 // ----------------------------------------------------------------------------- |
|
931 // IsInThisCharacterSetL() |
|
932 //The method tells how probable it is that a sample piece of text is encoded in this character set. |
|
933 //On return aConfidenceLevel, indicates how confident the function is about its return value. For |
|
934 //iscii it is the default implementation and it does not implement the autodetect functionality. |
|
935 //Loaded and called by the character conversion framework. |
|
936 // |
|
937 // Returns: EFalse: To tell CCnvCharacterSetConverter::AutoDetectCharacterSetL() that the plug-in DLL |
|
938 // is not implementing a function of this signature and is therefore empty. |
|
939 // |
|
940 // ----------------------------------------------------------------------------- |
|
941 // |
|
942 |
|
943 |
|
944 //Default implementation for IsInThisCharacterSetL() |
|
945 |
|
946 TBool CIsciiImplementation::IsInThisCharacterSetL( |
|
947 TBool& aSetToTrue, |
|
948 TInt& aConfidenceLevel, |
|
949 const TDesC8& ) |
|
950 { |
|
951 aSetToTrue = EFalse; |
|
952 aConfidenceLevel = 0; |
|
953 return EFalse; |
|
954 } |
|
955 |
|
956 // ----------------------------------------------------------------------------- |
|
957 // NewL() |
|
958 //Factory function for CIsciiImplementation(). Instantiates a CIsciiImplementation object on heap |
|
959 //and returns the pointer to it. |
|
960 // |
|
961 // Returns: CIsciiImplementation* |
|
962 // |
|
963 // ----------------------------------------------------------------------------- |
|
964 // |
|
965 |
|
966 CIsciiImplementation* CIsciiImplementation::NewL() |
|
967 { |
|
968 CIsciiImplementation* self = new(ELeave) CIsciiImplementation; |
|
969 return self; |
|
970 } |
|
971 |
|
972 // ----------------------------------------------------------------------------- |
|
973 // CIsciiImplementation() |
|
974 //default constructor, does nothing |
|
975 // |
|
976 // Returns: Nothing |
|
977 // |
|
978 // ----------------------------------------------------------------------------- |
|
979 // |
|
980 CIsciiImplementation::CIsciiImplementation() |
|
981 { |
|
982 } |
|
983 |
|
984 // ----------------------------------------------------------------------------- |
|
985 // ~CIsciiImplementation() |
|
986 //default desstructor, does nothing |
|
987 // |
|
988 // Returns: Nothing |
|
989 // |
|
990 // ----------------------------------------------------------------------------- |
|
991 // |
|
992 |
|
993 CIsciiImplementation::~CIsciiImplementation() |
|
994 { |
|
995 } |
|
996 |
|
997 // ECOM CREATION FUNCTION |
|
998 const TImplementationProxy ImplementationTable[] = |
|
999 { |
|
1000 // Used also in 0x1027508E.rss ( implementation_uid ) |
|
1001 IMPLEMENTATION_PROXY_ENTRY( 0x1027508E, CIsciiImplementation::NewL ) |
|
1002 }; |
|
1003 |
|
1004 // ----------------------------------------------------------------------------- |
|
1005 // ImplementationGroupProxy() |
|
1006 //Returns a pointer to TImplementationProxy object which contains the implementation uid vs factory |
|
1007 //function table. Also on return sets the aTableCount to the number of entries in the table. |
|
1008 // |
|
1009 // Returns: TImplementationProxy* |
|
1010 // |
|
1011 // ----------------------------------------------------------------------------- |
|
1012 // |
|
1013 EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount ) |
|
1014 { |
|
1015 aTableCount = sizeof( ImplementationTable ) / sizeof(TImplementationProxy); |
|
1016 return ImplementationTable; |
|
1017 } |
|
1018 #else |
|
1019 |
|
1020 #include <convplug.h> |
|
1021 |
|
1022 #ifndef EKA2 |
|
1023 // ----------------------------------------------------------------------------- |
|
1024 // E32Dll() |
|
1025 //For EKA1 this is the entry point for the DLL. |
|
1026 // |
|
1027 // Returns: KErrNone |
|
1028 // |
|
1029 // ----------------------------------------------------------------------------- |
|
1030 // |
|
1031 GLDEF_C TInt E32Dll(TDllReason) |
|
1032 { |
|
1033 return KErrNone; |
|
1034 } |
|
1035 #endif |
|
1036 |
|
1037 //Checks if a descriptor starts with another descriptor at the begining. |
|
1038 LOCAL_C TBool IsStartOf(const TDesC8& aEscapeSequence, const TDesC8& aBuffer) |
|
1039 { |
|
1040 const TInt lengthOfStart=aEscapeSequence.Length(); |
|
1041 return (aBuffer.Length()>=lengthOfStart) && (aBuffer.Left(lengthOfStart)==aEscapeSequence); |
|
1042 } |
|
1043 // ----------------------------------------------------------------------------- |
|
1044 // MatchesEscapeSequence() |
|
1045 //If the remainder of the foreign text starts with the passed escapesequence, modifies the remainder of the foreign text |
|
1046 //and sets the homogeneous run buffer that uses the same conversion data. |
|
1047 //The homogeneous run buffer is the buffer that will use a single conversion data, it doesn't contain the attribute code |
|
1048 // neither it contains the script switching code. |
|
1049 //The aRemainderOfForeign buffer |
|
1050 |
|
1051 // Returns: ETrue: If the sequence contains the escape sequence |
|
1052 // EFalse: If the sequence does not contain the escape sequence |
|
1053 // |
|
1054 // ----------------------------------------------------------------------------- |
|
1055 // |
|
1056 LOCAL_C TBool MatchesEscapeSequence(TInt& aNumberOfForeignBytesConsumed, TPtrC8& aHomogeneousRun, |
|
1057 TPtrC8& aRemainderOfForeign, const TDesC8& aEscapeSequence) |
|
1058 { |
|
1059 const TInt lengthOfEscapeSequence=aEscapeSequence.Length(); |
|
1060 if (IsStartOf(aEscapeSequence, aRemainderOfForeign)) |
|
1061 { |
|
1062 aRemainderOfForeign.Set(aRemainderOfForeign.Mid(lengthOfEscapeSequence)); |
|
1063 const TInt startOfNextEscapeSequence=aRemainderOfForeign.Locate(KControlCharacterEscape); |
|
1064 if (startOfNextEscapeSequence==KErrNotFound) |
|
1065 { |
|
1066 aHomogeneousRun.Set(aRemainderOfForeign); |
|
1067 aRemainderOfForeign.Set(NULL, 0); |
|
1068 } |
|
1069 else |
|
1070 { |
|
1071 aHomogeneousRun.Set(aRemainderOfForeign.Left(startOfNextEscapeSequence)); |
|
1072 aRemainderOfForeign.Set(aRemainderOfForeign.Mid(startOfNextEscapeSequence)); |
|
1073 } |
|
1074 aNumberOfForeignBytesConsumed+=lengthOfEscapeSequence; |
|
1075 return ETrue; |
|
1076 } |
|
1077 return EFalse; |
|
1078 } |
|
1079 |
|
1080 // ----------------------------------------------------------------------------- |
|
1081 // NextHomogeneousForeignRun() |
|
1082 //Matches the escape sequence of each of the elements of the SState array with the remainder of |
|
1083 //foreign text and if the escape sequence matches with the start of remainder of the foreign text, |
|
1084 //then the conversion data is set to the conversion data corresponding to the escape sequence |
|
1085 //Also the homogeneous foreign text for conversion with the same escape sequence is set. |
|
1086 |
|
1087 // Returns: ETrue: If length of the remainder of foreign buffer is nonzero. |
|
1088 // EFalse: If length of the remainder of foreign buffer is zero. |
|
1089 // |
|
1090 // ----------------------------------------------------------------------------- |
|
1091 // |
|
1092 |
|
1093 |
|
1094 LOCAL_C TBool NextHomogeneousForeignRun(const SCnvConversionData*& aConversionData, TInt& aNumberOfForeignBytesConsumed, TPtrC8& aHomogeneousRun, TPtrC8& aRemainderOfForeign, const TArray<CnvUtilities::SState>& aArrayOfStates, TUint& aOutputConversionFlags) |
|
1095 { |
|
1096 TBool returnValue = EFalse; |
|
1097 TBool foundState = EFalse; |
|
1098 __ASSERT_DEBUG((aRemainderOfForeign.Length()==0) || (aRemainderOfForeign[0]==KControlCharacterEscape), User::Panic(KPanicReason,EPanicBadRemainderOfForeign)); |
|
1099 if (aRemainderOfForeign.Length()==0) |
|
1100 { |
|
1101 return returnValue; |
|
1102 } |
|
1103 const TInt numberOfStates=aArrayOfStates.Count(); |
|
1104 TInt i; |
|
1105 for (i=0; i<numberOfStates; ++i) |
|
1106 { |
|
1107 const CnvUtilities::SState& state=aArrayOfStates[i]; |
|
1108 if (MatchesEscapeSequence(aNumberOfForeignBytesConsumed, aHomogeneousRun, aRemainderOfForeign, *state.iEscapeSequence)) |
|
1109 { |
|
1110 aConversionData=state.iConversionData; |
|
1111 foundState = ETrue; |
|
1112 } |
|
1113 } |
|
1114 if(!foundState) |
|
1115 { |
|
1116 for (i=0; i<numberOfStates; ++i) |
|
1117 { |
|
1118 if (IsStartOf(aRemainderOfForeign, *aArrayOfStates[i].iEscapeSequence)) |
|
1119 { |
|
1120 // aRemainderOfForeign ends with a truncated escape sequence, so ConvertToUnicode cannot convert any more |
|
1121 aOutputConversionFlags|=CCnvCharacterSetConverter::EOutputConversionFlagInputIsTruncated; |
|
1122 break; |
|
1123 } |
|
1124 } |
|
1125 |
|
1126 MatchesEscapeSequence(aNumberOfForeignBytesConsumed,aHomogeneousRun,aRemainderOfForeign,aRemainderOfForeign.Left(2)); |
|
1127 aConversionData = &conversionDataDummy; |
|
1128 returnValue = ETrue; |
|
1129 } |
|
1130 if (aHomogeneousRun.Length()>0) |
|
1131 { |
|
1132 returnValue = ETrue; |
|
1133 } |
|
1134 return returnValue; |
|
1135 } |
|
1136 // ----------------------------------------------------------------------------- |
|
1137 // ConvertFromUnicodeIntermediateBufferInPlace() |
|
1138 //Default implementation for conversion to the intermediate buffer |
|
1139 //It modifies the unicode buffer before it is converted back to iscii. |
|
1140 //The current implementation of iscii plug-in doesn't require any |
|
1141 //modification to the default implementation |
|
1142 // Returns: Nothing |
|
1143 // |
|
1144 // ----------------------------------------------------------------------------- |
|
1145 // |
|
1146 |
|
1147 |
|
1148 LOCAL_C void ConvertFromUnicodeIntermediateBufferInPlace(TInt aStartPositionInDescriptor, TDes8& aDescriptor, TInt& aNumberOfCharactersThatDroppedOut) |
|
1149 { |
|
1150 CnvUtilities::ConvertFromIntermediateBufferInPlace(aStartPositionInDescriptor, aDescriptor, aNumberOfCharactersThatDroppedOut, KEscapeSequenceDevanagari, 1); |
|
1151 } |
|
1152 |
|
1153 // ----------------------------------------------------------------------------- |
|
1154 // DoFindAndModifyBuffer() |
|
1155 //Modifies the iscii buffer by replacing the search buffer with the replacement buffer. |
|
1156 //Introduced for handling multibyte iscii sequence. |
|
1157 //Takes the search buffer array and the replacement buffer arrays as input to it and replaces all |
|
1158 //the occurances of the search buffer with the corresponding replace buffer. |
|
1159 // Returns: Nothing |
|
1160 // |
|
1161 // ----------------------------------------------------------------------------- |
|
1162 // |
|
1163 |
|
1164 LOCAL_C void DoFindAndModifyBuffer(TDes8& aModifyBuffer,const TDesC8& aSearchBuffer,const TDesC8& aReplaceBuffer) |
|
1165 { |
|
1166 FOREVER |
|
1167 { |
|
1168 TInt offset; |
|
1169 __ASSERT_ALWAYS((aSearchBuffer.Length()>= aReplaceBuffer.Length()),User::Panic(KPanicReason,EPanicBadReplacementBuffer)); |
|
1170 if((offset = aModifyBuffer.Find(aSearchBuffer)) != KErrNotFound) |
|
1171 { |
|
1172 TUint8 *pointerToBuffer = const_cast<TUint8*> (aModifyBuffer.Ptr()); |
|
1173 Mem::Copy(pointerToBuffer+offset,aReplaceBuffer.Ptr(),aReplaceBuffer.Length()); |
|
1174 Mem::Copy(pointerToBuffer+offset+aReplaceBuffer.Length(),pointerToBuffer+offset+aSearchBuffer.Length(),aModifyBuffer.Length()-aSearchBuffer.Length()-offset); |
|
1175 aModifyBuffer.SetLength(aModifyBuffer.Length() - aSearchBuffer.Length() + aReplaceBuffer.Length()); |
|
1176 } |
|
1177 else |
|
1178 break; |
|
1179 } |
|
1180 |
|
1181 } |
|
1182 |
|
1183 // ----------------------------------------------------------------------------- |
|
1184 // FindAndModifyBuffer() |
|
1185 //Modifies the iscii buffer by replacing the search buffer with the replacement buffer. |
|
1186 //Calls DoFindAndModifyBuffer() and supplies the search buffer and replacement buffer. |
|
1187 //Introduced for handling multibyte iscii sequence. |
|
1188 // Returns: Nothing |
|
1189 // |
|
1190 // ----------------------------------------------------------------------------- |
|
1191 // |
|
1192 |
|
1193 LOCAL_C void FindAndModifyBuffer(TDes8& aModifyBuffer) |
|
1194 { |
|
1195 RArray<TPtrC8> searchBuffer; |
|
1196 RArray<TPtrC8> replaceBuffer; |
|
1197 |
|
1198 searchBuffer.Append(KExplicitHalant().Mid(0)); |
|
1199 searchBuffer.Append(KSoftHalant().Mid(0)); |
|
1200 searchBuffer.Append(KOm().Mid(0)); |
|
1201 searchBuffer.Append(KAvagraha().Mid(0)); |
|
1202 |
|
1203 replaceBuffer.Append(KReplacementForExplicitHalant().Mid(0)); |
|
1204 replaceBuffer.Append(KReplacementForSoftHalant().Mid(0)); |
|
1205 replaceBuffer.Append(KReplacementForOm().Mid(0)); |
|
1206 replaceBuffer.Append(KReplacementForAvagraha().Mid(0)); |
|
1207 |
|
1208 for(TInt counter=0;counter<searchBuffer.Count();counter++) |
|
1209 { |
|
1210 DoFindAndModifyBuffer(aModifyBuffer,searchBuffer[counter],replaceBuffer[counter]); |
|
1211 } |
|
1212 searchBuffer.Reset(); |
|
1213 replaceBuffer.Reset(); |
|
1214 |
|
1215 } |
|
1216 |
|
1217 // ----------------------------------------------------------------------------- |
|
1218 // DoNormalizeReturnValue() |
|
1219 //Modifies the return value(Number of bytes did not get converted) according to the modified |
|
1220 //intermediate buffer. Takes the modified intermediate buffer, return value, search and replace |
|
1221 //buffers. Searches for the replace buffer in the intermediate buffer and if found, it looks for |
|
1222 //the actual buffer corresponding to the replace buffer and adds the difference of the lengths |
|
1223 //of the actual to replace buffer to the return value. |
|
1224 // Returns: Nothing |
|
1225 // |
|
1226 // ----------------------------------------------------------------------------- |
|
1227 // |
|
1228 |
|
1229 LOCAL_C void DoNormalizeReturnValue(TUint& aReturnValue,const TDesC8& aBuffer,RArray<TPtrC8>& anArrayOfSearches,RArray<TPtrC8>& anArrayOfReplaces) |
|
1230 { |
|
1231 TPtr8 buffer(const_cast<TUint8*>(aBuffer.Ptr()),aBuffer.Length(),aBuffer.Length()); |
|
1232 TUint count = anArrayOfSearches.Count(); |
|
1233 FOREVER |
|
1234 { |
|
1235 TBool flag = EFalse; |
|
1236 for(TUint i=0;i<count;i++) |
|
1237 { |
|
1238 TPtrC8 searchBufferForComparison(buffer.Right(anArrayOfReplaces[i].Length())); |
|
1239 TInt returnCompare = searchBufferForComparison.Compare(anArrayOfReplaces[i]); |
|
1240 if(returnCompare == 0) |
|
1241 { |
|
1242 flag =ETrue; |
|
1243 aReturnValue += (anArrayOfSearches[i].Length() - anArrayOfReplaces[i].Length()); |
|
1244 buffer=buffer.MidTPtr(0,buffer.Length()-anArrayOfReplaces[i].Length()); |
|
1245 break; |
|
1246 } |
|
1247 } |
|
1248 |
|
1249 if(buffer.Length() == 0) |
|
1250 { |
|
1251 break; |
|
1252 } |
|
1253 |
|
1254 if(!flag) |
|
1255 { |
|
1256 buffer=buffer.MidTPtr(0,buffer.Length()-1); |
|
1257 } |
|
1258 } |
|
1259 |
|
1260 } |
|
1261 |
|
1262 // ----------------------------------------------------------------------------- |
|
1263 // NormalizeReturnValue() |
|
1264 //Modifies the return value(Number of bytes did not get converted) according to the |
|
1265 //replacements done to the iscii buffer before conversion. |
|
1266 //Internally calls DoNormalizeReturnValue() by suppling the search and replacement |
|
1267 //buffers. |
|
1268 |
|
1269 // Returns: Nothing |
|
1270 // |
|
1271 // ----------------------------------------------------------------------------- |
|
1272 // |
|
1273 |
|
1274 LOCAL_C void NormalizeReturnValue(TUint& aReturnValue,const TDesC8& aBuffer) |
|
1275 { |
|
1276 RArray<TPtrC8> searchBuffer; |
|
1277 RArray<TPtrC8> replaceBuffer; |
|
1278 |
|
1279 searchBuffer.Append(KExplicitHalant().Mid(0)); |
|
1280 searchBuffer.Append(KSoftHalant().Mid(0)); |
|
1281 searchBuffer.Append(KOm().Mid(0)); |
|
1282 searchBuffer.Append(KAvagraha().Mid(0)); |
|
1283 |
|
1284 replaceBuffer.Append(KReplacementForExplicitHalant().Mid(0)); |
|
1285 replaceBuffer.Append(KReplacementForSoftHalant().Mid(0)); |
|
1286 replaceBuffer.Append(KReplacementForOm().Mid(0)); |
|
1287 replaceBuffer.Append(KReplacementForAvagraha().Mid(0)); |
|
1288 DoNormalizeReturnValue(aReturnValue,aBuffer,searchBuffer,replaceBuffer); |
|
1289 searchBuffer.Reset(); |
|
1290 replaceBuffer.Reset(); |
|
1291 } |
|
1292 |
|
1293 // ----------------------------------------------------------------------------- |
|
1294 // HandleHomogeneousRun() |
|
1295 //Handles a homogeneous foreign buffer and converts the foreign buffer to unicode |
|
1296 //On return the aUnicode argument contains the converted unicode data. |
|
1297 //Also it sets the return value, returned from the conversion. The return value also |
|
1298 //takes into account if there is any buffer modification done before passing it to |
|
1299 //CCnvCharacterSetConverter::DoConvertToUnicode() |
|
1300 //buffers. |
|
1301 |
|
1302 // Returns: Nothing |
|
1303 // |
|
1304 // ----------------------------------------------------------------------------- |
|
1305 // |
|
1306 |
|
1307 LOCAL_C void HandleHomogeneousRun(const SCnvConversionData*& aConversionData, |
|
1308 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, |
|
1309 TDes16& aUnicode, |
|
1310 const TDesC8& aHomogeneousForeign, |
|
1311 TInt& aNumberOfUnconvertibleCharacters, |
|
1312 TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter, |
|
1313 TUint& aOutputConversionFlags, |
|
1314 TUint aInputConversionFlags,TInt& aNumberOfForeignBytesConsumed, |
|
1315 TInt& aReturnValue) |
|
1316 { |
|
1317 TInt numberOfUnconvertibleCharacters; |
|
1318 TInt indexOfFirstByteOfFirstUnconvertibleCharacter; |
|
1319 TUint noOfConsumedBytes = 0; |
|
1320 if(aConversionData == NULL) |
|
1321 { |
|
1322 aReturnValue = CCnvCharacterSetConverter::EErrorIllFormedInput; |
|
1323 return; |
|
1324 } |
|
1325 aReturnValue = CCnvCharacterSetConverter::DoConvertToUnicode(*aConversionData,aDefaultEndiannessOfForeignCharacters, |
|
1326 aUnicode,aHomogeneousForeign,numberOfUnconvertibleCharacters, |
|
1327 indexOfFirstByteOfFirstUnconvertibleCharacter,aOutputConversionFlags, |
|
1328 |
|
1329 //The numberOfUnconvertibleCharacters and indexOfFirstByteOfFirstUnconvertibleCharacter are the values with |
|
1330 //respect to the intermediate iscii buffer and original values aIndexOfFirstByteOfFirstUnconvertibleCharacter and |
|
1331 //aNumberOfUnconvertibleCharacters need to be adjusted accordingly. |
|
1332 |
|
1333 aInputConversionFlags); |
|
1334 if(numberOfUnconvertibleCharacters>0) |
|
1335 { |
|
1336 if(aNumberOfUnconvertibleCharacters == 0) |
|
1337 { |
|
1338 aIndexOfFirstByteOfFirstUnconvertibleCharacter = aNumberOfForeignBytesConsumed + indexOfFirstByteOfFirstUnconvertibleCharacter; |
|
1339 } |
|
1340 aNumberOfUnconvertibleCharacters+=numberOfUnconvertibleCharacters; |
|
1341 } |
|
1342 noOfConsumedBytes = aHomogeneousForeign.Length(); |
|
1343 //To Check whether it is really required. |
|
1344 NormalizeReturnValue(noOfConsumedBytes,aHomogeneousForeign); |
|
1345 aNumberOfForeignBytesConsumed+=noOfConsumedBytes; |
|
1346 if(aReturnValue>0) |
|
1347 { |
|
1348 TUint normalizedReturnValue = aReturnValue; |
|
1349 |
|
1350 //There original iscii buffer copied to an intermediate iscii buffer and then modified |
|
1351 //and is then passed for conversion. Now, after conversion, the return value needs to |
|
1352 //be adjusted according to the original buffer. NormalizeReturnValue() does the |
|
1353 //same thing. |
|
1354 |
|
1355 NormalizeReturnValue(normalizedReturnValue,aHomogeneousForeign); |
|
1356 aNumberOfForeignBytesConsumed-=normalizedReturnValue; |
|
1357 aReturnValue=normalizedReturnValue; |
|
1358 } |
|
1359 |
|
1360 //The HandleHomogeneousRun() method is called in a loop and once there is some |
|
1361 //iscii codes converted to unicode, the ConvertToUnicode() should not return |
|
1362 //CCnvCharacterSetConverter::EErrorIllFormedInput even though the conversion |
|
1363 //method does not convert any of the iscii codes ppassed. To ensure that once the |
|
1364 //first non-zero number of iscii codes are converted, the internal input conversion |
|
1365 //flag is set to EInputConversionFlagAllowTruncatedInputNotEvenPartlyConsumable. |
|
1366 |
|
1367 if(aNumberOfForeignBytesConsumed>0) |
|
1368 { |
|
1369 aInputConversionFlags|=CCnvCharacterSetConverter::EInputConversionFlagAllowTruncatedInputNotEvenPartlyConsumable; |
|
1370 } |
|
1371 return; |
|
1372 } |
|
1373 |
|
1374 // ----------------------------------------------------------------------------- |
|
1375 // IsTruncatedDoubleByteIsciiSequence() |
|
1376 //Checks if anIsciiBuffer is a part of multi byte iscii sequence truncated in the middle. |
|
1377 //If it is a truncated sequence, then returns ETrue else returns EFalse. |
|
1378 // |
|
1379 // Returns: ETrue: If the intermediate input iscii buffer is truncated |
|
1380 // EFalse: If the intermediate input iscii buffer is not truncated |
|
1381 // |
|
1382 // ----------------------------------------------------------------------------- |
|
1383 // |
|
1384 |
|
1385 LOCAL_C TBool IsTruncatedDoubleByteIsciiSequence(const TDesC8& anIsciiBuffer) |
|
1386 { |
|
1387 RArray<TPtrC8> searchBuffer; |
|
1388 if(anIsciiBuffer.Length () == 0) |
|
1389 return EFalse; |
|
1390 if(anIsciiBuffer[anIsciiBuffer.Length()-1] == 0xEF) |
|
1391 return ETrue; |
|
1392 searchBuffer.Append(KSoftHalant().Mid(0)); |
|
1393 searchBuffer.Append(KOm().Mid(0)); |
|
1394 searchBuffer.Append(KAvagraha().Mid(0)); |
|
1395 searchBuffer.Append(KExplicitHalant().Mid(0)); |
|
1396 TBool ret = EFalse; |
|
1397 TBool isNotTruncated =EFalse; |
|
1398 |
|
1399 //First check if the intermediate iscii buffer is ending with a complete multi byte sequence. |
|
1400 //If it ends with a complete multi byte sequence, no need to check if the last character of |
|
1401 //intermediate iscii is same as first character of multi byte iscii sequence. And return EFalse. |
|
1402 for(TUint counter = 0;counter<searchBuffer.Count();counter++) |
|
1403 { |
|
1404 if(searchBuffer[counter].Compare(anIsciiBuffer.Right(searchBuffer[counter].Length())) == 0) |
|
1405 { |
|
1406 isNotTruncated = ETrue; |
|
1407 break; |
|
1408 } |
|
1409 } |
|
1410 //If the intermediate iscii buffer is not ending with a complete multi byte sequence, and the |
|
1411 //last code of the iscii buffer is a part of the multibyte sequence, then the iscii buffer is a |
|
1412 //truncated sequence and in that case return ETrue. |
|
1413 |
|
1414 for(TUint counter = 0;counter<searchBuffer.Count();counter++) |
|
1415 { |
|
1416 if(isNotTruncated) |
|
1417 break; |
|
1418 else if( (anIsciiBuffer[anIsciiBuffer.Length()-1] == searchBuffer[counter][0])) |
|
1419 { |
|
1420 ret =ETrue; |
|
1421 break; |
|
1422 } |
|
1423 } |
|
1424 searchBuffer.Reset(); |
|
1425 return ret; |
|
1426 } |
|
1427 |
|
1428 // ----------------------------------------------------------------------------- |
|
1429 // ReplacementForUnconvertibleUnicodeCharacters() |
|
1430 //Returns the replacement character for unconvertible unicode character. |
|
1431 //In the current implementation it is 0x1a (ASCII Substitute character) |
|
1432 //The default implementation calls ReplacementForUnconvertibleUnicodeCharacters_internal() |
|
1433 //in turn which is generated by cnvtool. |
|
1434 // |
|
1435 // Returns: Replacemt for unconvertible unicode characters (0x1a) |
|
1436 // |
|
1437 // ----------------------------------------------------------------------------- |
|
1438 // |
|
1439 |
|
1440 EXPORT_C const TDesC8& ReplacementForUnconvertibleUnicodeCharacters() |
|
1441 { |
|
1442 return ReplacementForUnconvertibleUnicodeCharacters_internal(); |
|
1443 } |
|
1444 |
|
1445 // ----------------------------------------------------------------------------- |
|
1446 // ConvertFromUnicode() |
|
1447 //The main conversion function for converting from unicode to iscii |
|
1448 //Loaded and called by the character conversion framework. |
|
1449 //In turn calls CnvUtilities::ConvertFromUnicode() which is Symbian provide |
|
1450 //utility method for converting unicode to modal character codes. |
|
1451 // |
|
1452 // Returns: The numbet of unicode codes it could not convert. |
|
1453 // |
|
1454 // ----------------------------------------------------------------------------- |
|
1455 // |
|
1456 |
|
1457 EXPORT_C TInt ConvertFromUnicode( |
|
1458 CCnvCharacterSetConverter::TEndianness |
|
1459 aDefaultEndiannessOfForeignCharacters, |
|
1460 const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, |
|
1461 TDes8& aForeign, |
|
1462 const TDesC16& aUnicode, |
|
1463 CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters ) |
|
1464 { |
|
1465 TFixedArray<CnvUtilities::SCharacterSet,KNumberOfIndicCharactersetsSupported> aArrayOfCharacterSets; |
|
1466 aArrayOfCharacterSets[0].iConversionData = &conversionData; |
|
1467 aArrayOfCharacterSets[0].iConvertFromIntermediateBufferInPlace = ConvertFromUnicodeIntermediateBufferInPlace; |
|
1468 aArrayOfCharacterSets[0].iEscapeSequence = &KEscapeSequenceDevanagari(); |
|
1469 |
|
1470 return CnvUtilities::ConvertFromUnicode( |
|
1471 aDefaultEndiannessOfForeignCharacters, |
|
1472 aReplacementForUnconvertibleUnicodeCharacters, |
|
1473 aForeign, |
|
1474 aUnicode, |
|
1475 aIndicesOfUnconvertibleCharacters, |
|
1476 aArrayOfCharacterSets.Array()); |
|
1477 } |
|
1478 |
|
1479 // ----------------------------------------------------------------------------- |
|
1480 // ConvertToUnicode() |
|
1481 //The main conversion function for converting from iscii to unicode |
|
1482 //Loaded and called by the character conversion framework. |
|
1483 //To support some of the iscii characters, the input forign buffer is |
|
1484 //copied to an intermediate buffer and then is then modified and |
|
1485 //CCnvCharactersetConverter::DoConvertToUnicode() is called with |
|
1486 //the modified buffer. For extensibility of iscii to other Indic languages |
|
1487 //it uses CnvUtilities::SState datastructure. CnvUtilities::SState is a |
|
1488 //Symbian defined class for modal charactersets. The escape sequence |
|
1489 //is specified to ATR followed by the script selection code and the conversion |
|
1490 //data is specified to be the conversion for the particular script. For the time |
|
1491 //being only Devanagari with script selection code 0x42 is supported. If |
|
1492 //any of the other script codes are used the conversion leads to unconvertible |
|
1493 //character i.e. 0xFFFD. |
|
1494 // Returns: The numbet of iscii codes it could not convert. |
|
1495 // |
|
1496 // ----------------------------------------------------------------------------- |
|
1497 // |
|
1498 |
|
1499 EXPORT_C TInt ConvertToUnicode( |
|
1500 CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, |
|
1501 TDes16& aUnicode, |
|
1502 const TDesC8& aForeign, |
|
1503 TInt& aState, |
|
1504 TInt& aNumberOfUnconvertibleCharacters, |
|
1505 TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter ) |
|
1506 { |
|
1507 aNumberOfUnconvertibleCharacters = 0; |
|
1508 TUint aOutputConversionFlags = CCnvCharacterSetConverter::KStateDefault; |
|
1509 aIndexOfFirstByteOfFirstUnconvertibleCharacter=-1; |
|
1510 TUint internalInputConversionFlags = 0; |
|
1511 TInt numberOfForeignBytesConsumed=0; |
|
1512 TPtrC8 remainderOfForeign(aForeign); |
|
1513 TInt returnValue; |
|
1514 TBool flag = EFalse; |
|
1515 TBool isSkipMatchSequence = EFalse; |
|
1516 const SCnvConversionData* convData; |
|
1517 //Set the iscii conversion data and escape sequence for Devanagari. |
|
1518 TFixedArray<CnvUtilities::SState,KNumberOfIndicCharactersetsSupported> modals; |
|
1519 modals[0].iConversionData = &conversionData; |
|
1520 modals[0].iEscapeSequence = &KEscapeSequenceDevanagari(); |
|
1521 |
|
1522 aUnicode.SetLength(0); |
|
1523 |
|
1524 //The internal input conversion flag for conversion is set to CCnvCharacterSetConverter::EInputConversionFlagAppend |
|
1525 //so that for each conversion in the conversion loop, the generated conversion buffer is appened to the aUnicode buffer. |
|
1526 internalInputConversionFlags |= CCnvCharacterSetConverter::EInputConversionFlagAppend; |
|
1527 if (aForeign.Length()==0) |
|
1528 { |
|
1529 return 0; |
|
1530 } |
|
1531 //Get the conversion data from the previous call else the conversion data is set to the default |
|
1532 //conversion data, i.e. Devanagari. |
|
1533 convData=(aState!=CCnvCharacterSetConverter::KStateDefault)? REINTERPRET_CAST(const SCnvConversionData*, aState): modals[0].iConversionData; |
|
1534 FOREVER |
|
1535 { |
|
1536 TBuf8<KMaximumLengthOfIntermediateBuffer> intermediateBuffer; |
|
1537 TUint numberOfForeignBytesConsumedThisTime = 0; |
|
1538 if((remainderOfForeign.Length() >=KMaximumLengthOfIntermediateBuffer) && (aUnicode.MaxLength()-aUnicode.Length() >=KMaximumLengthOfIntermediateBuffer)) |
|
1539 { |
|
1540 numberOfForeignBytesConsumedThisTime = KMaximumLengthOfIntermediateBuffer; |
|
1541 intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime); |
|
1542 //If the intermediate buffer is a part of truncated buffer sequence but the |
|
1543 //actual input buffer is not truncated then truncated sequence is not converted. |
|
1544 //The intermediate buffer is modified so as not to contain the truncated sequence. |
|
1545 |
|
1546 flag = IsTruncatedDoubleByteIsciiSequence(intermediateBuffer); |
|
1547 if(flag) |
|
1548 { |
|
1549 numberOfForeignBytesConsumedThisTime --; |
|
1550 intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime); |
|
1551 } |
|
1552 |
|
1553 } |
|
1554 else |
|
1555 { |
|
1556 flag = IsTruncatedDoubleByteIsciiSequence(remainderOfForeign.Left(aUnicode.MaxLength()-aUnicode.Length())); |
|
1557 if(!flag) |
|
1558 { |
|
1559 numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length(); |
|
1560 intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime); |
|
1561 } |
|
1562 else |
|
1563 { |
|
1564 if(aForeign.Length()>(numberOfForeignBytesConsumed+aUnicode.Length())) |
|
1565 { |
|
1566 numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length()-1; |
|
1567 intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime); |
|
1568 break; |
|
1569 } |
|
1570 else |
|
1571 { |
|
1572 numberOfForeignBytesConsumedThisTime = aUnicode.MaxLength()-aUnicode.Length(); |
|
1573 intermediateBuffer = remainderOfForeign.Left(numberOfForeignBytesConsumedThisTime); |
|
1574 } |
|
1575 } |
|
1576 } |
|
1577 |
|
1578 //The input intermediate iscii buffer is modified with the search and replace |
|
1579 //buffers. It is required for supporting multibyte iscii sequences. |
|
1580 FindAndModifyBuffer(intermediateBuffer); |
|
1581 TPtrC8 remainderOfForeignInternal(intermediateBuffer); |
|
1582 TPtrC8 homogeneousRun; |
|
1583 const TInt startOfNextEscapeSequence=intermediateBuffer.Locate(KControlCharacterEscape); |
|
1584 if (startOfNextEscapeSequence!=0) |
|
1585 { |
|
1586 if (startOfNextEscapeSequence==KErrNotFound) |
|
1587 { |
|
1588 homogeneousRun.Set(remainderOfForeignInternal); |
|
1589 remainderOfForeignInternal.Set(NULL, 0); |
|
1590 } |
|
1591 else |
|
1592 { |
|
1593 __ASSERT_DEBUG(startOfNextEscapeSequence>0, User::Panic(KPanicReason,EPanicBadStartOfNextEscapeSequence)); |
|
1594 homogeneousRun.Set(remainderOfForeignInternal.Left(startOfNextEscapeSequence)); |
|
1595 remainderOfForeignInternal.Set(remainderOfForeignInternal.Mid(startOfNextEscapeSequence)); |
|
1596 } |
|
1597 isSkipMatchSequence = ETrue; |
|
1598 } |
|
1599 FOREVER |
|
1600 { |
|
1601 if(!isSkipMatchSequence) |
|
1602 { |
|
1603 if (!NextHomogeneousForeignRun(convData, numberOfForeignBytesConsumed, homogeneousRun, |
|
1604 remainderOfForeignInternal, modals.Array(), aOutputConversionFlags)) |
|
1605 { |
|
1606 break; |
|
1607 } |
|
1608 } |
|
1609 HandleHomogeneousRun( convData, aDefaultEndiannessOfForeignCharacters, aUnicode, homogeneousRun, aNumberOfUnconvertibleCharacters, |
|
1610 aIndexOfFirstByteOfFirstUnconvertibleCharacter,aOutputConversionFlags,internalInputConversionFlags, |
|
1611 numberOfForeignBytesConsumed,returnValue); |
|
1612 if(returnValue<0) |
|
1613 { |
|
1614 return returnValue; |
|
1615 } |
|
1616 isSkipMatchSequence = EFalse; |
|
1617 } |
|
1618 if(returnValue > 0) |
|
1619 break; |
|
1620 if ((!flag && (numberOfForeignBytesConsumedThisTime != KMaximumLengthOfIntermediateBuffer)) || (flag && (numberOfForeignBytesConsumedThisTime != (KMaximumLengthOfIntermediateBuffer-1) ))) |
|
1621 break; |
|
1622 remainderOfForeign.Set(aForeign.Mid(numberOfForeignBytesConsumed)); |
|
1623 } |
|
1624 //If the number of iscii bytes consumed by the conversion is zero also the output conversion |
|
1625 //flag is not set to EOutputConversionFlagInputIsTruncated, then return EErrorIllFormedInput. |
|
1626 if ((numberOfForeignBytesConsumed==0) && (aOutputConversionFlags&CCnvCharacterSetConverter::EOutputConversionFlagInputIsTruncated)) |
|
1627 { |
|
1628 return CCnvCharacterSetConverter::EErrorIllFormedInput; |
|
1629 } |
|
1630 //Set the conversion data sothat next time when ConvertToUnicode() is called, |
|
1631 //will use the previous conversion data. |
|
1632 aState=REINTERPRET_CAST(TInt, convData); |
|
1633 return aForeign.Length()-numberOfForeignBytesConsumed; |
|
1634 } |
|
1635 |
|
1636 // ----------------------------------------------------------------------------- |
|
1637 // IsInThisCharacterSetL() |
|
1638 //The method tells how probable it is that a sample piece of text is encoded in this character set. |
|
1639 //On return aConfidenceLevel, indicates how confident the function is about its return value. For |
|
1640 //iscii it is the default implementation and it does not implement the autodetect functionality. |
|
1641 //Loaded and called by the character conversion framework. |
|
1642 // |
|
1643 // Returns: EFalse: To tell CCnvCharacterSetConverter::AutoDetectCharacterSetL() that the plug-in DLL |
|
1644 // is not implementing a function of this signature and is therefore empty. |
|
1645 // |
|
1646 // ----------------------------------------------------------------------------- |
|
1647 // |
|
1648 |
|
1649 |
|
1650 //Default implementation for IsInThisCharacterSetL() |
|
1651 |
|
1652 EXPORT_C TBool IsInThisCharacterSetL( |
|
1653 TBool& aSetToTrue, |
|
1654 TInt& aConfidenceLevel, |
|
1655 const TDesC8& ) |
|
1656 { |
|
1657 aSetToTrue = EFalse; |
|
1658 aConfidenceLevel = 0; |
|
1659 return EFalse; |
|
1660 } |
|
1661 |
|
1662 EXPORT_C void Reserved_2() |
|
1663 { |
|
1664 } |
|
1665 |
|
1666 EXPORT_C void Reserved_3() |
|
1667 { |
|
1668 } |
|
1669 |
|
1670 EXPORT_C void Reserved_4() |
|
1671 { |
|
1672 } |
|
1673 |
|
1674 EXPORT_C void Reserved_5() |
|
1675 { |
|
1676 } |
|
1677 |
|
1678 EXPORT_C void Reserved_6() |
|
1679 { |
|
1680 } |
|
1681 |
|
1682 EXPORT_C void Reserved_7() |
|
1683 { |
|
1684 } |
|
1685 |
|
1686 EXPORT_C void Reserved_8() |
|
1687 { |
|
1688 } |
|
1689 |
|
1690 #endif //EKA2 |