1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 #include "convertbig5hkscs.h"
30 #include "converter.h"
33 #include "osl/diagnose.h"
34 #include "rtl/alloc.h"
35 #include "rtl/textcvt.h"
36 #include "sal/types.h"
40 sal_Int32 m_nRow
; /* 0--255; 0 means none */
41 } ImplBig5HkscsToUnicodeContext
;
43 void * ImplCreateBig5HkscsToUnicodeContext(void)
46 = rtl_allocateMemory(sizeof (ImplBig5HkscsToUnicodeContext
));
47 ((ImplBig5HkscsToUnicodeContext
*) pContext
)->m_nRow
= 0;
51 void ImplResetBig5HkscsToUnicodeContext(void * pContext
)
54 ((ImplBig5HkscsToUnicodeContext
*) pContext
)->m_nRow
= 0;
57 sal_Size
ImplConvertBig5HkscsToUnicode(ImplTextConverterData
const * pData
,
59 sal_Char
const * pSrcBuf
,
61 sal_Unicode
* pDestBuf
,
65 sal_Size
* pSrcCvtBytes
)
67 sal_uInt16
const * pBig5Hkscs2001Data
68 = ((ImplBig5HkscsConverterData
const *) pData
)->
69 m_pBig5Hkscs2001ToUnicodeData
;
70 sal_Int32
const * pBig5Hkscs2001RowOffsets
71 = ((ImplBig5HkscsConverterData
const *) pData
)->
72 m_pBig5Hkscs2001ToUnicodeRowOffsets
;
73 ImplDBCSToUniLeadTab
const * pBig5Data
74 = ((ImplBig5HkscsConverterData
const *) pData
)->
78 sal_Size nConverted
= 0;
79 sal_Unicode
* pDestBufPtr
= pDestBuf
;
80 sal_Unicode
* pDestBufEnd
= pDestBuf
+ nDestChars
;
83 nRow
= ((ImplBig5HkscsToUnicodeContext
*) pContext
)->m_nRow
;
85 for (; nConverted
< nSrcBytes
; ++nConverted
)
87 sal_Bool bUndefined
= sal_True
;
88 sal_uInt32 nChar
= *(sal_uChar
const *) pSrcBuf
++;
91 if (pDestBufPtr
!= pDestBufEnd
)
92 *pDestBufPtr
++ = (sal_Unicode
) nChar
;
95 else if (nChar
>= 0x81 && nChar
<= 0xFE)
99 bUndefined
= sal_False
;
103 if ((nChar
>= 0x40 && nChar
<= 0x7E)
104 || (nChar
>= 0xA1 && nChar
<= 0xFE))
106 sal_uInt32 nUnicode
= 0xFFFF;
107 sal_Int32 nOffset
= pBig5Hkscs2001RowOffsets
[nRow
];
112 sal_uInt32 nFirstLast
= pBig5Hkscs2001Data
[nOffset
++];
113 nFirst
= nFirstLast
& 0xFF;
114 nLast
= nFirstLast
>> 8;
115 if (nChar
>= nFirst
&& nChar
<= nLast
)
117 = pBig5Hkscs2001Data
[nOffset
+ (nChar
- nFirst
)];
119 if (nUnicode
== 0xFFFF)
121 sal_uInt32 nFirst
= pBig5Data
[nRow
].mnTrailStart
;
123 && nChar
<= pBig5Data
[nRow
].mnTrailEnd
)
126 = pBig5Data
[nRow
].mpToUniTrailTab
[nChar
- nFirst
];
129 OSL_VERIFY(!ImplIsHighSurrogate(nUnicode
));
132 if (nUnicode
== 0xFFFF)
134 ImplDBCSEUDCData
const * p
135 = ((ImplBig5HkscsConverterData
const *) pData
)->
138 = ((ImplBig5HkscsConverterData
const *) pData
)->
141 for (i
= 0; i
< nCount
; ++i
)
143 if (nRow
>= p
->mnLeadStart
&& nRow
<= p
->mnLeadEnd
)
145 if (nChar
< p
->mnTrail1Start
)
147 if (nChar
<= p
->mnTrail1End
)
151 + (nRow
- p
->mnLeadStart
)
152 * p
->mnTrailRangeCount
153 + (nChar
- p
->mnTrail1Start
);
156 if (p
->mnTrailCount
< 2
157 || nChar
< p
->mnTrail2Start
)
159 if (nChar
<= p
->mnTrail2End
)
163 + (nRow
- p
->mnLeadStart
)
164 * p
->mnTrailRangeCount
165 + (nChar
- p
->mnTrail2Start
)
166 + (p
->mnTrail1End
- p
->mnTrail1Start
170 if (p
->mnTrailCount
< 3
171 || nChar
< p
->mnTrail3Start
)
173 if (nChar
<= p
->mnTrail3End
)
177 + (nRow
- p
->mnLeadStart
)
178 * p
->mnTrailRangeCount
179 + (nChar
- p
->mnTrail3Start
)
180 + (p
->mnTrail1End
- p
->mnTrail1Start
182 + (p
->mnTrail2End
- p
->mnTrail2Start
190 OSL_VERIFY(!ImplIsHighSurrogate(nUnicode
));
192 if (nUnicode
== 0xFFFF)
194 if (ImplIsHighSurrogate(nUnicode
))
195 if (pDestBufEnd
- pDestBufPtr
>= 2)
197 nOffset
+= nLast
- nFirst
+ 1;
198 nFirst
= pBig5Hkscs2001Data
[nOffset
++];
199 *pDestBufPtr
++ = (sal_Unicode
) nUnicode
;
201 = (sal_Unicode
) pBig5Hkscs2001Data
[
202 nOffset
+ (nChar
- nFirst
)];
207 if (pDestBufPtr
!= pDestBufEnd
)
208 *pDestBufPtr
++ = (sal_Unicode
) nUnicode
;
215 bUndefined
= sal_False
;
221 switch (ImplHandleBadInputTextToUnicodeConversion(
222 bUndefined
, sal_True
, 0, nFlags
, &pDestBufPtr
, pDestBufEnd
,
225 case IMPL_BAD_INPUT_STOP
:
229 case IMPL_BAD_INPUT_CONTINUE
:
233 case IMPL_BAD_INPUT_NO_OUTPUT
:
240 nInfo
|= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL
;
245 && (nInfo
& (RTL_TEXTTOUNICODE_INFO_ERROR
246 | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL
))
249 if ((nFlags
& RTL_TEXTTOUNICODE_FLAGS_FLUSH
) == 0)
250 nInfo
|= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL
;
252 switch (ImplHandleBadInputTextToUnicodeConversion(
253 sal_False
, sal_True
, 0, nFlags
, &pDestBufPtr
,
254 pDestBufEnd
, &nInfo
))
256 case IMPL_BAD_INPUT_STOP
:
257 case IMPL_BAD_INPUT_CONTINUE
:
261 case IMPL_BAD_INPUT_NO_OUTPUT
:
262 nInfo
|= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL
;
268 ((ImplBig5HkscsToUnicodeContext
*) pContext
)->m_nRow
= nRow
;
272 *pSrcCvtBytes
= nConverted
;
274 return pDestBufPtr
- pDestBuf
;
277 sal_Size
ImplConvertUnicodeToBig5Hkscs(ImplTextConverterData
const * pData
,
279 sal_Unicode
const * pSrcBuf
,
285 sal_Size
* pSrcCvtChars
)
287 sal_uInt16
const * pBig5Hkscs2001Data
288 = ((ImplBig5HkscsConverterData
const *) pData
)->
289 m_pUnicodeToBig5Hkscs2001Data
;
290 sal_Int32
const * pBig5Hkscs2001PageOffsets
291 = ((ImplBig5HkscsConverterData
const *) pData
)->
292 m_pUnicodeToBig5Hkscs2001PageOffsets
;
293 sal_Int32
const * pBig5Hkscs2001PlaneOffsets
294 = ((ImplBig5HkscsConverterData
const *) pData
)->
295 m_pUnicodeToBig5Hkscs2001PlaneOffsets
;
296 ImplUniToDBCSHighTab
const * pBig5Data
297 = ((ImplBig5HkscsConverterData
const *) pData
)->
298 m_pUnicodeToBig5Data
;
299 sal_Unicode nHighSurrogate
= 0;
300 sal_uInt32 nInfo
= 0;
301 sal_Size nConverted
= 0;
302 sal_Char
* pDestBufPtr
= pDestBuf
;
303 sal_Char
* pDestBufEnd
= pDestBuf
+ nDestBytes
;
307 = ((ImplUnicodeToTextContext
*) pContext
)->m_nHighSurrogate
;
309 for (; nConverted
< nSrcChars
; ++nConverted
)
311 sal_Bool bUndefined
= sal_True
;
312 sal_uInt32 nChar
= *pSrcBuf
++;
313 if (nHighSurrogate
== 0)
315 if (ImplIsHighSurrogate(nChar
))
317 nHighSurrogate
= (sal_Unicode
) nChar
;
321 else if (ImplIsLowSurrogate(nChar
))
322 nChar
= ImplCombineSurrogates(nHighSurrogate
, nChar
);
325 bUndefined
= sal_False
;
329 if (ImplIsLowSurrogate(nChar
) || ImplIsNoncharacter(nChar
))
331 bUndefined
= sal_False
;
336 if (pDestBufPtr
!= pDestBufEnd
)
337 *pDestBufPtr
++ = (sal_Char
) nChar
;
342 sal_uInt32 nBytes
= 0;
343 sal_Int32 nOffset
= pBig5Hkscs2001PlaneOffsets
[nChar
>> 16];
347 = pBig5Hkscs2001PageOffsets
[nOffset
+ ((nChar
& 0xFF00)
351 sal_uInt32 nFirstLast
= pBig5Hkscs2001Data
[nOffset
++];
352 sal_uInt32 nFirst
= nFirstLast
& 0xFF;
353 sal_uInt32 nLast
= nFirstLast
>> 8;
354 sal_uInt32 nIndex
= nChar
& 0xFF;
355 if (nIndex
>= nFirst
&& nIndex
<= nLast
)
358 = pBig5Hkscs2001Data
[nOffset
+ (nIndex
- nFirst
)];
364 sal_uInt32 nIndex1
= nChar
>> 8;
367 sal_uInt32 nIndex2
= nChar
& 0xFF;
368 sal_uInt32 nFirst
= pBig5Data
[nIndex1
].mnLowStart
;
369 if (nIndex2
>= nFirst
370 && nIndex2
<= pBig5Data
[nIndex1
].mnLowEnd
)
371 nBytes
= pBig5Data
[nIndex1
].
372 mpToUniTrailTab
[nIndex2
- nFirst
];
377 ImplDBCSEUDCData
const * p
378 = ((ImplBig5HkscsConverterData
const *) pData
)->
381 = ((ImplBig5HkscsConverterData
const *) pData
)->
384 for (i
= 0; i
< nCount
; ++i
) {
385 if (nChar
>= p
->mnUniStart
&& nChar
<= p
->mnUniEnd
)
387 sal_uInt32 nIndex
= nChar
- p
->mnUniStart
;
388 sal_uInt32 nLeadOff
= nIndex
/ p
->mnTrailRangeCount
;
389 sal_uInt32 nTrailOff
= nIndex
% p
->mnTrailRangeCount
;
391 nBytes
= (p
->mnLeadStart
+ nLeadOff
) << 8;
392 nSize
= p
->mnTrail1End
- p
->mnTrail1Start
+ 1;
393 if (nTrailOff
< nSize
)
395 nBytes
|= p
->mnTrail1Start
+ nTrailOff
;
399 nSize
= p
->mnTrail2End
- p
->mnTrail2Start
+ 1;
400 if (nTrailOff
< nSize
)
402 nBytes
|= p
->mnTrail2Start
+ nTrailOff
;
406 nBytes
|= p
->mnTrail3Start
+ nTrailOff
;
414 if (pDestBufEnd
- pDestBufPtr
>= 2)
416 *pDestBufPtr
++ = (sal_Char
) (nBytes
>> 8);
417 *pDestBufPtr
++ = (sal_Char
) (nBytes
& 0xFF);
426 switch (ImplHandleBadInputUnicodeToTextConversion(bUndefined
,
436 case IMPL_BAD_INPUT_STOP
:
440 case IMPL_BAD_INPUT_CONTINUE
:
444 case IMPL_BAD_INPUT_NO_OUTPUT
:
451 nInfo
|= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
;
455 if (nHighSurrogate
!= 0
456 && (nInfo
& (RTL_UNICODETOTEXT_INFO_ERROR
457 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
))
460 if ((nFlags
& RTL_UNICODETOTEXT_FLAGS_FLUSH
) != 0)
461 nInfo
|= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL
;
463 switch (ImplHandleBadInputUnicodeToTextConversion(sal_False
,
473 case IMPL_BAD_INPUT_STOP
:
474 case IMPL_BAD_INPUT_CONTINUE
:
478 case IMPL_BAD_INPUT_NO_OUTPUT
:
479 nInfo
|= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
;
485 ((ImplUnicodeToTextContext
*) pContext
)->m_nHighSurrogate
490 *pSrcCvtChars
= nConverted
;
492 return pDestBufPtr
- pDestBuf
;