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