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 <cassert>
32 : :
33 : : #include "rtl/textcvt.h"
34 : : #include "sal/types.h"
35 : :
36 : : #include "context.hxx"
37 : : #include "convertbig5hkscs.hxx"
38 : : #include "converter.hxx"
39 : : #include "tenchelp.hxx"
40 : : #include "unichars.hxx"
41 : :
42 : : namespace {
43 : :
44 : : struct ImplBig5HkscsToUnicodeContext
45 : : {
46 : : sal_Int32 m_nRow; // 0--255; 0 means none
47 : : };
48 : :
49 : : }
50 : :
51 : 0 : void * ImplCreateBig5HkscsToUnicodeContext()
52 : : {
53 : : ImplBig5HkscsToUnicodeContext * pContext =
54 : 0 : new ImplBig5HkscsToUnicodeContext;
55 : 0 : pContext->m_nRow = 0;
56 : 0 : return pContext;
57 : : }
58 : :
59 : 0 : void ImplResetBig5HkscsToUnicodeContext(void * pContext)
60 : : {
61 [ # # ]: 0 : if (pContext)
62 : 0 : static_cast< ImplBig5HkscsToUnicodeContext * >(pContext)->m_nRow = 0;
63 : 0 : }
64 : :
65 : 0 : void ImplDestroyBig5HkscsToUnicodeContext(void * pContext)
66 : : {
67 : 0 : delete static_cast< ImplBig5HkscsToUnicodeContext * >(pContext);
68 : 0 : }
69 : :
70 : 0 : sal_Size ImplConvertBig5HkscsToUnicode(void const * pData,
71 : : void * pContext,
72 : : char const * pSrcBuf,
73 : : sal_Size nSrcBytes,
74 : : sal_Unicode * pDestBuf,
75 : : sal_Size nDestChars,
76 : : sal_uInt32 nFlags,
77 : : sal_uInt32 * pInfo,
78 : : sal_Size * pSrcCvtBytes)
79 : : {
80 : : sal_uInt16 const * pBig5Hkscs2001Data
81 : : = static_cast< ImplBig5HkscsConverterData const * >(pData)->
82 : 0 : m_pBig5Hkscs2001ToUnicodeData;
83 : : sal_Int32 const * pBig5Hkscs2001RowOffsets
84 : : = static_cast< ImplBig5HkscsConverterData const * >(pData)->
85 : 0 : m_pBig5Hkscs2001ToUnicodeRowOffsets;
86 : : ImplDBCSToUniLeadTab const * pBig5Data
87 : : = static_cast< ImplBig5HkscsConverterData const * >(pData)->
88 : 0 : m_pBig5ToUnicodeData;
89 : 0 : sal_Int32 nRow = 0;
90 : 0 : sal_uInt32 nInfo = 0;
91 : 0 : sal_Size nConverted = 0;
92 : 0 : sal_Unicode * pDestBufPtr = pDestBuf;
93 : 0 : sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
94 : :
95 [ # # ]: 0 : if (pContext)
96 : 0 : nRow = static_cast< ImplBig5HkscsToUnicodeContext * >(pContext)->m_nRow;
97 : :
98 [ # # ]: 0 : for (; nConverted < nSrcBytes; ++nConverted)
99 : : {
100 : 0 : bool bUndefined = true;
101 : 0 : sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++;
102 [ # # ]: 0 : if (nRow == 0)
103 [ # # ]: 0 : if (nChar < 0x80)
104 [ # # ]: 0 : if (pDestBufPtr != pDestBufEnd)
105 : 0 : *pDestBufPtr++ = (sal_Unicode) nChar;
106 : : else
107 : 0 : goto no_output;
108 [ # # ][ # # ]: 0 : else if (nChar >= 0x81 && nChar <= 0xFE)
109 : 0 : nRow = nChar;
110 : : else
111 : : {
112 : 0 : bUndefined = false;
113 : 0 : goto bad_input;
114 : : }
115 : : else
116 [ # # ][ # # ]: 0 : if ((nChar >= 0x40 && nChar <= 0x7E)
[ # # ][ # # ]
117 : : || (nChar >= 0xA1 && nChar <= 0xFE))
118 : : {
119 : 0 : sal_uInt32 nUnicode = 0xFFFF;
120 : 0 : sal_Int32 nOffset = pBig5Hkscs2001RowOffsets[nRow];
121 : 0 : sal_uInt32 nFirst=0;
122 : 0 : sal_uInt32 nLast=0;
123 [ # # ]: 0 : if (nOffset != -1)
124 : : {
125 : 0 : sal_uInt32 nFirstLast = pBig5Hkscs2001Data[nOffset++];
126 : 0 : nFirst = nFirstLast & 0xFF;
127 : 0 : nLast = nFirstLast >> 8;
128 [ # # ][ # # ]: 0 : if (nChar >= nFirst && nChar <= nLast)
129 : : nUnicode
130 : 0 : = pBig5Hkscs2001Data[nOffset + (nChar - nFirst)];
131 : : }
132 [ # # ]: 0 : if (nUnicode == 0xFFFF)
133 : : {
134 : 0 : sal_uInt32 n = pBig5Data[nRow].mnTrailStart;
135 [ # # ][ # # ]: 0 : if (nChar >= n && nChar <= pBig5Data[nRow].mnTrailEnd)
136 : : {
137 : 0 : nUnicode = pBig5Data[nRow].mpToUniTrailTab[nChar - n];
138 [ # # ]: 0 : if (nUnicode == 0)
139 : 0 : nUnicode = 0xFFFF;
140 : : assert(!ImplIsHighSurrogate(nUnicode));
141 : : }
142 : : }
143 [ # # ]: 0 : if (nUnicode == 0xFFFF)
144 : : {
145 : : ImplDBCSEUDCData const * p
146 : : = static_cast< ImplBig5HkscsConverterData const * >(pData)->
147 : 0 : m_pEudcData;
148 : : sal_uInt32 nCount
149 : : = static_cast< ImplBig5HkscsConverterData const * >(pData)->
150 : 0 : m_nEudcCount;
151 : : sal_uInt32 i;
152 [ # # ]: 0 : for (i = 0; i < nCount; ++i)
153 : : {
154 [ # # ][ # # ]: 0 : if (nRow >= p->mnLeadStart && nRow <= p->mnLeadEnd)
155 : : {
156 [ # # ]: 0 : if (nChar < p->mnTrail1Start)
157 : 0 : break;
158 [ # # ]: 0 : if (nChar <= p->mnTrail1End)
159 : : {
160 : : nUnicode
161 : : = p->mnUniStart
162 : : + (nRow - p->mnLeadStart)
163 : : * p->mnTrailRangeCount
164 : 0 : + (nChar - p->mnTrail1Start);
165 : 0 : break;
166 : : }
167 [ # # ][ # # ]: 0 : if (p->mnTrailCount < 2
168 : : || nChar < p->mnTrail2Start)
169 : 0 : break;
170 [ # # ]: 0 : if (nChar <= p->mnTrail2End)
171 : : {
172 : : nUnicode
173 : : = p->mnUniStart
174 : : + (nRow - p->mnLeadStart)
175 : : * p->mnTrailRangeCount
176 : : + (nChar - p->mnTrail2Start)
177 : : + (p->mnTrail1End - p->mnTrail1Start
178 : 0 : + 1);
179 : 0 : break;
180 : : }
181 [ # # ][ # # ]: 0 : if (p->mnTrailCount < 3
182 : : || nChar < p->mnTrail3Start)
183 : 0 : break;
184 [ # # ]: 0 : if (nChar <= p->mnTrail3End)
185 : : {
186 : : nUnicode
187 : : = p->mnUniStart
188 : : + (nRow - p->mnLeadStart)
189 : : * p->mnTrailRangeCount
190 : : + (nChar - p->mnTrail3Start)
191 : : + (p->mnTrail1End - p->mnTrail1Start
192 : : + 1)
193 : : + (p->mnTrail2End - p->mnTrail2Start
194 : 0 : + 1);
195 : 0 : break;
196 : : }
197 : 0 : break;
198 : : }
199 : 0 : ++p;
200 : : }
201 : : assert(!ImplIsHighSurrogate(nUnicode));
202 : : }
203 [ # # ]: 0 : if (nUnicode == 0xFFFF)
204 : 0 : goto bad_input;
205 [ # # ]: 0 : if (ImplIsHighSurrogate(nUnicode))
206 [ # # ]: 0 : if (pDestBufEnd - pDestBufPtr >= 2)
207 : : {
208 : 0 : nOffset += nLast - nFirst + 1;
209 : 0 : nFirst = pBig5Hkscs2001Data[nOffset++];
210 : 0 : *pDestBufPtr++ = (sal_Unicode) nUnicode;
211 : : *pDestBufPtr++
212 : : = (sal_Unicode) pBig5Hkscs2001Data[
213 : 0 : nOffset + (nChar - nFirst)];
214 : : }
215 : : else
216 : 0 : goto no_output;
217 : : else
218 [ # # ]: 0 : if (pDestBufPtr != pDestBufEnd)
219 : 0 : *pDestBufPtr++ = (sal_Unicode) nUnicode;
220 : : else
221 : 0 : goto no_output;
222 : 0 : nRow = 0;
223 : : }
224 : : else
225 : : {
226 : 0 : bUndefined = false;
227 : 0 : goto bad_input;
228 : : }
229 : 0 : continue;
230 : :
231 : : bad_input:
232 [ # # # # ]: 0 : switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
233 : : bUndefined, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
234 [ # # ]: 0 : &nInfo))
235 : : {
236 : : case sal::detail::textenc::BAD_INPUT_STOP:
237 : 0 : nRow = 0;
238 : 0 : break;
239 : :
240 : : case sal::detail::textenc::BAD_INPUT_CONTINUE:
241 : 0 : nRow = 0;
242 : 0 : continue;
243 : :
244 : : case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
245 : 0 : goto no_output;
246 : : }
247 : 0 : break;
248 : :
249 : : no_output:
250 : 0 : --pSrcBuf;
251 : 0 : nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
252 : 0 : break;
253 : : }
254 : :
255 [ # # ][ # # ]: 0 : if (nRow != 0
256 : : && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
257 : : | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
258 : : == 0)
259 : : {
260 [ # # ]: 0 : if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
261 : 0 : nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
262 : : else
263 [ # # # ]: 0 : switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
264 : : false, true, 0, nFlags, &pDestBufPtr, pDestBufEnd,
265 [ # # ]: 0 : &nInfo))
266 : : {
267 : : case sal::detail::textenc::BAD_INPUT_STOP:
268 : : case sal::detail::textenc::BAD_INPUT_CONTINUE:
269 : 0 : nRow = 0;
270 : 0 : break;
271 : :
272 : : case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
273 : 0 : nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
274 : 0 : break;
275 : : }
276 : : }
277 : :
278 [ # # ]: 0 : if (pContext)
279 : 0 : static_cast< ImplBig5HkscsToUnicodeContext * >(pContext)->m_nRow = nRow;
280 [ # # ]: 0 : if (pInfo)
281 : 0 : *pInfo = nInfo;
282 [ # # ]: 0 : if (pSrcCvtBytes)
283 : 0 : *pSrcCvtBytes = nConverted;
284 : :
285 : 0 : return pDestBufPtr - pDestBuf;
286 : : }
287 : :
288 : 0 : sal_Size ImplConvertUnicodeToBig5Hkscs(void const * pData,
289 : : void * pContext,
290 : : sal_Unicode const * pSrcBuf,
291 : : sal_Size nSrcChars,
292 : : char * pDestBuf,
293 : : sal_Size nDestBytes,
294 : : sal_uInt32 nFlags,
295 : : sal_uInt32 * pInfo,
296 : : sal_Size * pSrcCvtChars)
297 : : {
298 : : sal_uInt16 const * pBig5Hkscs2001Data
299 : : = static_cast< ImplBig5HkscsConverterData const * >(pData)->
300 : 0 : m_pUnicodeToBig5Hkscs2001Data;
301 : : sal_Int32 const * pBig5Hkscs2001PageOffsets
302 : : = static_cast< ImplBig5HkscsConverterData const * >(pData)->
303 : 0 : m_pUnicodeToBig5Hkscs2001PageOffsets;
304 : : sal_Int32 const * pBig5Hkscs2001PlaneOffsets
305 : : = static_cast< ImplBig5HkscsConverterData const * >(pData)->
306 : 0 : m_pUnicodeToBig5Hkscs2001PlaneOffsets;
307 : : ImplUniToDBCSHighTab const * pBig5Data
308 : : = static_cast< ImplBig5HkscsConverterData const * >(pData)->
309 : 0 : m_pUnicodeToBig5Data;
310 : 0 : sal_Unicode nHighSurrogate = 0;
311 : 0 : sal_uInt32 nInfo = 0;
312 : 0 : sal_Size nConverted = 0;
313 : 0 : char * pDestBufPtr = pDestBuf;
314 : 0 : char * pDestBufEnd = pDestBuf + nDestBytes;
315 : :
316 [ # # ]: 0 : if (pContext)
317 : : nHighSurrogate
318 : 0 : = ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate;
319 : :
320 [ # # ]: 0 : for (; nConverted < nSrcChars; ++nConverted)
321 : : {
322 : 0 : bool bUndefined = true;
323 : 0 : sal_uInt32 nChar = *pSrcBuf++;
324 [ # # ]: 0 : if (nHighSurrogate == 0)
325 : : {
326 [ # # ]: 0 : if (ImplIsHighSurrogate(nChar))
327 : : {
328 : 0 : nHighSurrogate = (sal_Unicode) nChar;
329 : 0 : continue;
330 : : }
331 : : }
332 [ # # ]: 0 : else if (ImplIsLowSurrogate(nChar))
333 : 0 : nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
334 : : else
335 : : {
336 : 0 : bUndefined = false;
337 : 0 : goto bad_input;
338 : : }
339 : :
340 [ # # ][ # # ]: 0 : if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
[ # # ]
341 : : {
342 : 0 : bUndefined = false;
343 : 0 : goto bad_input;
344 : : }
345 : :
346 [ # # ]: 0 : if (nChar < 0x80)
347 [ # # ]: 0 : if (pDestBufPtr != pDestBufEnd)
348 : 0 : *pDestBufPtr++ = static_cast< char >(nChar);
349 : : else
350 : 0 : goto no_output;
351 : : else
352 : : {
353 : 0 : sal_uInt32 nBytes = 0;
354 : 0 : sal_Int32 nOffset = pBig5Hkscs2001PlaneOffsets[nChar >> 16];
355 [ # # ]: 0 : if (nOffset != -1)
356 : : {
357 : : nOffset
358 : : = pBig5Hkscs2001PageOffsets[nOffset + ((nChar & 0xFF00)
359 : 0 : >> 8)];
360 [ # # ]: 0 : if (nOffset != -1)
361 : : {
362 : 0 : sal_uInt32 nFirstLast = pBig5Hkscs2001Data[nOffset++];
363 : 0 : sal_uInt32 nFirst = nFirstLast & 0xFF;
364 : 0 : sal_uInt32 nLast = nFirstLast >> 8;
365 : 0 : sal_uInt32 nIndex = nChar & 0xFF;
366 [ # # ][ # # ]: 0 : if (nIndex >= nFirst && nIndex <= nLast)
367 : : {
368 : : nBytes
369 : 0 : = pBig5Hkscs2001Data[nOffset + (nIndex - nFirst)];
370 : : }
371 : : }
372 : : }
373 [ # # ]: 0 : if (nBytes == 0)
374 : : {
375 : 0 : sal_uInt32 nIndex1 = nChar >> 8;
376 [ # # ]: 0 : if (nIndex1 < 0x100)
377 : : {
378 : 0 : sal_uInt32 nIndex2 = nChar & 0xFF;
379 : 0 : sal_uInt32 nFirst = pBig5Data[nIndex1].mnLowStart;
380 [ # # ][ # # ]: 0 : if (nIndex2 >= nFirst
381 : 0 : && nIndex2 <= pBig5Data[nIndex1].mnLowEnd)
382 : 0 : nBytes = pBig5Data[nIndex1].
383 : 0 : mpToUniTrailTab[nIndex2 - nFirst];
384 : : }
385 : : }
386 [ # # ]: 0 : if (nBytes == 0)
387 : : {
388 : : ImplDBCSEUDCData const * p
389 : : = static_cast< ImplBig5HkscsConverterData const * >(pData)->
390 : 0 : m_pEudcData;
391 : : sal_uInt32 nCount
392 : : = static_cast< ImplBig5HkscsConverterData const * >(pData)->
393 : 0 : m_nEudcCount;
394 : : sal_uInt32 i;
395 [ # # ]: 0 : for (i = 0; i < nCount; ++i) {
396 [ # # ][ # # ]: 0 : if (nChar >= p->mnUniStart && nChar <= p->mnUniEnd)
397 : : {
398 : 0 : sal_uInt32 nIndex = nChar - p->mnUniStart;
399 : 0 : sal_uInt32 nLeadOff = nIndex / p->mnTrailRangeCount;
400 : 0 : sal_uInt32 nTrailOff = nIndex % p->mnTrailRangeCount;
401 : : sal_uInt32 nSize;
402 : 0 : nBytes = (p->mnLeadStart + nLeadOff) << 8;
403 : 0 : nSize = p->mnTrail1End - p->mnTrail1Start + 1;
404 [ # # ]: 0 : if (nTrailOff < nSize)
405 : : {
406 : 0 : nBytes |= p->mnTrail1Start + nTrailOff;
407 : 0 : break;
408 : : }
409 : 0 : nTrailOff -= nSize;
410 : 0 : nSize = p->mnTrail2End - p->mnTrail2Start + 1;
411 [ # # ]: 0 : if (nTrailOff < nSize)
412 : : {
413 : 0 : nBytes |= p->mnTrail2Start + nTrailOff;
414 : 0 : break;
415 : : }
416 : 0 : nTrailOff -= nSize;
417 : 0 : nBytes |= p->mnTrail3Start + nTrailOff;
418 : 0 : break;
419 : : }
420 : 0 : ++p;
421 : : }
422 : : }
423 [ # # ]: 0 : if (nBytes == 0)
424 : 0 : goto bad_input;
425 [ # # ]: 0 : if (pDestBufEnd - pDestBufPtr >= 2)
426 : : {
427 : 0 : *pDestBufPtr++ = static_cast< char >(nBytes >> 8);
428 : 0 : *pDestBufPtr++ = static_cast< char >(nBytes & 0xFF);
429 : : }
430 : : else
431 : 0 : goto no_output;
432 : : }
433 : 0 : nHighSurrogate = 0;
434 : 0 : continue;
435 : :
436 : : bad_input:
437 [ # # # # ]: 0 : switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
438 : : bUndefined, nChar, nFlags, &pDestBufPtr, pDestBufEnd,
439 [ # # ]: 0 : &nInfo, NULL, 0, NULL))
440 : : {
441 : : case sal::detail::textenc::BAD_INPUT_STOP:
442 : 0 : nHighSurrogate = 0;
443 : 0 : break;
444 : :
445 : : case sal::detail::textenc::BAD_INPUT_CONTINUE:
446 : 0 : nHighSurrogate = 0;
447 : 0 : continue;
448 : :
449 : : case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
450 : 0 : goto no_output;
451 : : }
452 : 0 : break;
453 : :
454 : : no_output:
455 : 0 : --pSrcBuf;
456 : 0 : nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
457 : 0 : break;
458 : : }
459 : :
460 [ # # ][ # # ]: 0 : if (nHighSurrogate != 0
461 : : && (nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
462 : : | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
463 : : == 0)
464 : : {
465 [ # # ]: 0 : if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
466 : 0 : nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
467 : : else
468 [ # # # ]: 0 : switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
469 : : false, 0, nFlags, &pDestBufPtr, pDestBufEnd, &nInfo,
470 [ # # ]: 0 : NULL, 0, NULL))
471 : : {
472 : : case sal::detail::textenc::BAD_INPUT_STOP:
473 : : case sal::detail::textenc::BAD_INPUT_CONTINUE:
474 : 0 : nHighSurrogate = 0;
475 : 0 : break;
476 : :
477 : : case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
478 : 0 : nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
479 : 0 : break;
480 : : }
481 : : }
482 : :
483 [ # # ]: 0 : if (pContext)
484 : : ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate
485 : 0 : = nHighSurrogate;
486 [ # # ]: 0 : if (pInfo)
487 : 0 : *pInfo = nInfo;
488 [ # # ]: 0 : if (pSrcCvtChars)
489 : 0 : *pSrcCvtChars = nConverted;
490 : :
491 : 0 : return pDestBufPtr - pDestBuf;
492 : : }
493 : :
494 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|