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 "converteuctw.hxx"
37 : : #include "tenchelp.hxx"
38 : : #include "unichars.hxx"
39 : :
40 : : namespace {
41 : :
42 : : enum ImplEucTwToUnicodeState
43 : : {
44 : : IMPL_EUC_TW_TO_UNICODE_STATE_0,
45 : : IMPL_EUC_TW_TO_UNICODE_STATE_1,
46 : : IMPL_EUC_TW_TO_UNICODE_STATE_2_1,
47 : : IMPL_EUC_TW_TO_UNICODE_STATE_2_2,
48 : : IMPL_EUC_TW_TO_UNICODE_STATE_2_3
49 : : };
50 : :
51 : : struct ImplEucTwToUnicodeContext
52 : : {
53 : : ImplEucTwToUnicodeState m_eState;
54 : : sal_Int32 m_nPlane; // 0--15
55 : : sal_Int32 m_nRow; // 0--93
56 : : };
57 : :
58 : : }
59 : :
60 : 0 : void * ImplCreateEucTwToUnicodeContext()
61 : : {
62 : 0 : ImplEucTwToUnicodeContext * pContext = new ImplEucTwToUnicodeContext;
63 : 0 : pContext->m_eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
64 : 0 : return pContext;
65 : : }
66 : :
67 : 0 : void ImplResetEucTwToUnicodeContext(void * pContext)
68 : : {
69 [ # # ]: 0 : if (pContext)
70 : : static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_eState
71 : 0 : = IMPL_EUC_TW_TO_UNICODE_STATE_0;
72 : 0 : }
73 : :
74 : 0 : void ImplDestroyEucTwToUnicodeContext(void * pContext)
75 : : {
76 : 0 : delete static_cast< ImplEucTwToUnicodeContext * >(pContext);
77 : 0 : }
78 : :
79 : 0 : sal_Size ImplConvertEucTwToUnicode(void const * pData,
80 : : void * pContext,
81 : : char const * pSrcBuf,
82 : : sal_Size nSrcBytes,
83 : : sal_Unicode * pDestBuf,
84 : : sal_Size nDestChars,
85 : : sal_uInt32 nFlags,
86 : : sal_uInt32 * pInfo,
87 : : sal_Size * pSrcCvtBytes)
88 : : {
89 : : sal_uInt16 const * pCns116431992Data
90 : : = static_cast< ImplEucTwConverterData const * >(pData)->
91 : 0 : m_pCns116431992ToUnicodeData;
92 : : sal_Int32 const * pCns116431992RowOffsets
93 : : = static_cast< ImplEucTwConverterData const * >(pData)->
94 : 0 : m_pCns116431992ToUnicodeRowOffsets;
95 : : sal_Int32 const * pCns116431992PlaneOffsets
96 : : = static_cast< ImplEucTwConverterData const * >(pData)->
97 : 0 : m_pCns116431992ToUnicodePlaneOffsets;
98 : 0 : ImplEucTwToUnicodeState eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
99 : 0 : sal_Int32 nPlane = 0;
100 : 0 : sal_Int32 nRow = 0;
101 : 0 : sal_uInt32 nInfo = 0;
102 : 0 : sal_Size nConverted = 0;
103 : 0 : sal_Unicode * pDestBufPtr = pDestBuf;
104 : 0 : sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
105 : :
106 [ # # ]: 0 : if (pContext)
107 : : {
108 : 0 : eState = static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_eState;
109 : 0 : nPlane = static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_nPlane;
110 : 0 : nRow = static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_nRow;
111 : : }
112 : :
113 [ # # ]: 0 : for (; nConverted < nSrcBytes; ++nConverted)
114 : : {
115 : 0 : bool bUndefined = true;
116 : 0 : sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++;
117 [ # # # # : 0 : switch (eState)
# # ]
118 : : {
119 : : case IMPL_EUC_TW_TO_UNICODE_STATE_0:
120 [ # # ]: 0 : if (nChar < 0x80)
121 [ # # ]: 0 : if (pDestBufPtr != pDestBufEnd)
122 : 0 : *pDestBufPtr++ = (sal_Unicode) nChar;
123 : : else
124 : 0 : goto no_output;
125 [ # # ][ # # ]: 0 : else if (nChar >= 0xA1 && nChar <= 0xFE)
126 : : {
127 : 0 : nRow = nChar - 0xA1;
128 : 0 : eState = IMPL_EUC_TW_TO_UNICODE_STATE_1;
129 : : }
130 [ # # ]: 0 : else if (nChar == 0x8E)
131 : 0 : eState = IMPL_EUC_TW_TO_UNICODE_STATE_2_1;
132 : : else
133 : : {
134 : 0 : bUndefined = false;
135 : 0 : goto bad_input;
136 : : }
137 : 0 : break;
138 : :
139 : : case IMPL_EUC_TW_TO_UNICODE_STATE_1:
140 [ # # ][ # # ]: 0 : if (nChar >= 0xA1 && nChar <= 0xFE)
141 : : {
142 : 0 : nPlane = 0;
143 : 0 : goto transform;
144 : : }
145 : : else
146 : : {
147 : 0 : bUndefined = false;
148 : 0 : goto bad_input;
149 : : }
150 : : break;
151 : :
152 : : case IMPL_EUC_TW_TO_UNICODE_STATE_2_1:
153 [ # # ][ # # ]: 0 : if (nChar >= 0xA1 && nChar <= 0xB0)
154 : : {
155 : 0 : nPlane = nChar - 0xA1;
156 : 0 : eState = IMPL_EUC_TW_TO_UNICODE_STATE_2_2;
157 : : }
158 : : else
159 : : {
160 : 0 : bUndefined = false;
161 : 0 : goto bad_input;
162 : : }
163 : 0 : break;
164 : :
165 : : case IMPL_EUC_TW_TO_UNICODE_STATE_2_2:
166 [ # # ][ # # ]: 0 : if (nChar >= 0xA1 && nChar <= 0xFE)
167 : : {
168 : 0 : nRow = nChar - 0xA1;
169 : 0 : eState = IMPL_EUC_TW_TO_UNICODE_STATE_2_3;
170 : : }
171 : : else
172 : : {
173 : 0 : bUndefined = false;
174 : 0 : goto bad_input;
175 : : }
176 : 0 : break;
177 : :
178 : : case IMPL_EUC_TW_TO_UNICODE_STATE_2_3:
179 [ # # ][ # # ]: 0 : if (nChar >= 0xA1 && nChar <= 0xFE)
180 : : goto transform;
181 : : else
182 : : {
183 : 0 : bUndefined = false;
184 : 0 : goto bad_input;
185 : : }
186 : : break;
187 : : }
188 : 0 : continue;
189 : :
190 : : transform:
191 : : {
192 : 0 : sal_Int32 nPlaneOffset = pCns116431992PlaneOffsets[nPlane];
193 [ # # ]: 0 : if (nPlaneOffset == -1)
194 : 0 : goto bad_input;
195 : : else
196 : : {
197 : : sal_Int32 nOffset
198 : 0 : = pCns116431992RowOffsets[nPlaneOffset + nRow];
199 [ # # ]: 0 : if (nOffset == -1)
200 : 0 : goto bad_input;
201 : : else
202 : : {
203 : 0 : sal_uInt32 nFirstLast = pCns116431992Data[nOffset++];
204 : 0 : sal_uInt32 nFirst = nFirstLast & 0xFF;
205 : 0 : sal_uInt32 nLast = nFirstLast >> 8;
206 : 0 : nChar -= 0xA0;
207 [ # # ][ # # ]: 0 : if (nChar >= nFirst && nChar <= nLast)
208 : : {
209 : : sal_uInt32 nUnicode
210 : 0 : = pCns116431992Data[nOffset + (nChar - nFirst)];
211 [ # # ]: 0 : if (nUnicode == 0xFFFF)
212 : 0 : goto bad_input;
213 [ # # ]: 0 : else if (ImplIsHighSurrogate(nUnicode))
214 [ # # ]: 0 : if (pDestBufEnd - pDestBufPtr >= 2)
215 : : {
216 : 0 : nOffset += nLast - nFirst + 1;
217 : 0 : nFirst = pCns116431992Data[nOffset++];
218 : 0 : *pDestBufPtr++ = (sal_Unicode) nUnicode;
219 : : *pDestBufPtr++
220 : : = (sal_Unicode)
221 : : pCns116431992Data[
222 : 0 : nOffset + (nChar - nFirst)];
223 : : }
224 : : else
225 : 0 : goto no_output;
226 : : else
227 [ # # ]: 0 : if (pDestBufPtr != pDestBufEnd)
228 : 0 : *pDestBufPtr++ = (sal_Unicode) nUnicode;
229 : : else
230 : 0 : goto no_output;
231 : : }
232 : : else
233 : : goto bad_input;
234 : 0 : eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
235 : : }
236 : : }
237 : 0 : continue;
238 : : }
239 : :
240 : : bad_input:
241 [ # # # # ]: 0 : switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
242 : : bUndefined, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
243 [ # # ]: 0 : &nInfo))
244 : : {
245 : : case sal::detail::textenc::BAD_INPUT_STOP:
246 : 0 : eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
247 : 0 : break;
248 : :
249 : : case sal::detail::textenc::BAD_INPUT_CONTINUE:
250 : 0 : eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
251 : 0 : continue;
252 : :
253 : : case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
254 : 0 : goto no_output;
255 : : }
256 : 0 : break;
257 : :
258 : : no_output:
259 : 0 : --pSrcBuf;
260 : 0 : nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
261 : 0 : break;
262 : : }
263 : :
264 [ # # ][ # # ]: 0 : if (eState != IMPL_EUC_TW_TO_UNICODE_STATE_0
265 : : && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
266 : : | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
267 : : == 0)
268 : : {
269 [ # # ]: 0 : if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
270 : 0 : nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
271 : : else
272 [ # # # ]: 0 : switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
273 : : false, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
274 [ # # ]: 0 : &nInfo))
275 : : {
276 : : case sal::detail::textenc::BAD_INPUT_STOP:
277 : : case sal::detail::textenc::BAD_INPUT_CONTINUE:
278 : 0 : eState = IMPL_EUC_TW_TO_UNICODE_STATE_0;
279 : 0 : break;
280 : :
281 : : case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
282 : 0 : nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
283 : 0 : break;
284 : : }
285 : : }
286 : :
287 [ # # ]: 0 : if (pContext)
288 : : {
289 : 0 : static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_eState = eState;
290 : 0 : static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_nPlane = nPlane;
291 : 0 : static_cast< ImplEucTwToUnicodeContext * >(pContext)->m_nRow = nRow;
292 : : }
293 [ # # ]: 0 : if (pInfo)
294 : 0 : *pInfo = nInfo;
295 [ # # ]: 0 : if (pSrcCvtBytes)
296 : 0 : *pSrcCvtBytes = nConverted;
297 : :
298 : 0 : return pDestBufPtr - pDestBuf;
299 : : }
300 : :
301 : 0 : sal_Size ImplConvertUnicodeToEucTw(void const * pData,
302 : : void * pContext,
303 : : sal_Unicode const * pSrcBuf,
304 : : sal_Size nSrcChars,
305 : : char * pDestBuf,
306 : : sal_Size nDestBytes,
307 : : sal_uInt32 nFlags,
308 : : sal_uInt32 * pInfo,
309 : : sal_Size * pSrcCvtChars)
310 : : {
311 : : sal_uInt8 const * pCns116431992Data
312 : : = static_cast< ImplEucTwConverterData const * >(pData)->
313 : 0 : m_pUnicodeToCns116431992Data;
314 : : sal_Int32 const * pCns116431992PageOffsets
315 : : = static_cast< ImplEucTwConverterData const * >(pData)->
316 : 0 : m_pUnicodeToCns116431992PageOffsets;
317 : : sal_Int32 const * pCns116431992PlaneOffsets
318 : : = static_cast< ImplEucTwConverterData const * >(pData)->
319 : 0 : m_pUnicodeToCns116431992PlaneOffsets;
320 : 0 : sal_Unicode nHighSurrogate = 0;
321 : 0 : sal_uInt32 nInfo = 0;
322 : 0 : sal_Size nConverted = 0;
323 : 0 : char * pDestBufPtr = pDestBuf;
324 : 0 : char * pDestBufEnd = pDestBuf + nDestBytes;
325 : :
326 [ # # ]: 0 : if (pContext)
327 : : nHighSurrogate
328 : 0 : = ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate;
329 : :
330 [ # # ]: 0 : for (; nConverted < nSrcChars; ++nConverted)
331 : : {
332 : 0 : bool bUndefined = true;
333 : 0 : sal_uInt32 nChar = *pSrcBuf++;
334 [ # # ]: 0 : if (nHighSurrogate == 0)
335 : : {
336 [ # # ]: 0 : if (ImplIsHighSurrogate(nChar))
337 : : {
338 : 0 : nHighSurrogate = (sal_Unicode) nChar;
339 : 0 : continue;
340 : : }
341 : : }
342 [ # # ]: 0 : else if (ImplIsLowSurrogate(nChar))
343 : 0 : nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
344 : : else
345 : : {
346 : 0 : bUndefined = false;
347 : 0 : goto bad_input;
348 : : }
349 : :
350 [ # # ][ # # ]: 0 : if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
[ # # ]
351 : : {
352 : 0 : bUndefined = false;
353 : 0 : goto bad_input;
354 : : }
355 : :
356 [ # # ]: 0 : if (nChar < 0x80)
357 [ # # ]: 0 : if (pDestBufPtr != pDestBufEnd)
358 : 0 : *pDestBufPtr++ = static_cast< char >(nChar);
359 : : else
360 : 0 : goto no_output;
361 : : else
362 : : {
363 : 0 : sal_Int32 nOffset = pCns116431992PlaneOffsets[nChar >> 16];
364 : : sal_uInt32 nFirst;
365 : : sal_uInt32 nLast;
366 : : sal_uInt32 nPlane;
367 [ # # ]: 0 : if (nOffset == -1)
368 : 0 : goto bad_input;
369 : : nOffset
370 : 0 : = pCns116431992PageOffsets[nOffset + ((nChar & 0xFF00) >> 8)];
371 [ # # ]: 0 : if (nOffset == -1)
372 : 0 : goto bad_input;
373 : 0 : nFirst = pCns116431992Data[nOffset++];
374 : 0 : nLast = pCns116431992Data[nOffset++];
375 : 0 : nChar &= 0xFF;
376 [ # # ][ # # ]: 0 : if (nChar < nFirst || nChar > nLast)
377 : : goto bad_input;
378 : 0 : nOffset += 3 * (nChar - nFirst);
379 : 0 : nPlane = pCns116431992Data[nOffset++];
380 [ # # ]: 0 : if (nPlane == 0)
381 : 0 : goto bad_input;
382 [ # # ][ # # ]: 0 : if (pDestBufEnd - pDestBufPtr < (nPlane == 1 ? 2 : 4))
383 : 0 : goto no_output;
384 [ # # ]: 0 : if (nPlane != 1)
385 : : {
386 : 0 : *pDestBufPtr++ = static_cast< char >(static_cast< unsigned char >(0x8E));
387 : 0 : *pDestBufPtr++ = static_cast< char >(0xA0 + nPlane);
388 : : }
389 : 0 : *pDestBufPtr++ = static_cast< char >(0xA0 + pCns116431992Data[nOffset++]);
390 : 0 : *pDestBufPtr++ = static_cast< char >(0xA0 + pCns116431992Data[nOffset]);
391 : : }
392 : 0 : nHighSurrogate = 0;
393 : 0 : continue;
394 : :
395 : : bad_input:
396 [ # # # # ]: 0 : switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
397 : : bUndefined, nChar, nFlags, &pDestBufPtr, pDestBufEnd,
398 [ # # ]: 0 : &nInfo, NULL, 0, NULL))
399 : : {
400 : : case sal::detail::textenc::BAD_INPUT_STOP:
401 : 0 : nHighSurrogate = 0;
402 : 0 : break;
403 : :
404 : : case sal::detail::textenc::BAD_INPUT_CONTINUE:
405 : 0 : nHighSurrogate = 0;
406 : 0 : continue;
407 : :
408 : : case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
409 : 0 : goto no_output;
410 : : }
411 : 0 : break;
412 : :
413 : : no_output:
414 : 0 : --pSrcBuf;
415 : 0 : nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
416 : 0 : break;
417 : : }
418 : :
419 [ # # ][ # # ]: 0 : if (nHighSurrogate != 0
420 : : && (nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
421 : : | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
422 : : == 0)
423 : : {
424 [ # # ]: 0 : if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
425 : 0 : nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
426 : : else
427 [ # # # ]: 0 : switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
428 : : false, 0, nFlags, &pDestBufPtr, pDestBufEnd, &nInfo,
429 [ # # ]: 0 : NULL, 0, NULL))
430 : : {
431 : : case sal::detail::textenc::BAD_INPUT_STOP:
432 : : case sal::detail::textenc::BAD_INPUT_CONTINUE:
433 : 0 : nHighSurrogate = 0;
434 : 0 : break;
435 : :
436 : : case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
437 : 0 : nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
438 : 0 : break;
439 : : }
440 : : }
441 : :
442 [ # # ]: 0 : if (pContext)
443 : : ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate
444 : 0 : = nHighSurrogate;
445 [ # # ]: 0 : if (pInfo)
446 : 0 : *pInfo = nInfo;
447 [ # # ]: 0 : if (pSrcCvtChars)
448 : 0 : *pSrcCvtChars = nConverted;
449 : :
450 : 0 : return pDestBufPtr - pDestBuf;
451 : : }
452 : :
453 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|