merged tag ooo/DEV300_m102
[LibreOffice.git] / sal / textenc / convertiso2022cn.c
blob6ae445d99e73b8b9fcb708c30a145f2d55bf0cea
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
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"
37 typedef enum /* order is important: */
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;
50 typedef struct
52 ImplIso2022CnToUnicodeState m_eState;
53 sal_uInt32 m_nRow;
54 sal_Bool m_bSo;
55 sal_Bool m_b116431;
56 } ImplIso2022CnToUnicodeContext;
58 typedef enum
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;
65 typedef struct
67 sal_Unicode m_nHighSurrogate;
68 ImplUnicodeToIso2022CnDesignator m_eSoDesignator;
69 sal_Bool m_b116432Designator;
70 sal_Bool m_bSo;
71 } ImplUnicodeToIso2022CnContext;
73 void * ImplCreateIso2022CnToUnicodeContext(void)
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;
84 void ImplResetIso2022CnToUnicodeContext(void * pContext)
86 if (pContext)
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;
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)
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;
127 if (pContext)
129 eState = ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState;
130 nRow = ((ImplIso2022CnToUnicodeContext *) pContext)->m_nRow;
131 bSo = ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo;
132 b116431 = ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431;
135 for (; nConverted < nSrcBytes; ++nConverted)
137 sal_Bool bUndefined = sal_True;
138 sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++;
139 sal_uInt32 nPlane;
140 switch (eState)
142 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII:
143 if (nChar == 0x0E) /* SO */
145 bSo = sal_True;
146 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
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
157 bUndefined = sal_False;
158 goto bad_input;
160 break;
162 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO:
163 if (nChar == 0x0F) /* SI */
165 bSo = sal_False;
166 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
168 else if (nChar == 0x1B) /* ESC */
169 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
170 else if (nChar >= 0x21 && nChar <= 0x7E)
172 nRow = nChar;
173 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2;
175 else
177 bUndefined = sal_False;
178 goto bad_input;
180 break;
182 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2:
183 if (nChar >= 0x21 && nChar <= 0x7E)
184 if (b116431)
186 nPlane = 0;
187 goto transform;
189 else
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)
203 *pDestBufPtr++ = (sal_Unicode) nUnicode;
204 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
206 else
207 goto no_output;
208 else
209 goto bad_input;
211 else
213 bUndefined = sal_False;
214 goto bad_input;
216 break;
218 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432:
219 if (nChar >= 0x21 && nChar <= 0x7E)
221 nRow = nChar;
222 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2;
224 else
226 bUndefined = sal_False;
227 goto bad_input;
229 break;
231 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2:
232 if (nChar >= 0x21 && nChar <= 0x7E)
234 nPlane = 1;
235 goto transform;
237 else
239 bUndefined = sal_False;
240 goto bad_input;
242 break;
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
251 bUndefined = sal_False;
252 goto bad_input;
254 break;
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
264 bUndefined = sal_False;
265 goto bad_input;
267 break;
269 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN:
270 if (nChar == 0x41) /* A */
272 b116431 = sal_False;
273 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
274 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
276 else if (nChar == 0x47) /* G */
278 b116431 = sal_True;
279 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
280 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
282 else
284 bUndefined = sal_False;
285 goto bad_input;
287 break;
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
295 bUndefined = sal_False;
296 goto bad_input;
298 break;
300 continue;
302 transform:
304 sal_Int32 nPlaneOffset = pCns116431992PlaneOffsets[nPlane];
305 if (nPlaneOffset == -1)
306 goto bad_input;
307 else
309 sal_Int32 nOffset
310 = pCns116431992RowOffsets[nPlaneOffset + (nRow - 0x21)];
311 if (nOffset == -1)
312 goto bad_input;
313 else
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)
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)
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)];
336 else
337 goto no_output;
338 else
339 if (pDestBufPtr != pDestBufEnd)
340 *pDestBufPtr++ = (sal_Unicode) nUnicode;
341 else
342 goto no_output;
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;
350 continue;
353 bad_input:
354 switch (ImplHandleBadInputTextToUnicodeConversion(
355 bUndefined, sal_True, 0, nFlags, &pDestBufPtr, pDestBufEnd,
356 &nInfo))
358 case IMPL_BAD_INPUT_STOP:
359 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
360 b116431 = sal_False;
361 break;
363 case IMPL_BAD_INPUT_CONTINUE:
364 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
365 b116431 = sal_False;
366 continue;
368 case IMPL_BAD_INPUT_NO_OUTPUT:
369 goto no_output;
371 break;
373 no_output:
374 --pSrcBuf;
375 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
376 break;
379 if (eState > IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO
380 && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
381 | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
382 == 0)
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))
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;
397 case IMPL_BAD_INPUT_NO_OUTPUT:
398 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
399 break;
403 if (pContext)
405 ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState = eState;
406 ((ImplIso2022CnToUnicodeContext *) pContext)->m_nRow = nRow;
407 ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo = bSo;
408 ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431 = b116431;
410 if (pInfo)
411 *pInfo = nInfo;
412 if (pSrcCvtBytes)
413 *pSrcCvtBytes = nConverted;
415 return pDestBufPtr - pDestBuf;
418 void * ImplCreateUnicodeToIso2022CnContext(void)
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;
431 void ImplResetUnicodeToIso2022CnContext(void * pContext)
433 if (pContext)
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;
444 static sal_uInt32 ImplIso2022CnTranslateTo2312(ImplUniToDBCSHighTab const *
445 pGb2312Data,
446 sal_uInt32 nChar)
448 sal_uInt32 nIndex1 = nChar >> 8;
449 if (nIndex1 < 0x100)
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;
457 return 0;
460 static sal_uInt32
461 ImplIso2022CnTranslateTo116431(sal_uInt8 const * pCns116431992Data,
462 sal_Int32 const * pCns116431992PageOffsets,
463 sal_Int32 const * pCns116431992PlaneOffsets,
464 sal_uInt32 nChar)
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]);
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)
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;
521 if (pContext)
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;
532 for (; nConverted < nSrcChars; ++nConverted)
534 sal_Bool bUndefined = sal_True;
535 sal_uInt32 nChar = *pSrcBuf++;
536 if (nHighSurrogate == 0)
538 if (ImplIsHighSurrogate(nChar))
540 nHighSurrogate = (sal_Unicode) nChar;
541 continue;
544 else if (ImplIsLowSurrogate(nChar))
545 nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
546 else
548 bUndefined = sal_False;
549 goto bad_input;
552 if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
554 bUndefined = sal_False;
555 goto bad_input;
558 if (nChar == 0x0A || nChar == 0x0D) /* LF, CR */
560 if (bSo)
562 if (pDestBufPtr != pDestBufEnd)
564 *pDestBufPtr++ = 0x0F; /* SI */
565 bSo = sal_False;
566 eSoDesignator
567 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
568 b116432Designator = sal_False;
570 else
571 goto no_output;
573 if (pDestBufPtr != pDestBufEnd)
574 *pDestBufPtr++ = (sal_Char) nChar;
575 else
576 goto no_output;
578 else if (nChar == 0x0E || nChar == 0x0F || nChar == 0x1B)
579 goto bad_input;
580 else if (nChar < 0x80)
582 if (bSo)
584 if (pDestBufPtr != pDestBufEnd)
586 *pDestBufPtr++ = 0x0F; /* SI */
587 bSo = sal_False;
589 else
590 goto no_output;
592 if (pDestBufPtr != pDestBufEnd)
593 *pDestBufPtr++ = (sal_Char) nChar;
594 else
595 goto no_output;
597 else
599 sal_uInt32 nBytes = 0;
600 ImplUnicodeToIso2022CnDesignator eNewDesignator =
601 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
602 switch (eSoDesignator)
604 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE:
605 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
606 if (nBytes != 0)
608 eNewDesignator
609 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
610 break;
612 nBytes = ImplIso2022CnTranslateTo116431(
613 pCns116431992Data,
614 pCns116431992PageOffsets,
615 pCns116431992PlaneOffsets,
616 nChar);
617 if (nBytes != 0)
619 eNewDesignator
620 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
621 break;
623 break;
625 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312:
626 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
627 if (nBytes != 0)
629 eNewDesignator
630 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
631 break;
633 nBytes = ImplIso2022CnTranslateTo116431(
634 pCns116431992Data,
635 pCns116431992PageOffsets,
636 pCns116431992PlaneOffsets,
637 nChar);
638 if (nBytes != 0)
640 eNewDesignator
641 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
642 break;
644 break;
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)
654 eNewDesignator
655 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
656 break;
658 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
659 if (nBytes != 0)
661 eNewDesignator
662 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
663 break;
665 break;
667 if (nBytes != 0)
669 if (eNewDesignator
670 != IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE)
672 if (bSo)
674 if (pDestBufPtr != pDestBufEnd)
676 *pDestBufPtr++ = 0x0F; /* SI */
677 bSo = sal_False;
679 else
680 goto no_output;
682 if (pDestBufEnd - pDestBufPtr >= 4)
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;
693 else
694 goto no_output;
696 if (!bSo)
698 if (pDestBufPtr != pDestBufEnd)
700 *pDestBufPtr++ = 0x0E; /* SO */
701 bSo = sal_True;
703 else
704 goto no_output;
706 if (pDestBufEnd - pDestBufPtr >= 4)
708 *pDestBufPtr++ = (sal_Char) (nBytes >> 8);
709 *pDestBufPtr++ = (sal_Char) (nBytes & 0xFF);
711 else
712 goto no_output;
714 else
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)
738 if (pDestBufEnd - pDestBufPtr >= 4)
740 *pDestBufPtr++ = 0x1B; /* ESC */
741 *pDestBufPtr++ = 0x24; /* $ */
742 *pDestBufPtr++ = 0x2A; /* * */
743 *pDestBufPtr++ = 0x48; /* H */
744 b116432Designator = sal_True;
746 else
747 goto no_output;
749 if (pDestBufEnd - pDestBufPtr >= 4)
751 *pDestBufPtr++ = 0x1B; /* ESC */
752 *pDestBufPtr++ = 0x4E; /* N */
753 *pDestBufPtr++
754 = (sal_Char) (0x20 + pCns116431992Data[nOffset++]);
755 *pDestBufPtr++
756 = (sal_Char) (0x20 + pCns116431992Data[nOffset]);
758 else
759 goto no_output;
762 nHighSurrogate = 0;
763 continue;
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))
776 case IMPL_BAD_INPUT_STOP:
777 nHighSurrogate = 0;
778 break;
780 case IMPL_BAD_INPUT_CONTINUE:
781 if (bWritten)
782 bSo = sal_False;
783 nHighSurrogate = 0;
784 continue;
786 case IMPL_BAD_INPUT_NO_OUTPUT:
787 goto no_output;
789 break;
791 no_output:
792 --pSrcBuf;
793 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
794 break;
797 if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
798 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
799 == 0)
801 sal_Bool bFlush = sal_True;
802 if (nHighSurrogate != 0)
804 if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
805 nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
806 else
807 switch (ImplHandleBadInputUnicodeToTextConversion(
808 sal_False,
810 nFlags,
811 &pDestBufPtr,
812 pDestBufEnd,
813 &nInfo,
814 "\x0F", /* SI */
815 bSo ? 1 : 0,
816 &bWritten))
818 case IMPL_BAD_INPUT_STOP:
819 nHighSurrogate = 0;
820 bFlush = sal_False;
821 break;
823 case IMPL_BAD_INPUT_CONTINUE:
824 if (bWritten)
825 bSo = sal_False;
826 nHighSurrogate = 0;
827 break;
829 case IMPL_BAD_INPUT_NO_OUTPUT:
830 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
831 break;
834 if (bFlush && bSo && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
836 if (pDestBufPtr != pDestBufEnd)
838 *pDestBufPtr++ = 0x0F; /* SI */
839 bSo = sal_False;
841 else
842 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
846 if (pContext)
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;
856 if (pInfo)
857 *pInfo = nInfo;
858 if (pSrcCvtChars)
859 *pSrcCvtChars = nConverted;
861 return pDestBufPtr - pDestBuf;