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