1 : /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Ervin Yan <ervin.yan@sun.com>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 : #include "nsISO2022CNToUnicode.h"
39 : #include "nsUCSupport.h"
40 : #include "nsICharsetConverterManager.h"
41 : #include "nsIServiceManager.h"
42 :
43 : static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
44 :
45 0 : NS_IMETHODIMP nsISO2022CNToUnicode::GB2312_To_Unicode(unsigned char *aSrc, PRInt32 aSrcLength, PRUnichar * aDest, PRInt32 * aDestLength)
46 : {
47 : nsresult rv;
48 :
49 0 : if(!mGB2312_Decoder) {
50 : // creating a delegate converter (GB2312)
51 : nsCOMPtr<nsICharsetConverterManager> ccm =
52 0 : do_GetService(kCharsetConverterManagerCID, &rv);
53 0 : if(NS_FAILED(rv))
54 0 : return NS_ERROR_UNEXPECTED;
55 :
56 0 : rv = ccm->GetUnicodeDecoderRaw("GB2312", getter_AddRefs(mGB2312_Decoder));
57 0 : if(NS_FAILED(rv))
58 0 : return NS_ERROR_UNEXPECTED;
59 : }
60 :
61 0 : if(!mGB2312_Decoder) // failed creating a delegate converter
62 0 : return NS_ERROR_UNEXPECTED;
63 :
64 0 : rv = mGB2312_Decoder->Convert((const char *)aSrc, &aSrcLength, aDest, aDestLength);
65 0 : return rv;
66 : }
67 :
68 0 : NS_IMETHODIMP nsISO2022CNToUnicode::EUCTW_To_Unicode(unsigned char *aSrc, PRInt32 aSrcLength, PRUnichar * aDest, PRInt32 * aDestLength)
69 : {
70 : nsresult rv;
71 :
72 0 : if(!mEUCTW_Decoder) {
73 : // creating a delegate converter (x-euc-tw)
74 : nsCOMPtr<nsICharsetConverterManager> ccm =
75 0 : do_GetService(kCharsetConverterManagerCID, &rv);
76 0 : if(NS_FAILED(rv))
77 0 : return NS_ERROR_UNEXPECTED;
78 :
79 0 : rv = ccm->GetUnicodeDecoderRaw("x-euc-tw", getter_AddRefs(mEUCTW_Decoder));
80 0 : if(NS_FAILED(rv))
81 0 : return NS_ERROR_UNEXPECTED;
82 : }
83 :
84 0 : if(!mEUCTW_Decoder) // failed creating a delegate converter
85 0 : return NS_ERROR_UNEXPECTED;
86 :
87 0 : rv = mEUCTW_Decoder->Convert((const char *)aSrc, &aSrcLength, aDest, aDestLength);
88 0 : return(rv);
89 : }
90 :
91 0 : NS_IMETHODIMP nsISO2022CNToUnicode::Convert(const char * aSrc, PRInt32 * aSrcLen, PRUnichar * aDest, PRInt32 * aDestLen)
92 : {
93 0 : const unsigned char * srcEnd = (unsigned char *)aSrc + *aSrcLen;
94 0 : const unsigned char * src = (unsigned char *) aSrc;
95 0 : PRUnichar* destEnd = aDest + *aDestLen;
96 0 : PRUnichar* dest = aDest;
97 : nsresult rv;
98 : PRInt32 aLen;
99 :
100 0 : while ((src < srcEnd))
101 : {
102 0 : switch (mState)
103 : {
104 : case eState_ASCII:
105 0 : if(ESC == *src) {
106 0 : mState = eState_ESC;
107 : } else {
108 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
109 0 : goto error1;
110 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
111 :
112 0 : mState = eState_ASCII;
113 : }
114 0 : break;
115 :
116 : case eState_ESC: // ESC
117 0 : if('$' == *src) {
118 0 : mState = eState_ESC_24;
119 : } else {
120 0 : if (CHECK_OVERRUN(dest, destEnd, 2))
121 0 : goto error1;
122 0 : *dest++ = (PRUnichar) ESC;
123 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
124 :
125 0 : mState = eState_ASCII;
126 : }
127 0 : break;
128 :
129 : case eState_ESC_24: // ESC $
130 0 : if(')' == *src) {
131 0 : mState = eState_ESC_24_29;
132 0 : } else if('*' == *src) {
133 0 : mState = eState_ESC_24_2A;
134 0 : } else if('+' == *src) {
135 0 : mState = eState_ESC_24_2B;
136 : } else {
137 0 : if (CHECK_OVERRUN(dest, destEnd, 3))
138 0 : goto error1;
139 0 : *dest++ = (PRUnichar) ESC;
140 0 : *dest++ = (PRUnichar) '$';
141 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
142 :
143 0 : mState = eState_ASCII;
144 : }
145 0 : break;
146 :
147 : case eState_ESC_24_29: // ESC $ )
148 0 : if('A' == *src) {
149 0 : mState = eState_ESC_24_29_A;
150 0 : } else if('G' == *src) {
151 0 : mState = eState_ESC_24_29_G;
152 : } else {
153 0 : if (CHECK_OVERRUN(dest, destEnd, 4))
154 0 : goto error1;
155 0 : *dest++ = (PRUnichar) ESC;
156 0 : *dest++ = (PRUnichar) '$';
157 0 : *dest++ = (PRUnichar) ')';
158 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
159 :
160 0 : mState = eState_ASCII;
161 : }
162 0 : break;
163 :
164 : case eState_ESC_24_29_A: // ESC $ ) A
165 0 : if(SO == *src) {
166 0 : mState = eState_GB2312_1980;
167 0 : mRunLength = 0;
168 : } else {
169 0 : if (CHECK_OVERRUN(dest, destEnd, 5))
170 0 : goto error1;
171 0 : *dest++ = (PRUnichar) ESC;
172 0 : *dest++ = (PRUnichar) '$';
173 0 : *dest++ = (PRUnichar) ')';
174 0 : *dest++ = (PRUnichar) 'A';
175 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
176 :
177 0 : mState = eState_ASCII;
178 : }
179 0 : break;
180 :
181 : case eState_GB2312_1980: // ESC $ ) A SO
182 0 : if(SI == *src) { // Shift-In (SI)
183 0 : mState = eState_ESC_24_29_A_SO_SI;
184 0 : if (mRunLength == 0) {
185 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
186 0 : goto error1;
187 0 : *dest++ = 0xFFFD;
188 : }
189 0 : mRunLength = 0;
190 0 : } else if(ESC == *src) {
191 0 : mState = eState_ESC;
192 : } else {
193 0 : if(0x20 < *src && *src < 0x7f) {
194 0 : mData = *src;
195 0 : mState = eState_GB2312_1980_2ndbyte;
196 : } else {
197 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
198 0 : goto error1;
199 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
200 : }
201 : }
202 0 : break;
203 :
204 : case eState_GB2312_1980_2ndbyte: // ESC $ ) A SO
205 0 : if(0x20 < *src && *src < 0x7f) {
206 : unsigned char gb[2];
207 0 : PRInt32 gbLen = 2;
208 :
209 0 : gb[0] = mData | 0x80;
210 0 : gb[1] = *src | 0x80;
211 :
212 0 : aLen = destEnd - dest;
213 0 : rv = GB2312_To_Unicode(gb, gbLen, dest, &aLen);
214 0 : ++mRunLength;
215 0 : if(rv == NS_OK_UDEC_MOREOUTPUT) {
216 0 : goto error1;
217 0 : } else if(NS_FAILED(rv)) {
218 0 : goto error2;
219 : }
220 :
221 0 : dest += aLen;
222 : } else {
223 0 : if (CHECK_OVERRUN(dest, destEnd, 2))
224 0 : goto error1;
225 0 : *dest++ = (PRUnichar) mData;
226 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
227 : }
228 0 : mState = eState_GB2312_1980;
229 0 : break;
230 :
231 : case eState_ESC_24_29_A_SO_SI: // ESC $ ) A SO SI
232 0 : if(SO == *src) {
233 0 : mState = eState_GB2312_1980;
234 0 : mRunLength = 0;
235 0 : } else if(ESC == *src) {
236 0 : mState = eState_ESC;
237 : } else {
238 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
239 0 : goto error1;
240 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
241 :
242 0 : mState = eState_ESC_24_29_A_SO_SI;
243 : }
244 0 : break;
245 :
246 : case eState_ESC_24_29_G: // ESC $ ) G
247 0 : if(SO == *src) {
248 0 : mState = eState_CNS11643_1;
249 0 : mRunLength = 0;
250 : } else {
251 0 : if (CHECK_OVERRUN(dest, destEnd, 5))
252 0 : goto error1;
253 0 : *dest++ = (PRUnichar) ESC;
254 0 : *dest++ = (PRUnichar) '$';
255 0 : *dest++ = (PRUnichar) ')';
256 0 : *dest++ = (PRUnichar) 'G';
257 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
258 :
259 0 : mState = eState_ASCII;
260 : }
261 0 : break;
262 :
263 : case eState_CNS11643_1: // ESC $ ) G SO
264 0 : if(SI == *src) { // Shift-In (SI)
265 0 : mState = eState_ESC_24_29_G_SO_SI;
266 0 : if (mRunLength == 0) {
267 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
268 0 : goto error1;
269 0 : *dest++ = 0xFFFD;
270 : }
271 0 : mRunLength = 0;
272 0 : } else if(ESC == *src) {
273 0 : mState = eState_ESC;
274 : } else {
275 0 : if(0x20 < *src && *src < 0x7f) {
276 0 : mData = *src;
277 0 : mState = eState_CNS11643_1_2ndbyte;
278 : } else {
279 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
280 0 : goto error1;
281 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
282 : }
283 : }
284 0 : break;
285 :
286 : case eState_CNS11643_1_2ndbyte: // ESC $ ) G SO
287 0 : if(0x20 < *src && *src < 0x7f) {
288 : unsigned char cns[4];
289 0 : PRInt32 cnsLen = 2;
290 :
291 0 : cns[0] = mData | 0x80;
292 0 : cns[1] = *src | 0x80;
293 :
294 0 : aLen = destEnd - dest;
295 0 : rv = EUCTW_To_Unicode(cns, cnsLen, dest, &aLen);
296 0 : ++mRunLength;
297 0 : if(rv == NS_OK_UDEC_MOREOUTPUT) {
298 0 : goto error1;
299 0 : } else if(NS_FAILED(rv)) {
300 0 : goto error2;
301 : }
302 :
303 0 : dest += aLen;
304 : } else {
305 0 : if (CHECK_OVERRUN(dest, destEnd, 2))
306 0 : goto error1;
307 0 : *dest++ = (PRUnichar) mData;
308 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
309 : }
310 0 : mState = eState_CNS11643_1;
311 0 : break;
312 :
313 : case eState_ESC_24_29_G_SO_SI: // ESC $ ) G SO SI
314 0 : if(SO == *src) {
315 0 : mState = eState_CNS11643_1;
316 0 : mRunLength = 0;
317 0 : } else if(ESC == *src) {
318 0 : mState = eState_ESC;
319 : } else {
320 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
321 0 : goto error1;
322 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
323 :
324 0 : mState = eState_ESC_24_29_G_SO_SI;
325 : }
326 0 : break;
327 :
328 : case eState_ESC_24_2A: // ESC $ *
329 0 : if('H' == *src) {
330 0 : mState = eState_ESC_24_2A_H;
331 : } else {
332 0 : if (CHECK_OVERRUN(dest, destEnd, 4))
333 0 : goto error1;
334 0 : *dest++ = (PRUnichar) ESC;
335 0 : *dest++ = (PRUnichar) '$';
336 0 : *dest++ = (PRUnichar) '*';
337 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
338 :
339 0 : mState = eState_ASCII;
340 : }
341 0 : break;
342 :
343 : case eState_ESC_24_2A_H: // ESC $ * H
344 0 : if(ESC == *src) {
345 0 : mState = eState_ESC_24_2A_H_ESC;
346 : } else {
347 0 : if (CHECK_OVERRUN(dest, destEnd, 5))
348 0 : goto error1;
349 0 : *dest++ = (PRUnichar) ESC;
350 0 : *dest++ = (PRUnichar) '$';
351 0 : *dest++ = (PRUnichar) '*';
352 0 : *dest++ = (PRUnichar) 'H';
353 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
354 :
355 0 : mState = eState_ASCII;
356 : }
357 0 : break;
358 :
359 : case eState_ESC_24_2A_H_ESC: // ESC $ * H ESC
360 0 : if(SS2 == *src) {
361 0 : mState = eState_CNS11643_2;
362 0 : mRunLength = 0;
363 0 : } else if('$' == *src) {
364 0 : mState = eState_ESC_24;
365 : } else {
366 0 : if (CHECK_OVERRUN(dest, destEnd, 6))
367 0 : goto error1;
368 0 : *dest++ = (PRUnichar) ESC;
369 0 : *dest++ = (PRUnichar) '$';
370 0 : *dest++ = (PRUnichar) '*';
371 0 : *dest++ = (PRUnichar) 'H';
372 0 : *dest++ = (PRUnichar) ESC;
373 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
374 :
375 0 : mState = eState_ASCII;
376 : }
377 0 : break;
378 :
379 : case eState_CNS11643_2: // ESC $ * H ESC SS2
380 0 : if(SI == *src) { // Shift-In (SI)
381 0 : mState = eState_ESC_24_2A_H_ESC_SS2_SI;
382 0 : if (mRunLength == 0) {
383 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
384 0 : goto error1;
385 0 : *dest++ = 0xFFFD;
386 : }
387 0 : mRunLength = 0;
388 0 : } else if(ESC == *src) {
389 0 : mState = eState_ESC_24_2A_H_ESC;
390 : } else {
391 0 : if(0x20 < *src && *src < 0x7f) {
392 0 : mData = *src;
393 0 : mState = eState_CNS11643_2_2ndbyte;
394 : } else {
395 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
396 0 : goto error1;
397 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
398 : }
399 : }
400 0 : break;
401 :
402 : case eState_CNS11643_2_2ndbyte: // ESC $ * H ESC SS2
403 0 : if(0x20 < *src && *src < 0x7f) {
404 : unsigned char cns[4];
405 0 : PRInt32 cnsLen = 4;
406 :
407 0 : cns[0] = (unsigned char) MBYTE;
408 0 : cns[1] = (unsigned char) (PMASK + 2);
409 0 : cns[2] = mData | 0x80;
410 0 : cns[3] = *src | 0x80;
411 :
412 0 : aLen = destEnd - dest;
413 0 : rv = EUCTW_To_Unicode(cns, cnsLen, dest, &aLen);
414 0 : ++mRunLength;
415 0 : if(rv == NS_OK_UDEC_MOREOUTPUT) {
416 0 : goto error1;
417 0 : } else if(NS_FAILED(rv)) {
418 0 : goto error2;
419 : }
420 :
421 0 : dest += aLen;
422 : } else {
423 0 : if (CHECK_OVERRUN(dest, destEnd, 2))
424 0 : goto error1;
425 0 : *dest++ = (PRUnichar) mData;
426 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
427 : }
428 0 : mState = eState_CNS11643_2;
429 0 : break;
430 :
431 : case eState_ESC_24_2A_H_ESC_SS2_SI: // ESC $ * H ESC SS2 SI
432 0 : if(ESC == *src) {
433 0 : mState = eState_ESC_24_2A_H_ESC_SS2_SI_ESC;
434 : } else {
435 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
436 0 : goto error1;
437 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
438 :
439 0 : mState = eState_ESC_24_2A_H_ESC_SS2_SI;
440 : }
441 0 : break;
442 :
443 : case eState_ESC_24_2A_H_ESC_SS2_SI_ESC: // ESC $ * H ESC SS2 SI ESC
444 0 : if(SS2 == *src) {
445 0 : mState = eState_CNS11643_2;
446 0 : mRunLength = 0;
447 0 : } else if('$' == *src) {
448 0 : mState = eState_ESC_24;
449 : } else {
450 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
451 0 : goto error1;
452 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
453 :
454 0 : mState = eState_ESC_24_2A_H_ESC_SS2_SI;
455 : }
456 0 : break;
457 :
458 : case eState_ESC_24_2B: // ESC $ +
459 0 : if('I' <= *src && *src <= 'M') {
460 0 : mState = eState_ESC_24_2B_I;
461 0 : mPlaneID = *src - 'I' + 3;
462 : } else {
463 0 : if (CHECK_OVERRUN(dest, destEnd, 4))
464 0 : goto error1;
465 0 : *dest++ = (PRUnichar) ESC;
466 0 : *dest++ = (PRUnichar) '$';
467 0 : *dest++ = (PRUnichar) '+';
468 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
469 :
470 0 : mState = eState_ASCII;
471 : }
472 0 : break;
473 :
474 : case eState_ESC_24_2B_I: // ESC $ + I
475 0 : if(ESC == *src) {
476 0 : mState = eState_ESC_24_2B_I_ESC;
477 : } else {
478 0 : if (CHECK_OVERRUN(dest, destEnd, 5))
479 0 : goto error1;
480 0 : *dest++ = (PRUnichar) ESC;
481 0 : *dest++ = (PRUnichar) '$';
482 0 : *dest++ = (PRUnichar) '+';
483 0 : *dest++ = (PRUnichar) 'I' + mPlaneID - 3;
484 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
485 :
486 0 : mState = eState_ASCII;
487 : }
488 0 : break;
489 :
490 : case eState_ESC_24_2B_I_ESC: // ESC $ + I ESC
491 0 : if(SS3 == *src) {
492 0 : mState = eState_CNS11643_3;
493 0 : mRunLength = 0;
494 0 : } else if('$' == *src) {
495 0 : mState = eState_ESC_24;
496 : } else {
497 0 : if (CHECK_OVERRUN(dest, destEnd, 6))
498 0 : goto error1;
499 0 : *dest++ = (PRUnichar) ESC;
500 0 : *dest++ = (PRUnichar) '$';
501 0 : *dest++ = (PRUnichar) '+';
502 0 : *dest++ = (PRUnichar) 'I' + mPlaneID - 3;
503 0 : *dest++ = (PRUnichar) ESC;
504 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
505 :
506 0 : mState = eState_ASCII;
507 : }
508 0 : break;
509 :
510 : case eState_CNS11643_3: // ESC $ + I ESC SS3
511 0 : if(SI == *src) { // Shift-In (SI)
512 0 : mState = eState_ESC_24_2B_I_ESC_SS3_SI;
513 0 : if (mRunLength == 0) {
514 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
515 0 : goto error1;
516 0 : *dest++ = 0xFFFD;
517 : }
518 0 : mRunLength = 0;
519 0 : } else if(ESC == *src) {
520 0 : mState = eState_ESC_24_2B_I_ESC;
521 : } else {
522 0 : if(0x20 < *src && *src < 0x7f) {
523 0 : mData = *src;
524 0 : mState = eState_CNS11643_3_2ndbyte;
525 : } else {
526 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
527 0 : goto error1;
528 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
529 : }
530 : }
531 :
532 0 : break;
533 :
534 : case eState_CNS11643_3_2ndbyte: // ESC $ + I ESC SS3
535 0 : if(0x20 < *src && *src < 0x7f) {
536 : unsigned char cns[4];
537 0 : PRInt32 cnsLen = 4;
538 :
539 0 : cns[0] = (unsigned char) MBYTE;
540 0 : cns[1] = (unsigned char) (PMASK + mPlaneID);
541 0 : cns[2] = mData | 0x80;
542 0 : cns[3] = *src | 0x80;
543 :
544 0 : aLen = destEnd - dest;
545 0 : rv = EUCTW_To_Unicode(cns, cnsLen, dest, &aLen);
546 0 : ++mRunLength;
547 0 : if(rv == NS_OK_UDEC_MOREOUTPUT) {
548 0 : goto error1;
549 0 : } else if(NS_FAILED(rv)) {
550 0 : goto error2;
551 : }
552 :
553 0 : dest += aLen;
554 : } else {
555 0 : if (CHECK_OVERRUN(dest, destEnd, 2))
556 0 : goto error1;
557 0 : *dest++ = (PRUnichar) mData;
558 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
559 : }
560 0 : mState = eState_CNS11643_3;
561 0 : break;
562 :
563 : case eState_ESC_24_2B_I_ESC_SS3_SI: // ESC $ + I ESC SS3 SI
564 0 : if(ESC == *src) {
565 0 : mState = eState_ESC_24_2B_I_ESC_SS3_SI_ESC;
566 : } else {
567 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
568 0 : goto error1;
569 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
570 :
571 0 : mState = eState_ESC_24_2B_I_ESC_SS3_SI;
572 : }
573 0 : break;
574 :
575 : case eState_ESC_24_2B_I_ESC_SS3_SI_ESC: // ESC $ + I ESC SS3 SI ESC
576 0 : if(SS3 == *src) {
577 0 : mState = eState_CNS11643_3;
578 0 : mRunLength = 0;
579 0 : } else if('$' == *src) {
580 0 : mState = eState_ESC_24;
581 : } else {
582 0 : if (CHECK_OVERRUN(dest, destEnd, 1))
583 0 : goto error1;
584 0 : *dest++ = (0x80 & *src) ? 0xFFFD : (PRUnichar) *src;
585 :
586 0 : mState = eState_ESC_24_2B_I_ESC_SS3_SI;
587 : }
588 0 : break;
589 :
590 : case eState_ERROR:
591 0 : NS_NOTREACHED("unhandled case");
592 0 : goto error2;
593 :
594 : } // switch
595 0 : src++;
596 : }
597 :
598 0 : *aDestLen = dest- aDest;
599 0 : return NS_OK;
600 :
601 : error1:
602 0 : *aDestLen = dest-aDest;
603 0 : *aSrcLen = src - (const unsigned char*)aSrc;
604 0 : return NS_OK_UDEC_MOREOUTPUT;
605 :
606 : error2:
607 0 : *aSrcLen = src - (const unsigned char*)aSrc;
608 0 : *aDestLen = dest-aDest;
609 0 : mState = eState_ASCII;
610 0 : return NS_ERROR_UNEXPECTED;
611 : }
|