update dev300-m58
[ooovba.git] / sal / textenc / convertiso2022cn.c
blob6ce7c63bfd5d86dd8783843ba439d16d9eb3a8cf
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: convertiso2022cn.c,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "convertiso2022cn.h"
32 #include "context.h"
33 #include "converter.h"
34 #include "tenchelp.h"
35 #include "unichars.h"
36 #include "rtl/alloc.h"
37 #include "rtl/textcvt.h"
38 #include "sal/types.h"
40 typedef enum /* order is important: */
42 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII,
43 IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO,
44 IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2,
45 IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432,
46 IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2,
47 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC,
48 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR,
49 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN,
50 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK
51 } ImplIso2022CnToUnicodeState;
53 typedef struct
55 ImplIso2022CnToUnicodeState m_eState;
56 sal_uInt32 m_nRow;
57 sal_Bool m_bSo;
58 sal_Bool m_b116431;
59 } ImplIso2022CnToUnicodeContext;
61 typedef enum
63 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE,
64 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312,
65 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431
66 } ImplUnicodeToIso2022CnDesignator;
68 typedef struct
70 sal_Unicode m_nHighSurrogate;
71 ImplUnicodeToIso2022CnDesignator m_eSoDesignator;
72 sal_Bool m_b116432Designator;
73 sal_Bool m_bSo;
74 } ImplUnicodeToIso2022CnContext;
76 void * ImplCreateIso2022CnToUnicodeContext(void)
78 void * pContext
79 = rtl_allocateMemory(sizeof (ImplIso2022CnToUnicodeContext));
80 ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState
81 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
82 ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo = sal_False;
83 ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431 = sal_False;
84 return pContext;
87 void ImplResetIso2022CnToUnicodeContext(void * pContext)
89 if (pContext)
91 ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState
92 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
93 ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo = sal_False;
94 ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431 = sal_False;
98 sal_Size ImplConvertIso2022CnToUnicode(ImplTextConverterData const * pData,
99 void * pContext,
100 sal_Char const * pSrcBuf,
101 sal_Size nSrcBytes,
102 sal_Unicode * pDestBuf,
103 sal_Size nDestChars,
104 sal_uInt32 nFlags,
105 sal_uInt32 * pInfo,
106 sal_Size * pSrcCvtBytes)
108 ImplDBCSToUniLeadTab const * pGb2312Data
109 = ((ImplIso2022CnConverterData const *) pData)->
110 m_pGb2312ToUnicodeData;
111 sal_uInt16 const * pCns116431992Data
112 = ((ImplIso2022CnConverterData const *) pData)->
113 m_pCns116431992ToUnicodeData;
114 sal_Int32 const * pCns116431992RowOffsets
115 = ((ImplIso2022CnConverterData const *) pData)->
116 m_pCns116431992ToUnicodeRowOffsets;
117 sal_Int32 const * pCns116431992PlaneOffsets
118 = ((ImplIso2022CnConverterData const *) pData)->
119 m_pCns116431992ToUnicodePlaneOffsets;
120 ImplIso2022CnToUnicodeState eState
121 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
122 sal_uInt32 nRow = 0;
123 sal_Bool bSo = sal_False;
124 sal_Bool b116431 = sal_False;
125 sal_uInt32 nInfo = 0;
126 sal_Size nConverted = 0;
127 sal_Unicode * pDestBufPtr = pDestBuf;
128 sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
130 if (pContext)
132 eState = ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState;
133 nRow = ((ImplIso2022CnToUnicodeContext *) pContext)->m_nRow;
134 bSo = ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo;
135 b116431 = ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431;
138 for (; nConverted < nSrcBytes; ++nConverted)
140 sal_Bool bUndefined = sal_True;
141 sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++;
142 sal_uInt32 nPlane;
143 switch (eState)
145 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII:
146 if (nChar == 0x0E) /* SO */
148 bSo = sal_True;
149 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
151 else if (nChar == 0x1B) /* ESC */
152 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
153 else if (nChar < 0x80)
154 if (pDestBufPtr != pDestBufEnd)
155 *pDestBufPtr++ = (sal_Unicode) nChar;
156 else
157 goto no_output;
158 else
160 bUndefined = sal_False;
161 goto bad_input;
163 break;
165 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO:
166 if (nChar == 0x0F) /* SI */
168 bSo = sal_False;
169 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
171 else if (nChar == 0x1B) /* ESC */
172 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
173 else if (nChar >= 0x21 && nChar <= 0x7E)
175 nRow = nChar;
176 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2;
178 else
180 bUndefined = sal_False;
181 goto bad_input;
183 break;
185 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2:
186 if (nChar >= 0x21 && nChar <= 0x7E)
187 if (b116431)
189 nPlane = 0;
190 goto transform;
192 else
194 sal_uInt16 nUnicode = 0;
195 sal_uInt32 nFirst;
196 nRow += 0x80;
197 nChar += 0x80;
198 nFirst = pGb2312Data[nRow].mnTrailStart;
199 if (nChar >= nFirst
200 && nChar <= pGb2312Data[nRow].mnTrailEnd)
201 nUnicode = pGb2312Data[nRow].
202 mpToUniTrailTab[nChar - nFirst];
203 if (nUnicode != 0)
204 if (pDestBufPtr != pDestBufEnd)
206 *pDestBufPtr++ = (sal_Unicode) nUnicode;
207 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
209 else
210 goto no_output;
211 else
212 goto bad_input;
214 else
216 bUndefined = sal_False;
217 goto bad_input;
219 break;
221 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432:
222 if (nChar >= 0x21 && nChar <= 0x7E)
224 nRow = nChar;
225 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2;
227 else
229 bUndefined = sal_False;
230 goto bad_input;
232 break;
234 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2:
235 if (nChar >= 0x21 && nChar <= 0x7E)
237 nPlane = 1;
238 goto transform;
240 else
242 bUndefined = sal_False;
243 goto bad_input;
245 break;
247 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC:
248 if (nChar == 0x24) /* $ */
249 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR;
250 else if (nChar == 0x4E) /* N */
251 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432;
252 else
254 bUndefined = sal_False;
255 goto bad_input;
257 break;
259 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR:
260 if (nChar == 0x29) /* ) */
261 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN;
262 else if (nChar == 0x2A) /* * */
263 eState
264 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK;
265 else
267 bUndefined = sal_False;
268 goto bad_input;
270 break;
272 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN:
273 if (nChar == 0x41) /* A */
275 b116431 = sal_False;
276 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
277 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
279 else if (nChar == 0x47) /* G */
281 b116431 = sal_True;
282 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
283 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
285 else
287 bUndefined = sal_False;
288 goto bad_input;
290 break;
292 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK:
293 if (nChar == 0x48) /* H */
294 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
295 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
296 else
298 bUndefined = sal_False;
299 goto bad_input;
301 break;
303 continue;
305 transform:
307 sal_Int32 nPlaneOffset = pCns116431992PlaneOffsets[nPlane];
308 if (nPlaneOffset == -1)
309 goto bad_input;
310 else
312 sal_Int32 nOffset
313 = pCns116431992RowOffsets[nPlaneOffset + (nRow - 0x21)];
314 if (nOffset == -1)
315 goto bad_input;
316 else
318 sal_uInt32 nFirstLast = pCns116431992Data[nOffset++];
319 sal_uInt32 nFirst = nFirstLast & 0xFF;
320 sal_uInt32 nLast = nFirstLast >> 8;
321 nChar -= 0x20;
322 if (nChar >= nFirst && nChar <= nLast)
324 sal_uInt32 nUnicode
325 = pCns116431992Data[nOffset + (nChar - nFirst)];
326 if (nUnicode == 0xFFFF)
327 goto bad_input;
328 else if (ImplIsHighSurrogate(nUnicode))
329 if (pDestBufEnd - pDestBufPtr >= 2)
331 nOffset += nLast - nFirst + 1;
332 nFirst = pCns116431992Data[nOffset++];
333 *pDestBufPtr++ = (sal_Unicode) nUnicode;
334 *pDestBufPtr++
335 = (sal_Unicode)
336 pCns116431992Data[
337 nOffset + (nChar - nFirst)];
339 else
340 goto no_output;
341 else
342 if (pDestBufPtr != pDestBufEnd)
343 *pDestBufPtr++ = (sal_Unicode) nUnicode;
344 else
345 goto no_output;
347 else
348 goto bad_input;
349 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
350 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
353 continue;
356 bad_input:
357 switch (ImplHandleBadInputTextToUnicodeConversion(
358 bUndefined, sal_True, 0, nFlags, &pDestBufPtr, pDestBufEnd,
359 &nInfo))
361 case IMPL_BAD_INPUT_STOP:
362 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
363 b116431 = sal_False;
364 break;
366 case IMPL_BAD_INPUT_CONTINUE:
367 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
368 b116431 = sal_False;
369 continue;
371 case IMPL_BAD_INPUT_NO_OUTPUT:
372 goto no_output;
374 break;
376 no_output:
377 --pSrcBuf;
378 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
379 break;
382 if (eState > IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO
383 && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
384 | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
385 == 0)
387 if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
388 nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
389 else
390 switch (ImplHandleBadInputTextToUnicodeConversion(
391 sal_False, sal_True, 0, nFlags, &pDestBufPtr, pDestBufEnd,
392 &nInfo))
394 case IMPL_BAD_INPUT_STOP:
395 case IMPL_BAD_INPUT_CONTINUE:
396 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
397 b116431 = sal_False;
398 break;
400 case IMPL_BAD_INPUT_NO_OUTPUT:
401 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
402 break;
406 if (pContext)
408 ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState = eState;
409 ((ImplIso2022CnToUnicodeContext *) pContext)->m_nRow = nRow;
410 ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo = bSo;
411 ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431 = b116431;
413 if (pInfo)
414 *pInfo = nInfo;
415 if (pSrcCvtBytes)
416 *pSrcCvtBytes = nConverted;
418 return pDestBufPtr - pDestBuf;
421 void * ImplCreateUnicodeToIso2022CnContext(void)
423 void * pContext
424 = rtl_allocateMemory(sizeof (ImplUnicodeToIso2022CnContext));
425 ((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate = 0;
426 ((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator
427 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
428 ((ImplUnicodeToIso2022CnContext *) pContext)->m_b116432Designator
429 = sal_False;
430 ((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo = sal_False;
431 return pContext;
434 void ImplResetUnicodeToIso2022CnContext(void * pContext)
436 if (pContext)
438 ((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate = 0;
439 ((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator
440 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
441 ((ImplUnicodeToIso2022CnContext *) pContext)->m_b116432Designator
442 = sal_False;
443 ((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo = sal_False;
447 static sal_uInt32 ImplIso2022CnTranslateTo2312(ImplUniToDBCSHighTab const *
448 pGb2312Data,
449 sal_uInt32 nChar)
451 sal_uInt32 nIndex1 = nChar >> 8;
452 if (nIndex1 < 0x100)
454 sal_uInt32 nIndex2 = nChar & 0xFF;
455 sal_uInt32 nFirst = pGb2312Data[nIndex1].mnLowStart;
456 if (nIndex2 >= nFirst && nIndex2 <= pGb2312Data[nIndex1].mnLowEnd)
457 return pGb2312Data[nIndex1].mpToUniTrailTab[nIndex2 - nFirst]
458 & 0x7F7F;
460 return 0;
463 static sal_uInt32
464 ImplIso2022CnTranslateTo116431(sal_uInt8 const * pCns116431992Data,
465 sal_Int32 const * pCns116431992PageOffsets,
466 sal_Int32 const * pCns116431992PlaneOffsets,
467 sal_uInt32 nChar)
469 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
470 sal_uInt32 nFirst;
471 sal_uInt32 nLast;
472 sal_uInt32 nPlane;
473 if (nOffset == -1)
474 return 0;
475 nOffset = pCns116431992PageOffsets[nOffset + ((nChar & 0xFF00) >> 8)];
476 if (nOffset == -1)
477 return 0;
478 nFirst = pCns116431992Data[nOffset++];
479 nLast = pCns116431992Data[nOffset++];
480 nChar &= 0xFF;
481 if (nChar < nFirst || nChar > nLast)
482 return 0;
483 nOffset += 3 * (nChar - nFirst);
484 nPlane = pCns116431992Data[nOffset++];
485 if (nPlane != 1)
486 return 0;
487 return (0x20 + pCns116431992Data[nOffset]) << 8
488 | (0x20 + pCns116431992Data[nOffset + 1]);
491 sal_Size ImplConvertUnicodeToIso2022Cn(ImplTextConverterData const * pData,
492 void * pContext,
493 sal_Unicode const * pSrcBuf,
494 sal_Size nSrcChars,
495 sal_Char * pDestBuf,
496 sal_Size nDestBytes,
497 sal_uInt32 nFlags,
498 sal_uInt32 * pInfo,
499 sal_Size * pSrcCvtChars)
501 ImplUniToDBCSHighTab const * pGb2312Data
502 = ((ImplIso2022CnConverterData const *) pData)->
503 m_pUnicodeToGb2312Data;
504 sal_uInt8 const * pCns116431992Data
505 = ((ImplIso2022CnConverterData const *) pData)->
506 m_pUnicodeToCns116431992Data;
507 sal_Int32 const * pCns116431992PageOffsets
508 = ((ImplIso2022CnConverterData const *) pData)->
509 m_pUnicodeToCns116431992PageOffsets;
510 sal_Int32 const * pCns116431992PlaneOffsets
511 = ((ImplIso2022CnConverterData const *) pData)->
512 m_pUnicodeToCns116431992PlaneOffsets;
513 sal_Unicode nHighSurrogate = 0;
514 ImplUnicodeToIso2022CnDesignator eSoDesignator
515 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
516 sal_Bool b116432Designator = sal_False;
517 sal_Bool bSo = sal_False;
518 sal_uInt32 nInfo = 0;
519 sal_Size nConverted = 0;
520 sal_Char * pDestBufPtr = pDestBuf;
521 sal_Char * pDestBufEnd = pDestBuf + nDestBytes;
522 sal_Bool bWritten;
524 if (pContext)
526 nHighSurrogate
527 = ((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate;
528 eSoDesignator
529 = ((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator;
530 b116432Designator = ((ImplUnicodeToIso2022CnContext *) pContext)->
531 m_b116432Designator;
532 bSo = ((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo;
535 for (; nConverted < nSrcChars; ++nConverted)
537 sal_Bool bUndefined = sal_True;
538 sal_uInt32 nChar = *pSrcBuf++;
539 if (nHighSurrogate == 0)
541 if (ImplIsHighSurrogate(nChar))
543 nHighSurrogate = (sal_Unicode) nChar;
544 continue;
547 else if (ImplIsLowSurrogate(nChar))
548 nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
549 else
551 bUndefined = sal_False;
552 goto bad_input;
555 if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
557 bUndefined = sal_False;
558 goto bad_input;
561 if (nChar == 0x0A || nChar == 0x0D) /* LF, CR */
563 if (bSo)
565 if (pDestBufPtr != pDestBufEnd)
567 *pDestBufPtr++ = 0x0F; /* SI */
568 bSo = sal_False;
569 eSoDesignator
570 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
571 b116432Designator = sal_False;
573 else
574 goto no_output;
576 if (pDestBufPtr != pDestBufEnd)
577 *pDestBufPtr++ = (sal_Char) nChar;
578 else
579 goto no_output;
581 else if (nChar == 0x0E || nChar == 0x0F || nChar == 0x1B)
582 goto bad_input;
583 else if (nChar < 0x80)
585 if (bSo)
587 if (pDestBufPtr != pDestBufEnd)
589 *pDestBufPtr++ = 0x0F; /* SI */
590 bSo = sal_False;
592 else
593 goto no_output;
595 if (pDestBufPtr != pDestBufEnd)
596 *pDestBufPtr++ = (sal_Char) nChar;
597 else
598 goto no_output;
600 else
602 sal_uInt32 nBytes = 0;
603 ImplUnicodeToIso2022CnDesignator eNewDesignator =
604 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
605 switch (eSoDesignator)
607 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE:
608 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
609 if (nBytes != 0)
611 eNewDesignator
612 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
613 break;
615 nBytes = ImplIso2022CnTranslateTo116431(
616 pCns116431992Data,
617 pCns116431992PageOffsets,
618 pCns116431992PlaneOffsets,
619 nChar);
620 if (nBytes != 0)
622 eNewDesignator
623 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
624 break;
626 break;
628 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312:
629 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
630 if (nBytes != 0)
632 eNewDesignator
633 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
634 break;
636 nBytes = ImplIso2022CnTranslateTo116431(
637 pCns116431992Data,
638 pCns116431992PageOffsets,
639 pCns116431992PlaneOffsets,
640 nChar);
641 if (nBytes != 0)
643 eNewDesignator
644 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
645 break;
647 break;
649 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431:
650 nBytes = ImplIso2022CnTranslateTo116431(
651 pCns116431992Data,
652 pCns116431992PageOffsets,
653 pCns116431992PlaneOffsets,
654 nChar);
655 if (nBytes != 0)
657 eNewDesignator
658 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
659 break;
661 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
662 if (nBytes != 0)
664 eNewDesignator
665 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
666 break;
668 break;
670 if (nBytes != 0)
672 if (eNewDesignator
673 != IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE)
675 if (bSo)
677 if (pDestBufPtr != pDestBufEnd)
679 *pDestBufPtr++ = 0x0F; /* SI */
680 bSo = sal_False;
682 else
683 goto no_output;
685 if (pDestBufEnd - pDestBufPtr >= 4)
687 *pDestBufPtr++ = 0x1B; /* ESC */
688 *pDestBufPtr++ = 0x24; /* $ */
689 *pDestBufPtr++ = 0x29; /* ) */
690 *pDestBufPtr++
691 = eNewDesignator
692 == IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312 ?
693 0x41 : 0x47; /* A, G */
694 eSoDesignator = eNewDesignator;
696 else
697 goto no_output;
699 if (!bSo)
701 if (pDestBufPtr != pDestBufEnd)
703 *pDestBufPtr++ = 0x0E; /* SO */
704 bSo = sal_True;
706 else
707 goto no_output;
709 if (pDestBufEnd - pDestBufPtr >= 4)
711 *pDestBufPtr++ = (sal_Char) (nBytes >> 8);
712 *pDestBufPtr++ = (sal_Char) (nBytes & 0xFF);
714 else
715 goto no_output;
717 else
719 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
720 sal_uInt32 nFirst;
721 sal_uInt32 nLast;
722 sal_uInt32 nPlane;
723 if (nOffset == -1)
724 goto bad_input;
725 nOffset
726 = pCns116431992PageOffsets[nOffset
727 + ((nChar & 0xFF00) >> 8)];
728 if (nOffset == -1)
729 goto bad_input;
730 nFirst = pCns116431992Data[nOffset++];
731 nLast = pCns116431992Data[nOffset++];
732 nChar &= 0xFF;
733 if (nChar < nFirst || nChar > nLast)
734 goto bad_input;
735 nOffset += 3 * (nChar - nFirst);
736 nPlane = pCns116431992Data[nOffset++];
737 if (nPlane != 2)
738 goto bad_input;
739 if (!b116432Designator)
741 if (pDestBufEnd - pDestBufPtr >= 4)
743 *pDestBufPtr++ = 0x1B; /* ESC */
744 *pDestBufPtr++ = 0x24; /* $ */
745 *pDestBufPtr++ = 0x2A; /* * */
746 *pDestBufPtr++ = 0x48; /* H */
747 b116432Designator = sal_True;
749 else
750 goto no_output;
752 if (pDestBufEnd - pDestBufPtr >= 4)
754 *pDestBufPtr++ = 0x1B; /* ESC */
755 *pDestBufPtr++ = 0x4E; /* N */
756 *pDestBufPtr++
757 = (sal_Char) (0x20 + pCns116431992Data[nOffset++]);
758 *pDestBufPtr++
759 = (sal_Char) (0x20 + pCns116431992Data[nOffset]);
761 else
762 goto no_output;
765 nHighSurrogate = 0;
766 continue;
768 bad_input:
769 switch (ImplHandleBadInputUnicodeToTextConversion(bUndefined,
770 nChar,
771 nFlags,
772 &pDestBufPtr,
773 pDestBufEnd,
774 &nInfo,
775 "\x0F", /* SI */
776 bSo ? 1 : 0,
777 &bWritten))
779 case IMPL_BAD_INPUT_STOP:
780 nHighSurrogate = 0;
781 break;
783 case IMPL_BAD_INPUT_CONTINUE:
784 if (bWritten)
785 bSo = sal_False;
786 nHighSurrogate = 0;
787 continue;
789 case IMPL_BAD_INPUT_NO_OUTPUT:
790 goto no_output;
792 break;
794 no_output:
795 --pSrcBuf;
796 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
797 break;
800 if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
801 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
802 == 0)
804 sal_Bool bFlush = sal_True;
805 if (nHighSurrogate != 0)
807 if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
808 nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
809 else
810 switch (ImplHandleBadInputUnicodeToTextConversion(
811 sal_False,
813 nFlags,
814 &pDestBufPtr,
815 pDestBufEnd,
816 &nInfo,
817 "\x0F", /* SI */
818 bSo ? 1 : 0,
819 &bWritten))
821 case IMPL_BAD_INPUT_STOP:
822 nHighSurrogate = 0;
823 bFlush = sal_False;
824 break;
826 case IMPL_BAD_INPUT_CONTINUE:
827 if (bWritten)
828 bSo = sal_False;
829 nHighSurrogate = 0;
830 break;
832 case IMPL_BAD_INPUT_NO_OUTPUT:
833 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
834 break;
837 if (bFlush && bSo && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
839 if (pDestBufPtr != pDestBufEnd)
841 *pDestBufPtr++ = 0x0F; /* SI */
842 bSo = sal_False;
844 else
845 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
849 if (pContext)
851 ((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate
852 = nHighSurrogate;
853 ((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator
854 = eSoDesignator;
855 ((ImplUnicodeToIso2022CnContext *) pContext)->m_b116432Designator
856 = b116432Designator;
857 ((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo = bSo;
859 if (pInfo)
860 *pInfo = nInfo;
861 if (pSrcCvtChars)
862 *pSrcCvtChars = nConverted;
864 return pDestBufPtr - pDestBuf;