Bump for 3.6-28
[LibreOffice.git] / sal / textenc / convertiso2022cn.cxx
blob8241c5b5519850e588ea6cfa9639d7f5766f3d81
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "sal/config.h"
31 #include "rtl/textcvt.h"
32 #include "sal/types.h"
34 #include "context.hxx"
35 #include "converter.hxx"
36 #include "convertiso2022cn.hxx"
37 #include "tenchelp.hxx"
38 #include "unichars.hxx"
40 namespace {
42 enum ImplIso2022CnToUnicodeState // order is important:
44 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII,
45 IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO,
46 IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2,
47 IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432,
48 IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2,
49 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC,
50 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR,
51 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN,
52 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK
55 struct ImplIso2022CnToUnicodeContext
57 ImplIso2022CnToUnicodeState m_eState;
58 sal_uInt32 m_nRow;
59 bool m_bSo;
60 bool m_b116431;
63 enum ImplUnicodeToIso2022CnDesignator
65 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE,
66 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312,
67 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431
70 struct ImplUnicodeToIso2022CnContext
72 sal_Unicode m_nHighSurrogate;
73 ImplUnicodeToIso2022CnDesignator m_eSoDesignator;
74 bool m_b116432Designator;
75 bool m_bSo;
80 void * ImplCreateIso2022CnToUnicodeContext()
82 ImplIso2022CnToUnicodeContext * pContext =
83 new ImplIso2022CnToUnicodeContext;
84 pContext->m_eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
85 pContext->m_bSo = false;
86 pContext->m_b116431 = false;
87 return pContext;
90 void ImplResetIso2022CnToUnicodeContext(void * pContext)
92 if (pContext)
94 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState
95 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
96 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo = false;
97 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431 = false;
101 void ImplDestroyIso2022CnToUnicodeContext(void * pContext)
103 delete static_cast< ImplIso2022CnToUnicodeContext * >(pContext);
106 sal_Size ImplConvertIso2022CnToUnicode(void const * pData,
107 void * pContext,
108 char const * pSrcBuf,
109 sal_Size nSrcBytes,
110 sal_Unicode * pDestBuf,
111 sal_Size nDestChars,
112 sal_uInt32 nFlags,
113 sal_uInt32 * pInfo,
114 sal_Size * pSrcCvtBytes)
116 ImplDBCSToUniLeadTab const * pGb2312Data
117 = static_cast< ImplIso2022CnConverterData const * >(pData)->
118 m_pGb2312ToUnicodeData;
119 sal_uInt16 const * pCns116431992Data
120 = static_cast< ImplIso2022CnConverterData const * >(pData)->
121 m_pCns116431992ToUnicodeData;
122 sal_Int32 const * pCns116431992RowOffsets
123 = static_cast< ImplIso2022CnConverterData const * >(pData)->
124 m_pCns116431992ToUnicodeRowOffsets;
125 sal_Int32 const * pCns116431992PlaneOffsets
126 = static_cast< ImplIso2022CnConverterData const * >(pData)->
127 m_pCns116431992ToUnicodePlaneOffsets;
128 ImplIso2022CnToUnicodeState eState
129 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
130 sal_uInt32 nRow = 0;
131 bool bSo = false;
132 bool b116431 = false;
133 sal_uInt32 nInfo = 0;
134 sal_Size nConverted = 0;
135 sal_Unicode * pDestBufPtr = pDestBuf;
136 sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
138 if (pContext)
140 eState = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState;
141 nRow = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_nRow;
142 bSo = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo;
143 b116431 = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431;
146 for (; nConverted < nSrcBytes; ++nConverted)
148 bool bUndefined = true;
149 sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++;
150 sal_uInt32 nPlane;
151 switch (eState)
153 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII:
154 if (nChar == 0x0E) // SO
156 bSo = true;
157 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
159 else if (nChar == 0x1B) // ESC
160 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
161 else if (nChar < 0x80)
162 if (pDestBufPtr != pDestBufEnd)
163 *pDestBufPtr++ = (sal_Unicode) nChar;
164 else
165 goto no_output;
166 else
168 bUndefined = false;
169 goto bad_input;
171 break;
173 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO:
174 if (nChar == 0x0F) // SI
176 bSo = false;
177 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
179 else if (nChar == 0x1B) // ESC
180 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
181 else if (nChar >= 0x21 && nChar <= 0x7E)
183 nRow = nChar;
184 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2;
186 else
188 bUndefined = false;
189 goto bad_input;
191 break;
193 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2:
194 if (nChar >= 0x21 && nChar <= 0x7E)
195 if (b116431)
197 nPlane = 0;
198 goto transform;
200 else
202 sal_uInt16 nUnicode = 0;
203 sal_uInt32 nFirst;
204 nRow += 0x80;
205 nChar += 0x80;
206 nFirst = pGb2312Data[nRow].mnTrailStart;
207 if (nChar >= nFirst
208 && nChar <= pGb2312Data[nRow].mnTrailEnd)
209 nUnicode = pGb2312Data[nRow].
210 mpToUniTrailTab[nChar - nFirst];
211 if (nUnicode != 0)
212 if (pDestBufPtr != pDestBufEnd)
214 *pDestBufPtr++ = (sal_Unicode) nUnicode;
215 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
217 else
218 goto no_output;
219 else
220 goto bad_input;
222 else
224 bUndefined = false;
225 goto bad_input;
227 break;
229 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432:
230 if (nChar >= 0x21 && nChar <= 0x7E)
232 nRow = nChar;
233 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2;
235 else
237 bUndefined = false;
238 goto bad_input;
240 break;
242 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2:
243 if (nChar >= 0x21 && nChar <= 0x7E)
245 nPlane = 1;
246 goto transform;
248 else
250 bUndefined = false;
251 goto bad_input;
253 break;
255 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC:
256 if (nChar == 0x24) // $
257 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR;
258 else if (nChar == 0x4E) // N
259 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432;
260 else
262 bUndefined = false;
263 goto bad_input;
265 break;
267 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR:
268 if (nChar == 0x29) // )
269 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN;
270 else if (nChar == 0x2A) // *
271 eState
272 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK;
273 else
275 bUndefined = false;
276 goto bad_input;
278 break;
280 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN:
281 if (nChar == 0x41) // A
283 b116431 = false;
284 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
285 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
287 else if (nChar == 0x47) // G
289 b116431 = true;
290 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
291 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
293 else
295 bUndefined = false;
296 goto bad_input;
298 break;
300 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK:
301 if (nChar == 0x48) // H
302 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
303 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
304 else
306 bUndefined = false;
307 goto bad_input;
309 break;
311 continue;
313 transform:
315 sal_Int32 nPlaneOffset = pCns116431992PlaneOffsets[nPlane];
316 if (nPlaneOffset == -1)
317 goto bad_input;
318 else
320 sal_Int32 nOffset
321 = pCns116431992RowOffsets[nPlaneOffset + (nRow - 0x21)];
322 if (nOffset == -1)
323 goto bad_input;
324 else
326 sal_uInt32 nFirstLast = pCns116431992Data[nOffset++];
327 sal_uInt32 nFirst = nFirstLast & 0xFF;
328 sal_uInt32 nLast = nFirstLast >> 8;
329 nChar -= 0x20;
330 if (nChar >= nFirst && nChar <= nLast)
332 sal_uInt32 nUnicode
333 = pCns116431992Data[nOffset + (nChar - nFirst)];
334 if (nUnicode == 0xFFFF)
335 goto bad_input;
336 else if (ImplIsHighSurrogate(nUnicode))
337 if (pDestBufEnd - pDestBufPtr >= 2)
339 nOffset += nLast - nFirst + 1;
340 nFirst = pCns116431992Data[nOffset++];
341 *pDestBufPtr++ = (sal_Unicode) nUnicode;
342 *pDestBufPtr++
343 = (sal_Unicode)
344 pCns116431992Data[
345 nOffset + (nChar - nFirst)];
347 else
348 goto no_output;
349 else
350 if (pDestBufPtr != pDestBufEnd)
351 *pDestBufPtr++ = (sal_Unicode) nUnicode;
352 else
353 goto no_output;
355 else
356 goto bad_input;
357 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
358 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
361 continue;
364 bad_input:
365 switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
366 bUndefined, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
367 &nInfo))
369 case sal::detail::textenc::BAD_INPUT_STOP:
370 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
371 b116431 = false;
372 break;
374 case sal::detail::textenc::BAD_INPUT_CONTINUE:
375 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
376 b116431 = false;
377 continue;
379 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
380 goto no_output;
382 break;
384 no_output:
385 --pSrcBuf;
386 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
387 break;
390 if (eState > IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO
391 && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
392 | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
393 == 0)
395 if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
396 nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
397 else
398 switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
399 false, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
400 &nInfo))
402 case sal::detail::textenc::BAD_INPUT_STOP:
403 case sal::detail::textenc::BAD_INPUT_CONTINUE:
404 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
405 b116431 = false;
406 break;
408 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
409 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
410 break;
414 if (pContext)
416 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState = eState;
417 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_nRow = nRow;
418 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo = bSo;
419 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431 = b116431;
421 if (pInfo)
422 *pInfo = nInfo;
423 if (pSrcCvtBytes)
424 *pSrcCvtBytes = nConverted;
426 return pDestBufPtr - pDestBuf;
429 void * ImplCreateUnicodeToIso2022CnContext(void)
431 ImplUnicodeToIso2022CnContext * pContext =
432 new ImplUnicodeToIso2022CnContext;
433 pContext->m_nHighSurrogate = 0;
434 pContext->m_eSoDesignator = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
435 pContext->m_b116432Designator = false;
436 pContext->m_bSo = false;
437 return pContext;
440 void ImplResetUnicodeToIso2022CnContext(void * pContext)
442 if (pContext)
444 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate = 0;
445 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator
446 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
447 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_b116432Designator
448 = false;
449 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo = false;
453 void ImplDestroyUnicodeToIso2022CnContext(void * pContext)
455 delete static_cast< ImplUnicodeToIso2022CnContext * >(pContext);
458 static sal_uInt32 ImplIso2022CnTranslateTo2312(ImplUniToDBCSHighTab const *
459 pGb2312Data,
460 sal_uInt32 nChar)
462 sal_uInt32 nIndex1 = nChar >> 8;
463 if (nIndex1 < 0x100)
465 sal_uInt32 nIndex2 = nChar & 0xFF;
466 sal_uInt32 nFirst = pGb2312Data[nIndex1].mnLowStart;
467 if (nIndex2 >= nFirst && nIndex2 <= pGb2312Data[nIndex1].mnLowEnd)
468 return pGb2312Data[nIndex1].mpToUniTrailTab[nIndex2 - nFirst]
469 & 0x7F7F;
471 return 0;
474 static sal_uInt32
475 ImplIso2022CnTranslateTo116431(sal_uInt8 const * pCns116431992Data,
476 sal_Int32 const * pCns116431992PageOffsets,
477 sal_Int32 const * pCns116431992PlaneOffsets,
478 sal_uInt32 nChar)
480 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
481 sal_uInt32 nFirst;
482 sal_uInt32 nLast;
483 sal_uInt32 nPlane;
484 if (nOffset == -1)
485 return 0;
486 nOffset = pCns116431992PageOffsets[nOffset + ((nChar & 0xFF00) >> 8)];
487 if (nOffset == -1)
488 return 0;
489 nFirst = pCns116431992Data[nOffset++];
490 nLast = pCns116431992Data[nOffset++];
491 nChar &= 0xFF;
492 if (nChar < nFirst || nChar > nLast)
493 return 0;
494 nOffset += 3 * (nChar - nFirst);
495 nPlane = pCns116431992Data[nOffset++];
496 if (nPlane != 1)
497 return 0;
498 return (0x20 + pCns116431992Data[nOffset]) << 8
499 | (0x20 + pCns116431992Data[nOffset + 1]);
502 sal_Size ImplConvertUnicodeToIso2022Cn(void const * pData,
503 void * pContext,
504 sal_Unicode const * pSrcBuf,
505 sal_Size nSrcChars,
506 char * pDestBuf,
507 sal_Size nDestBytes,
508 sal_uInt32 nFlags,
509 sal_uInt32 * pInfo,
510 sal_Size * pSrcCvtChars)
512 ImplUniToDBCSHighTab const * pGb2312Data
513 = static_cast< ImplIso2022CnConverterData const * >(pData)->
514 m_pUnicodeToGb2312Data;
515 sal_uInt8 const * pCns116431992Data
516 = static_cast< ImplIso2022CnConverterData const * >(pData)->
517 m_pUnicodeToCns116431992Data;
518 sal_Int32 const * pCns116431992PageOffsets
519 = static_cast< ImplIso2022CnConverterData const * >(pData)->
520 m_pUnicodeToCns116431992PageOffsets;
521 sal_Int32 const * pCns116431992PlaneOffsets
522 = static_cast< ImplIso2022CnConverterData const * >(pData)->
523 m_pUnicodeToCns116431992PlaneOffsets;
524 sal_Unicode nHighSurrogate = 0;
525 ImplUnicodeToIso2022CnDesignator eSoDesignator
526 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
527 bool b116432Designator = false;
528 bool bSo = false;
529 sal_uInt32 nInfo = 0;
530 sal_Size nConverted = 0;
531 char * pDestBufPtr = pDestBuf;
532 char * pDestBufEnd = pDestBuf + nDestBytes;
533 bool bWritten;
535 if (pContext)
537 nHighSurrogate
538 = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate;
539 eSoDesignator
540 = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator;
541 b116432Designator = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->
542 m_b116432Designator;
543 bSo = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo;
546 for (; nConverted < nSrcChars; ++nConverted)
548 bool bUndefined = true;
549 sal_uInt32 nChar = *pSrcBuf++;
550 if (nHighSurrogate == 0)
552 if (ImplIsHighSurrogate(nChar))
554 nHighSurrogate = (sal_Unicode) nChar;
555 continue;
558 else if (ImplIsLowSurrogate(nChar))
559 nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
560 else
562 bUndefined = false;
563 goto bad_input;
566 if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
568 bUndefined = false;
569 goto bad_input;
572 if (nChar == 0x0A || nChar == 0x0D) // LF, CR
574 if (bSo)
576 if (pDestBufPtr != pDestBufEnd)
578 *pDestBufPtr++ = 0x0F; // SI
579 bSo = false;
580 eSoDesignator
581 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
582 b116432Designator = false;
584 else
585 goto no_output;
587 if (pDestBufPtr != pDestBufEnd)
588 *pDestBufPtr++ = static_cast< char >(nChar);
589 else
590 goto no_output;
592 else if (nChar == 0x0E || nChar == 0x0F || nChar == 0x1B)
593 goto bad_input;
594 else if (nChar < 0x80)
596 if (bSo)
598 if (pDestBufPtr != pDestBufEnd)
600 *pDestBufPtr++ = 0x0F; // SI
601 bSo = false;
603 else
604 goto no_output;
606 if (pDestBufPtr != pDestBufEnd)
607 *pDestBufPtr++ = static_cast< char >(nChar);
608 else
609 goto no_output;
611 else
613 sal_uInt32 nBytes = 0;
614 ImplUnicodeToIso2022CnDesignator eNewDesignator =
615 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
616 switch (eSoDesignator)
618 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE:
619 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
620 if (nBytes != 0)
622 eNewDesignator
623 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
624 break;
626 nBytes = ImplIso2022CnTranslateTo116431(
627 pCns116431992Data,
628 pCns116431992PageOffsets,
629 pCns116431992PlaneOffsets,
630 nChar);
631 if (nBytes != 0)
633 eNewDesignator
634 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
635 break;
637 break;
639 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312:
640 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
641 if (nBytes != 0)
643 eNewDesignator
644 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
645 break;
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_116431;
656 break;
658 break;
660 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431:
661 nBytes = ImplIso2022CnTranslateTo116431(
662 pCns116431992Data,
663 pCns116431992PageOffsets,
664 pCns116431992PlaneOffsets,
665 nChar);
666 if (nBytes != 0)
668 eNewDesignator
669 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
670 break;
672 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
673 if (nBytes != 0)
675 eNewDesignator
676 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
677 break;
679 break;
681 if (nBytes != 0)
683 if (eNewDesignator
684 != IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE)
686 if (bSo)
688 if (pDestBufPtr != pDestBufEnd)
690 *pDestBufPtr++ = 0x0F; // SI
691 bSo = false;
693 else
694 goto no_output;
696 if (pDestBufEnd - pDestBufPtr >= 4)
698 *pDestBufPtr++ = 0x1B; // ESC
699 *pDestBufPtr++ = 0x24; // $
700 *pDestBufPtr++ = 0x29; // )
701 *pDestBufPtr++
702 = eNewDesignator
703 == IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312 ?
704 0x41 : 0x47; // A, G
705 eSoDesignator = eNewDesignator;
707 else
708 goto no_output;
710 if (!bSo)
712 if (pDestBufPtr != pDestBufEnd)
714 *pDestBufPtr++ = 0x0E; // SO
715 bSo = true;
717 else
718 goto no_output;
720 if (pDestBufEnd - pDestBufPtr >= 4)
722 *pDestBufPtr++ = static_cast< char >(nBytes >> 8);
723 *pDestBufPtr++ = static_cast< char >(nBytes & 0xFF);
725 else
726 goto no_output;
728 else
730 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
731 sal_uInt32 nFirst;
732 sal_uInt32 nLast;
733 sal_uInt32 nPlane;
734 if (nOffset == -1)
735 goto bad_input;
736 nOffset
737 = pCns116431992PageOffsets[nOffset
738 + ((nChar & 0xFF00) >> 8)];
739 if (nOffset == -1)
740 goto bad_input;
741 nFirst = pCns116431992Data[nOffset++];
742 nLast = pCns116431992Data[nOffset++];
743 nChar &= 0xFF;
744 if (nChar < nFirst || nChar > nLast)
745 goto bad_input;
746 nOffset += 3 * (nChar - nFirst);
747 nPlane = pCns116431992Data[nOffset++];
748 if (nPlane != 2)
749 goto bad_input;
750 if (!b116432Designator)
752 if (pDestBufEnd - pDestBufPtr >= 4)
754 *pDestBufPtr++ = 0x1B; // ESC
755 *pDestBufPtr++ = 0x24; // $
756 *pDestBufPtr++ = 0x2A; // *
757 *pDestBufPtr++ = 0x48; // H
758 b116432Designator = true;
760 else
761 goto no_output;
763 if (pDestBufEnd - pDestBufPtr >= 4)
765 *pDestBufPtr++ = 0x1B; // ESC
766 *pDestBufPtr++ = 0x4E; // N
767 *pDestBufPtr++
768 = static_cast< char >(0x20 + pCns116431992Data[nOffset++]);
769 *pDestBufPtr++
770 = static_cast< char >(0x20 + pCns116431992Data[nOffset]);
772 else
773 goto no_output;
776 nHighSurrogate = 0;
777 continue;
779 bad_input:
780 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
781 bUndefined, nChar, nFlags, &pDestBufPtr, pDestBufEnd,
782 &nInfo, "\x0F" /* SI */, bSo ? 1 : 0, &bWritten))
784 case sal::detail::textenc::BAD_INPUT_STOP:
785 nHighSurrogate = 0;
786 break;
788 case sal::detail::textenc::BAD_INPUT_CONTINUE:
789 if (bWritten)
790 bSo = false;
791 nHighSurrogate = 0;
792 continue;
794 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
795 goto no_output;
797 break;
799 no_output:
800 --pSrcBuf;
801 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
802 break;
805 if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
806 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
807 == 0)
809 bool bFlush = true;
810 if (nHighSurrogate != 0)
812 if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
813 nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
814 else
815 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
816 false, 0, nFlags, &pDestBufPtr, pDestBufEnd, &nInfo,
817 "\x0F" /* SI */, bSo ? 1 : 0, &bWritten))
819 case sal::detail::textenc::BAD_INPUT_STOP:
820 nHighSurrogate = 0;
821 bFlush = false;
822 break;
824 case sal::detail::textenc::BAD_INPUT_CONTINUE:
825 if (bWritten)
826 bSo = false;
827 nHighSurrogate = 0;
828 break;
830 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
831 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
832 break;
835 if (bFlush && bSo && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
837 if (pDestBufPtr != pDestBufEnd)
839 *pDestBufPtr++ = 0x0F; // SI
840 bSo = false;
842 else
843 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
847 if (pContext)
849 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate
850 = nHighSurrogate;
851 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator
852 = eSoDesignator;
853 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_b116432Designator
854 = b116432Designator;
855 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo = bSo;
857 if (pInfo)
858 *pInfo = nInfo;
859 if (pSrcCvtChars)
860 *pSrcCvtChars = nConverted;
862 return pDestBufPtr - pDestBuf;
865 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */