lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / sal / textenc / convertiso2022cn.cxx
blobe931d68f1f3507daed300f08ad20623bbdb2421b
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 "converter.hxx"
26 #include "convertiso2022cn.hxx"
27 #include "tenchelp.hxx"
28 #include "unichars.hxx"
30 namespace {
32 enum ImplIso2022CnToUnicodeState // order is important:
34 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII,
35 IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO,
36 IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2,
37 IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432,
38 IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2,
39 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC,
40 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR,
41 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN,
42 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK
45 struct ImplIso2022CnToUnicodeContext
47 ImplIso2022CnToUnicodeState m_eState;
48 sal_uInt32 m_nRow;
49 bool m_bSo;
50 bool m_b116431;
53 enum ImplUnicodeToIso2022CnDesignator
55 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE,
56 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312,
57 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431
60 struct ImplUnicodeToIso2022CnContext
62 sal_Unicode m_nHighSurrogate;
63 ImplUnicodeToIso2022CnDesignator m_eSoDesignator;
64 bool m_b116432Designator;
65 bool m_bSo;
70 void * ImplCreateIso2022CnToUnicodeContext()
72 ImplIso2022CnToUnicodeContext * pContext =
73 new ImplIso2022CnToUnicodeContext;
74 pContext->m_eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
75 pContext->m_bSo = false;
76 pContext->m_b116431 = false;
77 return pContext;
80 void ImplResetIso2022CnToUnicodeContext(void * pContext)
82 if (pContext)
84 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState
85 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
86 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo = false;
87 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431 = false;
91 void ImplDestroyIso2022CnToUnicodeContext(void * pContext)
93 delete static_cast< ImplIso2022CnToUnicodeContext * >(pContext);
96 sal_Size ImplConvertIso2022CnToUnicode(void const * pData,
97 void * pContext,
98 char const * pSrcBuf,
99 sal_Size nSrcBytes,
100 sal_Unicode * pDestBuf,
101 sal_Size nDestChars,
102 sal_uInt32 nFlags,
103 sal_uInt32 * pInfo,
104 sal_Size * pSrcCvtBytes)
106 ImplDBCSToUniLeadTab const * pGb2312Data
107 = static_cast< ImplIso2022CnConverterData const * >(pData)->
108 m_pGb2312ToUnicodeData;
109 sal_uInt16 const * pCns116431992Data
110 = static_cast< ImplIso2022CnConverterData const * >(pData)->
111 m_pCns116431992ToUnicodeData;
112 sal_Int32 const * pCns116431992RowOffsets
113 = static_cast< ImplIso2022CnConverterData const * >(pData)->
114 m_pCns116431992ToUnicodeRowOffsets;
115 sal_Int32 const * pCns116431992PlaneOffsets
116 = static_cast< ImplIso2022CnConverterData const * >(pData)->
117 m_pCns116431992ToUnicodePlaneOffsets;
118 ImplIso2022CnToUnicodeState eState
119 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
120 sal_uInt32 nRow = 0;
121 bool bSo = false;
122 bool b116431 = false;
123 sal_uInt32 nInfo = 0;
124 sal_Size nConverted = 0;
125 sal_Unicode * pDestBufPtr = pDestBuf;
126 sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
128 if (pContext)
130 eState = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState;
131 nRow = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_nRow;
132 bSo = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo;
133 b116431 = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431;
136 for (; nConverted < nSrcBytes; ++nConverted)
138 bool bUndefined = true;
139 sal_uInt32 nChar = *reinterpret_cast<unsigned char const *>(pSrcBuf++);
140 sal_uInt32 nPlane;
141 switch (eState)
143 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII:
144 if (nChar == 0x0E) // SO
146 bSo = true;
147 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
149 else if (nChar == 0x1B) // ESC
150 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
151 else if (nChar < 0x80)
152 if (pDestBufPtr != pDestBufEnd)
153 *pDestBufPtr++ = static_cast<sal_Unicode>(nChar);
154 else
155 goto no_output;
156 else
158 bUndefined = false;
159 goto bad_input;
161 break;
163 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO:
164 if (nChar == 0x0F) // SI
166 bSo = false;
167 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
169 else if (nChar == 0x1B) // ESC
170 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
171 else if (nChar >= 0x21 && nChar <= 0x7E)
173 nRow = nChar;
174 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2;
176 else
178 bUndefined = false;
179 goto bad_input;
181 break;
183 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2:
184 if (nChar >= 0x21 && nChar <= 0x7E)
185 if (b116431)
187 nPlane = 0;
188 goto transform;
190 else
192 sal_uInt16 nUnicode = 0;
193 sal_uInt32 nFirst;
194 nRow += 0x80;
195 nChar += 0x80;
196 nFirst = pGb2312Data[nRow].mnTrailStart;
197 if (nChar >= nFirst
198 && nChar <= pGb2312Data[nRow].mnTrailEnd)
199 nUnicode = pGb2312Data[nRow].
200 mpToUniTrailTab[nChar - nFirst];
201 if (nUnicode != 0)
202 if (pDestBufPtr != pDestBufEnd)
204 *pDestBufPtr++ = static_cast<sal_Unicode>(nUnicode);
205 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
207 else
208 goto no_output;
209 else
210 goto bad_input;
212 else
214 bUndefined = false;
215 goto bad_input;
217 break;
219 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432:
220 if (nChar >= 0x21 && nChar <= 0x7E)
222 nRow = nChar;
223 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2;
225 else
227 bUndefined = false;
228 goto bad_input;
230 break;
232 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2:
233 if (nChar >= 0x21 && nChar <= 0x7E)
235 nPlane = 1;
236 goto transform;
238 else
240 bUndefined = false;
241 goto bad_input;
243 break;
245 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC:
246 if (nChar == 0x24) // $
247 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR;
248 else if (nChar == 0x4E) // N
249 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432;
250 else
252 bUndefined = false;
253 goto bad_input;
255 break;
257 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR:
258 if (nChar == 0x29) // )
259 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN;
260 else if (nChar == 0x2A) // *
261 eState
262 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK;
263 else
265 bUndefined = false;
266 goto bad_input;
268 break;
270 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN:
271 if (nChar == 0x41) // A
273 b116431 = false;
274 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
275 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
277 else if (nChar == 0x47) // G
279 b116431 = true;
280 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
281 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
283 else
285 bUndefined = false;
286 goto bad_input;
288 break;
290 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK:
291 if (nChar == 0x48) // H
292 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
293 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
294 else
296 bUndefined = false;
297 goto bad_input;
299 break;
301 continue;
303 transform:
305 sal_Int32 nPlaneOffset = pCns116431992PlaneOffsets[nPlane];
306 if (nPlaneOffset == -1)
307 goto bad_input;
308 else
310 sal_Int32 nOffset
311 = pCns116431992RowOffsets[nPlaneOffset + (nRow - 0x21)];
312 if (nOffset == -1)
313 goto bad_input;
314 else
316 sal_uInt32 nFirstLast = pCns116431992Data[nOffset++];
317 sal_uInt32 nFirst = nFirstLast & 0xFF;
318 sal_uInt32 nLast = nFirstLast >> 8;
319 nChar -= 0x20;
320 if (nChar >= nFirst && nChar <= nLast)
322 sal_uInt32 nUnicode
323 = pCns116431992Data[nOffset + (nChar - nFirst)];
324 if (nUnicode == 0xFFFF)
325 goto bad_input;
326 else if (ImplIsHighSurrogate(nUnicode))
327 if (pDestBufEnd - pDestBufPtr >= 2)
329 nOffset += nLast - nFirst + 1;
330 nFirst = pCns116431992Data[nOffset++];
331 *pDestBufPtr++ = static_cast<sal_Unicode>(nUnicode);
332 *pDestBufPtr++
333 = static_cast<sal_Unicode>(pCns116431992Data[
334 nOffset + (nChar - nFirst)]);
336 else
337 goto no_output;
338 else
339 if (pDestBufPtr != pDestBufEnd)
340 *pDestBufPtr++ = static_cast<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 (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
355 bUndefined, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
356 &nInfo))
358 case sal::detail::textenc::BAD_INPUT_STOP:
359 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
360 b116431 = false;
361 break;
363 case sal::detail::textenc::BAD_INPUT_CONTINUE:
364 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
365 b116431 = false;
366 continue;
368 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
369 goto no_output;
371 break;
373 no_output:
374 --pSrcBuf;
375 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL;
376 break;
379 if (eState > IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO
380 && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
381 | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL))
382 == 0)
384 if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
385 nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL;
386 else
387 switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
388 false, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
389 &nInfo))
391 case sal::detail::textenc::BAD_INPUT_STOP:
392 case sal::detail::textenc::BAD_INPUT_CONTINUE:
393 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
394 b116431 = false;
395 break;
397 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
398 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL;
399 break;
403 if (pContext)
405 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState = eState;
406 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_nRow = nRow;
407 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo = bSo;
408 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431 = b116431;
410 if (pInfo)
411 *pInfo = nInfo;
412 if (pSrcCvtBytes)
413 *pSrcCvtBytes = nConverted;
415 return pDestBufPtr - pDestBuf;
418 void * ImplCreateUnicodeToIso2022CnContext()
420 ImplUnicodeToIso2022CnContext * pContext =
421 new ImplUnicodeToIso2022CnContext;
422 pContext->m_nHighSurrogate = 0;
423 pContext->m_eSoDesignator = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
424 pContext->m_b116432Designator = false;
425 pContext->m_bSo = false;
426 return pContext;
429 void ImplResetUnicodeToIso2022CnContext(void * pContext)
431 if (pContext)
433 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate = 0;
434 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator
435 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
436 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_b116432Designator
437 = false;
438 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo = false;
442 void ImplDestroyUnicodeToIso2022CnContext(void * pContext)
444 delete static_cast< ImplUnicodeToIso2022CnContext * >(pContext);
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(void const * pData,
492 void * pContext,
493 sal_Unicode const * pSrcBuf,
494 sal_Size nSrcChars,
495 char * pDestBuf,
496 sal_Size nDestBytes,
497 sal_uInt32 nFlags,
498 sal_uInt32 * pInfo,
499 sal_Size * pSrcCvtChars)
501 ImplUniToDBCSHighTab const * pGb2312Data
502 = static_cast< ImplIso2022CnConverterData const * >(pData)->
503 m_pUnicodeToGb2312Data;
504 sal_uInt8 const * pCns116431992Data
505 = static_cast< ImplIso2022CnConverterData const * >(pData)->
506 m_pUnicodeToCns116431992Data;
507 sal_Int32 const * pCns116431992PageOffsets
508 = static_cast< ImplIso2022CnConverterData const * >(pData)->
509 m_pUnicodeToCns116431992PageOffsets;
510 sal_Int32 const * pCns116431992PlaneOffsets
511 = static_cast< ImplIso2022CnConverterData const * >(pData)->
512 m_pUnicodeToCns116431992PlaneOffsets;
513 sal_Unicode nHighSurrogate = 0;
514 ImplUnicodeToIso2022CnDesignator eSoDesignator
515 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
516 bool b116432Designator = false;
517 bool bSo = false;
518 sal_uInt32 nInfo = 0;
519 sal_Size nConverted = 0;
520 char * pDestBufPtr = pDestBuf;
521 char * pDestBufEnd = pDestBuf + nDestBytes;
522 bool bWritten;
524 if (pContext)
526 nHighSurrogate
527 = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate;
528 eSoDesignator
529 = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator;
530 b116432Designator = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->
531 m_b116432Designator;
532 bSo = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo;
535 for (; nConverted < nSrcChars; ++nConverted)
537 bool bUndefined = true;
538 sal_uInt32 nChar = *pSrcBuf++;
539 if (nHighSurrogate == 0)
541 if (ImplIsHighSurrogate(nChar))
543 nHighSurrogate = static_cast<sal_Unicode>(nChar);
544 continue;
547 else if (ImplIsLowSurrogate(nChar))
548 nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
549 else
551 bUndefined = false;
552 goto bad_input;
555 if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
557 bUndefined = 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 = false;
569 eSoDesignator
570 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
571 b116432Designator = false;
573 else
574 goto no_output;
576 if (pDestBufPtr != pDestBufEnd)
577 *pDestBufPtr++ = static_cast< 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 = false;
592 else
593 goto no_output;
595 if (pDestBufPtr != pDestBufEnd)
596 *pDestBufPtr++ = static_cast< 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 = 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 = true;
706 else
707 goto no_output;
709 if (pDestBufEnd - pDestBufPtr >= 4)
711 *pDestBufPtr++ = static_cast< char >(nBytes >> 8);
712 *pDestBufPtr++ = static_cast< 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 = true;
749 else
750 goto no_output;
752 if (pDestBufEnd - pDestBufPtr >= 4)
754 *pDestBufPtr++ = 0x1B; // ESC
755 *pDestBufPtr++ = 0x4E; // N
756 *pDestBufPtr++
757 = static_cast< char >(0x20 + pCns116431992Data[nOffset++]);
758 *pDestBufPtr++
759 = static_cast< char >(0x20 + pCns116431992Data[nOffset]);
761 else
762 goto no_output;
765 nHighSurrogate = 0;
766 continue;
768 bad_input:
769 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
770 bUndefined, nChar, nFlags, &pDestBufPtr, pDestBufEnd,
771 &nInfo, "\x0F" /* SI */, bSo ? 1 : 0, &bWritten))
773 case sal::detail::textenc::BAD_INPUT_STOP:
774 nHighSurrogate = 0;
775 break;
777 case sal::detail::textenc::BAD_INPUT_CONTINUE:
778 if (bWritten)
779 bSo = false;
780 nHighSurrogate = 0;
781 continue;
783 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
784 goto no_output;
786 break;
788 no_output:
789 --pSrcBuf;
790 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
791 break;
794 if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
795 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
796 == 0)
798 bool bFlush = true;
799 if (nHighSurrogate != 0)
801 if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
802 nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
803 else
804 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
805 false, 0, nFlags, &pDestBufPtr, pDestBufEnd, &nInfo,
806 "\x0F" /* SI */, bSo ? 1 : 0, &bWritten))
808 case sal::detail::textenc::BAD_INPUT_STOP:
809 nHighSurrogate = 0;
810 bFlush = false;
811 break;
813 case sal::detail::textenc::BAD_INPUT_CONTINUE:
814 if (bWritten)
815 bSo = false;
816 nHighSurrogate = 0;
817 break;
819 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
820 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
821 break;
824 if (bFlush && bSo && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
826 if (pDestBufPtr != pDestBufEnd)
828 *pDestBufPtr++ = 0x0F; // SI
829 bSo = false;
831 else
832 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
836 if (pContext)
838 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate
839 = nHighSurrogate;
840 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator
841 = eSoDesignator;
842 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_b116432Designator
843 = b116432Designator;
844 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo = bSo;
846 if (pInfo)
847 *pInfo = nInfo;
848 if (pSrcCvtChars)
849 *pSrcCvtChars = nConverted;
851 return pDestBufPtr - pDestBuf;
854 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */