xref: /aoo42x/main/sal/textenc/convertiso2022jp.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 "convertiso2022jp.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_JP_TO_UNICODE_STATE_ASCII,
36cdf0e10cSrcweir     IMPL_ISO_2022_JP_TO_UNICODE_STATE_JIS_ROMAN,
37cdf0e10cSrcweir     IMPL_ISO_2022_JP_TO_UNICODE_STATE_0208,
38cdf0e10cSrcweir     IMPL_ISO_2022_JP_TO_UNICODE_STATE_0208_2,
39cdf0e10cSrcweir     IMPL_ISO_2022_JP_TO_UNICODE_STATE_ESC,
40cdf0e10cSrcweir     IMPL_ISO_2022_JP_TO_UNICODE_STATE_ESC_LPAREN,
41cdf0e10cSrcweir     IMPL_ISO_2022_JP_TO_UNICODE_STATE_ESC_DOLLAR
42cdf0e10cSrcweir } ImplIso2022JpToUnicodeState;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir typedef struct
45cdf0e10cSrcweir {
46cdf0e10cSrcweir     ImplIso2022JpToUnicodeState m_eState;
47cdf0e10cSrcweir     sal_uInt32 m_nRow;
48cdf0e10cSrcweir } ImplIso2022JpToUnicodeContext;
49cdf0e10cSrcweir 
50cdf0e10cSrcweir typedef struct
51cdf0e10cSrcweir {
52cdf0e10cSrcweir     sal_Unicode m_nHighSurrogate;
53cdf0e10cSrcweir     sal_Bool m_b0208;
54cdf0e10cSrcweir } ImplUnicodeToIso2022JpContext;
55cdf0e10cSrcweir 
ImplCreateIso2022JpToUnicodeContext(void)56cdf0e10cSrcweir void * ImplCreateIso2022JpToUnicodeContext(void)
57cdf0e10cSrcweir {
58cdf0e10cSrcweir     void * pContext
59cdf0e10cSrcweir         = rtl_allocateMemory(sizeof (ImplIso2022JpToUnicodeContext));
60cdf0e10cSrcweir     ((ImplIso2022JpToUnicodeContext *) pContext)->m_eState
61cdf0e10cSrcweir         = IMPL_ISO_2022_JP_TO_UNICODE_STATE_ASCII;
62cdf0e10cSrcweir     return pContext;
63cdf0e10cSrcweir }
64cdf0e10cSrcweir 
ImplResetIso2022JpToUnicodeContext(void * pContext)65cdf0e10cSrcweir void ImplResetIso2022JpToUnicodeContext(void * pContext)
66cdf0e10cSrcweir {
67cdf0e10cSrcweir     if (pContext)
68cdf0e10cSrcweir         ((ImplIso2022JpToUnicodeContext *) pContext)->m_eState
69cdf0e10cSrcweir             = IMPL_ISO_2022_JP_TO_UNICODE_STATE_ASCII;
70cdf0e10cSrcweir }
71cdf0e10cSrcweir 
ImplConvertIso2022JpToUnicode(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)72cdf0e10cSrcweir sal_Size ImplConvertIso2022JpToUnicode(ImplTextConverterData const * pData,
73cdf0e10cSrcweir                                        void * pContext,
74cdf0e10cSrcweir                                        sal_Char const * pSrcBuf,
75cdf0e10cSrcweir                                        sal_Size nSrcBytes,
76cdf0e10cSrcweir                                        sal_Unicode * pDestBuf,
77cdf0e10cSrcweir                                        sal_Size nDestChars,
78cdf0e10cSrcweir                                        sal_uInt32 nFlags,
79cdf0e10cSrcweir                                        sal_uInt32 * pInfo,
80cdf0e10cSrcweir                                        sal_Size * pSrcCvtBytes)
81cdf0e10cSrcweir {
82cdf0e10cSrcweir     ImplDBCSToUniLeadTab const * pJisX0208Data
83cdf0e10cSrcweir         = ((ImplIso2022JpConverterData const *) pData)->
84cdf0e10cSrcweir               m_pJisX0208ToUnicodeData;
85cdf0e10cSrcweir     ImplIso2022JpToUnicodeState eState
86cdf0e10cSrcweir         = IMPL_ISO_2022_JP_TO_UNICODE_STATE_ASCII;
87cdf0e10cSrcweir     sal_uInt32 nRow = 0;
88cdf0e10cSrcweir     sal_uInt32 nInfo = 0;
89cdf0e10cSrcweir     sal_Size nConverted = 0;
90cdf0e10cSrcweir     sal_Unicode * pDestBufPtr = pDestBuf;
91cdf0e10cSrcweir     sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
92cdf0e10cSrcweir 
93cdf0e10cSrcweir     if (pContext)
94cdf0e10cSrcweir     {
95cdf0e10cSrcweir         eState = ((ImplIso2022JpToUnicodeContext *) pContext)->m_eState;
96cdf0e10cSrcweir         nRow = ((ImplIso2022JpToUnicodeContext *) pContext)->m_nRow;
97cdf0e10cSrcweir     }
98cdf0e10cSrcweir 
99cdf0e10cSrcweir     for (; nConverted < nSrcBytes; ++nConverted)
100cdf0e10cSrcweir     {
101cdf0e10cSrcweir         sal_Bool bUndefined = sal_True;
102cdf0e10cSrcweir         sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++;
103cdf0e10cSrcweir         switch (eState)
104cdf0e10cSrcweir         {
105cdf0e10cSrcweir         case IMPL_ISO_2022_JP_TO_UNICODE_STATE_ASCII:
106cdf0e10cSrcweir             if (nChar == 0x1B) /* ESC */
107cdf0e10cSrcweir                 eState = IMPL_ISO_2022_JP_TO_UNICODE_STATE_ESC;
108cdf0e10cSrcweir             else if (nChar < 0x80)
109cdf0e10cSrcweir                 if (pDestBufPtr != pDestBufEnd)
110cdf0e10cSrcweir                     *pDestBufPtr++ = (sal_Unicode) nChar;
111cdf0e10cSrcweir                 else
112cdf0e10cSrcweir                     goto no_output;
113cdf0e10cSrcweir             else
114cdf0e10cSrcweir             {
115cdf0e10cSrcweir                 bUndefined = sal_False;
116cdf0e10cSrcweir                 goto bad_input;
117cdf0e10cSrcweir             }
118cdf0e10cSrcweir             break;
119cdf0e10cSrcweir 
120cdf0e10cSrcweir         case IMPL_ISO_2022_JP_TO_UNICODE_STATE_JIS_ROMAN:
121cdf0e10cSrcweir             if (nChar == 0x1B) /* ESC */
122cdf0e10cSrcweir                 eState = IMPL_ISO_2022_JP_TO_UNICODE_STATE_ESC;
123cdf0e10cSrcweir             else if (nChar < 0x80)
124cdf0e10cSrcweir                 if (pDestBufPtr != pDestBufEnd)
125cdf0e10cSrcweir                 {
126cdf0e10cSrcweir                     switch (nChar)
127cdf0e10cSrcweir                     {
128cdf0e10cSrcweir                     case 0x5C: /* \ */
129cdf0e10cSrcweir                         nChar = 0xA5; /* YEN SIGN */
130cdf0e10cSrcweir                         break;
131cdf0e10cSrcweir 
132cdf0e10cSrcweir                     case 0x7E: /* ~ */
133cdf0e10cSrcweir                         nChar = 0xAF; /* MACRON */
134cdf0e10cSrcweir                         break;
135cdf0e10cSrcweir                     }
136cdf0e10cSrcweir                     *pDestBufPtr++ = (sal_Unicode) nChar;
137cdf0e10cSrcweir                 }
138cdf0e10cSrcweir                 else
139cdf0e10cSrcweir                     goto no_output;
140cdf0e10cSrcweir             else
141cdf0e10cSrcweir             {
142cdf0e10cSrcweir                 bUndefined = sal_False;
143cdf0e10cSrcweir                 goto bad_input;
144cdf0e10cSrcweir             }
145cdf0e10cSrcweir             break;
146cdf0e10cSrcweir 
147cdf0e10cSrcweir         case IMPL_ISO_2022_JP_TO_UNICODE_STATE_0208:
148cdf0e10cSrcweir             if (nChar == 0x1B) /* ESC */
149cdf0e10cSrcweir                 eState = IMPL_ISO_2022_JP_TO_UNICODE_STATE_ESC;
150cdf0e10cSrcweir             else if (nChar >= 0x21 && nChar <= 0x7E)
151cdf0e10cSrcweir             {
152cdf0e10cSrcweir                 nRow = nChar;
153cdf0e10cSrcweir                 eState = IMPL_ISO_2022_JP_TO_UNICODE_STATE_0208_2;
154cdf0e10cSrcweir             }
155cdf0e10cSrcweir             else
156cdf0e10cSrcweir             {
157cdf0e10cSrcweir                 bUndefined = sal_False;
158cdf0e10cSrcweir                 goto bad_input;
159cdf0e10cSrcweir             }
160cdf0e10cSrcweir             break;
161cdf0e10cSrcweir 
162cdf0e10cSrcweir         case IMPL_ISO_2022_JP_TO_UNICODE_STATE_0208_2:
163cdf0e10cSrcweir             if (nChar >= 0x21 && nChar <= 0x7E)
164cdf0e10cSrcweir             {
165cdf0e10cSrcweir                 sal_uInt16 nUnicode = 0;
166cdf0e10cSrcweir                 sal_uInt32 nFirst = pJisX0208Data[nRow].mnTrailStart;
167cdf0e10cSrcweir                 if (nChar >= nFirst
168cdf0e10cSrcweir                     && nChar <= pJisX0208Data[nRow].mnTrailEnd)
169cdf0e10cSrcweir                     nUnicode = pJisX0208Data[nRow].
170cdf0e10cSrcweir                                    mpToUniTrailTab[nChar - nFirst];
171cdf0e10cSrcweir                 if (nUnicode != 0)
172cdf0e10cSrcweir                     if (pDestBufPtr != pDestBufEnd)
173cdf0e10cSrcweir                     {
174cdf0e10cSrcweir                         *pDestBufPtr++ = (sal_Unicode) nUnicode;
175cdf0e10cSrcweir                         eState = IMPL_ISO_2022_JP_TO_UNICODE_STATE_0208;
176cdf0e10cSrcweir                     }
177cdf0e10cSrcweir                     else
178cdf0e10cSrcweir                         goto no_output;
179cdf0e10cSrcweir                 else
180cdf0e10cSrcweir                     goto bad_input;
181cdf0e10cSrcweir             }
182cdf0e10cSrcweir             else
183cdf0e10cSrcweir             {
184cdf0e10cSrcweir                 bUndefined = sal_False;
185cdf0e10cSrcweir                 goto bad_input;
186cdf0e10cSrcweir             }
187cdf0e10cSrcweir             break;
188cdf0e10cSrcweir 
189cdf0e10cSrcweir         case IMPL_ISO_2022_JP_TO_UNICODE_STATE_ESC:
190cdf0e10cSrcweir             switch (nChar)
191cdf0e10cSrcweir             {
192cdf0e10cSrcweir             case 0x24: /* $ */
193cdf0e10cSrcweir                 eState = IMPL_ISO_2022_JP_TO_UNICODE_STATE_ESC_DOLLAR;
194cdf0e10cSrcweir                 break;
195cdf0e10cSrcweir 
196cdf0e10cSrcweir             case 0x28: /* ( */
197cdf0e10cSrcweir                 eState = IMPL_ISO_2022_JP_TO_UNICODE_STATE_ESC_LPAREN;
198cdf0e10cSrcweir                 break;
199cdf0e10cSrcweir 
200cdf0e10cSrcweir             default:
201cdf0e10cSrcweir                 bUndefined = sal_False;
202cdf0e10cSrcweir                 goto bad_input;
203cdf0e10cSrcweir             }
204cdf0e10cSrcweir             break;
205cdf0e10cSrcweir 
206cdf0e10cSrcweir         case IMPL_ISO_2022_JP_TO_UNICODE_STATE_ESC_LPAREN:
207cdf0e10cSrcweir             switch (nChar)
208cdf0e10cSrcweir             {
209cdf0e10cSrcweir             case 0x42: /* A */
210cdf0e10cSrcweir                 eState = IMPL_ISO_2022_JP_TO_UNICODE_STATE_ASCII;
211cdf0e10cSrcweir                 break;
212cdf0e10cSrcweir 
213cdf0e10cSrcweir             case 0x4A: /* J */
214cdf0e10cSrcweir                 eState = IMPL_ISO_2022_JP_TO_UNICODE_STATE_JIS_ROMAN;
215cdf0e10cSrcweir                 break;
216cdf0e10cSrcweir 
217cdf0e10cSrcweir             default:
218cdf0e10cSrcweir                 bUndefined = sal_False;
219cdf0e10cSrcweir                 goto bad_input;
220cdf0e10cSrcweir             }
221cdf0e10cSrcweir             break;
222cdf0e10cSrcweir 
223cdf0e10cSrcweir         case IMPL_ISO_2022_JP_TO_UNICODE_STATE_ESC_DOLLAR:
224cdf0e10cSrcweir             switch (nChar)
225cdf0e10cSrcweir             {
226cdf0e10cSrcweir             case 0x40: /* @ */
227cdf0e10cSrcweir             case 0x42: /* B */
228cdf0e10cSrcweir                 eState = IMPL_ISO_2022_JP_TO_UNICODE_STATE_0208;
229cdf0e10cSrcweir                 break;
230cdf0e10cSrcweir 
231cdf0e10cSrcweir             default:
232cdf0e10cSrcweir                 bUndefined = sal_False;
233cdf0e10cSrcweir                 goto bad_input;
234cdf0e10cSrcweir             }
235cdf0e10cSrcweir             break;
236cdf0e10cSrcweir         }
237cdf0e10cSrcweir         continue;
238cdf0e10cSrcweir 
239cdf0e10cSrcweir     bad_input:
240cdf0e10cSrcweir         switch (ImplHandleBadInputTextToUnicodeConversion(
241cdf0e10cSrcweir                     bUndefined, sal_True, 0, nFlags, &pDestBufPtr, pDestBufEnd,
242cdf0e10cSrcweir                     &nInfo))
243cdf0e10cSrcweir         {
244cdf0e10cSrcweir         case IMPL_BAD_INPUT_STOP:
245cdf0e10cSrcweir             eState = IMPL_ISO_2022_JP_TO_UNICODE_STATE_ASCII;
246cdf0e10cSrcweir             break;
247cdf0e10cSrcweir 
248cdf0e10cSrcweir         case IMPL_BAD_INPUT_CONTINUE:
249cdf0e10cSrcweir             eState = IMPL_ISO_2022_JP_TO_UNICODE_STATE_ASCII;
250cdf0e10cSrcweir             continue;
251cdf0e10cSrcweir 
252cdf0e10cSrcweir         case IMPL_BAD_INPUT_NO_OUTPUT:
253cdf0e10cSrcweir             goto no_output;
254cdf0e10cSrcweir         }
255cdf0e10cSrcweir         break;
256cdf0e10cSrcweir 
257cdf0e10cSrcweir     no_output:
258cdf0e10cSrcweir         --pSrcBuf;
259cdf0e10cSrcweir         nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
260cdf0e10cSrcweir         break;
261cdf0e10cSrcweir     }
262cdf0e10cSrcweir 
263cdf0e10cSrcweir     if (eState > IMPL_ISO_2022_JP_TO_UNICODE_STATE_0208
264cdf0e10cSrcweir         && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
265cdf0e10cSrcweir                          | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
266cdf0e10cSrcweir                == 0)
267cdf0e10cSrcweir     {
268cdf0e10cSrcweir         if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
269cdf0e10cSrcweir             nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
270cdf0e10cSrcweir         else
271cdf0e10cSrcweir             switch (ImplHandleBadInputTextToUnicodeConversion(
272cdf0e10cSrcweir                         sal_False, sal_True, 0, nFlags, &pDestBufPtr, pDestBufEnd,
273cdf0e10cSrcweir                         &nInfo))
274cdf0e10cSrcweir             {
275cdf0e10cSrcweir             case IMPL_BAD_INPUT_STOP:
276cdf0e10cSrcweir             case IMPL_BAD_INPUT_CONTINUE:
277cdf0e10cSrcweir                 eState = IMPL_ISO_2022_JP_TO_UNICODE_STATE_ASCII;
278cdf0e10cSrcweir                 break;
279cdf0e10cSrcweir 
280cdf0e10cSrcweir             case IMPL_BAD_INPUT_NO_OUTPUT:
281cdf0e10cSrcweir                 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
282cdf0e10cSrcweir                 break;
283cdf0e10cSrcweir             }
284cdf0e10cSrcweir     }
285cdf0e10cSrcweir 
286cdf0e10cSrcweir     if (pContext)
287cdf0e10cSrcweir     {
288cdf0e10cSrcweir         ((ImplIso2022JpToUnicodeContext *) pContext)->m_eState = eState;
289cdf0e10cSrcweir         ((ImplIso2022JpToUnicodeContext *) pContext)->m_nRow = nRow;
290cdf0e10cSrcweir     }
291cdf0e10cSrcweir     if (pInfo)
292cdf0e10cSrcweir         *pInfo = nInfo;
293cdf0e10cSrcweir     if (pSrcCvtBytes)
294cdf0e10cSrcweir         *pSrcCvtBytes = nConverted;
295cdf0e10cSrcweir 
296cdf0e10cSrcweir     return pDestBufPtr - pDestBuf;
297cdf0e10cSrcweir }
298cdf0e10cSrcweir 
ImplCreateUnicodeToIso2022JpContext(void)299cdf0e10cSrcweir void * ImplCreateUnicodeToIso2022JpContext(void)
300cdf0e10cSrcweir {
301cdf0e10cSrcweir     void * pContext
302cdf0e10cSrcweir         = rtl_allocateMemory(sizeof (ImplUnicodeToIso2022JpContext));
303cdf0e10cSrcweir     ((ImplUnicodeToIso2022JpContext *) pContext)->m_nHighSurrogate = 0;
304cdf0e10cSrcweir     ((ImplUnicodeToIso2022JpContext *) pContext)->m_b0208 = sal_False;
305cdf0e10cSrcweir     return pContext;
306cdf0e10cSrcweir }
307cdf0e10cSrcweir 
ImplResetUnicodeToIso2022JpContext(void * pContext)308cdf0e10cSrcweir void ImplResetUnicodeToIso2022JpContext(void * pContext)
309cdf0e10cSrcweir {
310cdf0e10cSrcweir     if (pContext)
311cdf0e10cSrcweir     {
312cdf0e10cSrcweir         ((ImplUnicodeToIso2022JpContext *) pContext)->m_nHighSurrogate = 0;
313cdf0e10cSrcweir         ((ImplUnicodeToIso2022JpContext *) pContext)->m_b0208 = sal_False;
314cdf0e10cSrcweir     }
315cdf0e10cSrcweir }
316cdf0e10cSrcweir 
ImplConvertUnicodeToIso2022Jp(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)317cdf0e10cSrcweir sal_Size ImplConvertUnicodeToIso2022Jp(ImplTextConverterData const * pData,
318cdf0e10cSrcweir                                        void * pContext,
319cdf0e10cSrcweir                                        sal_Unicode const * pSrcBuf,
320cdf0e10cSrcweir                                        sal_Size nSrcChars,
321cdf0e10cSrcweir                                        sal_Char * pDestBuf,
322cdf0e10cSrcweir                                        sal_Size nDestBytes,
323cdf0e10cSrcweir                                        sal_uInt32 nFlags,
324cdf0e10cSrcweir                                        sal_uInt32 * pInfo,
325cdf0e10cSrcweir                                        sal_Size * pSrcCvtChars)
326cdf0e10cSrcweir {
327cdf0e10cSrcweir     ImplUniToDBCSHighTab const * pJisX0208Data
328cdf0e10cSrcweir         = ((ImplIso2022JpConverterData const *) pData)->
329cdf0e10cSrcweir               m_pUnicodeToJisX0208Data;
330cdf0e10cSrcweir     sal_Unicode nHighSurrogate = 0;
331cdf0e10cSrcweir     sal_Bool b0208 = sal_False;
332cdf0e10cSrcweir     sal_uInt32 nInfo = 0;
333cdf0e10cSrcweir     sal_Size nConverted = 0;
334cdf0e10cSrcweir     sal_Char * pDestBufPtr = pDestBuf;
335cdf0e10cSrcweir     sal_Char * pDestBufEnd = pDestBuf + nDestBytes;
336cdf0e10cSrcweir     sal_Bool bWritten;
337cdf0e10cSrcweir 
338cdf0e10cSrcweir     if (pContext)
339cdf0e10cSrcweir     {
340cdf0e10cSrcweir         nHighSurrogate
341cdf0e10cSrcweir             = ((ImplUnicodeToIso2022JpContext *) pContext)->m_nHighSurrogate;
342cdf0e10cSrcweir         b0208 = ((ImplUnicodeToIso2022JpContext *) pContext)->m_b0208;
343cdf0e10cSrcweir     }
344cdf0e10cSrcweir 
345cdf0e10cSrcweir     for (; nConverted < nSrcChars; ++nConverted)
346cdf0e10cSrcweir     {
347cdf0e10cSrcweir         sal_Bool bUndefined = sal_True;
348cdf0e10cSrcweir         sal_uInt32 nChar = *pSrcBuf++;
349cdf0e10cSrcweir         if (nHighSurrogate == 0)
350cdf0e10cSrcweir         {
351cdf0e10cSrcweir             if (ImplIsHighSurrogate(nChar))
352cdf0e10cSrcweir             {
353cdf0e10cSrcweir                 nHighSurrogate = (sal_Unicode) nChar;
354cdf0e10cSrcweir                 continue;
355cdf0e10cSrcweir             }
356cdf0e10cSrcweir         }
357cdf0e10cSrcweir         else if (ImplIsLowSurrogate(nChar))
358cdf0e10cSrcweir             nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
359cdf0e10cSrcweir         else
360cdf0e10cSrcweir         {
361cdf0e10cSrcweir             bUndefined = sal_False;
362cdf0e10cSrcweir             goto bad_input;
363cdf0e10cSrcweir         }
364cdf0e10cSrcweir 
365cdf0e10cSrcweir         if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
366cdf0e10cSrcweir         {
367cdf0e10cSrcweir             bUndefined = sal_False;
368cdf0e10cSrcweir             goto bad_input;
369cdf0e10cSrcweir         }
370cdf0e10cSrcweir 
371cdf0e10cSrcweir         if (nChar == 0x0A || nChar == 0x0D) /* LF, CR */
372cdf0e10cSrcweir         {
373cdf0e10cSrcweir             if (b0208)
374cdf0e10cSrcweir             {
375cdf0e10cSrcweir                 if (pDestBufEnd - pDestBufPtr >= 3)
376cdf0e10cSrcweir                 {
377cdf0e10cSrcweir                     *pDestBufPtr++ = 0x1B; /* ESC */
378cdf0e10cSrcweir                     *pDestBufPtr++ = 0x28; /* ( */
379cdf0e10cSrcweir                     *pDestBufPtr++ = 0x42; /* B */
380cdf0e10cSrcweir                     b0208 = sal_False;
381cdf0e10cSrcweir                 }
382cdf0e10cSrcweir                 else
383cdf0e10cSrcweir                     goto no_output;
384cdf0e10cSrcweir             }
385cdf0e10cSrcweir             if (pDestBufPtr != pDestBufEnd)
386cdf0e10cSrcweir                 *pDestBufPtr++ = (sal_Char) nChar;
387cdf0e10cSrcweir             else
388cdf0e10cSrcweir                 goto no_output;
389cdf0e10cSrcweir         }
390cdf0e10cSrcweir         else if (nChar == 0x1B)
391cdf0e10cSrcweir             goto bad_input;
392cdf0e10cSrcweir         else if (nChar < 0x80)
393cdf0e10cSrcweir         {
394cdf0e10cSrcweir             if (b0208)
395cdf0e10cSrcweir             {
396cdf0e10cSrcweir                 if (pDestBufEnd - pDestBufPtr >= 3)
397cdf0e10cSrcweir                 {
398cdf0e10cSrcweir                     *pDestBufPtr++ = 0x1B; /* ESC */
399cdf0e10cSrcweir                     *pDestBufPtr++ = 0x28; /* ( */
400cdf0e10cSrcweir                     *pDestBufPtr++ = 0x42; /* B */
401cdf0e10cSrcweir                     b0208 = sal_False;
402cdf0e10cSrcweir                 }
403cdf0e10cSrcweir                 else
404cdf0e10cSrcweir                     goto no_output;
405cdf0e10cSrcweir             }
406cdf0e10cSrcweir             if (pDestBufPtr != pDestBufEnd)
407cdf0e10cSrcweir                 *pDestBufPtr++ = (sal_Char) nChar;
408cdf0e10cSrcweir             else
409cdf0e10cSrcweir                 goto no_output;
410cdf0e10cSrcweir         }
411cdf0e10cSrcweir         else
412cdf0e10cSrcweir         {
413cdf0e10cSrcweir             sal_uInt16 nBytes = 0;
414cdf0e10cSrcweir             sal_uInt32 nIndex1 = nChar >> 8;
415cdf0e10cSrcweir             if (nIndex1 < 0x100)
416cdf0e10cSrcweir             {
417cdf0e10cSrcweir                 sal_uInt32 nIndex2 = nChar & 0xFF;
418cdf0e10cSrcweir                 sal_uInt32 nFirst = pJisX0208Data[nIndex1].mnLowStart;
419cdf0e10cSrcweir                 if (nIndex2 >= nFirst
420cdf0e10cSrcweir                     && nIndex2 <= pJisX0208Data[nIndex1].mnLowEnd)
421cdf0e10cSrcweir                 {
422cdf0e10cSrcweir                     nBytes = pJisX0208Data[nIndex1].
423cdf0e10cSrcweir                                  mpToUniTrailTab[nIndex2 - nFirst];
424cdf0e10cSrcweir                     if (nBytes == 0)
425cdf0e10cSrcweir                         /* For some reason, the tables in tcvtjp4.tab do not
426cdf0e10cSrcweir                            include these two conversions: */
427cdf0e10cSrcweir                         switch (nChar)
428cdf0e10cSrcweir                         {
429cdf0e10cSrcweir                         case 0xA5: /* YEN SIGN */
430cdf0e10cSrcweir                             nBytes = 0x216F;
431cdf0e10cSrcweir                             break;
432cdf0e10cSrcweir 
433cdf0e10cSrcweir                         case 0xAF: /* MACRON */
434cdf0e10cSrcweir                             nBytes = 0x2131;
435cdf0e10cSrcweir                             break;
436cdf0e10cSrcweir                         }
437cdf0e10cSrcweir                 }
438cdf0e10cSrcweir             }
439cdf0e10cSrcweir             if (nBytes != 0)
440cdf0e10cSrcweir             {
441cdf0e10cSrcweir                 if (!b0208)
442cdf0e10cSrcweir                 {
443cdf0e10cSrcweir                     if (pDestBufEnd - pDestBufPtr >= 3)
444cdf0e10cSrcweir                     {
445cdf0e10cSrcweir                         *pDestBufPtr++ = 0x1B; /* ESC */
446cdf0e10cSrcweir                         *pDestBufPtr++ = 0x24; /* $ */
447cdf0e10cSrcweir                         *pDestBufPtr++ = 0x42; /* B */
448cdf0e10cSrcweir                         b0208 = sal_True;
449cdf0e10cSrcweir                     }
450cdf0e10cSrcweir                     else
451cdf0e10cSrcweir                         goto no_output;
452cdf0e10cSrcweir                 }
453cdf0e10cSrcweir                 if (pDestBufEnd - pDestBufPtr >= 2)
454cdf0e10cSrcweir                 {
455cdf0e10cSrcweir                     *pDestBufPtr++ = (sal_Char) (nBytes >> 8);
456cdf0e10cSrcweir                     *pDestBufPtr++ = (sal_Char) (nBytes & 0xFF);
457cdf0e10cSrcweir                 }
458cdf0e10cSrcweir                 else
459cdf0e10cSrcweir                     goto no_output;
460cdf0e10cSrcweir             }
461cdf0e10cSrcweir             else
462cdf0e10cSrcweir                 goto bad_input;
463cdf0e10cSrcweir         }
464cdf0e10cSrcweir         nHighSurrogate = 0;
465cdf0e10cSrcweir         continue;
466cdf0e10cSrcweir 
467cdf0e10cSrcweir     bad_input:
468cdf0e10cSrcweir         switch (ImplHandleBadInputUnicodeToTextConversion(
469cdf0e10cSrcweir                     bUndefined,
470cdf0e10cSrcweir                     nChar,
471cdf0e10cSrcweir                     nFlags,
472cdf0e10cSrcweir                     &pDestBufPtr,
473cdf0e10cSrcweir                     pDestBufEnd,
474cdf0e10cSrcweir                     &nInfo,
475cdf0e10cSrcweir                     "\x1B(B",
476cdf0e10cSrcweir                     b0208 ? 3 : 0,
477cdf0e10cSrcweir                     &bWritten))
478cdf0e10cSrcweir         {
479cdf0e10cSrcweir         case IMPL_BAD_INPUT_STOP:
480cdf0e10cSrcweir             nHighSurrogate = 0;
481cdf0e10cSrcweir             break;
482cdf0e10cSrcweir 
483cdf0e10cSrcweir         case IMPL_BAD_INPUT_CONTINUE:
484cdf0e10cSrcweir             if (bWritten)
485cdf0e10cSrcweir                 b0208 = sal_False;
486cdf0e10cSrcweir             nHighSurrogate = 0;
487cdf0e10cSrcweir             continue;
488cdf0e10cSrcweir 
489cdf0e10cSrcweir         case IMPL_BAD_INPUT_NO_OUTPUT:
490cdf0e10cSrcweir             goto no_output;
491cdf0e10cSrcweir         }
492cdf0e10cSrcweir         break;
493cdf0e10cSrcweir 
494cdf0e10cSrcweir     no_output:
495cdf0e10cSrcweir         --pSrcBuf;
496cdf0e10cSrcweir         nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
497cdf0e10cSrcweir         break;
498cdf0e10cSrcweir     }
499cdf0e10cSrcweir 
500cdf0e10cSrcweir     if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
501cdf0e10cSrcweir                       | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
502cdf0e10cSrcweir             == 0)
503cdf0e10cSrcweir     {
504cdf0e10cSrcweir         sal_Bool bFlush = sal_True;
505cdf0e10cSrcweir         if (nHighSurrogate != 0)
506cdf0e10cSrcweir         {
507cdf0e10cSrcweir             if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
508cdf0e10cSrcweir                 nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
509cdf0e10cSrcweir             else
510cdf0e10cSrcweir                 switch (ImplHandleBadInputUnicodeToTextConversion(
511cdf0e10cSrcweir                             sal_False,
512cdf0e10cSrcweir                             0,
513cdf0e10cSrcweir                             nFlags,
514cdf0e10cSrcweir                             &pDestBufPtr,
515cdf0e10cSrcweir                             pDestBufEnd,
516cdf0e10cSrcweir                             &nInfo,
517cdf0e10cSrcweir                             "\x1B(B",
518cdf0e10cSrcweir                             b0208 ? 3 : 0,
519cdf0e10cSrcweir                             &bWritten))
520cdf0e10cSrcweir                 {
521cdf0e10cSrcweir                 case IMPL_BAD_INPUT_STOP:
522cdf0e10cSrcweir                     nHighSurrogate = 0;
523cdf0e10cSrcweir                     bFlush = sal_False;
524cdf0e10cSrcweir                     break;
525cdf0e10cSrcweir 
526cdf0e10cSrcweir                 case IMPL_BAD_INPUT_CONTINUE:
527cdf0e10cSrcweir                     if (bWritten)
528cdf0e10cSrcweir                         b0208 = sal_False;
529cdf0e10cSrcweir                     nHighSurrogate = 0;
530cdf0e10cSrcweir                     break;
531cdf0e10cSrcweir 
532cdf0e10cSrcweir                 case IMPL_BAD_INPUT_NO_OUTPUT:
533cdf0e10cSrcweir                     nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
534cdf0e10cSrcweir                     break;
535cdf0e10cSrcweir                 }
536cdf0e10cSrcweir         }
537cdf0e10cSrcweir         if (bFlush
538cdf0e10cSrcweir             && b0208
539cdf0e10cSrcweir             && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
540cdf0e10cSrcweir         {
541cdf0e10cSrcweir             if (pDestBufEnd - pDestBufPtr >= 3)
542cdf0e10cSrcweir             {
543cdf0e10cSrcweir                 *pDestBufPtr++ = 0x1B; /* ESC */
544cdf0e10cSrcweir                 *pDestBufPtr++ = 0x28; /* ( */
545cdf0e10cSrcweir                 *pDestBufPtr++ = 0x42; /* B */
546cdf0e10cSrcweir                 b0208 = sal_False;
547cdf0e10cSrcweir             }
548cdf0e10cSrcweir             else
549cdf0e10cSrcweir                 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
550cdf0e10cSrcweir         }
551cdf0e10cSrcweir     }
552cdf0e10cSrcweir 
553cdf0e10cSrcweir     if (pContext)
554cdf0e10cSrcweir     {
555cdf0e10cSrcweir         ((ImplUnicodeToIso2022JpContext *) pContext)->m_nHighSurrogate
556cdf0e10cSrcweir             = nHighSurrogate;
557cdf0e10cSrcweir         ((ImplUnicodeToIso2022JpContext *) pContext)->m_b0208 = b0208;
558cdf0e10cSrcweir     }
559cdf0e10cSrcweir     if (pInfo)
560cdf0e10cSrcweir         *pInfo = nInfo;
561cdf0e10cSrcweir     if (pSrcCvtChars)
562cdf0e10cSrcweir         *pSrcCvtChars = nConverted;
563cdf0e10cSrcweir 
564cdf0e10cSrcweir     return pDestBufPtr - pDestBuf;
565cdf0e10cSrcweir }
566