xref: /aoo41x/main/sal/textenc/convertgb18030.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 "convertgb18030.h"
25cdf0e10cSrcweir #include "context.h"
26cdf0e10cSrcweir #include "converter.h"
27cdf0e10cSrcweir #include "tenchelp.h"
28cdf0e10cSrcweir #include "unichars.h"
29cdf0e10cSrcweir #include "rtl/alloc.h"
30cdf0e10cSrcweir #include "rtl/textcvt.h"
31cdf0e10cSrcweir #include "sal/types.h"
32cdf0e10cSrcweir 
33cdf0e10cSrcweir typedef enum
34cdf0e10cSrcweir {
35cdf0e10cSrcweir     IMPL_GB_18030_TO_UNICODE_STATE_0,
36cdf0e10cSrcweir     IMPL_GB_18030_TO_UNICODE_STATE_1,
37cdf0e10cSrcweir     IMPL_GB_18030_TO_UNICODE_STATE_2,
38cdf0e10cSrcweir     IMPL_GB_18030_TO_UNICODE_STATE_3
39cdf0e10cSrcweir } ImplGb18030ToUnicodeState;
40cdf0e10cSrcweir 
41cdf0e10cSrcweir typedef struct
42cdf0e10cSrcweir {
43cdf0e10cSrcweir     ImplGb18030ToUnicodeState m_eState;
44cdf0e10cSrcweir     sal_uInt32 m_nCode;
45cdf0e10cSrcweir } ImplGb18030ToUnicodeContext;
46cdf0e10cSrcweir 
ImplCreateGb18030ToUnicodeContext(void)47cdf0e10cSrcweir void * ImplCreateGb18030ToUnicodeContext(void)
48cdf0e10cSrcweir {
49cdf0e10cSrcweir     void * pContext
50cdf0e10cSrcweir         = rtl_allocateMemory(sizeof (ImplGb18030ToUnicodeContext));
51cdf0e10cSrcweir     ((ImplGb18030ToUnicodeContext *) pContext)->m_eState
52cdf0e10cSrcweir         = IMPL_GB_18030_TO_UNICODE_STATE_0;
53cdf0e10cSrcweir     return pContext;
54cdf0e10cSrcweir }
55cdf0e10cSrcweir 
ImplResetGb18030ToUnicodeContext(void * pContext)56cdf0e10cSrcweir void ImplResetGb18030ToUnicodeContext(void * pContext)
57cdf0e10cSrcweir {
58cdf0e10cSrcweir     if (pContext)
59cdf0e10cSrcweir         ((ImplGb18030ToUnicodeContext *) pContext)->m_eState
60cdf0e10cSrcweir             = IMPL_GB_18030_TO_UNICODE_STATE_0;
61cdf0e10cSrcweir }
62cdf0e10cSrcweir 
ImplConvertGb18030ToUnicode(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)63cdf0e10cSrcweir sal_Size ImplConvertGb18030ToUnicode(ImplTextConverterData const * pData,
64cdf0e10cSrcweir                                      void * pContext,
65cdf0e10cSrcweir                                      sal_Char const * pSrcBuf,
66cdf0e10cSrcweir                                      sal_Size nSrcBytes,
67cdf0e10cSrcweir                                      sal_Unicode * pDestBuf,
68cdf0e10cSrcweir                                      sal_Size nDestChars,
69cdf0e10cSrcweir                                      sal_uInt32 nFlags,
70cdf0e10cSrcweir                                      sal_uInt32 * pInfo,
71cdf0e10cSrcweir                                      sal_Size * pSrcCvtBytes)
72cdf0e10cSrcweir {
73cdf0e10cSrcweir     sal_Unicode const * pGb18030Data
74cdf0e10cSrcweir         = ((ImplGb18030ConverterData const *) pData)->m_pGb18030ToUnicodeData;
75cdf0e10cSrcweir     ImplGb180302000ToUnicodeRange const * pGb18030Ranges
76cdf0e10cSrcweir         = ((ImplGb18030ConverterData const *) pData)->
77cdf0e10cSrcweir               m_pGb18030ToUnicodeRanges;
78cdf0e10cSrcweir     ImplGb18030ToUnicodeState eState = IMPL_GB_18030_TO_UNICODE_STATE_0;
79cdf0e10cSrcweir     sal_uInt32 nCode = 0;
80cdf0e10cSrcweir     sal_uInt32 nInfo = 0;
81cdf0e10cSrcweir     sal_Size nConverted = 0;
82cdf0e10cSrcweir     sal_Unicode * pDestBufPtr = pDestBuf;
83cdf0e10cSrcweir     sal_Unicode * pDestBufEnd = pDestBuf + nDestChars;
84cdf0e10cSrcweir 
85cdf0e10cSrcweir     if (pContext)
86cdf0e10cSrcweir     {
87cdf0e10cSrcweir         eState = ((ImplGb18030ToUnicodeContext *) pContext)->m_eState;
88cdf0e10cSrcweir         nCode = ((ImplGb18030ToUnicodeContext *) pContext)->m_nCode;
89cdf0e10cSrcweir     }
90cdf0e10cSrcweir 
91cdf0e10cSrcweir     for (; nConverted < nSrcBytes; ++nConverted)
92cdf0e10cSrcweir     {
93cdf0e10cSrcweir         sal_Bool bUndefined = sal_True;
94cdf0e10cSrcweir         sal_uInt32 nChar = *(sal_uChar const *) pSrcBuf++;
95cdf0e10cSrcweir         switch (eState)
96cdf0e10cSrcweir         {
97cdf0e10cSrcweir         case IMPL_GB_18030_TO_UNICODE_STATE_0:
98cdf0e10cSrcweir             if (nChar < 0x80)
99cdf0e10cSrcweir                 if (pDestBufPtr != pDestBufEnd)
100cdf0e10cSrcweir                     *pDestBufPtr++ = (sal_Unicode) nChar;
101cdf0e10cSrcweir                 else
102cdf0e10cSrcweir                     goto no_output;
103cdf0e10cSrcweir             else if (nChar == 0x80)
104cdf0e10cSrcweir                 goto bad_input;
105cdf0e10cSrcweir             else if (nChar <= 0xFE)
106cdf0e10cSrcweir             {
107cdf0e10cSrcweir                 nCode = nChar - 0x81;
108cdf0e10cSrcweir                 eState = IMPL_GB_18030_TO_UNICODE_STATE_1;
109cdf0e10cSrcweir             }
110cdf0e10cSrcweir             else
111cdf0e10cSrcweir             {
112cdf0e10cSrcweir                 bUndefined = sal_False;
113cdf0e10cSrcweir                 goto bad_input;
114cdf0e10cSrcweir             }
115cdf0e10cSrcweir             break;
116cdf0e10cSrcweir 
117cdf0e10cSrcweir         case IMPL_GB_18030_TO_UNICODE_STATE_1:
118cdf0e10cSrcweir             if (nChar >= 0x30 && nChar <= 0x39)
119cdf0e10cSrcweir             {
120cdf0e10cSrcweir                 nCode = nCode * 10 + (nChar - 0x30);
121cdf0e10cSrcweir                 eState = IMPL_GB_18030_TO_UNICODE_STATE_2;
122cdf0e10cSrcweir             }
123cdf0e10cSrcweir             else if ((nChar >= 0x40 && nChar <= 0x7E)
124cdf0e10cSrcweir                      || (nChar >= 0x80 && nChar <= 0xFE))
125cdf0e10cSrcweir             {
126cdf0e10cSrcweir                 nCode = nCode * 190 + (nChar <= 0x7E ? nChar - 0x40 :
127cdf0e10cSrcweir                                                        nChar - 0x80 + 63);
128cdf0e10cSrcweir                 if (pDestBufPtr != pDestBufEnd)
129cdf0e10cSrcweir                     *pDestBufPtr++ = pGb18030Data[nCode];
130cdf0e10cSrcweir                 else
131cdf0e10cSrcweir                     goto no_output;
132cdf0e10cSrcweir                 eState = IMPL_GB_18030_TO_UNICODE_STATE_0;
133cdf0e10cSrcweir             }
134cdf0e10cSrcweir             else
135cdf0e10cSrcweir             {
136cdf0e10cSrcweir                 bUndefined = sal_False;
137cdf0e10cSrcweir                 goto bad_input;
138cdf0e10cSrcweir             }
139cdf0e10cSrcweir             break;
140cdf0e10cSrcweir 
141cdf0e10cSrcweir         case IMPL_GB_18030_TO_UNICODE_STATE_2:
142cdf0e10cSrcweir             if (nChar >= 0x81 && nChar <= 0xFE)
143cdf0e10cSrcweir             {
144cdf0e10cSrcweir                 nCode = nCode * 126 + (nChar - 0x81);
145cdf0e10cSrcweir                 eState = IMPL_GB_18030_TO_UNICODE_STATE_3;
146cdf0e10cSrcweir             }
147cdf0e10cSrcweir             else
148cdf0e10cSrcweir             {
149cdf0e10cSrcweir                 bUndefined = sal_False;
150cdf0e10cSrcweir                 goto bad_input;
151cdf0e10cSrcweir             }
152cdf0e10cSrcweir             break;
153cdf0e10cSrcweir 
154cdf0e10cSrcweir         case IMPL_GB_18030_TO_UNICODE_STATE_3:
155cdf0e10cSrcweir             if (nChar >= 0x30 && nChar <= 0x39)
156cdf0e10cSrcweir             {
157cdf0e10cSrcweir                 nCode = nCode * 10 + (nChar - 0x30);
158cdf0e10cSrcweir 
159cdf0e10cSrcweir                 /* 90 30 81 30 to E3 32 9A 35 maps to U+10000 to U+10FFFF: */
160cdf0e10cSrcweir                 if (nCode >= 189000 && nCode <= 1237575)
161cdf0e10cSrcweir                     if (pDestBufEnd - pDestBufPtr >= 2)
162cdf0e10cSrcweir                     {
163cdf0e10cSrcweir                         nCode -= 189000 - 0x10000;
164cdf0e10cSrcweir                         *pDestBufPtr++
165cdf0e10cSrcweir                             = (sal_Unicode) ImplGetHighSurrogate(nCode);
166cdf0e10cSrcweir                         *pDestBufPtr++
167cdf0e10cSrcweir                             = (sal_Unicode) ImplGetLowSurrogate(nCode);
168cdf0e10cSrcweir                     }
169cdf0e10cSrcweir                     else
170cdf0e10cSrcweir                         goto no_output;
171cdf0e10cSrcweir                 else
172cdf0e10cSrcweir                 {
173cdf0e10cSrcweir                     ImplGb180302000ToUnicodeRange const * pRange
174cdf0e10cSrcweir                         = pGb18030Ranges;
175cdf0e10cSrcweir                     sal_uInt32 nFirstNonRange = 0;
176cdf0e10cSrcweir                     for (;;)
177cdf0e10cSrcweir                     {
178cdf0e10cSrcweir                         if (pRange->m_nNonRangeDataIndex == -1)
179cdf0e10cSrcweir                             goto bad_input;
180cdf0e10cSrcweir                         else if (nCode < pRange->m_nFirstLinear)
181cdf0e10cSrcweir                         {
182cdf0e10cSrcweir                             if (pDestBufPtr != pDestBufEnd)
183cdf0e10cSrcweir                                 *pDestBufPtr++
184cdf0e10cSrcweir                                     = pGb18030Data[
185cdf0e10cSrcweir                                           pRange->m_nNonRangeDataIndex
186cdf0e10cSrcweir                                               + (nCode - nFirstNonRange)];
187cdf0e10cSrcweir                             else
188cdf0e10cSrcweir                                 goto no_output;
189cdf0e10cSrcweir                             break;
190cdf0e10cSrcweir                         }
191cdf0e10cSrcweir                         else if (nCode < pRange->m_nPastLinear)
192cdf0e10cSrcweir                         {
193cdf0e10cSrcweir                             if (pDestBufPtr != pDestBufEnd)
194cdf0e10cSrcweir                                 *pDestBufPtr++
195cdf0e10cSrcweir                                     = (sal_Unicode)
196cdf0e10cSrcweir                                           (pRange->m_nFirstUnicode
197cdf0e10cSrcweir                                                + (nCode
198cdf0e10cSrcweir                                                       - pRange->
199cdf0e10cSrcweir                                                             m_nFirstLinear));
200cdf0e10cSrcweir                             else
201cdf0e10cSrcweir                                 goto no_output;
202cdf0e10cSrcweir                             break;
203cdf0e10cSrcweir                         }
204cdf0e10cSrcweir                         nFirstNonRange = (pRange++)->m_nPastLinear;
205cdf0e10cSrcweir                     }
206cdf0e10cSrcweir                 }
207cdf0e10cSrcweir                 eState = IMPL_GB_18030_TO_UNICODE_STATE_0;
208cdf0e10cSrcweir             }
209cdf0e10cSrcweir             else
210cdf0e10cSrcweir             {
211cdf0e10cSrcweir                 bUndefined = sal_False;
212cdf0e10cSrcweir                 goto bad_input;
213cdf0e10cSrcweir             }
214cdf0e10cSrcweir             break;
215cdf0e10cSrcweir         }
216cdf0e10cSrcweir         continue;
217cdf0e10cSrcweir 
218cdf0e10cSrcweir     bad_input:
219cdf0e10cSrcweir         switch (ImplHandleBadInputTextToUnicodeConversion(
220cdf0e10cSrcweir                     bUndefined, sal_True, 0, nFlags, &pDestBufPtr, pDestBufEnd,
221cdf0e10cSrcweir                     &nInfo))
222cdf0e10cSrcweir         {
223cdf0e10cSrcweir         case IMPL_BAD_INPUT_STOP:
224cdf0e10cSrcweir             eState = IMPL_GB_18030_TO_UNICODE_STATE_0;
225cdf0e10cSrcweir             break;
226cdf0e10cSrcweir 
227cdf0e10cSrcweir         case IMPL_BAD_INPUT_CONTINUE:
228cdf0e10cSrcweir             eState = IMPL_GB_18030_TO_UNICODE_STATE_0;
229cdf0e10cSrcweir             continue;
230cdf0e10cSrcweir 
231cdf0e10cSrcweir         case IMPL_BAD_INPUT_NO_OUTPUT:
232cdf0e10cSrcweir             goto no_output;
233cdf0e10cSrcweir         }
234cdf0e10cSrcweir         break;
235cdf0e10cSrcweir 
236cdf0e10cSrcweir     no_output:
237cdf0e10cSrcweir         --pSrcBuf;
238cdf0e10cSrcweir         nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
239cdf0e10cSrcweir         break;
240cdf0e10cSrcweir     }
241cdf0e10cSrcweir 
242cdf0e10cSrcweir     if (eState != IMPL_GB_18030_TO_UNICODE_STATE_0
243cdf0e10cSrcweir         && (nInfo & (RTL_TEXTTOUNICODE_INFO_ERROR
244cdf0e10cSrcweir                          | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL))
245cdf0e10cSrcweir                == 0)
246cdf0e10cSrcweir     {
247cdf0e10cSrcweir         if ((nFlags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0)
248cdf0e10cSrcweir             nInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
249cdf0e10cSrcweir         else
250cdf0e10cSrcweir             switch (ImplHandleBadInputTextToUnicodeConversion(
251cdf0e10cSrcweir                         sal_False, sal_True, 0, nFlags, &pDestBufPtr,
252cdf0e10cSrcweir                         pDestBufEnd, &nInfo))
253cdf0e10cSrcweir             {
254cdf0e10cSrcweir             case IMPL_BAD_INPUT_STOP:
255cdf0e10cSrcweir             case IMPL_BAD_INPUT_CONTINUE:
256cdf0e10cSrcweir                 eState = IMPL_GB_18030_TO_UNICODE_STATE_0;
257cdf0e10cSrcweir                 break;
258cdf0e10cSrcweir 
259cdf0e10cSrcweir             case IMPL_BAD_INPUT_NO_OUTPUT:
260cdf0e10cSrcweir                 nInfo |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
261cdf0e10cSrcweir                 break;
262cdf0e10cSrcweir             }
263cdf0e10cSrcweir     }
264cdf0e10cSrcweir 
265cdf0e10cSrcweir     if (pContext)
266cdf0e10cSrcweir     {
267cdf0e10cSrcweir         ((ImplGb18030ToUnicodeContext *) pContext)->m_eState = eState;
268cdf0e10cSrcweir         ((ImplGb18030ToUnicodeContext *) pContext)->m_nCode = nCode;
269cdf0e10cSrcweir     }
270cdf0e10cSrcweir     if (pInfo)
271cdf0e10cSrcweir         *pInfo = nInfo;
272cdf0e10cSrcweir     if (pSrcCvtBytes)
273cdf0e10cSrcweir         *pSrcCvtBytes = nConverted;
274cdf0e10cSrcweir 
275cdf0e10cSrcweir     return pDestBufPtr - pDestBuf;
276cdf0e10cSrcweir }
277cdf0e10cSrcweir 
ImplConvertUnicodeToGb18030(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)278cdf0e10cSrcweir sal_Size ImplConvertUnicodeToGb18030(ImplTextConverterData const * pData,
279cdf0e10cSrcweir                                      void * pContext,
280cdf0e10cSrcweir                                      sal_Unicode const * pSrcBuf,
281cdf0e10cSrcweir                                      sal_Size nSrcChars,
282cdf0e10cSrcweir                                      sal_Char * pDestBuf,
283cdf0e10cSrcweir                                      sal_Size nDestBytes,
284cdf0e10cSrcweir                                      sal_uInt32 nFlags,
285cdf0e10cSrcweir                                      sal_uInt32 * pInfo,
286cdf0e10cSrcweir                                      sal_Size * pSrcCvtChars)
287cdf0e10cSrcweir {
288cdf0e10cSrcweir     sal_uInt32 const * pGb18030Data
289cdf0e10cSrcweir         = ((ImplGb18030ConverterData const *) pData)->
290cdf0e10cSrcweir               m_pUnicodeToGb18030Data;
291cdf0e10cSrcweir     ImplUnicodeToGb180302000Range const * pGb18030Ranges
292cdf0e10cSrcweir         = ((ImplGb18030ConverterData const *) pData)->
293cdf0e10cSrcweir               m_pUnicodeToGb18030Ranges;
294cdf0e10cSrcweir     sal_Unicode nHighSurrogate = 0;
295cdf0e10cSrcweir     sal_uInt32 nInfo = 0;
296cdf0e10cSrcweir     sal_Size nConverted = 0;
297cdf0e10cSrcweir     sal_Char * pDestBufPtr = pDestBuf;
298cdf0e10cSrcweir     sal_Char * pDestBufEnd = pDestBuf + nDestBytes;
299cdf0e10cSrcweir 
300cdf0e10cSrcweir     if (pContext)
301cdf0e10cSrcweir         nHighSurrogate
302cdf0e10cSrcweir             = ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate;
303cdf0e10cSrcweir 
304cdf0e10cSrcweir     for (; nConverted < nSrcChars; ++nConverted)
305cdf0e10cSrcweir     {
306cdf0e10cSrcweir         sal_Bool bUndefined = sal_True;
307cdf0e10cSrcweir         sal_uInt32 nChar = *pSrcBuf++;
308cdf0e10cSrcweir         if (nHighSurrogate == 0)
309cdf0e10cSrcweir         {
310cdf0e10cSrcweir             if (ImplIsHighSurrogate(nChar))
311cdf0e10cSrcweir             {
312cdf0e10cSrcweir                 nHighSurrogate = (sal_Unicode) nChar;
313cdf0e10cSrcweir                 continue;
314cdf0e10cSrcweir             }
315cdf0e10cSrcweir         }
316cdf0e10cSrcweir         else if (ImplIsLowSurrogate(nChar))
317cdf0e10cSrcweir             nChar = ImplCombineSurrogates(nHighSurrogate, nChar);
318cdf0e10cSrcweir         else
319cdf0e10cSrcweir         {
320cdf0e10cSrcweir             bUndefined = sal_False;
321cdf0e10cSrcweir             goto bad_input;
322cdf0e10cSrcweir         }
323cdf0e10cSrcweir 
324cdf0e10cSrcweir         if (ImplIsLowSurrogate(nChar) || ImplIsNoncharacter(nChar))
325cdf0e10cSrcweir         {
326cdf0e10cSrcweir             bUndefined = sal_False;
327cdf0e10cSrcweir             goto bad_input;
328cdf0e10cSrcweir         }
329cdf0e10cSrcweir 
330cdf0e10cSrcweir         if (nChar < 0x80)
331cdf0e10cSrcweir             if (pDestBufPtr != pDestBufEnd)
332cdf0e10cSrcweir                 *pDestBufPtr++ = (sal_Char) nChar;
333cdf0e10cSrcweir             else
334cdf0e10cSrcweir                 goto no_output;
335cdf0e10cSrcweir         else if (nChar < 0x10000)
336cdf0e10cSrcweir         {
337cdf0e10cSrcweir             ImplUnicodeToGb180302000Range const * pRange = pGb18030Ranges;
338cdf0e10cSrcweir             sal_Unicode nFirstNonRange = 0x80;
339cdf0e10cSrcweir             for (;;)
340cdf0e10cSrcweir             {
341cdf0e10cSrcweir                 if (nChar < pRange->m_nFirstUnicode)
342cdf0e10cSrcweir                 {
343cdf0e10cSrcweir                     sal_uInt32 nCode
344cdf0e10cSrcweir                         = pGb18030Data[pRange->m_nNonRangeDataIndex
345cdf0e10cSrcweir                                            + (nChar - nFirstNonRange)];
346cdf0e10cSrcweir                     if (pDestBufEnd - pDestBufPtr
347cdf0e10cSrcweir                             >= (nCode <= 0xFFFF ? 2 : 4))
348cdf0e10cSrcweir                     {
349cdf0e10cSrcweir                         if (nCode > 0xFFFF)
350cdf0e10cSrcweir                         {
351cdf0e10cSrcweir                             *pDestBufPtr++ = (sal_Char) (nCode >> 24);
352cdf0e10cSrcweir                             *pDestBufPtr++ = (sal_Char) (nCode >> 16 & 0xFF);
353cdf0e10cSrcweir                         }
354cdf0e10cSrcweir                         *pDestBufPtr++ = (sal_Char) (nCode >> 8 & 0xFF);
355cdf0e10cSrcweir                         *pDestBufPtr++ = (sal_Char) (nCode & 0xFF);
356cdf0e10cSrcweir                     }
357cdf0e10cSrcweir                     else
358cdf0e10cSrcweir                         goto no_output;
359cdf0e10cSrcweir                     break;
360cdf0e10cSrcweir                 }
361cdf0e10cSrcweir                 else if (nChar <= pRange->m_nLastUnicode)
362cdf0e10cSrcweir                 {
363cdf0e10cSrcweir                     if (pDestBufEnd - pDestBufPtr >= 4)
364cdf0e10cSrcweir                     {
365cdf0e10cSrcweir                         sal_uInt32 nCode
366cdf0e10cSrcweir                             = pRange->m_nFirstLinear
367cdf0e10cSrcweir                                   + (nChar - pRange->m_nFirstUnicode);
368cdf0e10cSrcweir                         *pDestBufPtr++ = (sal_Char) (nCode / 12600 + 0x81);
369cdf0e10cSrcweir                         *pDestBufPtr++
370cdf0e10cSrcweir                             = (sal_Char) (nCode / 1260 % 10 + 0x30);
371cdf0e10cSrcweir                         *pDestBufPtr++ = (sal_Char) (nCode / 10 % 126 + 0x81);
372cdf0e10cSrcweir                         *pDestBufPtr++ = (sal_Char) (nCode % 10 + 0x30);
373cdf0e10cSrcweir                     }
374cdf0e10cSrcweir                     else
375cdf0e10cSrcweir                         goto no_output;
376cdf0e10cSrcweir                     break;
377cdf0e10cSrcweir                 }
378cdf0e10cSrcweir                 nFirstNonRange
379cdf0e10cSrcweir                     = (sal_Unicode) ((pRange++)->m_nLastUnicode + 1);
380cdf0e10cSrcweir             }
381cdf0e10cSrcweir         }
382cdf0e10cSrcweir         else
383cdf0e10cSrcweir             if (pDestBufEnd - pDestBufPtr >= 4)
384cdf0e10cSrcweir             {
385cdf0e10cSrcweir                 sal_uInt32 nCode = nChar - 0x10000;
386cdf0e10cSrcweir                 *pDestBufPtr++ = (sal_Char) (nCode / 12600 + 0x90);
387cdf0e10cSrcweir                 *pDestBufPtr++ = (sal_Char) (nCode / 1260 % 10 + 0x30);
388cdf0e10cSrcweir                 *pDestBufPtr++ = (sal_Char) (nCode / 10 % 126 + 0x81);
389cdf0e10cSrcweir                 *pDestBufPtr++ = (sal_Char) (nCode % 10 + 0x30);
390cdf0e10cSrcweir             }
391cdf0e10cSrcweir             else
392cdf0e10cSrcweir                 goto no_output;
393cdf0e10cSrcweir         nHighSurrogate = 0;
394cdf0e10cSrcweir         continue;
395cdf0e10cSrcweir 
396cdf0e10cSrcweir     bad_input:
397cdf0e10cSrcweir         switch (ImplHandleBadInputUnicodeToTextConversion(bUndefined,
398cdf0e10cSrcweir                                                           nChar,
399cdf0e10cSrcweir                                                           nFlags,
400cdf0e10cSrcweir                                                           &pDestBufPtr,
401cdf0e10cSrcweir                                                           pDestBufEnd,
402cdf0e10cSrcweir                                                           &nInfo,
403cdf0e10cSrcweir                                                           NULL,
404cdf0e10cSrcweir                                                           0,
405cdf0e10cSrcweir                                                           NULL))
406cdf0e10cSrcweir         {
407cdf0e10cSrcweir         case IMPL_BAD_INPUT_STOP:
408cdf0e10cSrcweir             nHighSurrogate = 0;
409cdf0e10cSrcweir             break;
410cdf0e10cSrcweir 
411cdf0e10cSrcweir         case IMPL_BAD_INPUT_CONTINUE:
412cdf0e10cSrcweir             nHighSurrogate = 0;
413cdf0e10cSrcweir             continue;
414cdf0e10cSrcweir 
415cdf0e10cSrcweir         case IMPL_BAD_INPUT_NO_OUTPUT:
416cdf0e10cSrcweir             goto no_output;
417cdf0e10cSrcweir         }
418cdf0e10cSrcweir         break;
419cdf0e10cSrcweir 
420cdf0e10cSrcweir     no_output:
421cdf0e10cSrcweir         --pSrcBuf;
422cdf0e10cSrcweir         nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
423cdf0e10cSrcweir         break;
424cdf0e10cSrcweir     }
425cdf0e10cSrcweir 
426cdf0e10cSrcweir     if (nHighSurrogate != 0
427cdf0e10cSrcweir         && (nInfo & (RTL_UNICODETOTEXT_INFO_ERROR
428cdf0e10cSrcweir                          | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
429cdf0e10cSrcweir                == 0)
430cdf0e10cSrcweir     {
431cdf0e10cSrcweir         if ((nFlags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0)
432cdf0e10cSrcweir             nInfo |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
433cdf0e10cSrcweir         else
434cdf0e10cSrcweir             switch (ImplHandleBadInputUnicodeToTextConversion(sal_False,
435cdf0e10cSrcweir                                                               0,
436cdf0e10cSrcweir                                                               nFlags,
437cdf0e10cSrcweir                                                               &pDestBufPtr,
438cdf0e10cSrcweir                                                               pDestBufEnd,
439cdf0e10cSrcweir                                                               &nInfo,
440cdf0e10cSrcweir                                                               NULL,
441cdf0e10cSrcweir                                                               0,
442cdf0e10cSrcweir                                                               NULL))
443cdf0e10cSrcweir             {
444cdf0e10cSrcweir             case IMPL_BAD_INPUT_STOP:
445cdf0e10cSrcweir             case IMPL_BAD_INPUT_CONTINUE:
446cdf0e10cSrcweir                 nHighSurrogate = 0;
447cdf0e10cSrcweir                 break;
448cdf0e10cSrcweir 
449cdf0e10cSrcweir             case IMPL_BAD_INPUT_NO_OUTPUT:
450cdf0e10cSrcweir                 nInfo |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
451cdf0e10cSrcweir                 break;
452cdf0e10cSrcweir             }
453cdf0e10cSrcweir     }
454cdf0e10cSrcweir 
455cdf0e10cSrcweir     if (pContext)
456cdf0e10cSrcweir         ((ImplUnicodeToTextContext *) pContext)->m_nHighSurrogate
457cdf0e10cSrcweir             = nHighSurrogate;
458cdf0e10cSrcweir     if (pInfo)
459cdf0e10cSrcweir         *pInfo = nInfo;
460cdf0e10cSrcweir     if (pSrcCvtChars)
461cdf0e10cSrcweir         *pSrcCvtChars = nConverted;
462cdf0e10cSrcweir 
463cdf0e10cSrcweir     return pDestBufPtr - pDestBuf;
464cdf0e10cSrcweir }
465