fixed Windows build errors
[public/netxms.git] / src / libnetxms / cc_ucs4.cpp
CommitLineData
7768852d
VK
1/*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003-2016 Raden Solutions
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU Lesser General Public License as published
7 ** by the Free Software Foundation; either version 3 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU Lesser General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 **
19 ** File: cc_ucs4.cpp
20 **
21 **/
22
23#include "libnetxms.h"
24#include "unicode_cc.h"
25
26/**
27 * Convert UCS-4 to UCS-2 - internal dumb method
28 */
29static int __internal_ucs4_to_ucs2(const UCS4CHAR *src, int srcLen, UCS2CHAR *dst, int dstLen)
30{
31 int i, len;
32
33 len = (int)((srcLen == -1) ? ucs4_strlen(src) : srcLen);
34 if (len > (int)dstLen - 1)
35 len = (int)dstLen - 1;
36 for(i = 0; i < len; i++)
37 dst[i] = (UCS2CHAR)src[i];
38 dst[i] = 0;
39 return len;
40}
41
42/**
43 * Convert UCS-4 to UCS-2
44 */
45int LIBNETXMS_EXPORTABLE ucs4_to_ucs2(const UCS4CHAR *src, int srcLen, UCS2CHAR *dst, int dstLen)
46{
669fcb92 47#if !defined(__DISABLE_ICONV) && !defined(_WIN32)
7768852d
VK
48 iconv_t cd;
49 const char *inbuf;
50 char *outbuf;
51 size_t count, inbytes, outbytes;
52
53 cd = IconvOpen(UCS2_CODEPAGE_NAME, UCS4_CODEPAGE_NAME);
54 if (cd == (iconv_t)(-1))
55 {
56 return __internal_ucs4_to_ucs2(src, srcLen, dst, dstLen);
57 }
58
59 inbuf = (const char *) src;
60 inbytes = ((srcLen == -1) ? ucs4_strlen(src) + 1 : (size_t)srcLen) * sizeof(UCS4CHAR);
61 outbuf = (char *)dst;
62 outbytes = (size_t)dstLen * sizeof(UCS2CHAR);
63 count = iconv(cd, (ICONV_CONST char **) &inbuf, &inbytes, &outbuf, &outbytes);
64 IconvClose(cd);
65
66 if (count == (size_t) - 1)
67 {
68 if (errno == EILSEQ)
69 {
70 count = (dstLen * sizeof(UCS2CHAR) - outbytes) / sizeof(UCS2CHAR);
71 }
72 else
73 {
74 count = 0;
75 }
76 }
77 else
78 {
79 count = (dstLen * sizeof(UCS2CHAR) - outbytes) / sizeof(UCS2CHAR);
80 }
81 if (((char *) outbuf - (char *) dst > sizeof(UCS2CHAR)) && (*dst == 0xFEFF))
82 {
83 // Remove UNICODE byte order indicator if presented
84 memmove(dst, &dst[1], (char *) outbuf - (char *) dst - sizeof(UCS2CHAR));
85 outbuf -= sizeof(UCS2CHAR);
86 }
87 if ((srcLen == -1) && (outbytes >= sizeof(UCS2CHAR)))
88 {
89 *((UCS2CHAR *)outbuf) = 0;
90 }
91
92 return (int)count;
93#else
94 return __internal_ucs4_to_ucs2(src, srcLen, dst, dstLen);
95#endif
96}
97
98#if defined(_WIN32)
99
100/**
101 * Convert UCS-4 to UTF-8
102 */
103int LIBNETXMS_EXPORTABLE ucs4_to_utf8(const UCS4CHAR *src, int srcLen, char *dst, int dstLen)
104{
105 int len = (srcLen < 0) ? (int)ucs4_strlen(src) + 1 : srcLen;
106 WCHAR *buffer = (len <= 32768) ? (WCHAR *)alloca(len * sizeof(WCHAR)) : (WCHAR *)malloc(len * sizeof(WCHAR));
107 ucs4_to_ucs2(src, srcLen, buffer, len);
108 int ret = WideCharToMultiByte(CP_UTF8, 0, buffer, srcLen, dst, dstLen, NULL, NULL);
109 if (len > 32768)
110 free(buffer);
111 return ret;
112}
113
114/**
115 * Convert UCS-4 to multibyte
116 */
117int LIBNETXMS_EXPORTABLE ucs4_to_mb(const UCS4CHAR *src, int srcLen, char *dst, int dstLen)
118{
119 int len = (srcLen < 0) ? (int)ucs4_strlen(src) + 1 : srcLen;
120 WCHAR *buffer = (len <= 32768) ? (WCHAR *)alloca(len * sizeof(WCHAR)) : (WCHAR *)malloc(len * sizeof(WCHAR));
121 ucs4_to_ucs2(src, srcLen, buffer, len);
122 int ret = WideCharToMultiByte(CP_ACP, WC_DEFAULTCHAR | WC_COMPOSITECHECK, buffer, srcLen, dst, dstLen, NULL, NULL);
123 if (len > 32768)
124 free(buffer);
125 return ret;
126}
127
128#elif !defined(UNICODE_UCS4)
129
130/**
131 * Convert UCS-4 to UTF-8 using stub (no actual conversion for character codes above 0x007F)
132 */
133static int __internal_ucs4_to_utf8(const UCS4CHAR *src, int srcLen, char *dst, int dstLen)
134{
135 const UCS4CHAR *psrc;
136 char *pdst;
137 int pos, size;
138
139 size = (srcLen == -1) ? ucs4_strlen(src) : srcLen;
140 if (size >= dstLen)
141 size = dstLen - 1;
142 for(psrc = src, pos = 0, pdst = dst; pos < size; pos++, psrc++, pdst++)
143 *pdst = (*psrc < 128) ? (char) (*psrc) : '?';
144 *pdst = 0;
145 return size;
146}
147
148/**
149 * Convert UCS-4 to UTF-8
150 */
151int LIBNETXMS_EXPORTABLE ucs4_to_utf8(const UCS4CHAR *src, int srcLen, char *dst, int dstLen)
152{
153#if HAVE_ICONV && !defined(__DISABLE_ICONV)
154 iconv_t cd;
155 const char *inbuf;
156 char *outbuf;
157 size_t count, inbytes, outbytes;
158
159 cd = IconvOpen("UTF-8", UCS4_CODEPAGE_NAME);
160 if (cd == (iconv_t) (-1))
161 {
162 return __internal_ucs4_to_utf8(src, srcLen, dst, dstLen);
163 }
164
165 inbuf = (const char *) src;
166 inbytes = ((srcLen == -1) ? ucs2_strlen(src) + 1 : (size_t) srcLen) * sizeof(UCS4CHAR);
167 outbuf = (char *) dst;
168 outbytes = (size_t) dstLen;
169 count = iconv(cd, (ICONV_CONST char **) &inbuf, &inbytes, &outbuf, &outbytes);
170 IconvClose(cd);
171
172 if (count == (size_t) - 1)
173 {
174 if (errno == EILSEQ)
175 {
176 count = (dstLen * sizeof(char) - outbytes) / sizeof(char);
177 }
178 else
179 {
180 count = 0;
181 }
182 }
183 else
184 {
185 count = dstLen - outbytes;
186 }
187 if ((srcLen == -1) && (outbytes >= sizeof(char)))
188 {
189 *((char *) outbuf) = 0;
190 }
191
192 return (int)count;
193#else
194 return __internal_ucs4_to_utf8(src, srcLen, dst, dstLen);
195#endif
196}
197
198/**
199 * Convert UCS-4 to multibyte using stub (no actual conversion for character codes above 0x007F)
200 */
201static int __internal_ucs4_to_mb(const UCS4CHAR *src, int srcLen, char *dst, int dstLen)
202{
203 const UCS4CHAR *psrc;
204 char *pdst;
205 int pos, size;
206
207 size = (srcLen == -1) ? (int) ucs4_strlen(src) : srcLen;
208 if (size >= dstLen)
209 size = dstLen - 1;
210
211 for(psrc = src, pos = 0, pdst = dst; pos < size; pos++, psrc++, pdst++)
212 *pdst = (*psrc < 256) ? (char) (*psrc) : '?';
213 *pdst = 0;
214
215 return size;
216}
217
218/**
219 * Convert UCS-4 to multibyte
220 */
221int LIBNETXMS_EXPORTABLE ucs4_to_mb(const UCS4CHAR *src, int srcLen, char *dst, int dstLen)
222{
223#if HAVE_ICONV && !defined(__DISABLE_ICONV)
224 iconv_t cd;
225 const char *inbuf;
226 char *outbuf;
227 size_t count, inbytes, outbytes;
228
229 cd = IconvOpen(g_cpDefault, UCS4_CODEPAGE_NAME);
230 if (cd == (iconv_t) (-1))
231 {
232 return __internal_ucs4_to_mb(src, srcLen, dst, dstLen);
233 }
234
235 inbuf = (const char *) src;
236 inbytes = ((srcLen == -1) ? ucs4_strlen(src) + 1 : (size_t) srcLen) * sizeof(UCS4CHAR);
237 outbuf = (char *) dst;
238 outbytes = (size_t) dstLen;
239 count = iconv(cd, (ICONV_CONST char **) &inbuf, &inbytes, &outbuf, &outbytes);
240 IconvClose(cd);
241
242 if (count == (size_t) - 1)
243 {
244 if (errno == EILSEQ)
245 {
246 count = (dstLen * sizeof(char) - outbytes) / sizeof(char);
247 }
248 else
249 {
250 count = 0;
251 }
252 }
253 if ((srcLen == -1) && (outbytes >= sizeof(char)))
254 {
255 *((char *) outbuf) = 0;
256 }
257
258 return (int)count;
259#else
260 return __internal_ucs4_to_mb(src, srcLen, dst, dstLen);
261#endif
262}
263
264#endif