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 "rtl/textcvt.h"
32 : :
33 : : #include "handleundefinedunicodetotextchar.hxx"
34 : : #include "tenchelp.hxx"
35 : : #include "unichars.hxx"
36 : :
37 : : /* ======================================================================= */
38 : :
39 : : /* DBCS to Unicode conversion routine use a lead table for the first byte, */
40 : : /* where we determine the trail table or for single byte chars the unicode */
41 : : /* value. We have for all lead byte a separate table, because we can */
42 : : /* then share many tables for diffrent charset encodings. */
43 : :
44 : : /* ======================================================================= */
45 : :
46 : 795 : sal_Size ImplDBCSToUnicode( const void* pData, SAL_UNUSED_PARAMETER void*,
47 : : const char* pSrcBuf, sal_Size nSrcBytes,
48 : : sal_Unicode* pDestBuf, sal_Size nDestChars,
49 : : sal_uInt32 nFlags, sal_uInt32* pInfo,
50 : : sal_Size* pSrcCvtBytes )
51 : : {
52 : : sal_uChar cLead;
53 : : sal_uChar cTrail;
54 : : sal_Unicode cConv;
55 : : const ImplDBCSToUniLeadTab* pLeadEntry;
56 : 795 : const ImplDBCSConvertData* pConvertData = (const ImplDBCSConvertData*)pData;
57 : 795 : const ImplDBCSToUniLeadTab* pLeadTab = pConvertData->mpToUniLeadTab;
58 : : sal_Unicode* pEndDestBuf;
59 : : const char* pEndSrcBuf;
60 : :
61 : 795 : *pInfo = 0;
62 : 795 : pEndDestBuf = pDestBuf+nDestChars;
63 : 795 : pEndSrcBuf = pSrcBuf+nSrcBytes;
64 [ + + ]: 11970 : while ( pSrcBuf < pEndSrcBuf )
65 : : {
66 : 11180 : cLead = (sal_uChar)*pSrcBuf;
67 : :
68 : : /* get entry for the lead byte */
69 : 11180 : pLeadEntry = pLeadTab+cLead;
70 : :
71 : : /* SingleByte char? */
72 [ + + ][ + - ]: 11180 : if (pLeadEntry->mpToUniTrailTab == NULL
[ - + ]
73 : : || cLead < pConvertData->mnLeadStart
74 : : || cLead > pConvertData->mnLeadEnd)
75 : : {
76 : 10100 : cConv = pLeadEntry->mnUniChar;
77 [ - + ][ # # ]: 10100 : if ( !cConv && (cLead != 0) )
78 : : {
79 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_UNDEFINED;
80 [ # # ]: 0 : if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MASK) == RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR )
81 : : {
82 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR;
83 : 0 : break;
84 : : }
85 [ # # ]: 0 : else if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MASK) == RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_IGNORE )
86 : : {
87 : 0 : pSrcBuf++;
88 : 0 : continue;
89 : : }
90 : : else
91 : 0 : cConv = ImplGetUndefinedUnicodeChar(cLead, nFlags);
92 : : }
93 : : }
94 : : else
95 : : {
96 : : /* Source buffer to small */
97 [ + + ]: 1080 : if ( pSrcBuf +1 == pEndSrcBuf )
98 : : {
99 : 5 : *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
100 : 5 : break;
101 : : }
102 : :
103 : 1075 : pSrcBuf++;
104 : 1075 : cTrail = (sal_uChar)*pSrcBuf;
105 [ + - ][ + - ]: 1075 : if ( (cTrail >= pLeadEntry->mnTrailStart) && (cTrail <= pLeadEntry->mnTrailEnd) )
106 : 1075 : cConv = pLeadEntry->mpToUniTrailTab[cTrail-pLeadEntry->mnTrailStart];
107 : : else
108 : 0 : cConv = 0;
109 : :
110 [ - + ]: 1075 : if ( !cConv )
111 : : {
112 : : /* EUDC Ranges */
113 : : sal_uInt16 i;
114 : 0 : const ImplDBCSEUDCData* pEUDCTab = pConvertData->mpEUDCTab;
115 [ # # ]: 0 : for ( i = 0; i < pConvertData->mnEUDCCount; i++ )
116 : : {
117 [ # # ][ # # ]: 0 : if ( (cLead >= pEUDCTab->mnLeadStart) &&
118 : : (cLead <= pEUDCTab->mnLeadEnd) )
119 : : {
120 [ # # ][ # # ]: 0 : if ( (cTrail >= pEUDCTab->mnTrail1Start) &&
121 : : (cTrail <= pEUDCTab->mnTrail1End) )
122 : : {
123 : : cConv = pEUDCTab->mnUniStart+
124 : : ((cLead-pEUDCTab->mnLeadStart)*pEUDCTab->mnTrailRangeCount)+
125 : 0 : (cTrail-pEUDCTab->mnTrail1Start);
126 : 0 : break;
127 : : }
128 : : else
129 : : {
130 : 0 : sal_uInt16 nTrailCount = pEUDCTab->mnTrail1End-pEUDCTab->mnTrail1Start+1;
131 [ # # ][ # # ]: 0 : if ( (pEUDCTab->mnTrailCount >= 2) &&
[ # # ]
132 : : (cTrail >= pEUDCTab->mnTrail2Start) &&
133 : : (cTrail <= pEUDCTab->mnTrail2End) )
134 : : {
135 : : cConv = pEUDCTab->mnUniStart+
136 : : ((cLead-pEUDCTab->mnLeadStart)*pEUDCTab->mnTrailRangeCount)+
137 : : nTrailCount+
138 : 0 : (cTrail-pEUDCTab->mnTrail2Start);
139 : 0 : break;
140 : : }
141 : : else
142 : : {
143 : 0 : nTrailCount = pEUDCTab->mnTrail2End-pEUDCTab->mnTrail2Start+1;
144 [ # # ][ # # ]: 0 : if ( (pEUDCTab->mnTrailCount >= 3) &&
[ # # ]
145 : : (cTrail >= pEUDCTab->mnTrail3Start) &&
146 : : (cTrail <= pEUDCTab->mnTrail3End) )
147 : : {
148 : : cConv = pEUDCTab->mnUniStart+
149 : : ((cLead-pEUDCTab->mnLeadStart)*pEUDCTab->mnTrailRangeCount)+
150 : : nTrailCount+
151 : 0 : (cTrail-pEUDCTab->mnTrail3Start);
152 : 0 : break;
153 : : }
154 : : }
155 : : }
156 : : }
157 : :
158 : 0 : pEUDCTab++;
159 : : }
160 : :
161 [ # # ]: 0 : if ( !cConv )
162 : : {
163 : : /* We compare the full range of the trail we defined, */
164 : : /* which can often be greater than the limit. We do this */
165 : : /* so that extensions that don't consider encodings */
166 : : /* correctly treat double-byte characters as a single */
167 : : /* character as much as possible. */
168 : :
169 [ # # ][ # # ]: 0 : if (cLead < pConvertData->mnLeadStart
[ # # ][ # # ]
170 : : || cLead > pConvertData->mnLeadEnd
171 : : || cTrail < pConvertData->mnTrailStart
172 : : || cTrail > pConvertData->mnTrailEnd)
173 : : {
174 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_INVALID;
175 [ # # ]: 0 : if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) == RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR )
176 : : {
177 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR;
178 : 0 : break;
179 : : }
180 [ # # ]: 0 : else if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) == RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE )
181 : : {
182 : 0 : pSrcBuf++;
183 : 0 : continue;
184 : : }
185 : : else
186 : 0 : cConv = RTL_TEXTENC_UNICODE_REPLACEMENT_CHARACTER;
187 : : }
188 : : else
189 : : {
190 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_MBUNDEFINED;
191 [ # # ]: 0 : if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_MASK) == RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR )
192 : : {
193 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR;
194 : 0 : break;
195 : : }
196 [ # # ]: 0 : else if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_MASK) == RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_IGNORE )
197 : : {
198 : 0 : pSrcBuf++;
199 : 0 : continue;
200 : : }
201 : : else
202 : 0 : cConv = RTL_TEXTENC_UNICODE_REPLACEMENT_CHARACTER;
203 : : }
204 : : }
205 : : }
206 : : }
207 : :
208 [ - + ]: 11175 : if ( pDestBuf == pEndDestBuf )
209 : : {
210 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
211 : 0 : break;
212 : : }
213 : :
214 : 11175 : *pDestBuf = cConv;
215 : 11175 : pDestBuf++;
216 : 11175 : pSrcBuf++;
217 : : }
218 : :
219 : 795 : *pSrcCvtBytes = nSrcBytes - (pEndSrcBuf-pSrcBuf);
220 : 795 : return (nDestChars - (pEndDestBuf-pDestBuf));
221 : : }
222 : :
223 : : /* ----------------------------------------------------------------------- */
224 : :
225 : 183803 : sal_Size ImplUnicodeToDBCS( const void* pData, SAL_UNUSED_PARAMETER void*,
226 : : const sal_Unicode* pSrcBuf, sal_Size nSrcChars,
227 : : char* pDestBuf, sal_Size nDestBytes,
228 : : sal_uInt32 nFlags, sal_uInt32* pInfo,
229 : : sal_Size* pSrcCvtChars )
230 : : {
231 : : sal_uInt16 cConv;
232 : : sal_Unicode c;
233 : : sal_uChar nHighChar;
234 : : sal_uChar nLowChar;
235 : : const ImplUniToDBCSHighTab* pHighEntry;
236 : 183803 : const ImplDBCSConvertData* pConvertData = (const ImplDBCSConvertData*)pData;
237 : 183803 : const ImplUniToDBCSHighTab* pHighTab = pConvertData->mpToDBCSHighTab;
238 : : char* pEndDestBuf;
239 : : const sal_Unicode* pEndSrcBuf;
240 : :
241 : : bool bCheckRange =
242 [ + - ][ - + ]: 183803 : pConvertData->mnLeadStart != 0 || pConvertData->mnLeadEnd != 0xFF;
243 : : /* this statement has the effect that this extra check is only done for
244 : : EUC-KR, which uses the MS-949 tables, but does not support the full
245 : : range of MS-949 */
246 : :
247 : 183803 : *pInfo = 0;
248 : 183803 : pEndDestBuf = pDestBuf+nDestBytes;
249 : 183803 : pEndSrcBuf = pSrcBuf+nSrcChars;
250 [ + + ]: 242308 : while ( pSrcBuf < pEndSrcBuf )
251 : : {
252 : 184883 : c = *pSrcBuf;
253 : 184883 : nHighChar = (sal_uChar)((c >> 8) & 0xFF);
254 : 184883 : nLowChar = (sal_uChar)(c & 0xFF);
255 : :
256 : : /* get entry for the high byte */
257 : 184883 : pHighEntry = pHighTab+nHighChar;
258 : :
259 : : /* is low byte in the table range */
260 [ + + ][ + + ]: 184883 : if ( (nLowChar >= pHighEntry->mnLowStart) && (nLowChar <= pHighEntry->mnLowEnd) )
261 : : {
262 : 53800 : cConv = pHighEntry->mpToUniTrailTab[nLowChar-pHighEntry->mnLowStart];
263 [ - + ][ # # ]: 53800 : if (bCheckRange && cConv > 0x7F
[ # # ][ # # ]
[ # # ][ # # ]
264 : : && ((cConv >> 8) < pConvertData->mnLeadStart
265 : : || (cConv >> 8) > pConvertData->mnLeadEnd
266 : : || (cConv & 0xFF) < pConvertData->mnTrailStart
267 : : || (cConv & 0xFF) > pConvertData->mnTrailEnd))
268 : 0 : cConv = 0;
269 : : }
270 : : else
271 : 131083 : cConv = 0;
272 : :
273 [ + + ][ + + ]: 184883 : if (cConv == 0 && c != 0)
274 : : {
275 : : /* Map to EUDC ranges: */
276 : 136095 : ImplDBCSEUDCData const * pEUDCTab = pConvertData->mpEUDCTab;
277 : : sal_uInt32 i;
278 [ + + ]: 448816 : for (i = 0; i < pConvertData->mnEUDCCount; ++i)
279 : : {
280 [ + + ][ + + ]: 322443 : if (c >= pEUDCTab->mnUniStart && c <= pEUDCTab->mnUniEnd)
281 : : {
282 : 9722 : sal_uInt32 nIndex = c - pEUDCTab->mnUniStart;
283 : : sal_uInt32 nLeadOff
284 : 9722 : = nIndex / pEUDCTab->mnTrailRangeCount;
285 : : sal_uInt32 nTrailOff
286 : 9722 : = nIndex % pEUDCTab->mnTrailRangeCount;
287 : : sal_uInt32 nSize;
288 : : cConv = (sal_uInt16)
289 : 9722 : ((pEUDCTab->mnLeadStart + nLeadOff) << 8);
290 : : nSize
291 : 9722 : = pEUDCTab->mnTrail1End - pEUDCTab->mnTrail1Start + 1;
292 [ + + ]: 9722 : if (nTrailOff < nSize)
293 : : {
294 : 4791 : cConv |= pEUDCTab->mnTrail1Start + nTrailOff;
295 : 4791 : break;
296 : : }
297 : 4931 : nTrailOff -= nSize;
298 : : nSize
299 : 4931 : = pEUDCTab->mnTrail2End - pEUDCTab->mnTrail2Start + 1;
300 [ + + ]: 4931 : if (nTrailOff < nSize)
301 : : {
302 : 4917 : cConv |= pEUDCTab->mnTrail2Start + nTrailOff;
303 : 4917 : break;
304 : : }
305 : 14 : nTrailOff -= nSize;
306 : 14 : cConv |= pEUDCTab->mnTrail3Start + nTrailOff;
307 : 14 : break;
308 : : }
309 : 312721 : pEUDCTab++;
310 : : }
311 : :
312 : : /* FIXME
313 : : * SB: Not sure why this is in here. Plus, it does not work as
314 : : * intended when (c & 0xFF) == 0, because the next !cConv check
315 : : * will then think c has not yet been converted...
316 : : */
317 [ + + ][ + + ]: 136095 : if (c >= RTL_TEXTCVT_BYTE_PRIVATE_START
318 : : && c <= RTL_TEXTCVT_BYTE_PRIVATE_END)
319 : : {
320 [ - + ]: 256 : if ( nFlags & RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 )
321 : 0 : cConv = static_cast< char >(static_cast< unsigned char >(c & 0xFF));
322 : : }
323 : : }
324 : :
325 [ + + ]: 184883 : if ( !cConv )
326 : : {
327 : 126378 : if ( nFlags & RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE )
328 : : {
329 : : /* !!! */
330 : : }
331 : :
332 : 126378 : if ( nFlags & RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR )
333 : : {
334 : : /* !!! */
335 : : }
336 : :
337 : : /* Handle undefined and surrogates characters */
338 : : /* (all surrogates characters are undefined) */
339 [ - + ]: 126378 : if (sal::detail::textenc::handleUndefinedUnicodeToTextChar(
340 : : &pSrcBuf, pEndSrcBuf, &pDestBuf, pEndDestBuf, nFlags,
341 : : pInfo))
342 : 0 : continue;
343 : : else
344 : 126378 : break;
345 : : }
346 : :
347 : : /* SingleByte */
348 [ + + ]: 58505 : if ( !(cConv & 0xFF00) )
349 : : {
350 [ - + ]: 1186 : if ( pDestBuf == pEndDestBuf )
351 : : {
352 : 0 : *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
353 : 0 : break;
354 : : }
355 : :
356 : 1186 : *pDestBuf = static_cast< char >(static_cast< unsigned char >(cConv & 0xFF));
357 : 1186 : pDestBuf++;
358 : : }
359 : : else
360 : : {
361 [ - + ]: 57319 : if ( pDestBuf+1 >= pEndDestBuf )
362 : : {
363 : 0 : *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
364 : 0 : break;
365 : : }
366 : :
367 : 57319 : *pDestBuf = static_cast< char >(static_cast< unsigned char >((cConv >> 8) & 0xFF));
368 : 57319 : pDestBuf++;
369 : 57319 : *pDestBuf = static_cast< char >(static_cast< unsigned char >(cConv & 0xFF));
370 : 57319 : pDestBuf++;
371 : : }
372 : :
373 : 58505 : pSrcBuf++;
374 : : }
375 : :
376 : 183803 : *pSrcCvtChars = nSrcChars - (pEndSrcBuf-pSrcBuf);
377 : 183803 : return (nDestBytes - (pEndDestBuf-pDestBuf));
378 : : }
379 : :
380 : : /* ======================================================================= */
381 : :
382 : : #define JIS_EUC_LEAD_OFF 0x80
383 : : #define JIS_EUC_TRAIL_OFF 0x80
384 : :
385 : : /* ----------------------------------------------------------------------- */
386 : :
387 : 0 : sal_Size ImplEUCJPToUnicode( const void* pData,
388 : : SAL_UNUSED_PARAMETER void*,
389 : : const char* pSrcBuf, sal_Size nSrcBytes,
390 : : sal_Unicode* pDestBuf, sal_Size nDestChars,
391 : : sal_uInt32 nFlags, sal_uInt32* pInfo,
392 : : sal_Size* pSrcCvtBytes )
393 : : {
394 : : sal_uChar c;
395 : 0 : sal_uChar cLead = '\0';
396 : 0 : sal_uChar cTrail = '\0';
397 : : sal_Unicode cConv;
398 : : const ImplDBCSToUniLeadTab* pLeadEntry;
399 : : const ImplDBCSToUniLeadTab* pLeadTab;
400 : 0 : const ImplEUCJPConvertData* pConvertData = (const ImplEUCJPConvertData*)pData;
401 : : sal_Unicode* pEndDestBuf;
402 : : const char* pEndSrcBuf;
403 : :
404 : 0 : *pInfo = 0;
405 : 0 : pEndDestBuf = pDestBuf+nDestChars;
406 : 0 : pEndSrcBuf = pSrcBuf+nSrcBytes;
407 [ # # ]: 0 : while ( pSrcBuf < pEndSrcBuf )
408 : : {
409 : 0 : c = (sal_uChar)*pSrcBuf;
410 : :
411 : : /* ASCII */
412 [ # # ]: 0 : if ( c <= 0x7F )
413 : 0 : cConv = c;
414 : : else
415 : : {
416 : : /* SS2 - Half-width katakana */
417 : : /* 8E + A1-DF */
418 [ # # ]: 0 : if ( c == 0x8E )
419 : : {
420 : : /* Source buffer to small */
421 [ # # ]: 0 : if ( pSrcBuf + 1 == pEndSrcBuf )
422 : : {
423 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
424 : 0 : break;
425 : : }
426 : :
427 : 0 : pSrcBuf++;
428 : 0 : c = (sal_uChar)*pSrcBuf;
429 [ # # ][ # # ]: 0 : if ( (c >= 0xA1) && (c <= 0xDF) )
430 : 0 : cConv = 0xFF61+(c-0xA1);
431 : : else
432 : : {
433 : 0 : cConv = 0;
434 : 0 : cLead = 0x8E;
435 : 0 : cTrail = c;
436 : : }
437 : : }
438 : : else
439 : : {
440 : : /* SS3 - JIS 0212-1990 */
441 : : /* 8F + A1-FE + A1-FE */
442 [ # # ]: 0 : if ( c == 0x8F )
443 : : {
444 : : /* Source buffer to small */
445 [ # # ]: 0 : if (pEndSrcBuf - pSrcBuf < 3)
446 : : {
447 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
448 : 0 : break;
449 : : }
450 : :
451 : 0 : pSrcBuf++;
452 : 0 : cLead = (sal_uChar)*pSrcBuf;
453 : 0 : pSrcBuf++;
454 : 0 : cTrail = (sal_uChar)*pSrcBuf;
455 : 0 : pLeadTab = pConvertData->mpJIS0212ToUniLeadTab;
456 : : }
457 : : /* CodeSet 2 JIS 0208-1997 */
458 : : /* A1-FE + A1-FE */
459 : : else
460 : : {
461 : : /* Source buffer to small */
462 [ # # ]: 0 : if ( pSrcBuf + 1 == pEndSrcBuf )
463 : : {
464 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_SRCBUFFERTOSMALL;
465 : 0 : break;
466 : : }
467 : :
468 : 0 : cLead = c;
469 : 0 : pSrcBuf++;
470 : 0 : cTrail = (sal_uChar)*pSrcBuf;
471 : 0 : pLeadTab = pConvertData->mpJIS0208ToUniLeadTab;
472 : : }
473 : :
474 : : /* Undefined Range */
475 [ # # ][ # # ]: 0 : if ( (cLead < JIS_EUC_LEAD_OFF) || (cTrail < JIS_EUC_TRAIL_OFF) )
476 : 0 : cConv = 0;
477 : : else
478 : : {
479 : 0 : cLead -= JIS_EUC_LEAD_OFF;
480 : 0 : cTrail -= JIS_EUC_TRAIL_OFF;
481 : 0 : pLeadEntry = pLeadTab+cLead;
482 [ # # ][ # # ]: 0 : if ( (cTrail >= pLeadEntry->mnTrailStart) && (cTrail <= pLeadEntry->mnTrailEnd) )
483 : 0 : cConv = pLeadEntry->mpToUniTrailTab[cTrail-pLeadEntry->mnTrailStart];
484 : : else
485 : 0 : cConv = 0;
486 : : }
487 : : }
488 : :
489 [ # # ]: 0 : if ( !cConv )
490 : : {
491 : : /* We compare the full range of the trail we defined, */
492 : : /* which can often be greater than the limit. We do this */
493 : : /* so that extensions that don't consider encodings */
494 : : /* correctly treat double-byte characters as a single */
495 : : /* character as much as possible. */
496 : :
497 [ # # ][ # # ]: 0 : if ( (cLead < JIS_EUC_LEAD_OFF) || (cTrail < JIS_EUC_TRAIL_OFF) )
498 : : {
499 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_INVALID;
500 [ # # ]: 0 : if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) == RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR )
501 : : {
502 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR;
503 : 0 : break;
504 : : }
505 [ # # ]: 0 : else if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_INVALID_MASK) == RTL_TEXTTOUNICODE_FLAGS_INVALID_IGNORE )
506 : : {
507 : 0 : pSrcBuf++;
508 : 0 : continue;
509 : : }
510 : : else
511 : 0 : cConv = RTL_TEXTENC_UNICODE_REPLACEMENT_CHARACTER;
512 : : }
513 : : else
514 : : {
515 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_MBUNDEFINED;
516 [ # # ]: 0 : if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_MASK) == RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR )
517 : : {
518 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR;
519 : 0 : break;
520 : : }
521 [ # # ]: 0 : else if ( (nFlags & RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_MASK) == RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_IGNORE )
522 : : {
523 : 0 : pSrcBuf++;
524 : 0 : continue;
525 : : }
526 : : else
527 : 0 : cConv = RTL_TEXTENC_UNICODE_REPLACEMENT_CHARACTER;
528 : : }
529 : : }
530 : : }
531 : :
532 [ # # ]: 0 : if ( pDestBuf == pEndDestBuf )
533 : : {
534 : 0 : *pInfo |= RTL_TEXTTOUNICODE_INFO_ERROR | RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL;
535 : 0 : break;
536 : : }
537 : :
538 : 0 : *pDestBuf = cConv;
539 : 0 : pDestBuf++;
540 : 0 : pSrcBuf++;
541 : : }
542 : :
543 : 0 : *pSrcCvtBytes = nSrcBytes - (pEndSrcBuf-pSrcBuf);
544 : 0 : return (nDestChars - (pEndDestBuf-pDestBuf));
545 : : }
546 : :
547 : : /* ----------------------------------------------------------------------- */
548 : :
549 : 0 : sal_Size ImplUnicodeToEUCJP( const void* pData,
550 : : SAL_UNUSED_PARAMETER void*,
551 : : const sal_Unicode* pSrcBuf, sal_Size nSrcChars,
552 : : char* pDestBuf, sal_Size nDestBytes,
553 : : sal_uInt32 nFlags, sal_uInt32* pInfo,
554 : : sal_Size* pSrcCvtChars )
555 : : {
556 : : sal_uInt32 cConv;
557 : : sal_Unicode c;
558 : : sal_uChar nHighChar;
559 : : sal_uChar nLowChar;
560 : : const ImplUniToDBCSHighTab* pHighEntry;
561 : : const ImplUniToDBCSHighTab* pHighTab;
562 : 0 : const ImplEUCJPConvertData* pConvertData = (const ImplEUCJPConvertData*)pData;
563 : : char* pEndDestBuf;
564 : : const sal_Unicode* pEndSrcBuf;
565 : :
566 : 0 : *pInfo = 0;
567 : 0 : pEndDestBuf = pDestBuf+nDestBytes;
568 : 0 : pEndSrcBuf = pSrcBuf+nSrcChars;
569 [ # # ]: 0 : while ( pSrcBuf < pEndSrcBuf )
570 : : {
571 : 0 : c = *pSrcBuf;
572 : :
573 : : /* ASCII */
574 [ # # ]: 0 : if ( c <= 0x7F )
575 : 0 : cConv = c;
576 : : /* Half-width katakana */
577 [ # # ][ # # ]: 0 : else if ( (c >= 0xFF61) && (c <= 0xFF9F) )
578 : 0 : cConv = 0x8E00+0xA1+(c-0xFF61);
579 : : else
580 : : {
581 : 0 : nHighChar = (sal_uChar)((c >> 8) & 0xFF);
582 : 0 : nLowChar = (sal_uChar)(c & 0xFF);
583 : :
584 : : /* JIS 0208 */
585 : 0 : pHighTab = pConvertData->mpUniToJIS0208HighTab;
586 : 0 : pHighEntry = pHighTab+nHighChar;
587 [ # # ][ # # ]: 0 : if ( (nLowChar >= pHighEntry->mnLowStart) && (nLowChar <= pHighEntry->mnLowEnd) )
588 : : {
589 : 0 : cConv = pHighEntry->mpToUniTrailTab[nLowChar-pHighEntry->mnLowStart];
590 [ # # ]: 0 : if (cConv != 0)
591 : 0 : cConv |= 0x8080;
592 : : }
593 : : else
594 : 0 : cConv = 0;
595 : :
596 : : /* JIS 0212 */
597 [ # # ]: 0 : if ( !cConv )
598 : : {
599 : 0 : pHighTab = pConvertData->mpUniToJIS0212HighTab;
600 : 0 : pHighEntry = pHighTab+nHighChar;
601 [ # # ][ # # ]: 0 : if ( (nLowChar >= pHighEntry->mnLowStart) && (nLowChar <= pHighEntry->mnLowEnd) )
602 : : {
603 : 0 : cConv = pHighEntry->mpToUniTrailTab[nLowChar-pHighEntry->mnLowStart];
604 [ # # ]: 0 : if (cConv != 0)
605 : 0 : cConv |= 0x8F8080;
606 : : }
607 : :
608 [ # # ]: 0 : if ( !cConv )
609 : : {
610 : 0 : if ( nFlags & RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE )
611 : : {
612 : : /* !!! */
613 : : }
614 : :
615 : 0 : if ( nFlags & RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR )
616 : : {
617 : : /* !!! */
618 : : }
619 : :
620 : : /* Handle undefined and surrogates characters */
621 : : /* (all surrogates characters are undefined) */
622 [ # # ]: 0 : if (sal::detail::textenc::handleUndefinedUnicodeToTextChar(
623 : : &pSrcBuf, pEndSrcBuf, &pDestBuf, pEndDestBuf,
624 : : nFlags, pInfo))
625 : 0 : continue;
626 : : else
627 : 0 : break;
628 : : }
629 : : }
630 : : }
631 : :
632 : : /* SingleByte */
633 [ # # ]: 0 : if ( !(cConv & 0xFFFF00) )
634 : : {
635 [ # # ]: 0 : if ( pDestBuf == pEndDestBuf )
636 : : {
637 : 0 : *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
638 : 0 : break;
639 : : }
640 : :
641 : 0 : *pDestBuf = static_cast< char >(static_cast< unsigned char >(cConv & 0xFF));
642 : 0 : pDestBuf++;
643 : : }
644 : : /* DoubleByte */
645 [ # # ]: 0 : else if ( !(cConv & 0xFF0000) )
646 : : {
647 [ # # ]: 0 : if ( pDestBuf+1 >= pEndDestBuf )
648 : : {
649 : 0 : *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
650 : 0 : break;
651 : : }
652 : :
653 : 0 : *pDestBuf = static_cast< char >(static_cast< unsigned char >((cConv >> 8) & 0xFF));
654 : 0 : pDestBuf++;
655 : 0 : *pDestBuf = static_cast< char >(static_cast< unsigned char >(cConv & 0xFF));
656 : 0 : pDestBuf++;
657 : : }
658 : : else
659 : : {
660 [ # # ]: 0 : if ( pDestBuf+2 >= pEndDestBuf )
661 : : {
662 : 0 : *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
663 : 0 : break;
664 : : }
665 : :
666 : 0 : *pDestBuf = static_cast< char >(static_cast< unsigned char >((cConv >> 16) & 0xFF));
667 : 0 : pDestBuf++;
668 : 0 : *pDestBuf = static_cast< char >(static_cast< unsigned char >((cConv >> 8) & 0xFF));
669 : 0 : pDestBuf++;
670 : 0 : *pDestBuf = static_cast< char >(static_cast< unsigned char >(cConv & 0xFF));
671 : 0 : pDestBuf++;
672 : : }
673 : :
674 : 0 : pSrcBuf++;
675 : : }
676 : :
677 : 0 : *pSrcCvtChars = nSrcChars - (pEndSrcBuf-pSrcBuf);
678 : 0 : return (nDestBytes - (pEndDestBuf-pDestBuf));
679 : : }
680 : :
681 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|