xref: /aoo41x/main/sal/textenc/convertiso2022kr.c (revision 647f063d)
1*647f063dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*647f063dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*647f063dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*647f063dSAndrew Rist  * distributed with this work for additional information
6*647f063dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*647f063dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*647f063dSAndrew Rist  * "License"); you may not use this file except in compliance
9*647f063dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*647f063dSAndrew Rist  *
11*647f063dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*647f063dSAndrew Rist  *
13*647f063dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*647f063dSAndrew Rist  * software distributed under the License is distributed on an
15*647f063dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*647f063dSAndrew Rist  * KIND, either express or implied.  See the License for the
17*647f063dSAndrew Rist  * specific language governing permissions and limitations
18*647f063dSAndrew Rist  * under the License.
19*647f063dSAndrew Rist  *
20*647f063dSAndrew Rist  *************************************************************/
21*647f063dSAndrew Rist 
22*647f063dSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "convertiso2022kr.h"
25cdf0e10cSrcweir #include "context.h"
26cdf0e10cSrcweir #include "converter.h"
27cdf0e10cSrcweir #include "tenchelp.h"
28cdf0e10cSrcweir #include "unichars.h"
29cdf0e10cSrcweir #include "rtl/alloc.h"
30cdf0e10cSrcweir #include "rtl/textcvt.h"
31cdf0e10cSrcweir #include "sal/types.h"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir typedef enum /* order is important: */
34cdf0e10cSrcweir {
35cdf0e10cSrcweir     IMPL_ISO_2022_KR_TO_UNICODE_STATE_ASCII,
36cdf0e10cSrcweir     IMPL_ISO_2022_KR_TO_UNICODE_STATE_1001,
37cdf0e10cSrcweir     IMPL_ISO_2022_KR_TO_UNICODE_STATE_1001_2,
38cdf0e10cSrcweir     IMPL_ISO_2022_KR_TO_UNICODE_STATE_ESC,
39cdf0e10cSrcweir     IMPL_ISO_2022_KR_TO_UNICODE_STATE_ESC_DOLLAR,
40cdf0e10cSrcweir     IMPL_ISO_2022_KR_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN
41cdf0e10cSrcweir } ImplIso2022KrToUnicodeState;
42cdf0e10cSrcweir 
43cdf0e10cSrcweir typedef struct
44cdf0e10cSrcweir {
45cdf0e10cSrcweir     ImplIso2022KrToUnicodeState m_eState;
46cdf0e10cSrcweir     sal_uInt32 m_nRow;
47cdf0e10cSrcweir } ImplIso2022KrToUnicodeContext;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir typedef enum
50cdf0e10cSrcweir {
51cdf0e10cSrcweir     IMPL_UNICODE_TO_ISO_2022_KR_SET_NONE,
52cdf0e10cSrcweir     IMPL_UNICODE_TO_ISO_2022_KR_SET_ASCII,
53cdf0e10cSrcweir     IMPL_UNICODE_TO_ISO_2022_KR_SET_1001
54cdf0e10cSrcweir } ImplUnicodeToIso2022KrSet;
55cdf0e10cSrcweir 
56cdf0e10cSrcweir typedef struct
57cdf0e10cSrcweir {
58cdf0e10cSrcweir     sal_Unicode m_nHighSurrogate;
59cdf0e10cSrcweir     ImplUnicodeToIso2022KrSet m_eSet;
60cdf0e10cSrcweir } ImplUnicodeToIso2022KrContext;
61cdf0e10cSrcweir 
ImplCreateIso2022KrToUnicodeContext(void)62cdf0e10cSrcweir void * ImplCreateIso2022KrToUnicodeContext(void)
63cdf0e10cSrcweir {
64cdf0e10cSrcweir     void * pContext
65cdf0e10cSrcweir         = rtl_allocateMemory(sizeof (ImplIso2022KrToUnicodeContext));
66cdf0e10cSrcweir     ((ImplIso2022KrToUnicodeContext *) pContext)->m_eState
67cdf0e10cSrcweir         = IMPL_ISO_2022_KR_TO_UNICODE_STATE_ASCII;
68cdf0e10cSrcweir     return pContext;
69cdf0e10cSrcweir }
70cdf0e10cSrcweir 
ImplResetIso2022KrToUnicodeContext(void * pContext)71cdf0e10cSrcweir void ImplResetIso2022KrToUnicodeContext(void * pContext)
72cdf0e10cSrcweir {
73cdf0e10cSrcweir     if (pContext)
74cdf0e10cSrcweir         ((ImplIso2022KrToUnicodeContext *) pContext)->m_eState
75cdf0e10cSrcweir             = IMPL_ISO_2022_KR_TO_UNICODE_STATE_ASCII;
76cdf0e10cSrcweir }
77cdf0e10cSrcweir 
ImplConvertIso2022KrToUnicode(ImplTextConverterData const * pData,void * pContext,sal_Char const * pSrcBuf,sal_Size nSrcBytes,sal_Unicode * pDestBuf,sal_Size nDestChars,sal_uInt32 nFlags,sal_uInt32 * pInfo,sal_Size * pSrcCvtBytes)78cdf0e10cSrcweir sal_Size ImplConvertIso2022KrToUnicode(ImplTextConverterData const * pData,
79cdf0e10cSrcweir                                        void * pContext,
80cdf0e10cSrcweir                                        sal_Char const * pSrcBuf,
81cdf0e10cSrcweir                                        sal_Size nSrcBytes,
82cdf0e10cSrcweir                                        sal_Unicode * pDestBuf,
83cdf0e10cSrcweir                                        sal_Size nDestChars,
84cdf0e10cSrcweir                                        sal_uInt32 nFlags,
85cdf0e10cSrcweir                                        sal_uInt32 * pInfo,
86cdf0e10cSrcweir                                        sal_Size * pSrcCvtBytes)
87cdf0e10cSrcweir {
88cdf0e10cSrcweir     ImplDBCSToUniLeadTab const * pKsX1001Data
89cdf0e10cSrcweir         = ((ImplIso2022KrConverterData const *) pData)->
90cdf0e10cSrcweir               m_pKsX1001ToUnicodeData;
91cdf0e10cSrcweir     ImplIso2022KrToUnicodeState eState
92cdf0e10cSrcweir         = IMPL_ISO_2022_KR_TO_UNICODE_STATE_ASCII;
93cdf0e10cSrcweir     sal_uInt32 nRow = 0;
94cdf0e10cSrcweir     sal_uInt32 nInfo = 0;
95cdf0e10cSrcweir     sal_Size nConverted = 0;
96cdf0e10cSrcweir     sal_Unicode * pDestBufPtr = pDestBuf;
97cdf0e10cSrcweir     sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
98cdf0e10cSrcweir 
99cdf0e10cSrcweir     if (pContext)
100cdf0e10cSrcweir     {
101cdf0e10cSrcweir         eState = ((ImplIso2022KrToUnicodeContext *) pContext)->m_eState;
102cdf0e10cSrcweir         nRow = ((ImplIso2022KrToUnicodeContext *) pContext)->m_nRow;
103cdf0e10cSrcweir     }
104cdf0e10cSrcweir 
105cdf0e10cSrcweir     for (; nConverted < nSrcBytes; ++nConverted)
106cdf0e10cSrcweir     {
107cdf0e10cSrcweir         sal_Bool bUndefined = sal_True;
108cdf0e10cSrcweir         sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++;
109cdf0e10cSrcweir         switch (eState)
110cdf0e10cSrcweir         {
111cdf0e10cSrcweir         case IMPL_ISO_2022_KR_TO_UNICODE_STATE_ASCII:
112cdf0e10cSrcweir             if (nChar == 0x0E) /* SO */
113cdf0e10cSrcweir                 eState = IMPL_ISO_2022_KR_TO_UNICODE_STATE_1001;
114cdf0e10cSrcweir             else if (nChar == 0x1B) /* ESC */
115cdf0e10cSrcweir                 eState = IMPL_ISO_2022_KR_TO_UNICODE_STATE_ESC;
116cdf0e10cSrcweir             else if (nChar < 0x80)
117cdf0e10cSrcweir                 if (pDestBufPtr != pDestBufEnd)
118cdf0e10cSrcweir                     *pDestBufPtr++ = (sal_Unicode) nChar;
119cdf0e10cSrcweir                 else
120cdf0e10cSrcweir                     goto no_output;
121cdf0e10cSrcweir             else
122cdf0e10cSrcweir             {
123cdf0e10cSrcweir                 bUndefined = sal_False;
124cdf0e10cSrcweir                 goto bad_input;
125cdf0e10cSrcweir             }
126cdf0e10cSrcweir             break;
127cdf0e10cSrcweir 
128cdf0e10cSrcweir         case IMPL_ISO_2022_KR_TO_UNICODE_STATE_1001:
129cdf0e10cSrcweir             if (nChar == 0x0F) /* SI */
130cdf0e10cSrcweir                 eState = IMPL_ISO_2022_KR_TO_UNICODE_STATE_ASCII;
131cdf0e10cSrcweir             else if (nChar >= 0x21 && nChar <= 0x7E)
132cdf0e10cSrcweir             {
133cdf0e10cSrcweir                 nRow = nChar + 0x80;
134cdf0e10cSrcweir                 eState = IMPL_ISO_2022_KR_TO_UNICODE_STATE_1001_2;
135cdf0e10cSrcweir             }
136cdf0e10cSrcweir             else
137cdf0e10cSrcweir             {
138cdf0e10cSrcweir                 bUndefined = sal_False;
139cdf0e10cSrcweir                 goto bad_input;
140cdf0e10cSrcweir             }
141cdf0e10cSrcweir             break;
142cdf0e10cSrcweir 
143cdf0e10cSrcweir         case IMPL_ISO_2022_KR_TO_UNICODE_STATE_1001_2:
144cdf0e10cSrcweir             if (nChar >= 0x21 && nChar <= 0x7E)
145cdf0e10cSrcweir             {
146cdf0e10cSrcweir                 sal_uInt16 nUnicode = 0;
147cdf0e10cSrcweir                 sal_uInt32 nFirst = pKsX1001Data[nRow].mnTrailStart;
148cdf0e10cSrcweir                 nChar += 0x80;
149cdf0e10cSrcweir                 if (nChar >= nFirst && nChar <= pKsX1001Data[nRow].mnTrailEnd)
150cdf0e10cSrcweir                     nUnicode = pKsX1001Data[nRow].
151cdf0e10cSrcweir                                    mpToUniTrailTab[nChar - nFirst];
152cdf0e10cSrcweir                 if (nUnicode != 0)
153cdf0e10cSrcweir                     if (pDestBufPtr != pDestBufEnd)
154cdf0e10cSrcweir                     {
155cdf0e10cSrcweir                         *pDestBufPtr++ = (sal_Unicode) nUnicode;
156cdf0e10cSrcweir                         eState = IMPL_ISO_2022_KR_TO_UNICODE_STATE_1001;
157cdf0e10cSrcweir                     }
158cdf0e10cSrcweir                     else
159cdf0e10cSrcweir                         goto no_output;
160cdf0e10cSrcweir                 else
161cdf0e10cSrcweir                     goto bad_input;
162cdf0e10cSrcweir             }
163cdf0e10cSrcweir             else
164cdf0e10cSrcweir             {
165cdf0e10cSrcweir                 bUndefined = sal_False;
166cdf0e10cSrcweir                 goto bad_input;
167cdf0e10cSrcweir             }
168cdf0e10cSrcweir             break;
169cdf0e10cSrcweir 
170cdf0e10cSrcweir         case IMPL_ISO_2022_KR_TO_UNICODE_STATE_ESC:
171cdf0e10cSrcweir             if (nChar == 0x24) /* $ */
172cdf0e10cSrcweir                 eState = IMPL_ISO_2022_KR_TO_UNICODE_STATE_ESC_DOLLAR;
173cdf0e10cSrcweir             else
174cdf0e10cSrcweir             {
175cdf0e10cSrcweir                 bUndefined = sal_False;
176cdf0e10cSrcweir                 goto bad_input;
177cdf0e10cSrcweir             }
178cdf0e10cSrcweir             break;
179cdf0e10cSrcweir 
180cdf0e10cSrcweir         case IMPL_ISO_2022_KR_TO_UNICODE_STATE_ESC_DOLLAR:
181cdf0e10cSrcweir             if (nChar == 0x29) /* ) */
182cdf0e10cSrcweir                 eState = IMPL_ISO_2022_KR_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN;
183cdf0e10cSrcweir             else
184cdf0e10cSrcweir             {
185cdf0e10cSrcweir                 bUndefined = sal_False;
186cdf0e10cSrcweir                 goto bad_input;
187cdf0e10cSrcweir             }
188cdf0e10cSrcweir             break;
189cdf0e10cSrcweir 
190cdf0e10cSrcweir         case IMPL_ISO_2022_KR_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN:
191cdf0e10cSrcweir             if (nChar == 0x43) /* C */
192cdf0e10cSrcweir                 eState = IMPL_ISO_2022_KR_TO_UNICODE_STATE_ASCII;
193cdf0e10cSrcweir             else
194cdf0e10cSrcweir             {
195cdf0e10cSrcweir                 bUndefined = sal_False;
196cdf0e10cSrcweir                 goto bad_input;
197cdf0e10cSrcweir             }
198cdf0e10cSrcweir             break;
199cdf0e10cSrcweir         }
200cdf0e10cSrcweir         continue;
201cdf0e10cSrcweir 
202cdf0e10cSrcweir     bad_input:
203cdf0e10cSrcweir         switch (ImplHandleBadInputTextToUnicodeConversion(
204cdf0e10cSrcweir                     bUndefined, sal_True, 0, nFlags, &pDestBufPtr, pDestBufEnd,
205cdf0e10cSrcweir                     &nInfo))
206cdf0e10cSrcweir         {
207cdf0e10cSrcweir         case IMPL_BAD_INPUT_STOP:
208cdf0e10cSrcweir             eState = IMPL_ISO_2022_KR_TO_UNICODE_STATE_ASCII;
209cdf0e10cSrcweir             break;
210cdf0e10cSrcweir 
211cdf0e10cSrcweir         case IMPL_BAD_INPUT_CONTINUE:
212cdf0e10cSrcweir             eState = IMPL_ISO_2022_KR_TO_UNICODE_STATE_ASCII;
213cdf0e10cSrcweir             continue;
214cdf0e10cSrcweir 
215cdf0e10cSrcweir         case IMPL_BAD_INPUT_NO_OUTPUT:
216cdf0e10cSrcweir             goto no_output;
217cdf0e10cSrcweir         }
218cdf0e10cSrcweir         break;
219cdf0e10cSrcweir 
220cdf0e10cSrcweir     no_output:
221cdf0e10cSrcweir         --pSrcBuf;
222cdf0e10cSrcweir         nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
223cdf0e10cSrcweir         break;
224cdf0e10cSrcweir     }
225cdf0e10cSrcweir 
226cdf0e10cSrcweir     if (eState > IMPL_ISO_2022_KR_TO_UNICODE_STATE_1001
227cdf0e10cSrcweir         && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
228cdf0e10cSrcweir                          | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
229cdf0e10cSrcweir                == 0)
230cdf0e10cSrcweir     {
231cdf0e10cSrcweir         if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
232cdf0e10cSrcweir             nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
233cdf0e10cSrcweir         else
234cdf0e10cSrcweir             switch (ImplHandleBadInputTextToUnicodeConversion(
235cdf0e10cSrcweir                         sal_False, sal_True, 0, nFlags, &pDestBufPtr, pDestBufEnd,
236cdf0e10cSrcweir                         &nInfo))
237cdf0e10cSrcweir             {
238cdf0e10cSrcweir             case IMPL_BAD_INPUT_STOP:
239cdf0e10cSrcweir             case IMPL_BAD_INPUT_CONTINUE:
240cdf0e10cSrcweir                 eState = IMPL_ISO_2022_KR_TO_UNICODE_STATE_ASCII;
241cdf0e10cSrcweir                 break;
242cdf0e10cSrcweir 
243cdf0e10cSrcweir             case IMPL_BAD_INPUT_NO_OUTPUT:
244cdf0e10cSrcweir                 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
245cdf0e10cSrcweir                 break;
246cdf0e10cSrcweir             }
247cdf0e10cSrcweir     }
248cdf0e10cSrcweir 
249cdf0e10cSrcweir     if (pContext)
250cdf0e10cSrcweir     {
251cdf0e10cSrcweir         ((ImplIso2022KrToUnicodeContext *) pContext)->m_eState = eState;
252cdf0e10cSrcweir         ((ImplIso2022KrToUnicodeContext *) pContext)->m_nRow = nRow;
253cdf0e10cSrcweir     }
254cdf0e10cSrcweir     if (pInfo)
255cdf0e10cSrcweir         *pInfo = nInfo;
256cdf0e10cSrcweir     if (pSrcCvtBytes)
257cdf0e10cSrcweir         *pSrcCvtBytes = nConverted;
258cdf0e10cSrcweir 
259cdf0e10cSrcweir     return pDestBufPtr - pDestBuf;
260cdf0e10cSrcweir }
261cdf0e10cSrcweir 
ImplCreateUnicodeToIso2022KrContext(void)262cdf0e10cSrcweir void * ImplCreateUnicodeToIso2022KrContext(void)
263cdf0e10cSrcweir {
264cdf0e10cSrcweir     void * pContext
265cdf0e10cSrcweir         = rtl_allocateMemory(sizeof (ImplUnicodeToIso2022KrContext));
266cdf0e10cSrcweir     ((ImplUnicodeToIso2022KrContext *) pContext)->m_nHighSurrogate = 0;
267cdf0e10cSrcweir     ((ImplUnicodeToIso2022KrContext *) pContext)->m_eSet
268cdf0e10cSrcweir         = IMPL_UNICODE_TO_ISO_2022_KR_SET_NONE;
269cdf0e10cSrcweir     return pContext;
270cdf0e10cSrcweir }
271cdf0e10cSrcweir 
ImplResetUnicodeToIso2022KrContext(void * pContext)272cdf0e10cSrcweir void ImplResetUnicodeToIso2022KrContext(void * pContext)
273cdf0e10cSrcweir {
274cdf0e10cSrcweir     if (pContext)
275cdf0e10cSrcweir     {
276cdf0e10cSrcweir         ((ImplUnicodeToIso2022KrContext *) pContext)->m_nHighSurrogate = 0;
277cdf0e10cSrcweir         ((ImplUnicodeToIso2022KrContext *) pContext)->m_eSet
278cdf0e10cSrcweir             = IMPL_UNICODE_TO_ISO_2022_KR_SET_NONE;
279cdf0e10cSrcweir     }
280cdf0e10cSrcweir }
281cdf0e10cSrcweir 
ImplConvertUnicodeToIso2022Kr(ImplTextConverterData const * pData,void * pContext,sal_Unicode const * pSrcBuf,sal_Size nSrcChars,sal_Char * pDestBuf,sal_Size nDestBytes,sal_uInt32 nFlags,sal_uInt32 * pInfo,sal_Size * pSrcCvtChars)282cdf0e10cSrcweir sal_Size ImplConvertUnicodeToIso2022Kr(ImplTextConverterData const * pData,
283cdf0e10cSrcweir                                        void * pContext,
284cdf0e10cSrcweir                                        sal_Unicode const * pSrcBuf,
285cdf0e10cSrcweir                                        sal_Size nSrcChars,
286cdf0e10cSrcweir                                        sal_Char * pDestBuf,
287cdf0e10cSrcweir                                        sal_Size nDestBytes,
288cdf0e10cSrcweir                                        sal_uInt32 nFlags,
289cdf0e10cSrcweir                                        sal_uInt32 * pInfo,
290cdf0e10cSrcweir                                        sal_Size * pSrcCvtChars)
291cdf0e10cSrcweir {
292cdf0e10cSrcweir     ImplUniToDBCSHighTab const * pKsX1001Data
293cdf0e10cSrcweir         = ((ImplIso2022KrConverterData const *) pData)->
294cdf0e10cSrcweir               m_pUnicodeToKsX1001Data;
295cdf0e10cSrcweir     sal_Unicode nHighSurrogate = 0;
296cdf0e10cSrcweir     ImplUnicodeToIso2022KrSet eSet = IMPL_UNICODE_TO_ISO_2022_KR_SET_NONE;
297cdf0e10cSrcweir     sal_uInt32 nInfo = 0;
298cdf0e10cSrcweir     sal_Size nConverted = 0;
299cdf0e10cSrcweir     sal_Char * pDestBufPtr = pDestBuf;
300cdf0e10cSrcweir     sal_Char * pDestBufEnd = pDestBuf + nDestBytes;
301cdf0e10cSrcweir     sal_Bool bWritten;
302cdf0e10cSrcweir 
303cdf0e10cSrcweir     if (pContext)
304cdf0e10cSrcweir     {
305cdf0e10cSrcweir         nHighSurrogate
306cdf0e10cSrcweir             = ((ImplUnicodeToIso2022KrContext *) pContext)->m_nHighSurrogate;
307cdf0e10cSrcweir         eSet = ((ImplUnicodeToIso2022KrContext *) pContext)->m_eSet;
308cdf0e10cSrcweir     }
309cdf0e10cSrcweir 
310cdf0e10cSrcweir     if (eSet == IMPL_UNICODE_TO_ISO_2022_KR_SET_NONE)
311cdf0e10cSrcweir     {
312cdf0e10cSrcweir         if (pDestBufEnd - pDestBufPtr >= 4)
313cdf0e10cSrcweir         {
314cdf0e10cSrcweir             *pDestBufPtr++ = 0x1B; /* ESC */
315cdf0e10cSrcweir             *pDestBufPtr++ = 0x24; /* $ */
316cdf0e10cSrcweir             *pDestBufPtr++ = 0x29; /* ) */
317cdf0e10cSrcweir             *pDestBufPtr++ = 0x43; /* C */
318cdf0e10cSrcweir             eSet = IMPL_UNICODE_TO_ISO_2022_KR_SET_ASCII;
319cdf0e10cSrcweir         }
320cdf0e10cSrcweir         else
321cdf0e10cSrcweir             nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
322cdf0e10cSrcweir     }
323cdf0e10cSrcweir 
324cdf0e10cSrcweir     if ((nInfo & RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL) == 0)
325cdf0e10cSrcweir         for (; nConverted < nSrcChars; ++nConverted)
326cdf0e10cSrcweir         {
327cdf0e10cSrcweir             sal_Bool bUndefined = sal_True;
328cdf0e10cSrcweir             sal_uInt32 nChar = *pSrcBuf++;
329cdf0e10cSrcweir             if (nHighSurrogate == 0)
330cdf0e10cSrcweir             {
331cdf0e10cSrcweir                 if (ImplIsHighSurrogate(nChar))
332cdf0e10cSrcweir                 {
333cdf0e10cSrcweir                     nHighSurrogate = (sal_Unicode) nChar;
334cdf0e10cSrcweir                     continue;
335cdf0e10cSrcweir                 }
336cdf0e10cSrcweir             }
337cdf0e10cSrcweir             else if (ImplIsLowSurrogate(nChar))
338cdf0e10cSrcweir                 nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
339cdf0e10cSrcweir             else
340cdf0e10cSrcweir             {
341cdf0e10cSrcweir                 bUndefined = sal_False;
342cdf0e10cSrcweir                 goto bad_input;
343cdf0e10cSrcweir             }
344cdf0e10cSrcweir 
345cdf0e10cSrcweir             if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
346cdf0e10cSrcweir             {
347cdf0e10cSrcweir                 bUndefined = sal_False;
348cdf0e10cSrcweir                 goto bad_input;
349cdf0e10cSrcweir             }
350cdf0e10cSrcweir 
351cdf0e10cSrcweir             if (nChar == 0x0A || nChar == 0x0D) /* LF, CR */
352cdf0e10cSrcweir             {
353cdf0e10cSrcweir                 if (eSet == IMPL_UNICODE_TO_ISO_2022_KR_SET_1001)
354cdf0e10cSrcweir                 {
355cdf0e10cSrcweir                     if (pDestBufPtr != pDestBufEnd)
356cdf0e10cSrcweir                     {
357cdf0e10cSrcweir                         *pDestBufPtr++ = 0x0F; /* SI */
358cdf0e10cSrcweir                         eSet = IMPL_UNICODE_TO_ISO_2022_KR_SET_ASCII;
359cdf0e10cSrcweir                     }
360cdf0e10cSrcweir                     else
361cdf0e10cSrcweir                         goto no_output;
362cdf0e10cSrcweir                 }
363cdf0e10cSrcweir                 if (pDestBufPtr != pDestBufEnd)
364cdf0e10cSrcweir                     *pDestBufPtr++ = (sal_Char) nChar;
365cdf0e10cSrcweir                 else
366cdf0e10cSrcweir                     goto no_output;
367cdf0e10cSrcweir             }
368cdf0e10cSrcweir             else if (nChar == 0x0E || nChar == 0x0F || nChar == 0x1B)
369cdf0e10cSrcweir                 goto bad_input;
370cdf0e10cSrcweir             else if (nChar < 0x80)
371cdf0e10cSrcweir             {
372cdf0e10cSrcweir                 if (eSet == IMPL_UNICODE_TO_ISO_2022_KR_SET_1001)
373cdf0e10cSrcweir                 {
374cdf0e10cSrcweir                     if (pDestBufPtr != pDestBufEnd)
375cdf0e10cSrcweir                     {
376cdf0e10cSrcweir                         *pDestBufPtr++ = 0x0F; /* SI */
377cdf0e10cSrcweir                         eSet = IMPL_UNICODE_TO_ISO_2022_KR_SET_ASCII;
378cdf0e10cSrcweir                     }
379cdf0e10cSrcweir                     else
380cdf0e10cSrcweir                         goto no_output;
381cdf0e10cSrcweir                 }
382cdf0e10cSrcweir                 if (pDestBufPtr != pDestBufEnd)
383cdf0e10cSrcweir                     *pDestBufPtr++ = (sal_Char) nChar;
384cdf0e10cSrcweir                 else
385cdf0e10cSrcweir                     goto no_output;
386cdf0e10cSrcweir             }
387cdf0e10cSrcweir             else
388cdf0e10cSrcweir             {
389cdf0e10cSrcweir                 sal_uInt16 nBytes = 0;
390cdf0e10cSrcweir                 sal_uInt32 nIndex1 = nChar >> 8;
391cdf0e10cSrcweir                 if (nIndex1 < 0x100)
392cdf0e10cSrcweir                 {
393cdf0e10cSrcweir                     sal_uInt32 nIndex2 = nChar & 0xFF;
394cdf0e10cSrcweir                     sal_uInt32 nFirst = pKsX1001Data[nIndex1].mnLowStart;
395cdf0e10cSrcweir                     if (nIndex2 >= nFirst
396cdf0e10cSrcweir                         && nIndex2 <= pKsX1001Data[nIndex1].mnLowEnd)
397cdf0e10cSrcweir                         nBytes = pKsX1001Data[nIndex1].
398cdf0e10cSrcweir                                      mpToUniTrailTab[nIndex2 - nFirst];
399cdf0e10cSrcweir                 }
400cdf0e10cSrcweir                 if (nBytes != 0)
401cdf0e10cSrcweir                 {
402cdf0e10cSrcweir                     if (eSet == IMPL_UNICODE_TO_ISO_2022_KR_SET_ASCII)
403cdf0e10cSrcweir                     {
404cdf0e10cSrcweir                         if (pDestBufPtr != pDestBufEnd)
405cdf0e10cSrcweir                         {
406cdf0e10cSrcweir                             *pDestBufPtr++ = 0x0E; /* SO */
407cdf0e10cSrcweir                             eSet = IMPL_UNICODE_TO_ISO_2022_KR_SET_1001;
408cdf0e10cSrcweir                         }
409cdf0e10cSrcweir                         else
410cdf0e10cSrcweir                             goto no_output;
411cdf0e10cSrcweir                     }
412cdf0e10cSrcweir                     if (pDestBufEnd - pDestBufPtr >= 2)
413cdf0e10cSrcweir                     {
414cdf0e10cSrcweir                         *pDestBufPtr++ = (sal_Char) ((nBytes >> 8) & 0x7F);
415cdf0e10cSrcweir                         *pDestBufPtr++ = (sal_Char) (nBytes & 0x7F);
416cdf0e10cSrcweir                     }
417cdf0e10cSrcweir                     else
418cdf0e10cSrcweir                         goto no_output;
419cdf0e10cSrcweir                 }
420cdf0e10cSrcweir                 else
421cdf0e10cSrcweir                     goto bad_input;
422cdf0e10cSrcweir             }
423cdf0e10cSrcweir             nHighSurrogate = 0;
424cdf0e10cSrcweir             continue;
425cdf0e10cSrcweir 
426cdf0e10cSrcweir         bad_input:
427cdf0e10cSrcweir             switch (ImplHandleBadInputUnicodeToTextConversion(
428cdf0e10cSrcweir                         bUndefined,
429cdf0e10cSrcweir                         nChar,
430cdf0e10cSrcweir                         nFlags,
431cdf0e10cSrcweir                         &pDestBufPtr,
432cdf0e10cSrcweir                         pDestBufEnd,
433cdf0e10cSrcweir                         &nInfo,
434cdf0e10cSrcweir                         "\x0F", /* SI */
435cdf0e10cSrcweir                         eSet == IMPL_UNICODE_TO_ISO_2022_KR_SET_ASCII ? 0 : 1,
436cdf0e10cSrcweir                         &bWritten))
437cdf0e10cSrcweir             {
438cdf0e10cSrcweir             case IMPL_BAD_INPUT_STOP:
439cdf0e10cSrcweir                 nHighSurrogate = 0;
440cdf0e10cSrcweir                 break;
441cdf0e10cSrcweir 
442cdf0e10cSrcweir             case IMPL_BAD_INPUT_CONTINUE:
443cdf0e10cSrcweir                 if (bWritten)
444cdf0e10cSrcweir                     eSet = IMPL_UNICODE_TO_ISO_2022_KR_SET_ASCII;
445cdf0e10cSrcweir                 nHighSurrogate = 0;
446cdf0e10cSrcweir                 continue;
447cdf0e10cSrcweir 
448cdf0e10cSrcweir             case IMPL_BAD_INPUT_NO_OUTPUT:
449cdf0e10cSrcweir                 goto no_output;
450cdf0e10cSrcweir             }
451cdf0e10cSrcweir             break;
452cdf0e10cSrcweir 
453cdf0e10cSrcweir         no_output:
454cdf0e10cSrcweir             --pSrcBuf;
455cdf0e10cSrcweir             nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
456cdf0e10cSrcweir             break;
457cdf0e10cSrcweir         }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir     if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
460cdf0e10cSrcweir                       | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
461cdf0e10cSrcweir             == 0)
462cdf0e10cSrcweir     {
463cdf0e10cSrcweir         sal_Bool bFlush = sal_True;
464cdf0e10cSrcweir         if (nHighSurrogate != 0)
465cdf0e10cSrcweir         {
466cdf0e10cSrcweir             if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
467cdf0e10cSrcweir                 nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
468cdf0e10cSrcweir             else
469cdf0e10cSrcweir                 switch (ImplHandleBadInputUnicodeToTextConversion(
470cdf0e10cSrcweir                             sal_False,
471cdf0e10cSrcweir                             0,
472cdf0e10cSrcweir                             nFlags,
473cdf0e10cSrcweir                             &pDestBufPtr,
474cdf0e10cSrcweir                             pDestBufEnd,
475cdf0e10cSrcweir                             &nInfo,
476cdf0e10cSrcweir                             "\x0F", /* SI */
477cdf0e10cSrcweir                             eSet == IMPL_UNICODE_TO_ISO_2022_KR_SET_ASCII ?
478cdf0e10cSrcweir                                 0 : 1,
479cdf0e10cSrcweir                             &bWritten))
480cdf0e10cSrcweir                 {
481cdf0e10cSrcweir                 case IMPL_BAD_INPUT_STOP:
482cdf0e10cSrcweir                     nHighSurrogate = 0;
483cdf0e10cSrcweir                     bFlush = sal_False;
484cdf0e10cSrcweir                     break;
485cdf0e10cSrcweir 
486cdf0e10cSrcweir                 case IMPL_BAD_INPUT_CONTINUE:
487cdf0e10cSrcweir                     if (bWritten)
488cdf0e10cSrcweir                         eSet = IMPL_UNICODE_TO_ISO_2022_KR_SET_ASCII;
489cdf0e10cSrcweir                     nHighSurrogate = 0;
490cdf0e10cSrcweir                     break;
491cdf0e10cSrcweir 
492cdf0e10cSrcweir                 case IMPL_BAD_INPUT_NO_OUTPUT:
493cdf0e10cSrcweir                     nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
494cdf0e10cSrcweir                     break;
495cdf0e10cSrcweir                 }
496cdf0e10cSrcweir         }
497cdf0e10cSrcweir         if (bFlush
498cdf0e10cSrcweir             && eSet == IMPL_UNICODE_TO_ISO_2022_KR_SET_1001
499cdf0e10cSrcweir             && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
500cdf0e10cSrcweir         {
501cdf0e10cSrcweir             if (pDestBufPtr != pDestBufEnd)
502cdf0e10cSrcweir             {
503cdf0e10cSrcweir                 *pDestBufPtr++ = 0x0F; /* SI */
504cdf0e10cSrcweir                 eSet = IMPL_UNICODE_TO_ISO_2022_KR_SET_ASCII;
505cdf0e10cSrcweir             }
506cdf0e10cSrcweir             else
507cdf0e10cSrcweir                 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
508cdf0e10cSrcweir         }
509cdf0e10cSrcweir     }
510cdf0e10cSrcweir 
511cdf0e10cSrcweir     if (pContext)
512cdf0e10cSrcweir     {
513cdf0e10cSrcweir         ((ImplUnicodeToIso2022KrContext *) pContext)->m_nHighSurrogate
514cdf0e10cSrcweir             = nHighSurrogate;
515cdf0e10cSrcweir         ((ImplUnicodeToIso2022KrContext *) pContext)->m_eSet = eSet;
516cdf0e10cSrcweir     }
517cdf0e10cSrcweir     if (pInfo)
518cdf0e10cSrcweir         *pInfo = nInfo;
519cdf0e10cSrcweir     if (pSrcCvtChars)
520cdf0e10cSrcweir         *pSrcCvtChars = nConverted;
521cdf0e10cSrcweir 
522cdf0e10cSrcweir     return pDestBufPtr - pDestBuf;
523cdf0e10cSrcweir }
524