Line data Source code
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 :
10 : #include "sal/config.h"
11 :
12 : #include "rtl/textcvt.h"
13 : #include "sal/types.h"
14 :
15 : #include "handleundefinedunicodetotextchar.hxx"
16 : #include "tenchelp.hxx"
17 :
18 : namespace {
19 :
20 379831 : bool ImplIsUnicodeIgnoreChar(sal_Unicode c, sal_uInt32 nFlags)
21 : {
22 : return
23 379831 : ((nFlags & RTL_UNICODETOTEXT_FLAGS_NONSPACING_IGNORE) != 0
24 0 : && ImplIsZeroWidth(c))
25 379831 : || ((nFlags & RTL_UNICODETOTEXT_FLAGS_CONTROL_IGNORE) != 0
26 0 : && ImplIsControlOrFormat(c))
27 759662 : || ((nFlags & RTL_UNICODETOTEXT_FLAGS_PRIVATE_IGNORE) != 0
28 379831 : && ImplIsPrivateUse(c));
29 : }
30 :
31 597 : bool ImplGetUndefinedAsciiMultiByte(sal_uInt32 nFlags,
32 : char * pBuf,
33 : sal_Size nMaxLen)
34 : {
35 597 : if (nMaxLen == 0)
36 0 : return false;
37 597 : switch (nFlags & RTL_UNICODETOTEXT_FLAGS_UNDEFINED_MASK)
38 : {
39 : case RTL_UNICODETOTEXT_FLAGS_UNDEFINED_0:
40 0 : *pBuf = 0x00;
41 0 : break;
42 :
43 : case RTL_UNICODETOTEXT_FLAGS_UNDEFINED_QUESTIONMARK:
44 : default: /* RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT */
45 597 : *pBuf = 0x3F;
46 597 : break;
47 :
48 : case RTL_UNICODETOTEXT_FLAGS_UNDEFINED_UNDERLINE:
49 0 : *pBuf = 0x5F;
50 0 : break;
51 : }
52 597 : return true;
53 : }
54 :
55 0 : bool ImplGetInvalidAsciiMultiByte(sal_uInt32 nFlags,
56 : char * pBuf,
57 : sal_Size nMaxLen)
58 : {
59 0 : if (nMaxLen == 0)
60 0 : return false;
61 0 : switch (nFlags & RTL_UNICODETOTEXT_FLAGS_INVALID_MASK)
62 : {
63 : case RTL_UNICODETOTEXT_FLAGS_INVALID_0:
64 0 : *pBuf = 0x00;
65 0 : break;
66 :
67 : case RTL_UNICODETOTEXT_FLAGS_INVALID_QUESTIONMARK:
68 : default: /* RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT */
69 0 : *pBuf = 0x3F;
70 0 : break;
71 :
72 : case RTL_UNICODETOTEXT_FLAGS_INVALID_UNDERLINE:
73 0 : *pBuf = 0x5F;
74 0 : break;
75 : }
76 0 : return true;
77 : }
78 :
79 : }
80 :
81 379831 : bool sal::detail::textenc::handleUndefinedUnicodeToTextChar(
82 : sal_Unicode const ** ppSrcBuf, sal_Unicode const * pEndSrcBuf,
83 : char ** ppDestBuf, char const * pEndDestBuf, sal_uInt32 nFlags,
84 : sal_uInt32 * pInfo)
85 : {
86 379831 : sal_Unicode c = **ppSrcBuf;
87 :
88 : /* Should the private character map to one byte */
89 379831 : if ( (c >= RTL_TEXTCVT_BYTE_PRIVATE_START) && (c <= RTL_TEXTCVT_BYTE_PRIVATE_END) )
90 : {
91 0 : if ( nFlags & RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 )
92 : {
93 0 : **ppDestBuf = (char)(unsigned char)(c-RTL_TEXTCVT_BYTE_PRIVATE_START);
94 0 : (*ppDestBuf)++;
95 0 : (*ppSrcBuf)++;
96 0 : return true;
97 : }
98 : }
99 :
100 : /* Should this character ignored (Private, Non Spacing, Control) */
101 379831 : if ( ImplIsUnicodeIgnoreChar( c, nFlags ) )
102 : {
103 0 : (*ppSrcBuf)++;
104 0 : return true;
105 : }
106 :
107 : /* Surrogates Characters should result in */
108 : /* one replacement character */
109 379831 : if (ImplIsHighSurrogate(c))
110 : {
111 15360 : if ( ((*ppSrcBuf) + 1) == pEndSrcBuf )
112 : {
113 15360 : *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR | RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
114 15360 : return false;
115 : }
116 :
117 0 : c = *((*ppSrcBuf)+1);
118 0 : if (ImplIsLowSurrogate(c))
119 0 : (*ppSrcBuf)++;
120 : else
121 : {
122 0 : *pInfo |= RTL_UNICODETOTEXT_INFO_INVALID;
123 0 : if ( (nFlags & RTL_UNICODETOTEXT_FLAGS_INVALID_MASK) == RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR )
124 : {
125 0 : *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR;
126 0 : return false;
127 : }
128 0 : else if ( (nFlags & RTL_UNICODETOTEXT_FLAGS_INVALID_MASK) == RTL_UNICODETOTEXT_FLAGS_INVALID_IGNORE )
129 : {
130 0 : (*ppSrcBuf)++;
131 0 : return true;
132 : }
133 0 : else if (ImplGetInvalidAsciiMultiByte(nFlags,
134 : *ppDestBuf,
135 0 : pEndDestBuf - *ppDestBuf))
136 : {
137 0 : ++*ppSrcBuf;
138 0 : ++*ppDestBuf;
139 0 : return true;
140 : }
141 : else
142 : {
143 : *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR
144 0 : | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
145 0 : return false;
146 : }
147 : }
148 : }
149 :
150 364471 : *pInfo |= RTL_UNICODETOTEXT_INFO_UNDEFINED;
151 364471 : if ( (nFlags & RTL_UNICODETOTEXT_FLAGS_UNDEFINED_MASK) == RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR )
152 : {
153 363538 : *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR;
154 363538 : return false;
155 : }
156 933 : else if ( (nFlags & RTL_UNICODETOTEXT_FLAGS_UNDEFINED_MASK) == RTL_UNICODETOTEXT_FLAGS_UNDEFINED_IGNORE )
157 336 : (*ppSrcBuf)++;
158 597 : else if (ImplGetUndefinedAsciiMultiByte(nFlags,
159 : *ppDestBuf,
160 597 : pEndDestBuf - *ppDestBuf))
161 : {
162 597 : ++*ppSrcBuf;
163 597 : ++*ppDestBuf;
164 : }
165 : else
166 : {
167 : *pInfo |= RTL_UNICODETOTEXT_INFO_ERROR
168 0 : | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
169 0 : return false;
170 : }
171 :
172 933 : return true;
173 : }
174 :
175 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|