bump product version to 5.0.4.1
[LibreOffice.git] / sal / textenc / convertiso2022cn.cxx
blob7adece94fff01c42f0247ba93553639251a55b15
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++ = (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++ = (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++ = (sal_Unicode) nUnicode;
332 *pDestBufPtr++
333 = (sal_Unicode)
334 pCns116431992Data[
335 nOffset + (nChar - nFirst)];
337 else
338 goto no_output;
339 else
340 if (pDestBufPtr != pDestBufEnd)
341 *pDestBufPtr++ = (sal_Unicode) nUnicode;
342 else
343 goto no_output;
345 else
346 goto bad_input;
347 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
348 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
351 continue;
354 bad_input:
355 switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
356 bUndefined, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
357 &nInfo))
359 case sal::detail::textenc::BAD_INPUT_STOP:
360 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
361 b116431 = false;
362 break;
364 case sal::detail::textenc::BAD_INPUT_CONTINUE:
365 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
366 b116431 = false;
367 continue;
369 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
370 goto no_output;
372 break;
374 no_output:
375 --pSrcBuf;
376 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
377 break;
380 if (eState > IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO
381 && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
382 | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
383 == 0)
385 if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
386 nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
387 else
388 switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
389 false, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
390 &nInfo))
392 case sal::detail::textenc::BAD_INPUT_STOP:
393 case sal::detail::textenc::BAD_INPUT_CONTINUE:
394 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
395 b116431 = false;
396 break;
398 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
399 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
400 break;
404 if (pContext)
406 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_eState = eState;
407 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_nRow = nRow;
408 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_bSo = bSo;
409 static_cast< ImplIso2022CnToUnicodeContext * >(pContext)->m_b116431 = b116431;
411 if (pInfo)
412 *pInfo = nInfo;
413 if (pSrcCvtBytes)
414 *pSrcCvtBytes = nConverted;
416 return pDestBufPtr - pDestBuf;
419 void * ImplCreateUnicodeToIso2022CnContext()
421 ImplUnicodeToIso2022CnContext * pContext =
422 new ImplUnicodeToIso2022CnContext;
423 pContext->m_nHighSurrogate = 0;
424 pContext->m_eSoDesignator = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
425 pContext->m_b116432Designator = false;
426 pContext->m_bSo = false;
427 return pContext;
430 void ImplResetUnicodeToIso2022CnContext(void * pContext)
432 if (pContext)
434 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate = 0;
435 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator
436 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
437 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_b116432Designator
438 = false;
439 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo = false;
443 void ImplDestroyUnicodeToIso2022CnContext(void * pContext)
445 delete static_cast< ImplUnicodeToIso2022CnContext * >(pContext);
448 static sal_uInt32 ImplIso2022CnTranslateTo2312(ImplUniToDBCSHighTab const *
449 pGb2312Data,
450 sal_uInt32 nChar)
452 sal_uInt32 nIndex1 = nChar >> 8;
453 if (nIndex1 < 0x100)
455 sal_uInt32 nIndex2 = nChar & 0xFF;
456 sal_uInt32 nFirst = pGb2312Data[nIndex1].mnLowStart;
457 if (nIndex2 >= nFirst && nIndex2 <= pGb2312Data[nIndex1].mnLowEnd)
458 return pGb2312Data[nIndex1].mpToUniTrailTab[nIndex2 - nFirst]
459 & 0x7F7F;
461 return 0;
464 static sal_uInt32
465 ImplIso2022CnTranslateTo116431(sal_uInt8 const * pCns116431992Data,
466 sal_Int32 const * pCns116431992PageOffsets,
467 sal_Int32 const * pCns116431992PlaneOffsets,
468 sal_uInt32 nChar)
470 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
471 sal_uInt32 nFirst;
472 sal_uInt32 nLast;
473 sal_uInt32 nPlane;
474 if (nOffset == -1)
475 return 0;
476 nOffset = pCns116431992PageOffsets[nOffset + ((nChar & 0xFF00) >> 8)];
477 if (nOffset == -1)
478 return 0;
479 nFirst = pCns116431992Data[nOffset++];
480 nLast = pCns116431992Data[nOffset++];
481 nChar &= 0xFF;
482 if (nChar < nFirst || nChar > nLast)
483 return 0;
484 nOffset += 3 * (nChar - nFirst);
485 nPlane = pCns116431992Data[nOffset++];
486 if (nPlane != 1)
487 return 0;
488 return (0x20 + pCns116431992Data[nOffset]) << 8
489 | (0x20 + pCns116431992Data[nOffset + 1]);
492 sal_Size ImplConvertUnicodeToIso2022Cn(void const * pData,
493 void * pContext,
494 sal_Unicode const * pSrcBuf,
495 sal_Size nSrcChars,
496 char * pDestBuf,
497 sal_Size nDestBytes,
498 sal_uInt32 nFlags,
499 sal_uInt32 * pInfo,
500 sal_Size * pSrcCvtChars)
502 ImplUniToDBCSHighTab const * pGb2312Data
503 = static_cast< ImplIso2022CnConverterData const * >(pData)->
504 m_pUnicodeToGb2312Data;
505 sal_uInt8 const * pCns116431992Data
506 = static_cast< ImplIso2022CnConverterData const * >(pData)->
507 m_pUnicodeToCns116431992Data;
508 sal_Int32 const * pCns116431992PageOffsets
509 = static_cast< ImplIso2022CnConverterData const * >(pData)->
510 m_pUnicodeToCns116431992PageOffsets;
511 sal_Int32 const * pCns116431992PlaneOffsets
512 = static_cast< ImplIso2022CnConverterData const * >(pData)->
513 m_pUnicodeToCns116431992PlaneOffsets;
514 sal_Unicode nHighSurrogate = 0;
515 ImplUnicodeToIso2022CnDesignator eSoDesignator
516 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
517 bool b116432Designator = false;
518 bool bSo = false;
519 sal_uInt32 nInfo = 0;
520 sal_Size nConverted = 0;
521 char * pDestBufPtr = pDestBuf;
522 char * pDestBufEnd = pDestBuf + nDestBytes;
523 bool bWritten;
525 if (pContext)
527 nHighSurrogate
528 = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate;
529 eSoDesignator
530 = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator;
531 b116432Designator = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->
532 m_b116432Designator;
533 bSo = static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo;
536 for (; nConverted < nSrcChars; ++nConverted)
538 bool bUndefined = true;
539 sal_uInt32 nChar = *pSrcBuf++;
540 if (nHighSurrogate == 0)
542 if (ImplIsHighSurrogate(nChar))
544 nHighSurrogate = (sal_Unicode) nChar;
545 continue;
548 else if (ImplIsLowSurrogate(nChar))
549 nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
550 else
552 bUndefined = false;
553 goto bad_input;
556 if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
558 bUndefined = false;
559 goto bad_input;
562 if (nChar == 0x0A || nChar == 0x0D) // LF, CR
564 if (bSo)
566 if (pDestBufPtr != pDestBufEnd)
568 *pDestBufPtr++ = 0x0F; // SI
569 bSo = false;
570 eSoDesignator
571 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
572 b116432Designator = false;
574 else
575 goto no_output;
577 if (pDestBufPtr != pDestBufEnd)
578 *pDestBufPtr++ = static_cast< char >(nChar);
579 else
580 goto no_output;
582 else if (nChar == 0x0E || nChar == 0x0F || nChar == 0x1B)
583 goto bad_input;
584 else if (nChar < 0x80)
586 if (bSo)
588 if (pDestBufPtr != pDestBufEnd)
590 *pDestBufPtr++ = 0x0F; // SI
591 bSo = false;
593 else
594 goto no_output;
596 if (pDestBufPtr != pDestBufEnd)
597 *pDestBufPtr++ = static_cast< char >(nChar);
598 else
599 goto no_output;
601 else
603 sal_uInt32 nBytes = 0;
604 ImplUnicodeToIso2022CnDesignator eNewDesignator =
605 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
606 switch (eSoDesignator)
608 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE:
609 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
610 if (nBytes != 0)
612 eNewDesignator
613 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
614 break;
616 nBytes = ImplIso2022CnTranslateTo116431(
617 pCns116431992Data,
618 pCns116431992PageOffsets,
619 pCns116431992PlaneOffsets,
620 nChar);
621 if (nBytes != 0)
623 eNewDesignator
624 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
625 break;
627 break;
629 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312:
630 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
631 if (nBytes != 0)
633 eNewDesignator
634 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
635 break;
637 nBytes = ImplIso2022CnTranslateTo116431(
638 pCns116431992Data,
639 pCns116431992PageOffsets,
640 pCns116431992PlaneOffsets,
641 nChar);
642 if (nBytes != 0)
644 eNewDesignator
645 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
646 break;
648 break;
650 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431:
651 nBytes = ImplIso2022CnTranslateTo116431(
652 pCns116431992Data,
653 pCns116431992PageOffsets,
654 pCns116431992PlaneOffsets,
655 nChar);
656 if (nBytes != 0)
658 eNewDesignator
659 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
660 break;
662 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
663 if (nBytes != 0)
665 eNewDesignator
666 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
667 break;
669 break;
671 if (nBytes != 0)
673 if (eNewDesignator
674 != IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE)
676 if (bSo)
678 if (pDestBufPtr != pDestBufEnd)
680 *pDestBufPtr++ = 0x0F; // SI
681 bSo = false;
683 else
684 goto no_output;
686 if (pDestBufEnd - pDestBufPtr >= 4)
688 *pDestBufPtr++ = 0x1B; // ESC
689 *pDestBufPtr++ = 0x24; // $
690 *pDestBufPtr++ = 0x29; // )
691 *pDestBufPtr++
692 = eNewDesignator
693 == IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312 ?
694 0x41 : 0x47; // A, G
695 eSoDesignator = eNewDesignator;
697 else
698 goto no_output;
700 if (!bSo)
702 if (pDestBufPtr != pDestBufEnd)
704 *pDestBufPtr++ = 0x0E; // SO
705 bSo = true;
707 else
708 goto no_output;
710 if (pDestBufEnd - pDestBufPtr >= 4)
712 *pDestBufPtr++ = static_cast< char >(nBytes >> 8);
713 *pDestBufPtr++ = static_cast< char >(nBytes & 0xFF);
715 else
716 goto no_output;
718 else
720 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
721 sal_uInt32 nFirst;
722 sal_uInt32 nLast;
723 sal_uInt32 nPlane;
724 if (nOffset == -1)
725 goto bad_input;
726 nOffset
727 = pCns116431992PageOffsets[nOffset
728 + ((nChar & 0xFF00) >> 8)];
729 if (nOffset == -1)
730 goto bad_input;
731 nFirst = pCns116431992Data[nOffset++];
732 nLast = pCns116431992Data[nOffset++];
733 nChar &= 0xFF;
734 if (nChar < nFirst || nChar > nLast)
735 goto bad_input;
736 nOffset += 3 * (nChar - nFirst);
737 nPlane = pCns116431992Data[nOffset++];
738 if (nPlane != 2)
739 goto bad_input;
740 if (!b116432Designator)
742 if (pDestBufEnd - pDestBufPtr >= 4)
744 *pDestBufPtr++ = 0x1B; // ESC
745 *pDestBufPtr++ = 0x24; // $
746 *pDestBufPtr++ = 0x2A; // *
747 *pDestBufPtr++ = 0x48; // H
748 b116432Designator = true;
750 else
751 goto no_output;
753 if (pDestBufEnd - pDestBufPtr >= 4)
755 *pDestBufPtr++ = 0x1B; // ESC
756 *pDestBufPtr++ = 0x4E; // N
757 *pDestBufPtr++
758 = static_cast< char >(0x20 + pCns116431992Data[nOffset++]);
759 *pDestBufPtr++
760 = static_cast< char >(0x20 + pCns116431992Data[nOffset]);
762 else
763 goto no_output;
766 nHighSurrogate = 0;
767 continue;
769 bad_input:
770 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
771 bUndefined, nChar, nFlags, &pDestBufPtr, pDestBufEnd,
772 &nInfo, "\x0F" /* SI */, bSo ? 1 : 0, &bWritten))
774 case sal::detail::textenc::BAD_INPUT_STOP:
775 nHighSurrogate = 0;
776 break;
778 case sal::detail::textenc::BAD_INPUT_CONTINUE:
779 if (bWritten)
780 bSo = false;
781 nHighSurrogate = 0;
782 continue;
784 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
785 goto no_output;
787 break;
789 no_output:
790 --pSrcBuf;
791 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
792 break;
795 if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
796 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
797 == 0)
799 bool bFlush = true;
800 if (nHighSurrogate != 0)
802 if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
803 nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
804 else
805 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
806 false, 0, nFlags, &pDestBufPtr, pDestBufEnd, &nInfo,
807 "\x0F" /* SI */, bSo ? 1 : 0, &bWritten))
809 case sal::detail::textenc::BAD_INPUT_STOP:
810 nHighSurrogate = 0;
811 bFlush = false;
812 break;
814 case sal::detail::textenc::BAD_INPUT_CONTINUE:
815 if (bWritten)
816 bSo = false;
817 nHighSurrogate = 0;
818 break;
820 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
821 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
822 break;
825 if (bFlush && bSo && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
827 if (pDestBufPtr != pDestBufEnd)
829 *pDestBufPtr++ = 0x0F; // SI
830 bSo = false;
832 else
833 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
837 if (pContext)
839 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_nHighSurrogate
840 = nHighSurrogate;
841 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_eSoDesignator
842 = eSoDesignator;
843 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_b116432Designator
844 = b116432Designator;
845 static_cast< ImplUnicodeToIso2022CnContext * >(pContext)->m_bSo = bSo;
847 if (pInfo)
848 *pInfo = nInfo;
849 if (pSrcCvtChars)
850 *pSrcCvtChars = nConverted;
852 return pDestBufPtr - pDestBuf;
855 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */