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