intl/uconv/ucvcn/nsISO2022CNToUnicode.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial