1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "convertiso2022cn.h"
25 #include "context.h"
26 #include "converter.h"
27 #include "tenchelp.h"
28 #include "unichars.h"
29 #include "rtl/alloc.h"
30 #include "rtl/textcvt.h"
31 #include "sal/types.h"
32
33 typedef enum /* order is important: */
34 {
35 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII,
36 IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO,
37 IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2,
38 IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432,
39 IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2,
40 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC,
41 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR,
42 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN,
43 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK
44 } ImplIso2022CnToUnicodeState;
45
46 typedef struct
47 {
48 ImplIso2022CnToUnicodeState m_eState;
49 sal_uInt32 m_nRow;
50 sal_Bool m_bSo;
51 sal_Bool m_b116431;
52 } ImplIso2022CnToUnicodeContext;
53
54 typedef enum
55 {
56 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE,
57 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312,
58 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431
59 } ImplUnicodeToIso2022CnDesignator;
60
61 typedef struct
62 {
63 sal_Unicode m_nHighSurrogate;
64 ImplUnicodeToIso2022CnDesignator m_eSoDesignator;
65 sal_Bool m_b116432Designator;
66 sal_Bool m_bSo;
67 } ImplUnicodeToIso2022CnContext;
68
ImplCreateIso2022CnToUnicodeContext(void)69 void * ImplCreateIso2022CnToUnicodeContext(void)
70 {
71 void * pContext
72 = rtl_allocateMemory(sizeof (ImplIso2022CnToUnicodeContext));
73 ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState
74 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
75 ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo = sal_False;
76 ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431 = sal_False;
77 return pContext;
78 }
79
ImplResetIso2022CnToUnicodeContext(void * pContext)80 void ImplResetIso2022CnToUnicodeContext(void * pContext)
81 {
82 if (pContext)
83 {
84 ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState
85 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
86 ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo = sal_False;
87 ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431 = sal_False;
88 }
89 }
90
ImplConvertIso2022CnToUnicode(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)91 sal_Size ImplConvertIso2022CnToUnicode(ImplTextConverterData const * pData,
92 void * pContext,
93 sal_Char const * pSrcBuf,
94 sal_Size nSrcBytes,
95 sal_Unicode * pDestBuf,
96 sal_Size nDestChars,
97 sal_uInt32 nFlags,
98 sal_uInt32 * pInfo,
99 sal_Size * pSrcCvtBytes)
100 {
101 ImplDBCSToUniLeadTab const * pGb2312Data
102 = ((ImplIso2022CnConverterData const *) pData)->
103 m_pGb2312ToUnicodeData;
104 sal_uInt16 const * pCns116431992Data
105 = ((ImplIso2022CnConverterData const *) pData)->
106 m_pCns116431992ToUnicodeData;
107 sal_Int32 const * pCns116431992RowOffsets
108 = ((ImplIso2022CnConverterData const *) pData)->
109 m_pCns116431992ToUnicodeRowOffsets;
110 sal_Int32 const * pCns116431992PlaneOffsets
111 = ((ImplIso2022CnConverterData const *) pData)->
112 m_pCns116431992ToUnicodePlaneOffsets;
113 ImplIso2022CnToUnicodeState eState
114 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
115 sal_uInt32 nRow = 0;
116 sal_Bool bSo = sal_False;
117 sal_Bool b116431 = sal_False;
118 sal_uInt32 nInfo = 0;
119 sal_Size nConverted = 0;
120 sal_Unicode * pDestBufPtr = pDestBuf;
121 sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
122
123 if (pContext)
124 {
125 eState = ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState;
126 nRow = ((ImplIso2022CnToUnicodeContext *) pContext)->m_nRow;
127 bSo = ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo;
128 b116431 = ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431;
129 }
130
131 for (; nConverted < nSrcBytes; ++nConverted)
132 {
133 sal_Bool bUndefined = sal_True;
134 sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++;
135 sal_uInt32 nPlane;
136 switch (eState)
137 {
138 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII:
139 if (nChar == 0x0E) /* SO */
140 {
141 bSo = sal_True;
142 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
143 }
144 else if (nChar == 0x1B) /* ESC */
145 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
146 else if (nChar < 0x80)
147 if (pDestBufPtr != pDestBufEnd)
148 *pDestBufPtr++ = (sal_Unicode) nChar;
149 else
150 goto no_output;
151 else
152 {
153 bUndefined = sal_False;
154 goto bad_input;
155 }
156 break;
157
158 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO:
159 if (nChar == 0x0F) /* SI */
160 {
161 bSo = sal_False;
162 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
163 }
164 else if (nChar == 0x1B) /* ESC */
165 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC;
166 else if (nChar >= 0x21 && nChar <= 0x7E)
167 {
168 nRow = nChar;
169 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2;
170 }
171 else
172 {
173 bUndefined = sal_False;
174 goto bad_input;
175 }
176 break;
177
178 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO_2:
179 if (nChar >= 0x21 && nChar <= 0x7E)
180 if (b116431)
181 {
182 nPlane = 0;
183 goto transform;
184 }
185 else
186 {
187 sal_uInt16 nUnicode = 0;
188 sal_uInt32 nFirst;
189 nRow += 0x80;
190 nChar += 0x80;
191 nFirst = pGb2312Data[nRow].mnTrailStart;
192 if (nChar >= nFirst
193 && nChar <= pGb2312Data[nRow].mnTrailEnd)
194 nUnicode = pGb2312Data[nRow].
195 mpToUniTrailTab[nChar - nFirst];
196 if (nUnicode != 0)
197 if (pDestBufPtr != pDestBufEnd)
198 {
199 *pDestBufPtr++ = (sal_Unicode) nUnicode;
200 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO;
201 }
202 else
203 goto no_output;
204 else
205 goto bad_input;
206 }
207 else
208 {
209 bUndefined = sal_False;
210 goto bad_input;
211 }
212 break;
213
214 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432:
215 if (nChar >= 0x21 && nChar <= 0x7E)
216 {
217 nRow = nChar;
218 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2;
219 }
220 else
221 {
222 bUndefined = sal_False;
223 goto bad_input;
224 }
225 break;
226
227 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432_2:
228 if (nChar >= 0x21 && nChar <= 0x7E)
229 {
230 nPlane = 1;
231 goto transform;
232 }
233 else
234 {
235 bUndefined = sal_False;
236 goto bad_input;
237 }
238 break;
239
240 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC:
241 if (nChar == 0x24) /* $ */
242 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR;
243 else if (nChar == 0x4E) /* N */
244 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_116432;
245 else
246 {
247 bUndefined = sal_False;
248 goto bad_input;
249 }
250 break;
251
252 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR:
253 if (nChar == 0x29) /* ) */
254 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN;
255 else if (nChar == 0x2A) /* * */
256 eState
257 = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK;
258 else
259 {
260 bUndefined = sal_False;
261 goto bad_input;
262 }
263 break;
264
265 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_RPAREN:
266 if (nChar == 0x41) /* A */
267 {
268 b116431 = sal_False;
269 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
270 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
271 }
272 else if (nChar == 0x47) /* G */
273 {
274 b116431 = sal_True;
275 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
276 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
277 }
278 else
279 {
280 bUndefined = sal_False;
281 goto bad_input;
282 }
283 break;
284
285 case IMPL_ISO_2022_CN_TO_UNICODE_STATE_ESC_DOLLAR_ASTERISK:
286 if (nChar == 0x48) /* H */
287 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
288 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
289 else
290 {
291 bUndefined = sal_False;
292 goto bad_input;
293 }
294 break;
295 }
296 continue;
297
298 transform:
299 {
300 sal_Int32 nPlaneOffset = pCns116431992PlaneOffsets[nPlane];
301 if (nPlaneOffset == -1)
302 goto bad_input;
303 else
304 {
305 sal_Int32 nOffset
306 = pCns116431992RowOffsets[nPlaneOffset + (nRow - 0x21)];
307 if (nOffset == -1)
308 goto bad_input;
309 else
310 {
311 sal_uInt32 nFirstLast = pCns116431992Data[nOffset++];
312 sal_uInt32 nFirst = nFirstLast & 0xFF;
313 sal_uInt32 nLast = nFirstLast >> 8;
314 nChar -= 0x20;
315 if (nChar >= nFirst && nChar <= nLast)
316 {
317 sal_uInt32 nUnicode
318 = pCns116431992Data[nOffset + (nChar - nFirst)];
319 if (nUnicode == 0xFFFF)
320 goto bad_input;
321 else if (ImplIsHighSurrogate(nUnicode))
322 if (pDestBufEnd - pDestBufPtr >= 2)
323 {
324 nOffset += nLast - nFirst + 1;
325 nFirst = pCns116431992Data[nOffset++];
326 *pDestBufPtr++ = (sal_Unicode) nUnicode;
327 *pDestBufPtr++
328 = (sal_Unicode)
329 pCns116431992Data[
330 nOffset + (nChar - nFirst)];
331 }
332 else
333 goto no_output;
334 else
335 if (pDestBufPtr != pDestBufEnd)
336 *pDestBufPtr++ = (sal_Unicode) nUnicode;
337 else
338 goto no_output;
339 }
340 else
341 goto bad_input;
342 eState = bSo ? IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO :
343 IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
344 }
345 }
346 continue;
347 }
348
349 bad_input:
350 switch (ImplHandleBadInputTextToUnicodeConversion(
351 bUndefined, sal_True, 0, nFlags, &pDestBufPtr, pDestBufEnd,
352 &nInfo))
353 {
354 case IMPL_BAD_INPUT_STOP:
355 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
356 b116431 = sal_False;
357 break;
358
359 case IMPL_BAD_INPUT_CONTINUE:
360 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
361 b116431 = sal_False;
362 continue;
363
364 case IMPL_BAD_INPUT_NO_OUTPUT:
365 goto no_output;
366 }
367 break;
368
369 no_output:
370 --pSrcBuf;
371 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
372 break;
373 }
374
375 if (eState > IMPL_ISO_2022_CN_TO_UNICODE_STATE_SO
376 && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
377 | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
378 == 0)
379 {
380 if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
381 nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
382 else
383 switch (ImplHandleBadInputTextToUnicodeConversion(
384 sal_False, sal_True, 0, nFlags, &pDestBufPtr, pDestBufEnd,
385 &nInfo))
386 {
387 case IMPL_BAD_INPUT_STOP:
388 case IMPL_BAD_INPUT_CONTINUE:
389 eState = IMPL_ISO_2022_CN_TO_UNICODE_STATE_ASCII;
390 b116431 = sal_False;
391 break;
392
393 case IMPL_BAD_INPUT_NO_OUTPUT:
394 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
395 break;
396 }
397 }
398
399 if (pContext)
400 {
401 ((ImplIso2022CnToUnicodeContext *) pContext)->m_eState = eState;
402 ((ImplIso2022CnToUnicodeContext *) pContext)->m_nRow = nRow;
403 ((ImplIso2022CnToUnicodeContext *) pContext)->m_bSo = bSo;
404 ((ImplIso2022CnToUnicodeContext *) pContext)->m_b116431 = b116431;
405 }
406 if (pInfo)
407 *pInfo = nInfo;
408 if (pSrcCvtBytes)
409 *pSrcCvtBytes = nConverted;
410
411 return pDestBufPtr - pDestBuf;
412 }
413
ImplCreateUnicodeToIso2022CnContext(void)414 void * ImplCreateUnicodeToIso2022CnContext(void)
415 {
416 void * pContext
417 = rtl_allocateMemory(sizeof (ImplUnicodeToIso2022CnContext));
418 ((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate = 0;
419 ((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator
420 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
421 ((ImplUnicodeToIso2022CnContext *) pContext)->m_b116432Designator
422 = sal_False;
423 ((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo = sal_False;
424 return pContext;
425 }
426
ImplResetUnicodeToIso2022CnContext(void * pContext)427 void ImplResetUnicodeToIso2022CnContext(void * pContext)
428 {
429 if (pContext)
430 {
431 ((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate = 0;
432 ((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator
433 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
434 ((ImplUnicodeToIso2022CnContext *) pContext)->m_b116432Designator
435 = sal_False;
436 ((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo = sal_False;
437 }
438 }
439
ImplIso2022CnTranslateTo2312(ImplUniToDBCSHighTab const * pGb2312Data,sal_uInt32 nChar)440 static sal_uInt32 ImplIso2022CnTranslateTo2312(ImplUniToDBCSHighTab const *
441 pGb2312Data,
442 sal_uInt32 nChar)
443 {
444 sal_uInt32 nIndex1 = nChar >> 8;
445 if (nIndex1 < 0x100)
446 {
447 sal_uInt32 nIndex2 = nChar & 0xFF;
448 sal_uInt32 nFirst = pGb2312Data[nIndex1].mnLowStart;
449 if (nIndex2 >= nFirst && nIndex2 <= pGb2312Data[nIndex1].mnLowEnd)
450 return pGb2312Data[nIndex1].mpToUniTrailTab[nIndex2 - nFirst]
451 & 0x7F7F;
452 }
453 return 0;
454 }
455
456 static sal_uInt32
ImplIso2022CnTranslateTo116431(sal_uInt8 const * pCns116431992Data,sal_Int32 const * pCns116431992PageOffsets,sal_Int32 const * pCns116431992PlaneOffsets,sal_uInt32 nChar)457 ImplIso2022CnTranslateTo116431(sal_uInt8 const * pCns116431992Data,
458 sal_Int32 const * pCns116431992PageOffsets,
459 sal_Int32 const * pCns116431992PlaneOffsets,
460 sal_uInt32 nChar)
461 {
462 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
463 sal_uInt32 nFirst;
464 sal_uInt32 nLast;
465 sal_uInt32 nPlane;
466 if (nOffset == -1)
467 return 0;
468 nOffset = pCns116431992PageOffsets[nOffset + ((nChar & 0xFF00) >> 8)];
469 if (nOffset == -1)
470 return 0;
471 nFirst = pCns116431992Data[nOffset++];
472 nLast = pCns116431992Data[nOffset++];
473 nChar &= 0xFF;
474 if (nChar < nFirst || nChar > nLast)
475 return 0;
476 nOffset += 3 * (nChar - nFirst);
477 nPlane = pCns116431992Data[nOffset++];
478 if (nPlane != 1)
479 return 0;
480 return (0x20 + pCns116431992Data[nOffset]) << 8
481 | (0x20 + pCns116431992Data[nOffset + 1]);
482 }
483
ImplConvertUnicodeToIso2022Cn(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)484 sal_Size ImplConvertUnicodeToIso2022Cn(ImplTextConverterData const * pData,
485 void * pContext,
486 sal_Unicode const * pSrcBuf,
487 sal_Size nSrcChars,
488 sal_Char * pDestBuf,
489 sal_Size nDestBytes,
490 sal_uInt32 nFlags,
491 sal_uInt32 * pInfo,
492 sal_Size * pSrcCvtChars)
493 {
494 ImplUniToDBCSHighTab const * pGb2312Data
495 = ((ImplIso2022CnConverterData const *) pData)->
496 m_pUnicodeToGb2312Data;
497 sal_uInt8 const * pCns116431992Data
498 = ((ImplIso2022CnConverterData const *) pData)->
499 m_pUnicodeToCns116431992Data;
500 sal_Int32 const * pCns116431992PageOffsets
501 = ((ImplIso2022CnConverterData const *) pData)->
502 m_pUnicodeToCns116431992PageOffsets;
503 sal_Int32 const * pCns116431992PlaneOffsets
504 = ((ImplIso2022CnConverterData const *) pData)->
505 m_pUnicodeToCns116431992PlaneOffsets;
506 sal_Unicode nHighSurrogate = 0;
507 ImplUnicodeToIso2022CnDesignator eSoDesignator
508 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
509 sal_Bool b116432Designator = sal_False;
510 sal_Bool bSo = sal_False;
511 sal_uInt32 nInfo = 0;
512 sal_Size nConverted = 0;
513 sal_Char * pDestBufPtr = pDestBuf;
514 sal_Char * pDestBufEnd = pDestBuf + nDestBytes;
515 sal_Bool bWritten;
516
517 if (pContext)
518 {
519 nHighSurrogate
520 = ((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate;
521 eSoDesignator
522 = ((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator;
523 b116432Designator = ((ImplUnicodeToIso2022CnContext *) pContext)->
524 m_b116432Designator;
525 bSo = ((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo;
526 }
527
528 for (; nConverted < nSrcChars; ++nConverted)
529 {
530 sal_Bool bUndefined = sal_True;
531 sal_uInt32 nChar = *pSrcBuf++;
532 if (nHighSurrogate == 0)
533 {
534 if (ImplIsHighSurrogate(nChar))
535 {
536 nHighSurrogate = (sal_Unicode) nChar;
537 continue;
538 }
539 }
540 else if (ImplIsLowSurrogate(nChar))
541 nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
542 else
543 {
544 bUndefined = sal_False;
545 goto bad_input;
546 }
547
548 if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
549 {
550 bUndefined = sal_False;
551 goto bad_input;
552 }
553
554 if (nChar == 0x0A || nChar == 0x0D) /* LF, CR */
555 {
556 if (bSo)
557 {
558 if (pDestBufPtr != pDestBufEnd)
559 {
560 *pDestBufPtr++ = 0x0F; /* SI */
561 bSo = sal_False;
562 eSoDesignator
563 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
564 b116432Designator = sal_False;
565 }
566 else
567 goto no_output;
568 }
569 if (pDestBufPtr != pDestBufEnd)
570 *pDestBufPtr++ = (sal_Char) nChar;
571 else
572 goto no_output;
573 }
574 else if (nChar == 0x0E || nChar == 0x0F || nChar == 0x1B)
575 goto bad_input;
576 else if (nChar < 0x80)
577 {
578 if (bSo)
579 {
580 if (pDestBufPtr != pDestBufEnd)
581 {
582 *pDestBufPtr++ = 0x0F; /* SI */
583 bSo = sal_False;
584 }
585 else
586 goto no_output;
587 }
588 if (pDestBufPtr != pDestBufEnd)
589 *pDestBufPtr++ = (sal_Char) nChar;
590 else
591 goto no_output;
592 }
593 else
594 {
595 sal_uInt32 nBytes = 0;
596 ImplUnicodeToIso2022CnDesignator eNewDesignator =
597 IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
598 switch (eSoDesignator)
599 {
600 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE:
601 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
602 if (nBytes != 0)
603 {
604 eNewDesignator
605 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
606 break;
607 }
608 nBytes = ImplIso2022CnTranslateTo116431(
609 pCns116431992Data,
610 pCns116431992PageOffsets,
611 pCns116431992PlaneOffsets,
612 nChar);
613 if (nBytes != 0)
614 {
615 eNewDesignator
616 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
617 break;
618 }
619 break;
620
621 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312:
622 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
623 if (nBytes != 0)
624 {
625 eNewDesignator
626 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
627 break;
628 }
629 nBytes = ImplIso2022CnTranslateTo116431(
630 pCns116431992Data,
631 pCns116431992PageOffsets,
632 pCns116431992PlaneOffsets,
633 nChar);
634 if (nBytes != 0)
635 {
636 eNewDesignator
637 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431;
638 break;
639 }
640 break;
641
642 case IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_116431:
643 nBytes = ImplIso2022CnTranslateTo116431(
644 pCns116431992Data,
645 pCns116431992PageOffsets,
646 pCns116431992PlaneOffsets,
647 nChar);
648 if (nBytes != 0)
649 {
650 eNewDesignator
651 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE;
652 break;
653 }
654 nBytes = ImplIso2022CnTranslateTo2312(pGb2312Data, nChar);
655 if (nBytes != 0)
656 {
657 eNewDesignator
658 = IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312;
659 break;
660 }
661 break;
662 }
663 if (nBytes != 0)
664 {
665 if (eNewDesignator
666 != IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_NONE)
667 {
668 if (bSo)
669 {
670 if (pDestBufPtr != pDestBufEnd)
671 {
672 *pDestBufPtr++ = 0x0F; /* SI */
673 bSo = sal_False;
674 }
675 else
676 goto no_output;
677 }
678 if (pDestBufEnd - pDestBufPtr >= 4)
679 {
680 *pDestBufPtr++ = 0x1B; /* ESC */
681 *pDestBufPtr++ = 0x24; /* $ */
682 *pDestBufPtr++ = 0x29; /* ) */
683 *pDestBufPtr++
684 = eNewDesignator
685 == IMPL_UNICODE_TO_ISO_2022_CN_DESIGNATOR_2312 ?
686 0x41 : 0x47; /* A, G */
687 eSoDesignator = eNewDesignator;
688 }
689 else
690 goto no_output;
691 }
692 if (!bSo)
693 {
694 if (pDestBufPtr != pDestBufEnd)
695 {
696 *pDestBufPtr++ = 0x0E; /* SO */
697 bSo = sal_True;
698 }
699 else
700 goto no_output;
701 }
702 if (pDestBufEnd - pDestBufPtr >= 4)
703 {
704 *pDestBufPtr++ = (sal_Char) (nBytes >> 8);
705 *pDestBufPtr++ = (sal_Char) (nBytes & 0xFF);
706 }
707 else
708 goto no_output;
709 }
710 else
711 {
712 sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
713 sal_uInt32 nFirst;
714 sal_uInt32 nLast;
715 sal_uInt32 nPlane;
716 if (nOffset == -1)
717 goto bad_input;
718 nOffset
719 = pCns116431992PageOffsets[nOffset
720 + ((nChar & 0xFF00) >> 8)];
721 if (nOffset == -1)
722 goto bad_input;
723 nFirst = pCns116431992Data[nOffset++];
724 nLast = pCns116431992Data[nOffset++];
725 nChar &= 0xFF;
726 if (nChar < nFirst || nChar > nLast)
727 goto bad_input;
728 nOffset += 3 * (nChar - nFirst);
729 nPlane = pCns116431992Data[nOffset++];
730 if (nPlane != 2)
731 goto bad_input;
732 if (!b116432Designator)
733 {
734 if (pDestBufEnd - pDestBufPtr >= 4)
735 {
736 *pDestBufPtr++ = 0x1B; /* ESC */
737 *pDestBufPtr++ = 0x24; /* $ */
738 *pDestBufPtr++ = 0x2A; /* * */
739 *pDestBufPtr++ = 0x48; /* H */
740 b116432Designator = sal_True;
741 }
742 else
743 goto no_output;
744 }
745 if (pDestBufEnd - pDestBufPtr >= 4)
746 {
747 *pDestBufPtr++ = 0x1B; /* ESC */
748 *pDestBufPtr++ = 0x4E; /* N */
749 *pDestBufPtr++
750 = (sal_Char) (0x20 + pCns116431992Data[nOffset++]);
751 *pDestBufPtr++
752 = (sal_Char) (0x20 + pCns116431992Data[nOffset]);
753 }
754 else
755 goto no_output;
756 }
757 }
758 nHighSurrogate = 0;
759 continue;
760
761 bad_input:
762 switch (ImplHandleBadInputUnicodeToTextConversion(bUndefined,
763 nChar,
764 nFlags,
765 &pDestBufPtr,
766 pDestBufEnd,
767 &nInfo,
768 "\x0F", /* SI */
769 bSo ? 1 : 0,
770 &bWritten))
771 {
772 case IMPL_BAD_INPUT_STOP:
773 nHighSurrogate = 0;
774 break;
775
776 case IMPL_BAD_INPUT_CONTINUE:
777 if (bWritten)
778 bSo = sal_False;
779 nHighSurrogate = 0;
780 continue;
781
782 case IMPL_BAD_INPUT_NO_OUTPUT:
783 goto no_output;
784 }
785 break;
786
787 no_output:
788 --pSrcBuf;
789 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
790 break;
791 }
792
793 if ((nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
794 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
795 == 0)
796 {
797 sal_Bool bFlush = sal_True;
798 if (nHighSurrogate != 0)
799 {
800 if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
801 nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
802 else
803 switch (ImplHandleBadInputUnicodeToTextConversion(
804 sal_False,
805 0,
806 nFlags,
807 &pDestBufPtr,
808 pDestBufEnd,
809 &nInfo,
810 "\x0F", /* SI */
811 bSo ? 1 : 0,
812 &bWritten))
813 {
814 case IMPL_BAD_INPUT_STOP:
815 nHighSurrogate = 0;
816 bFlush = sal_False;
817 break;
818
819 case IMPL_BAD_INPUT_CONTINUE:
820 if (bWritten)
821 bSo = sal_False;
822 nHighSurrogate = 0;
823 break;
824
825 case IMPL_BAD_INPUT_NO_OUTPUT:
826 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
827 break;
828 }
829 }
830 if (bFlush && bSo && (nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
831 {
832 if (pDestBufPtr != pDestBufEnd)
833 {
834 *pDestBufPtr++ = 0x0F; /* SI */
835 bSo = sal_False;
836 }
837 else
838 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
839 }
840 }
841
842 if (pContext)
843 {
844 ((ImplUnicodeToIso2022CnContext *) pContext)->m_nHighSurrogate
845 = nHighSurrogate;
846 ((ImplUnicodeToIso2022CnContext *) pContext)->m_eSoDesignator
847 = eSoDesignator;
848 ((ImplUnicodeToIso2022CnContext *) pContext)->m_b116432Designator
849 = b116432Designator;
850 ((ImplUnicodeToIso2022CnContext *) pContext)->m_bSo = bSo;
851 }
852 if (pInfo)
853 *pInfo = nInfo;
854 if (pSrcCvtChars)
855 *pSrcCvtChars = nConverted;
856
857 return pDestBufPtr - pDestBuf;
858 }
859