tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / sal / textenc / convertiso2022cn.cxx
blobd4747913f1628f5afd2beb0d0fe1b646fc2f1cf0
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 <cassert>
24 #include <rtl/character.hxx>
25 #include <rtl/textcvt.h>
26 #include <sal/types.h>
28 #include "converter.hxx"
29 #include "convertiso2022cn.hxx"
30 #include "tenchelp.hxx"
32 namespace {
34 enum ImplIso2022CnToUnicodeState // order is important:
36 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII,
37 IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO,
38 IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2,
39 IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432,
40 IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2,
41 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC,
42 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR,
43 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN,
44 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK
47 struct ImplIso2022CnToUnicodeContext
49 ImplIso2022CnToUnicodeState m_eState;
50 sal_uInt32 m_nRow;
51 bool m_bSo;
52 bool m_b116431;
55 enum ImplUnicodeToIso2022CnDesignator
57 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE,
58 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312,
59 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431
62 struct ImplUnicodeToIso2022CnContext
64 sal_Unicode m_nHighSurrogate;
65 ImplUnicodeToIso2022CnDesignator m_eSoDesignator;
66 bool m_b116432Designator;
67 bool m_bSo;
72 void * ImplCreateIso2022CnToUnicodeContext()
74 ImplIso2022CnToUnicodeContext * pContext =
75 new ImplIso2022CnToUnicodeContext;
76 pContext->m_eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
77 pContext->m_bSo = false;
78 pContext->m_b116431 = false;
79 return pContext;
82 void ImplResetIso2022CnToUnicodeContext(void * pContext)
84 if (pContext)
86 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState
87 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
88 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo = false;
89 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431 = false;
93 void ImplDestroyIso2022CnToUnicodeContext(void * pContext)
95 delete static_cast< ImplIso2022CnToUnicodeContext * >(pContext);
98 sal_Size ImplConvertIso2022CnToUnicode(void const * pData,
99 void * pContext,
100 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 = static_cast< ImplIso2022CnConverterData const * >(pData)->
110 m_pGb2312ToUnicodeData;
111 sal_uInt16 const * pCns116431992Data
112 = static_cast< ImplIso2022CnConverterData const * >(pData)->
113 m_pCns116431992ToUnicodeData;
114 sal_Int32 const * pCns116431992RowOffsets
115 = static_cast< ImplIso2022CnConverterData const * >(pData)->
116 m_pCns116431992ToUnicodeRowOffsets;
117 sal_Int32 const * pCns116431992PlaneOffsets
118 = static_cast< ImplIso2022CnConverterData const * >(pData)->
119 m_pCns116431992ToUnicodePlaneOffsets;
120 ImplIso2022CnToUnicodeState eState
121 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
122 sal_uInt32 nRow = 0;
123 bool bSo = false;
124 bool b116431 = false;
125 sal_uInt32 nInfo = 0;
126 sal_Size nConverted = 0;
127 sal_Unicode * pDestBufPtr = pDestBuf;
128 sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
129 sal_Size startOfCurrentChar = 0;
131 if (pContext)
133 eState = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState;
134 nRow = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_nRow;
135 bSo = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo;
136 b116431 = static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431;
139 for (; nConverted < nSrcBytes; ++nConverted)
141 bool bUndefined = true;
142 sal_uInt32 nChar = *reinterpret_cast<unsigned char const *>(pSrcBuf++);
143 sal_uInt32 nPlane;
144 switch (eState)
146 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII:
147 if (nChar == 0x0E) // SO
149 bSo = true;
150 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
152 else if (nChar == 0x1B) // ESC
153 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
154 else if (nChar < 0x80)
155 if (pDestBufPtr != pDestBufEnd) {
156 *pDestBufPtr++ = static_cast<sal_Unicode>(nChar);
157 startOfCurrentChar = nConverted + 1;
158 } else
159 goto no_output;
160 else
162 bUndefined = false;
163 goto bad_input;
165 break;
167 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO:
168 if (nChar == 0x0F) // SI
170 bSo = false;
171 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
173 else if (nChar == 0x1B) // ESC
174 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
175 else if (nChar >= 0x21 && nChar <= 0x7E)
177 nRow = nChar;
178 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2;
180 else
182 bUndefined = false;
183 goto bad_input;
185 break;
187 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2:
188 if (nChar >= 0x21 && nChar <= 0x7E)
189 if (b116431)
191 nPlane = 0;
192 goto transform;
194 else
196 sal_uInt16 nUnicode = 0;
197 sal_uInt32 nFirst;
198 nRow += 0x80;
199 nChar += 0x80;
200 nFirst = pGb2312Data[nRow].mnTrailStart;
201 if (nChar >= nFirst
202 && nChar <= pGb2312Data[nRow].mnTrailEnd)
203 nUnicode = pGb2312Data[nRow].
204 mpToUniTrailTab[nChar - nFirst];
205 if (nUnicode != 0)
206 if (pDestBufPtr != pDestBufEnd)
208 *pDestBufPtr++ = static_cast<sal_Unicode>(nUnicode);
209 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
210 startOfCurrentChar = nConverted + 1;
212 else
213 goto no_output;
214 else
215 goto bad_input;
217 else
219 bUndefined = false;
220 goto bad_input;
222 break;
224 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432:
225 if (nChar >= 0x21 && nChar <= 0x7E)
227 nRow = nChar;
228 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2;
230 else
232 bUndefined = false;
233 goto bad_input;
235 break;
237 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2:
238 if (nChar >= 0x21 && nChar <= 0x7E)
240 nPlane = 1;
241 goto transform;
243 else
245 bUndefined = false;
246 goto bad_input;
248 break;
250 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC:
251 if (nChar == 0x24) // $
252 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR;
253 else if (nChar == 0x4E) // N
254 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432;
255 else
257 bUndefined = false;
258 goto bad_input;
260 break;
262 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR:
263 if (nChar == 0x29) // )
264 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN;
265 else if (nChar == 0x2A) // *
266 eState
267 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK;
268 else
270 bUndefined = false;
271 goto bad_input;
273 break;
275 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN:
276 if (nChar == 0x41) // A
278 b116431 = false;
279 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
280 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
282 else if (nChar == 0x47) // G
284 b116431 = true;
285 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
286 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
288 else
290 bUndefined = false;
291 goto bad_input;
293 break;
295 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK:
296 if (nChar == 0x48) // H
297 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
298 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
299 else
301 bUndefined = false;
302 goto bad_input;
304 break;
306 continue;
308 transform:
310 sal_Int32 nPlaneOffset = pCns116431992PlaneOffsets[nPlane];
311 if (nPlaneOffset == -1)
312 goto bad_input;
313 else
315 sal_Int32 nOffset
316 = pCns116431992RowOffsets[nPlaneOffset + (nRow - 0x21)];
317 if (nOffset == -1)
318 goto bad_input;
319 else
321 sal_uInt32 nFirstLast = pCns116431992Data[nOffset++];
322 sal_uInt32 nFirst = nFirstLast & 0xFF;
323 sal_uInt32 nLast = nFirstLast >> 8;
324 nChar -= 0x20;
325 if (nChar >= nFirst && nChar <= nLast)
327 sal_uInt32 nUnicode
328 = pCns116431992Data[nOffset + (nChar - nFirst)];
329 if (nUnicode == 0xFFFF)
330 goto bad_input;
331 else if (rtl::isHighSurrogate(nUnicode))
332 if (pDestBufEnd - pDestBufPtr >= 2)
334 nOffset += nLast - nFirst + 1;
335 nFirst = pCns116431992Data[nOffset++];
336 *pDestBufPtr++ = static_cast<sal_Unicode>(nUnicode);
337 *pDestBufPtr++
338 = static_cast<sal_Unicode>(pCns116431992Data[
339 nOffset + (nChar - nFirst)]);
340 startOfCurrentChar = nConverted + 1;
342 else
343 goto no_output;
344 else
345 if (pDestBufPtr != pDestBufEnd) {
346 *pDestBufPtr++ = static_cast<sal_Unicode>(nUnicode);
347 startOfCurrentChar = nConverted + 1;
348 } else
349 goto no_output;
351 else
352 goto bad_input;
353 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
354 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
357 continue;
360 bad_input:
361 switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
362 bUndefined, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
363 &nInfo))
365 case sal::detail::textenc::BAD_INPUT_STOP:
366 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
367 b116431 = false;
368 if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0) {
369 ++nConverted;
370 } else {
371 nConverted = startOfCurrentChar;
373 break;
375 case sal::detail::textenc::BAD_INPUT_CONTINUE:
376 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
377 b116431 = false;
378 startOfCurrentChar = nConverted + 1;
379 continue;
381 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
382 goto no_output;
384 break;
386 no_output:
387 --pSrcBuf;
388 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL;
389 break;
392 if (eState > IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO
393 && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
394 | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL))
395 == 0)
397 if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
398 nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOOSMALL;
399 else
400 switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
401 false, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
402 &nInfo))
404 case sal::detail::textenc::BAD_INPUT_STOP:
405 if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) != 0) {
406 nConverted = startOfCurrentChar;
408 [[fallthrough]];
409 case sal::detail::textenc::BAD_INPUT_CONTINUE:
410 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
411 b116431 = false;
412 break;
414 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
415 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL;
416 break;
420 if (pContext)
422 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState = eState;
423 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_nRow = nRow;
424 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo = bSo;
425 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431 = b116431;
427 if (pInfo)
428 *pInfo = nInfo;
429 if (pSrcCvtBytes)
430 *pSrcCvtBytes = nConverted;
432 return pDestBufPtr - pDestBuf;
435 void * ImplCreateUnicodeToIso2022CnContext()
437 ImplUnicodeToIso2022CnContext * pContext =
438 new ImplUnicodeToIso2022CnContext;
439 pContext->m_nHighSurrogate = 0;
440 pContext->m_eSoDesignator = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
441 pContext->m_b116432Designator = false;
442 pContext->m_bSo = false;
443 return pContext;
446 void ImplResetUnicodeToIso2022CnContext(void * pContext)
448 if (pContext)
450 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate = 0;
451 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator
452 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
453 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_b116432Designator
454 = false;
455 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo = false;
459 void ImplDestroyUnicodeToIso2022CnContext(void * pContext)
461 delete static_cast< ImplUnicodeToIso2022CnContext * >(pContext);
464 static sal_uInt32 ImplIso2022CnTranslateTo2312(ImplUniToDBCSHighTab const *
465 pGb2312Data,
466 sal_uInt32 nChar)
468 sal_uInt32 nIndex1 = nChar >> 8;
469 if (nIndex1 < 0x100)
471 sal_uInt32 nIndex2 = nChar & 0xFF;
472 sal_uInt32 nFirst = pGb2312Data[nIndex1].mnLowStart;
473 if (nIndex2 >= nFirst && nIndex2 <= pGb2312Data[nIndex1].mnLowEnd)
474 return pGb2312Data[nIndex1].mpToUniTrailTab[nIndex2 - nFirst]
475 & 0x7F7F;
477 return 0;
480 static sal_uInt32
481 ImplIso2022CnTranslateTo116431(sal_uInt8 const * pCns116431992Data,
482 sal_Int32 const * pCns116431992PageOffsets,
483 sal_Int32 const * pCns116431992PlaneOffsets,
484 sal_uInt32 nChar)
486 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
487 sal_uInt32 nFirst;
488 sal_uInt32 nLast;
489 sal_uInt32 nPlane;
490 if (nOffset == -1)
491 return 0;
492 nOffset = pCns116431992PageOffsets[nOffset + ((nChar & 0xFF00) >> 8)];
493 if (nOffset == -1)
494 return 0;
495 nFirst = pCns116431992Data[nOffset++];
496 nLast = pCns116431992Data[nOffset++];
497 nChar &= 0xFF;
498 if (nChar < nFirst || nChar > nLast)
499 return 0;
500 nOffset += 3 * (nChar - nFirst);
501 nPlane = pCns116431992Data[nOffset++];
502 if (nPlane != 1)
503 return 0;
504 return (0x20 + pCns116431992Data[nOffset]) << 8
505 | (0x20 + pCns116431992Data[nOffset + 1]);
508 sal_Size ImplConvertUnicodeToIso2022Cn(void const * pData,
509 void * pContext,
510 sal_Unicode const * pSrcBuf,
511 sal_Size nSrcChars,
512 char * pDestBuf,
513 sal_Size nDestBytes,
514 sal_uInt32 nFlags,
515 sal_uInt32 * pInfo,
516 sal_Size * pSrcCvtChars)
518 ImplUniToDBCSHighTab const * pGb2312Data
519 = static_cast< ImplIso2022CnConverterData const * >(pData)->
520 m_pUnicodeToGb2312Data;
521 sal_uInt8 const * pCns116431992Data
522 = static_cast< ImplIso2022CnConverterData const * >(pData)->
523 m_pUnicodeToCns116431992Data;
524 sal_Int32 const * pCns116431992PageOffsets
525 = static_cast< ImplIso2022CnConverterData const * >(pData)->
526 m_pUnicodeToCns116431992PageOffsets;
527 sal_Int32 const * pCns116431992PlaneOffsets
528 = static_cast< ImplIso2022CnConverterData const * >(pData)->
529 m_pUnicodeToCns116431992PlaneOffsets;
530 sal_Unicode nHighSurrogate = 0;
531 ImplUnicodeToIso2022CnDesignator eSoDesignator
532 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
533 bool b116432Designator = false;
534 bool bSo = false;
535 sal_uInt32 nInfo = 0;
536 sal_Size nConverted = 0;
537 char * pDestBufPtr = pDestBuf;
538 char * pDestBufEnd = pDestBuf + nDestBytes;
539 bool bWritten;
541 if (pContext)
543 nHighSurrogate
544 = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate;
545 eSoDesignator
546 = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator;
547 b116432Designator = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->
548 m_b116432Designator;
549 bSo = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo;
552 for (; nConverted < nSrcChars; ++nConverted)
554 bool bUndefined = true;
555 sal_uInt32 nChar = *pSrcBuf++;
556 if (nHighSurrogate == 0)
558 if (rtl::isHighSurrogate(nChar))
560 nHighSurrogate = static_cast<sal_Unicode>(nChar);
561 continue;
563 else if (rtl::isLowSurrogate(nChar))
565 bUndefined = false;
566 goto bad_input;
569 else if (rtl::isLowSurrogate(nChar))
570 nChar = rtl::combineSurrogates(nHighSurrogate, nChar);
571 else
573 bUndefined = false;
574 goto bad_input;
577 assert(rtl::isUnicodeScalarValue(nChar));
579 if (nChar == 0x0A || nChar == 0x0D) // LF, CR
581 if (bSo)
583 if (pDestBufPtr != pDestBufEnd)
585 *pDestBufPtr++ = 0x0F; // SI
586 bSo = false;
587 eSoDesignator
588 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
589 b116432Designator = false;
591 else
592 goto no_output;
594 if (pDestBufPtr != pDestBufEnd)
595 *pDestBufPtr++ = static_cast< char >(nChar);
596 else
597 goto no_output;
599 else if (nChar == 0x0E || nChar == 0x0F || nChar == 0x1B)
600 goto bad_input;
601 else if (nChar < 0x80)
603 if (bSo)
605 if (pDestBufPtr != pDestBufEnd)
607 *pDestBufPtr++ = 0x0F; // SI
608 bSo = false;
610 else
611 goto no_output;
613 if (pDestBufPtr != pDestBufEnd)
614 *pDestBufPtr++ = static_cast< char >(nChar);
615 else
616 goto no_output;
618 else
620 sal_uInt32 nBytes = 0;
621 ImplUnicodeToIso2022CnDesignator eNewDesignator =
622 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
623 switch (eSoDesignator)
625 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE:
626 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
627 if (nBytes != 0)
629 eNewDesignator
630 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
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_2312:
647 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
648 if (nBytes != 0)
650 eNewDesignator
651 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
652 break;
654 nBytes = ImplIso2022CnTranslateTo116431(
655 pCns116431992Data,
656 pCns116431992PageOffsets,
657 pCns116431992PlaneOffsets,
658 nChar);
659 if (nBytes != 0)
661 eNewDesignator
662 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
663 break;
665 break;
667 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431:
668 nBytes = ImplIso2022CnTranslateTo116431(
669 pCns116431992Data,
670 pCns116431992PageOffsets,
671 pCns116431992PlaneOffsets,
672 nChar);
673 if (nBytes != 0)
675 eNewDesignator
676 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
677 break;
679 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
680 if (nBytes != 0)
682 eNewDesignator
683 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
684 break;
686 break;
688 if (nBytes != 0)
690 if (eNewDesignator
691 != IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE)
693 if (bSo)
695 if (pDestBufPtr != pDestBufEnd)
697 *pDestBufPtr++ = 0x0F; // SI
698 bSo = false;
700 else
701 goto no_output;
703 if (pDestBufEnd - pDestBufPtr >= 4)
705 *pDestBufPtr++ = 0x1B; // ESC
706 *pDestBufPtr++ = 0x24; // $
707 *pDestBufPtr++ = 0x29; // )
708 *pDestBufPtr++
709 = eNewDesignator
710 == IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312 ?
711 0x41 : 0x47; // A, G
712 eSoDesignator = eNewDesignator;
714 else
715 goto no_output;
717 if (!bSo)
719 if (pDestBufPtr != pDestBufEnd)
721 *pDestBufPtr++ = 0x0E; // SO
722 bSo = true;
724 else
725 goto no_output;
727 if (pDestBufEnd - pDestBufPtr >= 4)
729 *pDestBufPtr++ = static_cast< char >(nBytes >> 8);
730 *pDestBufPtr++ = static_cast< char >(nBytes & 0xFF);
732 else
733 goto no_output;
735 else
737 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
738 sal_uInt32 nFirst;
739 sal_uInt32 nLast;
740 sal_uInt32 nPlane;
741 if (nOffset == -1)
742 goto bad_input;
743 nOffset
744 = pCns116431992PageOffsets[nOffset
745 + ((nChar & 0xFF00) >> 8)];
746 if (nOffset == -1)
747 goto bad_input;
748 nFirst = pCns116431992Data[nOffset++];
749 nLast = pCns116431992Data[nOffset++];
750 nChar &= 0xFF;
751 if (nChar < nFirst || nChar > nLast)
752 goto bad_input;
753 nOffset += 3 * (nChar - nFirst);
754 nPlane = pCns116431992Data[nOffset++];
755 if (nPlane != 2)
756 goto bad_input;
757 if (!b116432Designator)
759 if (pDestBufEnd - pDestBufPtr >= 4)
761 *pDestBufPtr++ = 0x1B; // ESC
762 *pDestBufPtr++ = 0x24; // $
763 *pDestBufPtr++ = 0x2A; // *
764 *pDestBufPtr++ = 0x48; // H
765 b116432Designator = true;
767 else
768 goto no_output;
770 if (pDestBufEnd - pDestBufPtr >= 4)
772 *pDestBufPtr++ = 0x1B; // ESC
773 *pDestBufPtr++ = 0x4E; // N
774 *pDestBufPtr++
775 = static_cast< char >(0x20 + pCns116431992Data[nOffset++]);
776 *pDestBufPtr++
777 = static_cast< char >(0x20 + pCns116431992Data[nOffset]);
779 else
780 goto no_output;
783 nHighSurrogate = 0;
784 continue;
786 bad_input:
787 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
788 bUndefined, nChar, nFlags, &pDestBufPtr, pDestBufEnd,
789 &nInfo, "\x0F" /* SI */, bSo ? 1 : 0, &bWritten))
791 case sal::detail::textenc::BAD_INPUT_STOP:
792 nHighSurrogate = 0;
793 break;
795 case sal::detail::textenc::BAD_INPUT_CONTINUE:
796 if (bWritten)
797 bSo = false;
798 nHighSurrogate = 0;
799 continue;
801 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
802 goto no_output;
804 break;
806 no_output:
807 --pSrcBuf;
808 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
809 break;
812 if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
813 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
814 == 0)
816 bool bFlush = true;
817 if (nHighSurrogate != 0)
819 if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
820 nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
821 else
822 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
823 false, 0, nFlags, &pDestBufPtr, pDestBufEnd, &nInfo,
824 "\x0F" /* SI */, bSo ? 1 : 0, &bWritten))
826 case sal::detail::textenc::BAD_INPUT_STOP:
827 nHighSurrogate = 0;
828 bFlush = false;
829 break;
831 case sal::detail::textenc::BAD_INPUT_CONTINUE:
832 if (bWritten)
833 bSo = false;
834 nHighSurrogate = 0;
835 break;
837 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
838 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
839 break;
842 if (bFlush && bSo && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
844 if (pDestBufPtr != pDestBufEnd)
846 *pDestBufPtr++ = 0x0F; // SI
847 bSo = false;
849 else
850 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
854 if (pContext)
856 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate
857 = nHighSurrogate;
858 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator
859 = eSoDesignator;
860 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_b116432Designator
861 = b116432Designator;
862 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo = bSo;
864 if (pInfo)
865 *pInfo = nInfo;
866 if (pSrcCvtChars)
867 *pSrcCvtChars = nConverted;
869 return pDestBufPtr - pDestBuf;
872 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */