1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "convertiso2022cn.h" 29 #include "context.h" 30 #include "converter.h" 31 #include "tenchelp.h" 32 #include "unichars.h" 33 #include "rtl/alloc.h" 34 #include "rtl/textcvt.h" 35 #include "sal/types.h" 36 37 typedef enum /* order is important: */ 38 { 39 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII, 40 IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO, 41 IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2, 42 IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432, 43 IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2, 44 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC, 45 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR, 46 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN, 47 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK 48 } ImplIso2022CnToUnicodeState; 49 50 typedef struct 51 { 52 ImplIso2022CnToUnicodeState m_eState; 53 sal_uInt32 m_nRow; 54 sal_Bool m_bSo; 55 sal_Bool m_b116431; 56 } ImplIso2022CnToUnicodeContext; 57 58 typedef enum 59 { 60 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE, 61 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312, 62 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431 63 } ImplUnicodeToIso2022CnDesignator; 64 65 typedef struct 66 { 67 sal_Unicode m_nHighSurrogate; 68 ImplUnicodeToIso2022CnDesignator m_eSoDesignator; 69 sal_Bool m_b116432Designator; 70 sal_Bool m_bSo; 71 } ImplUnicodeToIso2022CnContext; 72 73 void * ImplCreateIso2022CnToUnicodeContext(void) 74 { 75 void * pContext 76 = rtl_allocateMemory(sizeof (ImplIso2022CnToUnicodeContext)); 77 ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState 78 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII; 79 ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo = sal_False; 80 ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431 = sal_False; 81 return pContext; 82 } 83 84 void ImplResetIso2022CnToUnicodeContext(void * pContext) 85 { 86 if (pContext) 87 { 88 ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState 89 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII; 90 ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo = sal_False; 91 ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431 = sal_False; 92 } 93 } 94 95 sal_Size ImplConvertIso2022CnToUnicode(ImplTextConverterData const * pData, 96 void * pContext, 97 sal_Char const * pSrcBuf, 98 sal_Size nSrcBytes, 99 sal_Unicode * pDestBuf, 100 sal_Size nDestChars, 101 sal_uInt32 nFlags, 102 sal_uInt32 * pInfo, 103 sal_Size * pSrcCvtBytes) 104 { 105 ImplDBCSToUniLeadTab const * pGb2312Data 106 = ((ImplIso2022CnConverterData const *) pData)-> 107 m_pGb2312ToUnicodeData; 108 sal_uInt16 const * pCns116431992Data 109 = ((ImplIso2022CnConverterData const *) pData)-> 110 m_pCns116431992ToUnicodeData; 111 sal_Int32 const * pCns116431992RowOffsets 112 = ((ImplIso2022CnConverterData const *) pData)-> 113 m_pCns116431992ToUnicodeRowOffsets; 114 sal_Int32 const * pCns116431992PlaneOffsets 115 = ((ImplIso2022CnConverterData const *) pData)-> 116 m_pCns116431992ToUnicodePlaneOffsets; 117 ImplIso2022CnToUnicodeState eState 118 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII; 119 sal_uInt32 nRow = 0; 120 sal_Bool bSo = sal_False; 121 sal_Bool b116431 = sal_False; 122 sal_uInt32 nInfo = 0; 123 sal_Size nConverted = 0; 124 sal_Unicode * pDestBufPtr = pDestBuf; 125 sal_Unicode * pDestBufEnd = pDestBuf + nDestChars; 126 127 if (pContext) 128 { 129 eState = ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState; 130 nRow = ((ImplIso2022CnToUnicodeContext *) pContext)->m_nRow; 131 bSo = ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo; 132 b116431 = ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431; 133 } 134 135 for (; nConverted < nSrcBytes; ++nConverted) 136 { 137 sal_Bool bUndefined = sal_True; 138 sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++; 139 sal_uInt32 nPlane; 140 switch (eState) 141 { 142 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII: 143 if (nChar == 0x0E) /* SO */ 144 { 145 bSo = sal_True; 146 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO; 147 } 148 else if (nChar == 0x1B) /* ESC */ 149 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC; 150 else if (nChar < 0x80) 151 if (pDestBufPtr != pDestBufEnd) 152 *pDestBufPtr++ = (sal_Unicode) nChar; 153 else 154 goto no_output; 155 else 156 { 157 bUndefined = sal_False; 158 goto bad_input; 159 } 160 break; 161 162 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO: 163 if (nChar == 0x0F) /* SI */ 164 { 165 bSo = sal_False; 166 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII; 167 } 168 else if (nChar == 0x1B) /* ESC */ 169 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC; 170 else if (nChar >= 0x21 && nChar <= 0x7E) 171 { 172 nRow = nChar; 173 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2; 174 } 175 else 176 { 177 bUndefined = sal_False; 178 goto bad_input; 179 } 180 break; 181 182 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2: 183 if (nChar >= 0x21 && nChar <= 0x7E) 184 if (b116431) 185 { 186 nPlane = 0; 187 goto transform; 188 } 189 else 190 { 191 sal_uInt16 nUnicode = 0; 192 sal_uInt32 nFirst; 193 nRow += 0x80; 194 nChar += 0x80; 195 nFirst = pGb2312Data[nRow].mnTrailStart; 196 if (nChar >= nFirst 197 && nChar <= pGb2312Data[nRow].mnTrailEnd) 198 nUnicode = pGb2312Data[nRow]. 199 mpToUniTrailTab[nChar - nFirst]; 200 if (nUnicode != 0) 201 if (pDestBufPtr != pDestBufEnd) 202 { 203 *pDestBufPtr++ = (sal_Unicode) nUnicode; 204 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO; 205 } 206 else 207 goto no_output; 208 else 209 goto bad_input; 210 } 211 else 212 { 213 bUndefined = sal_False; 214 goto bad_input; 215 } 216 break; 217 218 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432: 219 if (nChar >= 0x21 && nChar <= 0x7E) 220 { 221 nRow = nChar; 222 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2; 223 } 224 else 225 { 226 bUndefined = sal_False; 227 goto bad_input; 228 } 229 break; 230 231 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2: 232 if (nChar >= 0x21 && nChar <= 0x7E) 233 { 234 nPlane = 1; 235 goto transform; 236 } 237 else 238 { 239 bUndefined = sal_False; 240 goto bad_input; 241 } 242 break; 243 244 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC: 245 if (nChar == 0x24) /* $ */ 246 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR; 247 else if (nChar == 0x4E) /* N */ 248 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432; 249 else 250 { 251 bUndefined = sal_False; 252 goto bad_input; 253 } 254 break; 255 256 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR: 257 if (nChar == 0x29) /* ) */ 258 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN; 259 else if (nChar == 0x2A) /* * */ 260 eState 261 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK; 262 else 263 { 264 bUndefined = sal_False; 265 goto bad_input; 266 } 267 break; 268 269 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN: 270 if (nChar == 0x41) /* A */ 271 { 272 b116431 = sal_False; 273 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO : 274 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII; 275 } 276 else if (nChar == 0x47) /* G */ 277 { 278 b116431 = sal_True; 279 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO : 280 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII; 281 } 282 else 283 { 284 bUndefined = sal_False; 285 goto bad_input; 286 } 287 break; 288 289 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK: 290 if (nChar == 0x48) /* H */ 291 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO : 292 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII; 293 else 294 { 295 bUndefined = sal_False; 296 goto bad_input; 297 } 298 break; 299 } 300 continue; 301 302 transform: 303 { 304 sal_Int32 nPlaneOffset = pCns116431992PlaneOffsets[nPlane]; 305 if (nPlaneOffset == -1) 306 goto bad_input; 307 else 308 { 309 sal_Int32 nOffset 310 = pCns116431992RowOffsets[nPlaneOffset + (nRow - 0x21)]; 311 if (nOffset == -1) 312 goto bad_input; 313 else 314 { 315 sal_uInt32 nFirstLast = pCns116431992Data[nOffset++]; 316 sal_uInt32 nFirst = nFirstLast & 0xFF; 317 sal_uInt32 nLast = nFirstLast >> 8; 318 nChar -= 0x20; 319 if (nChar >= nFirst && nChar <= nLast) 320 { 321 sal_uInt32 nUnicode 322 = pCns116431992Data[nOffset + (nChar - nFirst)]; 323 if (nUnicode == 0xFFFF) 324 goto bad_input; 325 else if (ImplIsHighSurrogate(nUnicode)) 326 if (pDestBufEnd - pDestBufPtr >= 2) 327 { 328 nOffset += nLast - nFirst + 1; 329 nFirst = pCns116431992Data[nOffset++]; 330 *pDestBufPtr++ = (sal_Unicode) nUnicode; 331 *pDestBufPtr++ 332 = (sal_Unicode) 333 pCns116431992Data[ 334 nOffset + (nChar - nFirst)]; 335 } 336 else 337 goto no_output; 338 else 339 if (pDestBufPtr != pDestBufEnd) 340 *pDestBufPtr++ = (sal_Unicode) nUnicode; 341 else 342 goto no_output; 343 } 344 else 345 goto bad_input; 346 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO : 347 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII; 348 } 349 } 350 continue; 351 } 352 353 bad_input: 354 switch (ImplHandleBadInputTextToUnicodeConversion( 355 bUndefined, sal_True, 0, nFlags, &pDestBufPtr, pDestBufEnd, 356 &nInfo)) 357 { 358 case IMPL_BAD_INPUT_STOP: 359 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII; 360 b116431 = sal_False; 361 break; 362 363 case IMPL_BAD_INPUT_CONTINUE: 364 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII; 365 b116431 = sal_False; 366 continue; 367 368 case IMPL_BAD_INPUT_NO_OUTPUT: 369 goto no_output; 370 } 371 break; 372 373 no_output: 374 --pSrcBuf; 375 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; 376 break; 377 } 378 379 if (eState > IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO 380 && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR 381 | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL)) 382 == 0) 383 { 384 if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0) 385 nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL; 386 else 387 switch (ImplHandleBadInputTextToUnicodeConversion( 388 sal_False, sal_True, 0, nFlags, &pDestBufPtr, pDestBufEnd, 389 &nInfo)) 390 { 391 case IMPL_BAD_INPUT_STOP: 392 case IMPL_BAD_INPUT_CONTINUE: 393 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII; 394 b116431 = sal_False; 395 break; 396 397 case IMPL_BAD_INPUT_NO_OUTPUT: 398 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL; 399 break; 400 } 401 } 402 403 if (pContext) 404 { 405 ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState = eState; 406 ((ImplIso2022CnToUnicodeContext *) pContext)->m_nRow = nRow; 407 ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo = bSo; 408 ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431 = b116431; 409 } 410 if (pInfo) 411 *pInfo = nInfo; 412 if (pSrcCvtBytes) 413 *pSrcCvtBytes = nConverted; 414 415 return pDestBufPtr - pDestBuf; 416 } 417 418 void * ImplCreateUnicodeToIso2022CnContext(void) 419 { 420 void * pContext 421 = rtl_allocateMemory(sizeof (ImplUnicodeToIso2022CnContext)); 422 ((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate = 0; 423 ((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator 424 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE; 425 ((ImplUnicodeToIso2022CnContext *) pContext)->m_b116432Designator 426 = sal_False; 427 ((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo = sal_False; 428 return pContext; 429 } 430 431 void ImplResetUnicodeToIso2022CnContext(void * pContext) 432 { 433 if (pContext) 434 { 435 ((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate = 0; 436 ((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator 437 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE; 438 ((ImplUnicodeToIso2022CnContext *) pContext)->m_b116432Designator 439 = sal_False; 440 ((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo = sal_False; 441 } 442 } 443 444 static sal_uInt32 ImplIso2022CnTranslateTo2312(ImplUniToDBCSHighTab const * 445 pGb2312Data, 446 sal_uInt32 nChar) 447 { 448 sal_uInt32 nIndex1 = nChar >> 8; 449 if (nIndex1 < 0x100) 450 { 451 sal_uInt32 nIndex2 = nChar & 0xFF; 452 sal_uInt32 nFirst = pGb2312Data[nIndex1].mnLowStart; 453 if (nIndex2 >= nFirst && nIndex2 <= pGb2312Data[nIndex1].mnLowEnd) 454 return pGb2312Data[nIndex1].mpToUniTrailTab[nIndex2 - nFirst] 455 & 0x7F7F; 456 } 457 return 0; 458 } 459 460 static sal_uInt32 461 ImplIso2022CnTranslateTo116431(sal_uInt8 const * pCns116431992Data, 462 sal_Int32 const * pCns116431992PageOffsets, 463 sal_Int32 const * pCns116431992PlaneOffsets, 464 sal_uInt32 nChar) 465 { 466 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16]; 467 sal_uInt32 nFirst; 468 sal_uInt32 nLast; 469 sal_uInt32 nPlane; 470 if (nOffset == -1) 471 return 0; 472 nOffset = pCns116431992PageOffsets[nOffset + ((nChar & 0xFF00) >> 8)]; 473 if (nOffset == -1) 474 return 0; 475 nFirst = pCns116431992Data[nOffset++]; 476 nLast = pCns116431992Data[nOffset++]; 477 nChar &= 0xFF; 478 if (nChar < nFirst || nChar > nLast) 479 return 0; 480 nOffset += 3 * (nChar - nFirst); 481 nPlane = pCns116431992Data[nOffset++]; 482 if (nPlane != 1) 483 return 0; 484 return (0x20 + pCns116431992Data[nOffset]) << 8 485 | (0x20 + pCns116431992Data[nOffset + 1]); 486 } 487 488 sal_Size ImplConvertUnicodeToIso2022Cn(ImplTextConverterData const * pData, 489 void * pContext, 490 sal_Unicode const * pSrcBuf, 491 sal_Size nSrcChars, 492 sal_Char * pDestBuf, 493 sal_Size nDestBytes, 494 sal_uInt32 nFlags, 495 sal_uInt32 * pInfo, 496 sal_Size * pSrcCvtChars) 497 { 498 ImplUniToDBCSHighTab const * pGb2312Data 499 = ((ImplIso2022CnConverterData const *) pData)-> 500 m_pUnicodeToGb2312Data; 501 sal_uInt8 const * pCns116431992Data 502 = ((ImplIso2022CnConverterData const *) pData)-> 503 m_pUnicodeToCns116431992Data; 504 sal_Int32 const * pCns116431992PageOffsets 505 = ((ImplIso2022CnConverterData const *) pData)-> 506 m_pUnicodeToCns116431992PageOffsets; 507 sal_Int32 const * pCns116431992PlaneOffsets 508 = ((ImplIso2022CnConverterData const *) pData)-> 509 m_pUnicodeToCns116431992PlaneOffsets; 510 sal_Unicode nHighSurrogate = 0; 511 ImplUnicodeToIso2022CnDesignator eSoDesignator 512 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE; 513 sal_Bool b116432Designator = sal_False; 514 sal_Bool bSo = sal_False; 515 sal_uInt32 nInfo = 0; 516 sal_Size nConverted = 0; 517 sal_Char * pDestBufPtr = pDestBuf; 518 sal_Char * pDestBufEnd = pDestBuf + nDestBytes; 519 sal_Bool bWritten; 520 521 if (pContext) 522 { 523 nHighSurrogate 524 = ((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate; 525 eSoDesignator 526 = ((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator; 527 b116432Designator = ((ImplUnicodeToIso2022CnContext *) pContext)-> 528 m_b116432Designator; 529 bSo = ((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo; 530 } 531 532 for (; nConverted < nSrcChars; ++nConverted) 533 { 534 sal_Bool bUndefined = sal_True; 535 sal_uInt32 nChar = *pSrcBuf++; 536 if (nHighSurrogate == 0) 537 { 538 if (ImplIsHighSurrogate(nChar)) 539 { 540 nHighSurrogate = (sal_Unicode) nChar; 541 continue; 542 } 543 } 544 else if (ImplIsLowSurrogate(nChar)) 545 nChar = ImplCombineSurrogates(nHighSurrogate, nChar); 546 else 547 { 548 bUndefined = sal_False; 549 goto bad_input; 550 } 551 552 if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar)) 553 { 554 bUndefined = sal_False; 555 goto bad_input; 556 } 557 558 if (nChar == 0x0A || nChar == 0x0D) /* LF, CR */ 559 { 560 if (bSo) 561 { 562 if (pDestBufPtr != pDestBufEnd) 563 { 564 *pDestBufPtr++ = 0x0F; /* SI */ 565 bSo = sal_False; 566 eSoDesignator 567 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE; 568 b116432Designator = sal_False; 569 } 570 else 571 goto no_output; 572 } 573 if (pDestBufPtr != pDestBufEnd) 574 *pDestBufPtr++ = (sal_Char) nChar; 575 else 576 goto no_output; 577 } 578 else if (nChar == 0x0E || nChar == 0x0F || nChar == 0x1B) 579 goto bad_input; 580 else if (nChar < 0x80) 581 { 582 if (bSo) 583 { 584 if (pDestBufPtr != pDestBufEnd) 585 { 586 *pDestBufPtr++ = 0x0F; /* SI */ 587 bSo = sal_False; 588 } 589 else 590 goto no_output; 591 } 592 if (pDestBufPtr != pDestBufEnd) 593 *pDestBufPtr++ = (sal_Char) nChar; 594 else 595 goto no_output; 596 } 597 else 598 { 599 sal_uInt32 nBytes = 0; 600 ImplUnicodeToIso2022CnDesignator eNewDesignator = 601 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE; 602 switch (eSoDesignator) 603 { 604 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE: 605 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar); 606 if (nBytes != 0) 607 { 608 eNewDesignator 609 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312; 610 break; 611 } 612 nBytes = ImplIso2022CnTranslateTo116431( 613 pCns116431992Data, 614 pCns116431992PageOffsets, 615 pCns116431992PlaneOffsets, 616 nChar); 617 if (nBytes != 0) 618 { 619 eNewDesignator 620 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431; 621 break; 622 } 623 break; 624 625 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312: 626 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar); 627 if (nBytes != 0) 628 { 629 eNewDesignator 630 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE; 631 break; 632 } 633 nBytes = ImplIso2022CnTranslateTo116431( 634 pCns116431992Data, 635 pCns116431992PageOffsets, 636 pCns116431992PlaneOffsets, 637 nChar); 638 if (nBytes != 0) 639 { 640 eNewDesignator 641 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431; 642 break; 643 } 644 break; 645 646 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431: 647 nBytes = ImplIso2022CnTranslateTo116431( 648 pCns116431992Data, 649 pCns116431992PageOffsets, 650 pCns116431992PlaneOffsets, 651 nChar); 652 if (nBytes != 0) 653 { 654 eNewDesignator 655 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE; 656 break; 657 } 658 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar); 659 if (nBytes != 0) 660 { 661 eNewDesignator 662 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312; 663 break; 664 } 665 break; 666 } 667 if (nBytes != 0) 668 { 669 if (eNewDesignator 670 != IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE) 671 { 672 if (bSo) 673 { 674 if (pDestBufPtr != pDestBufEnd) 675 { 676 *pDestBufPtr++ = 0x0F; /* SI */ 677 bSo = sal_False; 678 } 679 else 680 goto no_output; 681 } 682 if (pDestBufEnd - pDestBufPtr >= 4) 683 { 684 *pDestBufPtr++ = 0x1B; /* ESC */ 685 *pDestBufPtr++ = 0x24; /* $ */ 686 *pDestBufPtr++ = 0x29; /* ) */ 687 *pDestBufPtr++ 688 = eNewDesignator 689 == IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312 ? 690 0x41 : 0x47; /* A, G */ 691 eSoDesignator = eNewDesignator; 692 } 693 else 694 goto no_output; 695 } 696 if (!bSo) 697 { 698 if (pDestBufPtr != pDestBufEnd) 699 { 700 *pDestBufPtr++ = 0x0E; /* SO */ 701 bSo = sal_True; 702 } 703 else 704 goto no_output; 705 } 706 if (pDestBufEnd - pDestBufPtr >= 4) 707 { 708 *pDestBufPtr++ = (sal_Char) (nBytes >> 8); 709 *pDestBufPtr++ = (sal_Char) (nBytes & 0xFF); 710 } 711 else 712 goto no_output; 713 } 714 else 715 { 716 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16]; 717 sal_uInt32 nFirst; 718 sal_uInt32 nLast; 719 sal_uInt32 nPlane; 720 if (nOffset == -1) 721 goto bad_input; 722 nOffset 723 = pCns116431992PageOffsets[nOffset 724 + ((nChar & 0xFF00) >> 8)]; 725 if (nOffset == -1) 726 goto bad_input; 727 nFirst = pCns116431992Data[nOffset++]; 728 nLast = pCns116431992Data[nOffset++]; 729 nChar &= 0xFF; 730 if (nChar < nFirst || nChar > nLast) 731 goto bad_input; 732 nOffset += 3 * (nChar - nFirst); 733 nPlane = pCns116431992Data[nOffset++]; 734 if (nPlane != 2) 735 goto bad_input; 736 if (!b116432Designator) 737 { 738 if (pDestBufEnd - pDestBufPtr >= 4) 739 { 740 *pDestBufPtr++ = 0x1B; /* ESC */ 741 *pDestBufPtr++ = 0x24; /* $ */ 742 *pDestBufPtr++ = 0x2A; /* * */ 743 *pDestBufPtr++ = 0x48; /* H */ 744 b116432Designator = sal_True; 745 } 746 else 747 goto no_output; 748 } 749 if (pDestBufEnd - pDestBufPtr >= 4) 750 { 751 *pDestBufPtr++ = 0x1B; /* ESC */ 752 *pDestBufPtr++ = 0x4E; /* N */ 753 *pDestBufPtr++ 754 = (sal_Char) (0x20 + pCns116431992Data[nOffset++]); 755 *pDestBufPtr++ 756 = (sal_Char) (0x20 + pCns116431992Data[nOffset]); 757 } 758 else 759 goto no_output; 760 } 761 } 762 nHighSurrogate = 0; 763 continue; 764 765 bad_input: 766 switch (ImplHandleBadInputUnicodeToTextConversion(bUndefined, 767 nChar, 768 nFlags, 769 &pDestBufPtr, 770 pDestBufEnd, 771 &nInfo, 772 "\x0F", /* SI */ 773 bSo ? 1 : 0, 774 &bWritten)) 775 { 776 case IMPL_BAD_INPUT_STOP: 777 nHighSurrogate = 0; 778 break; 779 780 case IMPL_BAD_INPUT_CONTINUE: 781 if (bWritten) 782 bSo = sal_False; 783 nHighSurrogate = 0; 784 continue; 785 786 case IMPL_BAD_INPUT_NO_OUTPUT: 787 goto no_output; 788 } 789 break; 790 791 no_output: 792 --pSrcBuf; 793 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL; 794 break; 795 } 796 797 if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR 798 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL)) 799 == 0) 800 { 801 sal_Bool bFlush = sal_True; 802 if (nHighSurrogate != 0) 803 { 804 if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0) 805 nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL; 806 else 807 switch (ImplHandleBadInputUnicodeToTextConversion( 808 sal_False, 809 0, 810 nFlags, 811 &pDestBufPtr, 812 pDestBufEnd, 813 &nInfo, 814 "\x0F", /* SI */ 815 bSo ? 1 : 0, 816 &bWritten)) 817 { 818 case IMPL_BAD_INPUT_STOP: 819 nHighSurrogate = 0; 820 bFlush = sal_False; 821 break; 822 823 case IMPL_BAD_INPUT_CONTINUE: 824 if (bWritten) 825 bSo = sal_False; 826 nHighSurrogate = 0; 827 break; 828 829 case IMPL_BAD_INPUT_NO_OUTPUT: 830 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL; 831 break; 832 } 833 } 834 if (bFlush && bSo && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0) 835 { 836 if (pDestBufPtr != pDestBufEnd) 837 { 838 *pDestBufPtr++ = 0x0F; /* SI */ 839 bSo = sal_False; 840 } 841 else 842 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL; 843 } 844 } 845 846 if (pContext) 847 { 848 ((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate 849 = nHighSurrogate; 850 ((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator 851 = eSoDesignator; 852 ((ImplUnicodeToIso2022CnContext *) pContext)->m_b116432Designator 853 = b116432Designator; 854 ((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo = bSo; 855 } 856 if (pInfo) 857 *pInfo = nInfo; 858 if (pSrcCvtChars) 859 *pSrcCvtChars = nConverted; 860 861 return pDestBufPtr - pDestBuf; 862 } 863