xref: /aoo41x/main/sal/textenc/convertbig5hkscs.c (revision 647f063d)
1*647f063dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*647f063dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*647f063dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*647f063dSAndrew Rist  * distributed with this work for additional information
6*647f063dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*647f063dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*647f063dSAndrew Rist  * "License"); you may not use this file except in compliance
9*647f063dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*647f063dSAndrew Rist  *
11*647f063dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*647f063dSAndrew Rist  *
13*647f063dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*647f063dSAndrew Rist  * software distributed under the License is distributed on an
15*647f063dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*647f063dSAndrew Rist  * KIND, either express or implied.  See the License for the
17*647f063dSAndrew Rist  * specific language governing permissions and limitations
18*647f063dSAndrew Rist  * under the License.
19*647f063dSAndrew Rist  *
20*647f063dSAndrew Rist  *************************************************************/
21*647f063dSAndrew Rist 
22*647f063dSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "convertbig5hkscs.h"
25cdf0e10cSrcweir #include "context.h"
26cdf0e10cSrcweir #include "converter.h"
27cdf0e10cSrcweir #include "tenchelp.h"
28cdf0e10cSrcweir #include "unichars.h"
29cdf0e10cSrcweir #include "osl/diagnose.h"
30cdf0e10cSrcweir #include "rtl/alloc.h"
31cdf0e10cSrcweir #include "rtl/textcvt.h"
32cdf0e10cSrcweir #include "sal/types.h"
33cdf0e10cSrcweir 
34cdf0e10cSrcweir typedef struct
35cdf0e10cSrcweir {
36cdf0e10cSrcweir     sal_Int32 m_nRow; /* 0--255; 0 means none */
37cdf0e10cSrcweir } ImplBig5HkscsToUnicodeContext;
38cdf0e10cSrcweir 
ImplCreateBig5HkscsToUnicodeContext(void)39cdf0e10cSrcweir void * ImplCreateBig5HkscsToUnicodeContext(void)
40cdf0e10cSrcweir {
41cdf0e10cSrcweir     void * pContext
42cdf0e10cSrcweir         = rtl_allocateMemory(sizeof (ImplBig5HkscsToUnicodeContext));
43cdf0e10cSrcweir     ((ImplBig5HkscsToUnicodeContext *) pContext)->m_nRow = 0;
44cdf0e10cSrcweir     return pContext;
45cdf0e10cSrcweir }
46cdf0e10cSrcweir 
ImplResetBig5HkscsToUnicodeContext(void * pContext)47cdf0e10cSrcweir void ImplResetBig5HkscsToUnicodeContext(void * pContext)
48cdf0e10cSrcweir {
49cdf0e10cSrcweir     if (pContext)
50cdf0e10cSrcweir         ((ImplBig5HkscsToUnicodeContext *) pContext)->m_nRow = 0;
51cdf0e10cSrcweir }
52cdf0e10cSrcweir 
ImplConvertBig5HkscsToUnicode(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)53cdf0e10cSrcweir sal_Size ImplConvertBig5HkscsToUnicode(ImplTextConverterData const * pData,
54cdf0e10cSrcweir                                        void * pContext,
55cdf0e10cSrcweir                                        sal_Char const * pSrcBuf,
56cdf0e10cSrcweir                                        sal_Size nSrcBytes,
57cdf0e10cSrcweir                                        sal_Unicode * pDestBuf,
58cdf0e10cSrcweir                                        sal_Size nDestChars,
59cdf0e10cSrcweir                                        sal_uInt32 nFlags,
60cdf0e10cSrcweir                                        sal_uInt32 * pInfo,
61cdf0e10cSrcweir                                        sal_Size * pSrcCvtBytes)
62cdf0e10cSrcweir {
63cdf0e10cSrcweir     sal_uInt16 const * pBig5Hkscs2001Data
64cdf0e10cSrcweir         = ((ImplBig5HkscsConverterData const *) pData)->
65cdf0e10cSrcweir               m_pBig5Hkscs2001ToUnicodeData;
66cdf0e10cSrcweir     sal_Int32 const * pBig5Hkscs2001RowOffsets
67cdf0e10cSrcweir         = ((ImplBig5HkscsConverterData const *) pData)->
68cdf0e10cSrcweir               m_pBig5Hkscs2001ToUnicodeRowOffsets;
69cdf0e10cSrcweir     ImplDBCSToUniLeadTab const * pBig5Data
70cdf0e10cSrcweir         = ((ImplBig5HkscsConverterData const *) pData)->
71cdf0e10cSrcweir               m_pBig5ToUnicodeData;
72cdf0e10cSrcweir     sal_Int32 nRow = 0;
73cdf0e10cSrcweir     sal_uInt32 nInfo = 0;
74cdf0e10cSrcweir     sal_Size nConverted = 0;
75cdf0e10cSrcweir     sal_Unicode * pDestBufPtr = pDestBuf;
76cdf0e10cSrcweir     sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
77cdf0e10cSrcweir 
78cdf0e10cSrcweir     if (pContext)
79cdf0e10cSrcweir         nRow = ((ImplBig5HkscsToUnicodeContext *) pContext)->m_nRow;
80cdf0e10cSrcweir 
81cdf0e10cSrcweir     for (; nConverted < nSrcBytes; ++nConverted)
82cdf0e10cSrcweir     {
83cdf0e10cSrcweir         sal_Bool bUndefined = sal_True;
84cdf0e10cSrcweir         sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++;
85cdf0e10cSrcweir         if (nRow == 0)
86cdf0e10cSrcweir             if (nChar < 0x80)
87cdf0e10cSrcweir                 if (pDestBufPtr != pDestBufEnd)
88cdf0e10cSrcweir                     *pDestBufPtr++ = (sal_Unicode) nChar;
89cdf0e10cSrcweir                 else
90cdf0e10cSrcweir                     goto no_output;
91cdf0e10cSrcweir             else if (nChar >= 0x81 && nChar <= 0xFE)
92cdf0e10cSrcweir                 nRow = nChar;
93cdf0e10cSrcweir             else
94cdf0e10cSrcweir             {
95cdf0e10cSrcweir                 bUndefined = sal_False;
96cdf0e10cSrcweir                 goto bad_input;
97cdf0e10cSrcweir             }
98cdf0e10cSrcweir         else
99cdf0e10cSrcweir             if ((nChar >= 0x40 && nChar <= 0x7E)
100cdf0e10cSrcweir                 || (nChar >= 0xA1 && nChar <= 0xFE))
101cdf0e10cSrcweir             {
102cdf0e10cSrcweir                 sal_uInt32 nUnicode = 0xFFFF;
103cdf0e10cSrcweir                 sal_Int32 nOffset = pBig5Hkscs2001RowOffsets[nRow];
104cdf0e10cSrcweir                 sal_uInt32 nFirst=0;
105cdf0e10cSrcweir                 sal_uInt32 nLast=0;
106cdf0e10cSrcweir                 if (nOffset != -1)
107cdf0e10cSrcweir                 {
108cdf0e10cSrcweir                     sal_uInt32 nFirstLast = pBig5Hkscs2001Data[nOffset++];
109cdf0e10cSrcweir                     nFirst = nFirstLast & 0xFF;
110cdf0e10cSrcweir                     nLast = nFirstLast >> 8;
111cdf0e10cSrcweir                     if (nChar >= nFirst && nChar <= nLast)
112cdf0e10cSrcweir                         nUnicode
113cdf0e10cSrcweir                             = pBig5Hkscs2001Data[nOffset + (nChar - nFirst)];
114cdf0e10cSrcweir                 }
115cdf0e10cSrcweir                 if (nUnicode == 0xFFFF)
116cdf0e10cSrcweir                 {
117cdf0e10cSrcweir                     sal_uInt32 nFirst = pBig5Data[nRow].mnTrailStart;
118cdf0e10cSrcweir                     if (nChar >= nFirst
119cdf0e10cSrcweir                         && nChar <= pBig5Data[nRow].mnTrailEnd)
120cdf0e10cSrcweir                     {
121cdf0e10cSrcweir                         nUnicode
122cdf0e10cSrcweir                             = pBig5Data[nRow].mpToUniTrailTab[nChar - nFirst];
123cdf0e10cSrcweir                         if (nUnicode == 0)
124cdf0e10cSrcweir                             nUnicode = 0xFFFF;
125cdf0e10cSrcweir                         OSL_VERIFY(!ImplIsHighSurrogate(nUnicode));
126cdf0e10cSrcweir                     }
127cdf0e10cSrcweir                 }
128cdf0e10cSrcweir                 if (nUnicode == 0xFFFF)
129cdf0e10cSrcweir                 {
130cdf0e10cSrcweir                     ImplDBCSEUDCData const * p
131cdf0e10cSrcweir                         = ((ImplBig5HkscsConverterData const *) pData)->
132cdf0e10cSrcweir                               m_pEudcData;
133cdf0e10cSrcweir                     sal_uInt32 nCount
134cdf0e10cSrcweir                         = ((ImplBig5HkscsConverterData const *) pData)->
135cdf0e10cSrcweir                               m_nEudcCount;
136cdf0e10cSrcweir                     sal_uInt32 i;
137cdf0e10cSrcweir                     for (i = 0; i < nCount; ++i)
138cdf0e10cSrcweir                     {
139cdf0e10cSrcweir                         if (nRow >= p->mnLeadStart && nRow <= p->mnLeadEnd)
140cdf0e10cSrcweir                         {
141cdf0e10cSrcweir                             if (nChar < p->mnTrail1Start)
142cdf0e10cSrcweir                                 break;
143cdf0e10cSrcweir                             if (nChar <= p->mnTrail1End)
144cdf0e10cSrcweir                             {
145cdf0e10cSrcweir                                 nUnicode
146cdf0e10cSrcweir                                     = p->mnUniStart
147cdf0e10cSrcweir                                           + (nRow - p->mnLeadStart)
148cdf0e10cSrcweir                                                 * p->mnTrailRangeCount
149cdf0e10cSrcweir                                           + (nChar - p->mnTrail1Start);
150cdf0e10cSrcweir                                 break;
151cdf0e10cSrcweir                             }
152cdf0e10cSrcweir                             if (p->mnTrailCount < 2
153cdf0e10cSrcweir                                 || nChar < p->mnTrail2Start)
154cdf0e10cSrcweir                                 break;
155cdf0e10cSrcweir                             if (nChar <= p->mnTrail2End)
156cdf0e10cSrcweir                             {
157cdf0e10cSrcweir                                 nUnicode
158cdf0e10cSrcweir                                     = p->mnUniStart
159cdf0e10cSrcweir                                           + (nRow - p->mnLeadStart)
160cdf0e10cSrcweir                                                 * p->mnTrailRangeCount
161cdf0e10cSrcweir                                           + (nChar - p->mnTrail2Start)
162cdf0e10cSrcweir                                           + (p->mnTrail1End - p->mnTrail1Start
163cdf0e10cSrcweir                                                  + 1);
164cdf0e10cSrcweir                                 break;
165cdf0e10cSrcweir                             }
166cdf0e10cSrcweir                             if (p->mnTrailCount < 3
167cdf0e10cSrcweir                                 || nChar < p->mnTrail3Start)
168cdf0e10cSrcweir                                 break;
169cdf0e10cSrcweir                             if (nChar <= p->mnTrail3End)
170cdf0e10cSrcweir                             {
171cdf0e10cSrcweir                                 nUnicode
172cdf0e10cSrcweir                                     = p->mnUniStart
173cdf0e10cSrcweir                                           + (nRow - p->mnLeadStart)
174cdf0e10cSrcweir                                                 * p->mnTrailRangeCount
175cdf0e10cSrcweir                                           + (nChar - p->mnTrail3Start)
176cdf0e10cSrcweir                                           + (p->mnTrail1End - p->mnTrail1Start
177cdf0e10cSrcweir                                                  + 1)
178cdf0e10cSrcweir                                           + (p->mnTrail2End - p->mnTrail2Start
179cdf0e10cSrcweir                                                  + 1);
180cdf0e10cSrcweir                                 break;
181cdf0e10cSrcweir                             }
182cdf0e10cSrcweir                             break;
183cdf0e10cSrcweir                         }
184cdf0e10cSrcweir                         ++p;
185cdf0e10cSrcweir                     }
186cdf0e10cSrcweir                     OSL_VERIFY(!ImplIsHighSurrogate(nUnicode));
187cdf0e10cSrcweir                 }
188cdf0e10cSrcweir                 if (nUnicode == 0xFFFF)
189cdf0e10cSrcweir                     goto bad_input;
190cdf0e10cSrcweir                 if (ImplIsHighSurrogate(nUnicode))
191cdf0e10cSrcweir                     if (pDestBufEnd - pDestBufPtr >= 2)
192cdf0e10cSrcweir                     {
193cdf0e10cSrcweir                         nOffset += nLast - nFirst + 1;
194cdf0e10cSrcweir                         nFirst = pBig5Hkscs2001Data[nOffset++];
195cdf0e10cSrcweir                         *pDestBufPtr++ = (sal_Unicode) nUnicode;
196cdf0e10cSrcweir                         *pDestBufPtr++
197cdf0e10cSrcweir                             = (sal_Unicode) pBig5Hkscs2001Data[
198cdf0e10cSrcweir                                                 nOffset + (nChar - nFirst)];
199cdf0e10cSrcweir                     }
200cdf0e10cSrcweir                     else
201cdf0e10cSrcweir                         goto no_output;
202cdf0e10cSrcweir                 else
203cdf0e10cSrcweir                     if (pDestBufPtr != pDestBufEnd)
204cdf0e10cSrcweir                         *pDestBufPtr++ = (sal_Unicode) nUnicode;
205cdf0e10cSrcweir                     else
206cdf0e10cSrcweir                         goto no_output;
207cdf0e10cSrcweir                 nRow = 0;
208cdf0e10cSrcweir             }
209cdf0e10cSrcweir             else
210cdf0e10cSrcweir             {
211cdf0e10cSrcweir                 bUndefined = sal_False;
212cdf0e10cSrcweir                 goto bad_input;
213cdf0e10cSrcweir             }
214cdf0e10cSrcweir         continue;
215cdf0e10cSrcweir 
216cdf0e10cSrcweir     bad_input:
217cdf0e10cSrcweir         switch (ImplHandleBadInputTextToUnicodeConversion(
218cdf0e10cSrcweir                     bUndefined, sal_True, 0, nFlags, &pDestBufPtr, pDestBufEnd,
219cdf0e10cSrcweir                     &nInfo))
220cdf0e10cSrcweir         {
221cdf0e10cSrcweir         case IMPL_BAD_INPUT_STOP:
222cdf0e10cSrcweir             nRow = 0;
223cdf0e10cSrcweir             break;
224cdf0e10cSrcweir 
225cdf0e10cSrcweir         case IMPL_BAD_INPUT_CONTINUE:
226cdf0e10cSrcweir             nRow = 0;
227cdf0e10cSrcweir             continue;
228cdf0e10cSrcweir 
229cdf0e10cSrcweir         case IMPL_BAD_INPUT_NO_OUTPUT:
230cdf0e10cSrcweir             goto no_output;
231cdf0e10cSrcweir         }
232cdf0e10cSrcweir         break;
233cdf0e10cSrcweir 
234cdf0e10cSrcweir     no_output:
235cdf0e10cSrcweir         --pSrcBuf;
236cdf0e10cSrcweir         nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
237cdf0e10cSrcweir         break;
238cdf0e10cSrcweir     }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir     if (nRow != 0
241cdf0e10cSrcweir         && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
242cdf0e10cSrcweir                          | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
243cdf0e10cSrcweir                == 0)
244cdf0e10cSrcweir     {
245cdf0e10cSrcweir         if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
246cdf0e10cSrcweir             nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
247cdf0e10cSrcweir         else
248cdf0e10cSrcweir             switch (ImplHandleBadInputTextToUnicodeConversion(
249cdf0e10cSrcweir                         sal_False, sal_True, 0, nFlags, &pDestBufPtr,
250cdf0e10cSrcweir                         pDestBufEnd, &nInfo))
251cdf0e10cSrcweir             {
252cdf0e10cSrcweir             case IMPL_BAD_INPUT_STOP:
253cdf0e10cSrcweir             case IMPL_BAD_INPUT_CONTINUE:
254cdf0e10cSrcweir                 nRow = 0;
255cdf0e10cSrcweir                 break;
256cdf0e10cSrcweir 
257cdf0e10cSrcweir             case IMPL_BAD_INPUT_NO_OUTPUT:
258cdf0e10cSrcweir                 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
259cdf0e10cSrcweir                 break;
260cdf0e10cSrcweir             }
261cdf0e10cSrcweir     }
262cdf0e10cSrcweir 
263cdf0e10cSrcweir     if (pContext)
264cdf0e10cSrcweir         ((ImplBig5HkscsToUnicodeContext *) pContext)->m_nRow = nRow;
265cdf0e10cSrcweir     if (pInfo)
266cdf0e10cSrcweir         *pInfo = nInfo;
267cdf0e10cSrcweir     if (pSrcCvtBytes)
268cdf0e10cSrcweir         *pSrcCvtBytes = nConverted;
269cdf0e10cSrcweir 
270cdf0e10cSrcweir     return pDestBufPtr - pDestBuf;
271cdf0e10cSrcweir }
272cdf0e10cSrcweir 
ImplConvertUnicodeToBig5Hkscs(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)273cdf0e10cSrcweir sal_Size ImplConvertUnicodeToBig5Hkscs(ImplTextConverterData const * pData,
274cdf0e10cSrcweir                                        void * pContext,
275cdf0e10cSrcweir                                        sal_Unicode const * pSrcBuf,
276cdf0e10cSrcweir                                        sal_Size nSrcChars,
277cdf0e10cSrcweir                                        sal_Char * pDestBuf,
278cdf0e10cSrcweir                                        sal_Size nDestBytes,
279cdf0e10cSrcweir                                        sal_uInt32 nFlags,
280cdf0e10cSrcweir                                        sal_uInt32 * pInfo,
281cdf0e10cSrcweir                                        sal_Size * pSrcCvtChars)
282cdf0e10cSrcweir {
283cdf0e10cSrcweir     sal_uInt16 const * pBig5Hkscs2001Data
284cdf0e10cSrcweir         = ((ImplBig5HkscsConverterData const *) pData)->
285cdf0e10cSrcweir               m_pUnicodeToBig5Hkscs2001Data;
286cdf0e10cSrcweir     sal_Int32 const * pBig5Hkscs2001PageOffsets
287cdf0e10cSrcweir         = ((ImplBig5HkscsConverterData const *) pData)->
288cdf0e10cSrcweir               m_pUnicodeToBig5Hkscs2001PageOffsets;
289cdf0e10cSrcweir     sal_Int32 const * pBig5Hkscs2001PlaneOffsets
290cdf0e10cSrcweir         = ((ImplBig5HkscsConverterData const *) pData)->
291cdf0e10cSrcweir               m_pUnicodeToBig5Hkscs2001PlaneOffsets;
292cdf0e10cSrcweir     ImplUniToDBCSHighTab const * pBig5Data
293cdf0e10cSrcweir         = ((ImplBig5HkscsConverterData const *) pData)->
294cdf0e10cSrcweir               m_pUnicodeToBig5Data;
295cdf0e10cSrcweir     sal_Unicode nHighSurrogate = 0;
296cdf0e10cSrcweir     sal_uInt32 nInfo = 0;
297cdf0e10cSrcweir     sal_Size nConverted = 0;
298cdf0e10cSrcweir     sal_Char * pDestBufPtr = pDestBuf;
299cdf0e10cSrcweir     sal_Char * pDestBufEnd = pDestBuf + nDestBytes;
300cdf0e10cSrcweir 
301cdf0e10cSrcweir     if (pContext)
302cdf0e10cSrcweir         nHighSurrogate
303cdf0e10cSrcweir             = ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate;
304cdf0e10cSrcweir 
305cdf0e10cSrcweir     for (; nConverted < nSrcChars; ++nConverted)
306cdf0e10cSrcweir     {
307cdf0e10cSrcweir         sal_Bool bUndefined = sal_True;
308cdf0e10cSrcweir         sal_uInt32 nChar = *pSrcBuf++;
309cdf0e10cSrcweir         if (nHighSurrogate == 0)
310cdf0e10cSrcweir         {
311cdf0e10cSrcweir             if (ImplIsHighSurrogate(nChar))
312cdf0e10cSrcweir             {
313cdf0e10cSrcweir                 nHighSurrogate = (sal_Unicode) nChar;
314cdf0e10cSrcweir                 continue;
315cdf0e10cSrcweir             }
316cdf0e10cSrcweir         }
317cdf0e10cSrcweir         else if (ImplIsLowSurrogate(nChar))
318cdf0e10cSrcweir             nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
319cdf0e10cSrcweir         else
320cdf0e10cSrcweir         {
321cdf0e10cSrcweir             bUndefined = sal_False;
322cdf0e10cSrcweir             goto bad_input;
323cdf0e10cSrcweir         }
324cdf0e10cSrcweir 
325cdf0e10cSrcweir         if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
326cdf0e10cSrcweir         {
327cdf0e10cSrcweir             bUndefined = sal_False;
328cdf0e10cSrcweir             goto bad_input;
329cdf0e10cSrcweir         }
330cdf0e10cSrcweir 
331cdf0e10cSrcweir         if (nChar < 0x80)
332cdf0e10cSrcweir             if (pDestBufPtr != pDestBufEnd)
333cdf0e10cSrcweir                 *pDestBufPtr++ = (sal_Char) nChar;
334cdf0e10cSrcweir             else
335cdf0e10cSrcweir                 goto no_output;
336cdf0e10cSrcweir         else
337cdf0e10cSrcweir         {
338cdf0e10cSrcweir             sal_uInt32 nBytes = 0;
339cdf0e10cSrcweir             sal_Int32 nOffset = pBig5Hkscs2001PlaneOffsets[nChar >> 16];
340cdf0e10cSrcweir             if (nOffset != -1)
341cdf0e10cSrcweir             {
342cdf0e10cSrcweir                 nOffset
343cdf0e10cSrcweir                     = pBig5Hkscs2001PageOffsets[nOffset + ((nChar & 0xFF00)
344cdf0e10cSrcweir                                                                >> 8)];
345cdf0e10cSrcweir                 if (nOffset != -1)
346cdf0e10cSrcweir                 {
347cdf0e10cSrcweir                     sal_uInt32 nFirstLast = pBig5Hkscs2001Data[nOffset++];
348cdf0e10cSrcweir                     sal_uInt32 nFirst = nFirstLast & 0xFF;
349cdf0e10cSrcweir                     sal_uInt32 nLast = nFirstLast >> 8;
350cdf0e10cSrcweir                     sal_uInt32 nIndex = nChar & 0xFF;
351cdf0e10cSrcweir                     if (nIndex >= nFirst && nIndex <= nLast)
352cdf0e10cSrcweir                     {
353cdf0e10cSrcweir                         nBytes
354cdf0e10cSrcweir                             = pBig5Hkscs2001Data[nOffset + (nIndex - nFirst)];
355cdf0e10cSrcweir                     }
356cdf0e10cSrcweir                 }
357cdf0e10cSrcweir             }
358cdf0e10cSrcweir             if (nBytes == 0)
359cdf0e10cSrcweir             {
360cdf0e10cSrcweir                 sal_uInt32 nIndex1 = nChar >> 8;
361cdf0e10cSrcweir                 if (nIndex1 < 0x100)
362cdf0e10cSrcweir                 {
363cdf0e10cSrcweir                     sal_uInt32 nIndex2 = nChar & 0xFF;
364cdf0e10cSrcweir                     sal_uInt32 nFirst = pBig5Data[nIndex1].mnLowStart;
365cdf0e10cSrcweir                     if (nIndex2 >= nFirst
366cdf0e10cSrcweir                         && nIndex2 <= pBig5Data[nIndex1].mnLowEnd)
367cdf0e10cSrcweir                         nBytes = pBig5Data[nIndex1].
368cdf0e10cSrcweir                                      mpToUniTrailTab[nIndex2 - nFirst];
369cdf0e10cSrcweir                 }
370cdf0e10cSrcweir             }
371cdf0e10cSrcweir             if (nBytes == 0)
372cdf0e10cSrcweir             {
373cdf0e10cSrcweir                 ImplDBCSEUDCData const * p
374cdf0e10cSrcweir                     = ((ImplBig5HkscsConverterData const *) pData)->
375cdf0e10cSrcweir                           m_pEudcData;
376cdf0e10cSrcweir                 sal_uInt32 nCount
377cdf0e10cSrcweir                     = ((ImplBig5HkscsConverterData const *) pData)->
378cdf0e10cSrcweir                           m_nEudcCount;
379cdf0e10cSrcweir                 sal_uInt32 i;
380cdf0e10cSrcweir                 for (i = 0; i < nCount; ++i) {
381cdf0e10cSrcweir                     if (nChar >= p->mnUniStart && nChar <= p->mnUniEnd)
382cdf0e10cSrcweir                     {
383cdf0e10cSrcweir                         sal_uInt32 nIndex = nChar - p->mnUniStart;
384cdf0e10cSrcweir                         sal_uInt32 nLeadOff = nIndex / p->mnTrailRangeCount;
385cdf0e10cSrcweir                         sal_uInt32 nTrailOff = nIndex % p->mnTrailRangeCount;
386cdf0e10cSrcweir                         sal_uInt32 nSize;
387cdf0e10cSrcweir                         nBytes = (p->mnLeadStart + nLeadOff) << 8;
388cdf0e10cSrcweir                         nSize = p->mnTrail1End - p->mnTrail1Start + 1;
389cdf0e10cSrcweir                         if (nTrailOff < nSize)
390cdf0e10cSrcweir                         {
391cdf0e10cSrcweir                             nBytes |= p->mnTrail1Start + nTrailOff;
392cdf0e10cSrcweir                             break;
393cdf0e10cSrcweir                         }
394cdf0e10cSrcweir                         nTrailOff -= nSize;
395cdf0e10cSrcweir                         nSize = p->mnTrail2End - p->mnTrail2Start + 1;
396cdf0e10cSrcweir                         if (nTrailOff < nSize)
397cdf0e10cSrcweir                         {
398cdf0e10cSrcweir                             nBytes |= p->mnTrail2Start + nTrailOff;
399cdf0e10cSrcweir                             break;
400cdf0e10cSrcweir                         }
401cdf0e10cSrcweir                         nTrailOff -= nSize;
402cdf0e10cSrcweir                         nBytes |= p->mnTrail3Start + nTrailOff;
403cdf0e10cSrcweir                         break;
404cdf0e10cSrcweir                     }
405cdf0e10cSrcweir                     ++p;
406cdf0e10cSrcweir                 }
407cdf0e10cSrcweir             }
408cdf0e10cSrcweir             if (nBytes == 0)
409cdf0e10cSrcweir                 goto bad_input;
410cdf0e10cSrcweir             if (pDestBufEnd - pDestBufPtr >= 2)
411cdf0e10cSrcweir             {
412cdf0e10cSrcweir                 *pDestBufPtr++ = (sal_Char) (nBytes >> 8);
413cdf0e10cSrcweir                 *pDestBufPtr++ = (sal_Char) (nBytes & 0xFF);
414cdf0e10cSrcweir             }
415cdf0e10cSrcweir             else
416cdf0e10cSrcweir                 goto no_output;
417cdf0e10cSrcweir         }
418cdf0e10cSrcweir         nHighSurrogate = 0;
419cdf0e10cSrcweir         continue;
420cdf0e10cSrcweir 
421cdf0e10cSrcweir     bad_input:
422cdf0e10cSrcweir         switch (ImplHandleBadInputUnicodeToTextConversion(bUndefined,
423cdf0e10cSrcweir                                                           nChar,
424cdf0e10cSrcweir                                                           nFlags,
425cdf0e10cSrcweir                                                           &pDestBufPtr,
426cdf0e10cSrcweir                                                           pDestBufEnd,
427cdf0e10cSrcweir                                                           &nInfo,
428cdf0e10cSrcweir                                                           NULL,
429cdf0e10cSrcweir                                                           0,
430cdf0e10cSrcweir                                                           NULL))
431cdf0e10cSrcweir         {
432cdf0e10cSrcweir         case IMPL_BAD_INPUT_STOP:
433cdf0e10cSrcweir             nHighSurrogate = 0;
434cdf0e10cSrcweir             break;
435cdf0e10cSrcweir 
436cdf0e10cSrcweir         case IMPL_BAD_INPUT_CONTINUE:
437cdf0e10cSrcweir             nHighSurrogate = 0;
438cdf0e10cSrcweir             continue;
439cdf0e10cSrcweir 
440cdf0e10cSrcweir         case IMPL_BAD_INPUT_NO_OUTPUT:
441cdf0e10cSrcweir             goto no_output;
442cdf0e10cSrcweir         }
443cdf0e10cSrcweir         break;
444cdf0e10cSrcweir 
445cdf0e10cSrcweir     no_output:
446cdf0e10cSrcweir         --pSrcBuf;
447cdf0e10cSrcweir         nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
448cdf0e10cSrcweir         break;
449cdf0e10cSrcweir     }
450cdf0e10cSrcweir 
451cdf0e10cSrcweir     if (nHighSurrogate != 0
452cdf0e10cSrcweir         && (nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
453cdf0e10cSrcweir                          | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
454cdf0e10cSrcweir                == 0)
455cdf0e10cSrcweir     {
456cdf0e10cSrcweir         if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
457cdf0e10cSrcweir             nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
458cdf0e10cSrcweir         else
459cdf0e10cSrcweir             switch (ImplHandleBadInputUnicodeToTextConversion(sal_False,
460cdf0e10cSrcweir                                                               0,
461cdf0e10cSrcweir                                                               nFlags,
462cdf0e10cSrcweir                                                               &pDestBufPtr,
463cdf0e10cSrcweir                                                               pDestBufEnd,
464cdf0e10cSrcweir                                                               &nInfo,
465cdf0e10cSrcweir                                                               NULL,
466cdf0e10cSrcweir                                                               0,
467cdf0e10cSrcweir                                                               NULL))
468cdf0e10cSrcweir             {
469cdf0e10cSrcweir             case IMPL_BAD_INPUT_STOP:
470cdf0e10cSrcweir             case IMPL_BAD_INPUT_CONTINUE:
471cdf0e10cSrcweir                 nHighSurrogate = 0;
472cdf0e10cSrcweir                 break;
473cdf0e10cSrcweir 
474cdf0e10cSrcweir             case IMPL_BAD_INPUT_NO_OUTPUT:
475cdf0e10cSrcweir                 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
476cdf0e10cSrcweir                 break;
477cdf0e10cSrcweir             }
478cdf0e10cSrcweir     }
479cdf0e10cSrcweir 
480cdf0e10cSrcweir     if (pContext)
481cdf0e10cSrcweir         ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate
482cdf0e10cSrcweir             = nHighSurrogate;
483cdf0e10cSrcweir     if (pInfo)
484cdf0e10cSrcweir         *pInfo = nInfo;
485cdf0e10cSrcweir     if (pSrcCvtChars)
486cdf0e10cSrcweir         *pSrcCvtChars = nConverted;
487cdf0e10cSrcweir 
488cdf0e10cSrcweir     return pDestBufPtr - pDestBuf;
489cdf0e10cSrcweir }
490