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