Coverage Report

Created: 2026-09-28 10:59

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