Version 4.2.0.1, tag libreoffice-4.2.0.1
[LibreOffice.git] / sal / textenc / convertiso2022cn.cxx
blob87302f537ffe6a85c71722784bfb9a59c37892bc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "sal/config.h"
22 #include "rtl/textcvt.h"
23 #include "sal/types.h"
25 #include "context.hxx"
26 #include "converter.hxx"
27 #include "convertiso2022cn.hxx"
28 #include "tenchelp.hxx"
29 #include "unichars.hxx"
31 namespace {
33 enum ImplIso2022CnToUnicodeState // order is important:
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
46 struct ImplIso2022CnToUnicodeContext
48 ImplIso2022CnToUnicodeState m_eState;
49 sal_uInt32 m_nRow;
50 bool m_bSo;
51 bool m_b116431;
54 enum ImplUnicodeToIso2022CnDesignator
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
61 struct ImplUnicodeToIso2022CnContext
63 sal_Unicode m_nHighSurrogate;
64 ImplUnicodeToIso2022CnDesignator m_eSoDesignator;
65 bool m_b116432Designator;
66 bool m_bSo;
71 void * ImplCreateIso2022CnToUnicodeContext()
73 ImplIso2022CnToUnicodeContext * pContext =
74 new ImplIso2022CnToUnicodeContext;
75 pContext->m_eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
76 pContext->m_bSo = false;
77 pContext->m_b116431 = false;
78 return pContext;
81 void ImplResetIso2022CnToUnicodeContext(void * pContext)
83 if (pContext)
85 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState
86 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
87 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo = false;
88 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431 = false;
92 void ImplDestroyIso2022CnToUnicodeContext(void * pContext)
94 delete static_cast< ImplIso2022CnToUnicodeContext * >(pContext);
97 sal_Size ImplConvertIso2022CnToUnicode(void const * pData,
98 void * pContext,
99 char const * pSrcBuf,
100 sal_Size nSrcBytes,
101 sal_Unicode * pDestBuf,
102 sal_Size nDestChars,
103 sal_uInt32 nFlags,
104 sal_uInt32 * pInfo,
105 sal_Size * pSrcCvtBytes)
107 ImplDBCSToUniLeadTab const * pGb2312Data
108 = static_cast< ImplIso2022CnConverterData const * >(pData)->
109 m_pGb2312ToUnicodeData;
110 sal_uInt16 const * pCns116431992Data
111 = static_cast< ImplIso2022CnConverterData const * >(pData)->
112 m_pCns116431992ToUnicodeData;
113 sal_Int32 const * pCns116431992RowOffsets
114 = static_cast< ImplIso2022CnConverterData const * >(pData)->
115 m_pCns116431992ToUnicodeRowOffsets;
116 sal_Int32 const * pCns116431992PlaneOffsets
117 = static_cast< ImplIso2022CnConverterData const * >(pData)->
118 m_pCns116431992ToUnicodePlaneOffsets;
119 ImplIso2022CnToUnicodeState eState
120 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
121 sal_uInt32 nRow = 0;
122 bool bSo = false;
123 bool b116431 = false;
124 sal_uInt32 nInfo = 0;
125 sal_Size nConverted = 0;
126 sal_Unicode * pDestBufPtr = pDestBuf;
127 sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
129 if (pContext)
131 eState = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState;
132 nRow = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_nRow;
133 bSo = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo;
134 b116431 = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431;
137 for (; nConverted < nSrcBytes; ++nConverted)
139 bool bUndefined = true;
140 sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++;
141 sal_uInt32 nPlane;
142 switch (eState)
144 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII:
145 if (nChar == 0x0E) // SO
147 bSo = true;
148 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
150 else if (nChar == 0x1B) // ESC
151 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
152 else if (nChar < 0x80)
153 if (pDestBufPtr != pDestBufEnd)
154 *pDestBufPtr++ = (sal_Unicode) nChar;
155 else
156 goto no_output;
157 else
159 bUndefined = false;
160 goto bad_input;
162 break;
164 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO:
165 if (nChar == 0x0F) // SI
167 bSo = false;
168 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
170 else if (nChar == 0x1B) // ESC
171 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
172 else if (nChar >= 0x21 && nChar <= 0x7E)
174 nRow = nChar;
175 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2;
177 else
179 bUndefined = false;
180 goto bad_input;
182 break;
184 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2:
185 if (nChar >= 0x21 && nChar <= 0x7E)
186 if (b116431)
188 nPlane = 0;
189 goto transform;
191 else
193 sal_uInt16 nUnicode = 0;
194 sal_uInt32 nFirst;
195 nRow += 0x80;
196 nChar += 0x80;
197 nFirst = pGb2312Data[nRow].mnTrailStart;
198 if (nChar >= nFirst
199 && nChar <= pGb2312Data[nRow].mnTrailEnd)
200 nUnicode = pGb2312Data[nRow].
201 mpToUniTrailTab[nChar - nFirst];
202 if (nUnicode != 0)
203 if (pDestBufPtr != pDestBufEnd)
205 *pDestBufPtr++ = (sal_Unicode) nUnicode;
206 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
208 else
209 goto no_output;
210 else
211 goto bad_input;
213 else
215 bUndefined = false;
216 goto bad_input;
218 break;
220 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432:
221 if (nChar >= 0x21 && nChar <= 0x7E)
223 nRow = nChar;
224 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2;
226 else
228 bUndefined = false;
229 goto bad_input;
231 break;
233 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2:
234 if (nChar >= 0x21 && nChar <= 0x7E)
236 nPlane = 1;
237 goto transform;
239 else
241 bUndefined = false;
242 goto bad_input;
244 break;
246 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC:
247 if (nChar == 0x24) // $
248 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR;
249 else if (nChar == 0x4E) // N
250 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432;
251 else
253 bUndefined = false;
254 goto bad_input;
256 break;
258 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR:
259 if (nChar == 0x29) // )
260 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN;
261 else if (nChar == 0x2A) // *
262 eState
263 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK;
264 else
266 bUndefined = false;
267 goto bad_input;
269 break;
271 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN:
272 if (nChar == 0x41) // A
274 b116431 = false;
275 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
276 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
278 else if (nChar == 0x47) // G
280 b116431 = true;
281 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
282 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
284 else
286 bUndefined = false;
287 goto bad_input;
289 break;
291 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK:
292 if (nChar == 0x48) // H
293 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
294 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
295 else
297 bUndefined = false;
298 goto bad_input;
300 break;
302 continue;
304 transform:
306 sal_Int32 nPlaneOffset = pCns116431992PlaneOffsets[nPlane];
307 if (nPlaneOffset == -1)
308 goto bad_input;
309 else
311 sal_Int32 nOffset
312 = pCns116431992RowOffsets[nPlaneOffset + (nRow - 0x21)];
313 if (nOffset == -1)
314 goto bad_input;
315 else
317 sal_uInt32 nFirstLast = pCns116431992Data[nOffset++];
318 sal_uInt32 nFirst = nFirstLast & 0xFF;
319 sal_uInt32 nLast = nFirstLast >> 8;
320 nChar -= 0x20;
321 if (nChar >= nFirst && nChar <= nLast)
323 sal_uInt32 nUnicode
324 = pCns116431992Data[nOffset + (nChar - nFirst)];
325 if (nUnicode == 0xFFFF)
326 goto bad_input;
327 else if (ImplIsHighSurrogate(nUnicode))
328 if (pDestBufEnd - pDestBufPtr >= 2)
330 nOffset += nLast - nFirst + 1;
331 nFirst = pCns116431992Data[nOffset++];
332 *pDestBufPtr++ = (sal_Unicode) nUnicode;
333 *pDestBufPtr++
334 = (sal_Unicode)
335 pCns116431992Data[
336 nOffset + (nChar - nFirst)];
338 else
339 goto no_output;
340 else
341 if (pDestBufPtr != pDestBufEnd)
342 *pDestBufPtr++ = (sal_Unicode) nUnicode;
343 else
344 goto no_output;
346 else
347 goto bad_input;
348 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
349 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
352 continue;
355 bad_input:
356 switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
357 bUndefined, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
358 &nInfo))
360 case sal::detail::textenc::BAD_INPUT_STOP:
361 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
362 b116431 = false;
363 break;
365 case sal::detail::textenc::BAD_INPUT_CONTINUE:
366 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
367 b116431 = false;
368 continue;
370 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
371 goto no_output;
373 break;
375 no_output:
376 --pSrcBuf;
377 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
378 break;
381 if (eState > IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO
382 && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
383 | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
384 == 0)
386 if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
387 nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
388 else
389 switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
390 false, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
391 &nInfo))
393 case sal::detail::textenc::BAD_INPUT_STOP:
394 case sal::detail::textenc::BAD_INPUT_CONTINUE:
395 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
396 b116431 = false;
397 break;
399 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
400 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
401 break;
405 if (pContext)
407 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState = eState;
408 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_nRow = nRow;
409 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo = bSo;
410 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431 = b116431;
412 if (pInfo)
413 *pInfo = nInfo;
414 if (pSrcCvtBytes)
415 *pSrcCvtBytes = nConverted;
417 return pDestBufPtr - pDestBuf;
420 void * ImplCreateUnicodeToIso2022CnContext(void)
422 ImplUnicodeToIso2022CnContext * pContext =
423 new ImplUnicodeToIso2022CnContext;
424 pContext->m_nHighSurrogate = 0;
425 pContext->m_eSoDesignator = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
426 pContext->m_b116432Designator = false;
427 pContext->m_bSo = false;
428 return pContext;
431 void ImplResetUnicodeToIso2022CnContext(void * pContext)
433 if (pContext)
435 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate = 0;
436 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator
437 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
438 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_b116432Designator
439 = false;
440 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo = false;
444 void ImplDestroyUnicodeToIso2022CnContext(void * pContext)
446 delete static_cast< ImplUnicodeToIso2022CnContext * >(pContext);
449 static sal_uInt32 ImplIso2022CnTranslateTo2312(ImplUniToDBCSHighTab const *
450 pGb2312Data,
451 sal_uInt32 nChar)
453 sal_uInt32 nIndex1 = nChar >> 8;
454 if (nIndex1 < 0x100)
456 sal_uInt32 nIndex2 = nChar & 0xFF;
457 sal_uInt32 nFirst = pGb2312Data[nIndex1].mnLowStart;
458 if (nIndex2 >= nFirst && nIndex2 <= pGb2312Data[nIndex1].mnLowEnd)
459 return pGb2312Data[nIndex1].mpToUniTrailTab[nIndex2 - nFirst]
460 & 0x7F7F;
462 return 0;
465 static sal_uInt32
466 ImplIso2022CnTranslateTo116431(sal_uInt8 const * pCns116431992Data,
467 sal_Int32 const * pCns116431992PageOffsets,
468 sal_Int32 const * pCns116431992PlaneOffsets,
469 sal_uInt32 nChar)
471 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
472 sal_uInt32 nFirst;
473 sal_uInt32 nLast;
474 sal_uInt32 nPlane;
475 if (nOffset == -1)
476 return 0;
477 nOffset = pCns116431992PageOffsets[nOffset + ((nChar & 0xFF00) >> 8)];
478 if (nOffset == -1)
479 return 0;
480 nFirst = pCns116431992Data[nOffset++];
481 nLast = pCns116431992Data[nOffset++];
482 nChar &= 0xFF;
483 if (nChar < nFirst || nChar > nLast)
484 return 0;
485 nOffset += 3 * (nChar - nFirst);
486 nPlane = pCns116431992Data[nOffset++];
487 if (nPlane != 1)
488 return 0;
489 return (0x20 + pCns116431992Data[nOffset]) << 8
490 | (0x20 + pCns116431992Data[nOffset + 1]);
493 sal_Size ImplConvertUnicodeToIso2022Cn(void const * pData,
494 void * pContext,
495 sal_Unicode const * pSrcBuf,
496 sal_Size nSrcChars,
497 char * pDestBuf,
498 sal_Size nDestBytes,
499 sal_uInt32 nFlags,
500 sal_uInt32 * pInfo,
501 sal_Size * pSrcCvtChars)
503 ImplUniToDBCSHighTab const * pGb2312Data
504 = static_cast< ImplIso2022CnConverterData const * >(pData)->
505 m_pUnicodeToGb2312Data;
506 sal_uInt8 const * pCns116431992Data
507 = static_cast< ImplIso2022CnConverterData const * >(pData)->
508 m_pUnicodeToCns116431992Data;
509 sal_Int32 const * pCns116431992PageOffsets
510 = static_cast< ImplIso2022CnConverterData const * >(pData)->
511 m_pUnicodeToCns116431992PageOffsets;
512 sal_Int32 const * pCns116431992PlaneOffsets
513 = static_cast< ImplIso2022CnConverterData const * >(pData)->
514 m_pUnicodeToCns116431992PlaneOffsets;
515 sal_Unicode nHighSurrogate = 0;
516 ImplUnicodeToIso2022CnDesignator eSoDesignator
517 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
518 bool b116432Designator = false;
519 bool bSo = false;
520 sal_uInt32 nInfo = 0;
521 sal_Size nConverted = 0;
522 char * pDestBufPtr = pDestBuf;
523 char * pDestBufEnd = pDestBuf + nDestBytes;
524 bool bWritten;
526 if (pContext)
528 nHighSurrogate
529 = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate;
530 eSoDesignator
531 = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator;
532 b116432Designator = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->
533 m_b116432Designator;
534 bSo = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo;
537 for (; nConverted < nSrcChars; ++nConverted)
539 bool bUndefined = true;
540 sal_uInt32 nChar = *pSrcBuf++;
541 if (nHighSurrogate == 0)
543 if (ImplIsHighSurrogate(nChar))
545 nHighSurrogate = (sal_Unicode) nChar;
546 continue;
549 else if (ImplIsLowSurrogate(nChar))
550 nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
551 else
553 bUndefined = false;
554 goto bad_input;
557 if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
559 bUndefined = false;
560 goto bad_input;
563 if (nChar == 0x0A || nChar == 0x0D) // LF, CR
565 if (bSo)
567 if (pDestBufPtr != pDestBufEnd)
569 *pDestBufPtr++ = 0x0F; // SI
570 bSo = false;
571 eSoDesignator
572 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
573 b116432Designator = false;
575 else
576 goto no_output;
578 if (pDestBufPtr != pDestBufEnd)
579 *pDestBufPtr++ = static_cast< char >(nChar);
580 else
581 goto no_output;
583 else if (nChar == 0x0E || nChar == 0x0F || nChar == 0x1B)
584 goto bad_input;
585 else if (nChar < 0x80)
587 if (bSo)
589 if (pDestBufPtr != pDestBufEnd)
591 *pDestBufPtr++ = 0x0F; // SI
592 bSo = false;
594 else
595 goto no_output;
597 if (pDestBufPtr != pDestBufEnd)
598 *pDestBufPtr++ = static_cast< char >(nChar);
599 else
600 goto no_output;
602 else
604 sal_uInt32 nBytes = 0;
605 ImplUnicodeToIso2022CnDesignator eNewDesignator =
606 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
607 switch (eSoDesignator)
609 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE:
610 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
611 if (nBytes != 0)
613 eNewDesignator
614 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
615 break;
617 nBytes = ImplIso2022CnTranslateTo116431(
618 pCns116431992Data,
619 pCns116431992PageOffsets,
620 pCns116431992PlaneOffsets,
621 nChar);
622 if (nBytes != 0)
624 eNewDesignator
625 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
626 break;
628 break;
630 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312:
631 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
632 if (nBytes != 0)
634 eNewDesignator
635 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
636 break;
638 nBytes = ImplIso2022CnTranslateTo116431(
639 pCns116431992Data,
640 pCns116431992PageOffsets,
641 pCns116431992PlaneOffsets,
642 nChar);
643 if (nBytes != 0)
645 eNewDesignator
646 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
647 break;
649 break;
651 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431:
652 nBytes = ImplIso2022CnTranslateTo116431(
653 pCns116431992Data,
654 pCns116431992PageOffsets,
655 pCns116431992PlaneOffsets,
656 nChar);
657 if (nBytes != 0)
659 eNewDesignator
660 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
661 break;
663 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
664 if (nBytes != 0)
666 eNewDesignator
667 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
668 break;
670 break;
672 if (nBytes != 0)
674 if (eNewDesignator
675 != IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE)
677 if (bSo)
679 if (pDestBufPtr != pDestBufEnd)
681 *pDestBufPtr++ = 0x0F; // SI
682 bSo = false;
684 else
685 goto no_output;
687 if (pDestBufEnd - pDestBufPtr >= 4)
689 *pDestBufPtr++ = 0x1B; // ESC
690 *pDestBufPtr++ = 0x24; // $
691 *pDestBufPtr++ = 0x29; // )
692 *pDestBufPtr++
693 = eNewDesignator
694 == IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312 ?
695 0x41 : 0x47; // A, G
696 eSoDesignator = eNewDesignator;
698 else
699 goto no_output;
701 if (!bSo)
703 if (pDestBufPtr != pDestBufEnd)
705 *pDestBufPtr++ = 0x0E; // SO
706 bSo = true;
708 else
709 goto no_output;
711 if (pDestBufEnd - pDestBufPtr >= 4)
713 *pDestBufPtr++ = static_cast< char >(nBytes >> 8);
714 *pDestBufPtr++ = static_cast< char >(nBytes & 0xFF);
716 else
717 goto no_output;
719 else
721 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
722 sal_uInt32 nFirst;
723 sal_uInt32 nLast;
724 sal_uInt32 nPlane;
725 if (nOffset == -1)
726 goto bad_input;
727 nOffset
728 = pCns116431992PageOffsets[nOffset
729 + ((nChar & 0xFF00) >> 8)];
730 if (nOffset == -1)
731 goto bad_input;
732 nFirst = pCns116431992Data[nOffset++];
733 nLast = pCns116431992Data[nOffset++];
734 nChar &= 0xFF;
735 if (nChar < nFirst || nChar > nLast)
736 goto bad_input;
737 nOffset += 3 * (nChar - nFirst);
738 nPlane = pCns116431992Data[nOffset++];
739 if (nPlane != 2)
740 goto bad_input;
741 if (!b116432Designator)
743 if (pDestBufEnd - pDestBufPtr >= 4)
745 *pDestBufPtr++ = 0x1B; // ESC
746 *pDestBufPtr++ = 0x24; // $
747 *pDestBufPtr++ = 0x2A; // *
748 *pDestBufPtr++ = 0x48; // H
749 b116432Designator = true;
751 else
752 goto no_output;
754 if (pDestBufEnd - pDestBufPtr >= 4)
756 *pDestBufPtr++ = 0x1B; // ESC
757 *pDestBufPtr++ = 0x4E; // N
758 *pDestBufPtr++
759 = static_cast< char >(0x20 + pCns116431992Data[nOffset++]);
760 *pDestBufPtr++
761 = static_cast< char >(0x20 + pCns116431992Data[nOffset]);
763 else
764 goto no_output;
767 nHighSurrogate = 0;
768 continue;
770 bad_input:
771 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
772 bUndefined, nChar, nFlags, &pDestBufPtr, pDestBufEnd,
773 &nInfo, "\x0F" /* SI */, bSo ? 1 : 0, &bWritten))
775 case sal::detail::textenc::BAD_INPUT_STOP:
776 nHighSurrogate = 0;
777 break;
779 case sal::detail::textenc::BAD_INPUT_CONTINUE:
780 if (bWritten)
781 bSo = false;
782 nHighSurrogate = 0;
783 continue;
785 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
786 goto no_output;
788 break;
790 no_output:
791 --pSrcBuf;
792 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
793 break;
796 if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
797 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
798 == 0)
800 bool bFlush = true;
801 if (nHighSurrogate != 0)
803 if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
804 nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
805 else
806 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
807 false, 0, nFlags, &pDestBufPtr, pDestBufEnd, &nInfo,
808 "\x0F" /* SI */, bSo ? 1 : 0, &bWritten))
810 case sal::detail::textenc::BAD_INPUT_STOP:
811 nHighSurrogate = 0;
812 bFlush = false;
813 break;
815 case sal::detail::textenc::BAD_INPUT_CONTINUE:
816 if (bWritten)
817 bSo = false;
818 nHighSurrogate = 0;
819 break;
821 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
822 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
823 break;
826 if (bFlush && bSo && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
828 if (pDestBufPtr != pDestBufEnd)
830 *pDestBufPtr++ = 0x0F; // SI
831 bSo = false;
833 else
834 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
838 if (pContext)
840 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate
841 = nHighSurrogate;
842 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator
843 = eSoDesignator;
844 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_b116432Designator
845 = b116432Designator;
846 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo = bSo;
848 if (pInfo)
849 *pInfo = nInfo;
850 if (pSrcCvtChars)
851 *pSrcCvtChars = nConverted;
853 return pDestBufPtr - pDestBuf;
856 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */