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