source: vendor/synergy/1.3.1/lib/arch/CMultibyte.cpp

Last change on this file was 2749, checked in by bird, 19 years ago

synergy v1.3.1 sources (zip).

File size: 4.2 KB
Line 
1/*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2002 Chris Schoeneman
4 *
5 * This package is free software you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * found in the file COPYING that should have accompanied this file.
8 *
9 * This package is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#ifndef CMULTIBYTE_H
16#define CMULTIBYTE_H
17
18#include "common.h"
19#include "CArch.h"
20#include <limits.h>
21#include <string.h>
22#if HAVE_LOCALE_H
23# include <locale.h>
24#endif
25#if HAVE_WCHAR_H || defined(_MSC_VER)
26# include <wchar.h>
27#elif __APPLE__
28 // wtf? Darwin puts mbtowc() et al. in stdlib
29# include <stdlib.h>
30#else
31 // platform apparently has no wchar_t support. provide dummy
32 // implementations. hopefully at least the C++ compiler has
33 // a built-in wchar_t type.
34
35static inline
36int
37mbtowc(wchar_t* dst, const char* src, int n)
38{
39 *dst = static_cast<wchar_t>(*src);
40 return 1;
41}
42
43static inline
44int
45wctomb(char* dst, wchar_t src)
46{
47 *dst = static_cast<char>(src);
48 return 1;
49}
50
51#endif
52
53//
54// use C library non-reentrant multibyte conversion with mutex
55//
56
57static CArchMutex s_mutex = NULL;
58
59ARCH_STRING::ARCH_STRING()
60{
61 s_mutex = ARCH->newMutex();
62
63#if HAVE_LOCALE_H
64 // see if we can convert a Latin-1 character
65 char mb[MB_LEN_MAX];
66 if (wctomb(mb, 0xe3) == -1) {
67 // can't convert. try another locale so we can convert latin-1.
68 setlocale(LC_CTYPE, "en_US");
69 }
70#endif
71}
72
73ARCH_STRING::~ARCH_STRING()
74{
75 ARCH->closeMutex(s_mutex);
76 s_mutex = NULL;
77}
78
79int
80ARCH_STRING::convStringWCToMB(char* dst,
81 const wchar_t* src, UInt32 n, bool* errors)
82{
83 int len = 0;
84
85 bool dummyErrors;
86 if (errors == NULL) {
87 errors = &dummyErrors;
88 }
89
90 ARCH->lockMutex(s_mutex);
91 if (dst == NULL) {
92 char dummy[MB_LEN_MAX];
93 for (const wchar_t* scan = src; n > 0; ++scan, --n) {
94 int mblen = wctomb(dummy, *scan);
95 if (mblen == -1) {
96 *errors = true;
97 mblen = 1;
98 }
99 len += mblen;
100 }
101 int mblen = wctomb(dummy, L'\0');
102 if (mblen != -1) {
103 len += mblen - 1;
104 }
105 }
106 else {
107 char* dst0 = dst;
108 for (const wchar_t* scan = src; n > 0; ++scan, --n) {
109 int mblen = wctomb(dst, *scan);
110 if (mblen == -1) {
111 *errors = true;
112 *dst++ = '?';
113 }
114 else {
115 dst += mblen;
116 }
117 }
118 int mblen = wctomb(dst, L'\0');
119 if (mblen != -1) {
120 // don't include nul terminator
121 dst += mblen - 1;
122 }
123 len = (int)(dst - dst0);
124 }
125 ARCH->unlockMutex(s_mutex);
126
127 return len;
128}
129
130int
131ARCH_STRING::convStringMBToWC(wchar_t* dst,
132 const char* src, UInt32 n, bool* errors)
133{
134 int len = 0;
135 wchar_t dummy;
136
137 bool dummyErrors;
138 if (errors == NULL) {
139 errors = &dummyErrors;
140 }
141
142 ARCH->lockMutex(s_mutex);
143 if (dst == NULL) {
144 for (const char* scan = src; n > 0; ) {
145 int mblen = mbtowc(&dummy, scan, n);
146 switch (mblen) {
147 case -2:
148 // incomplete last character. convert to unknown character.
149 *errors = true;
150 len += 1;
151 n = 0;
152 break;
153
154 case -1:
155 // invalid character. count one unknown character and
156 // start at the next byte.
157 *errors = true;
158 len += 1;
159 scan += 1;
160 n -= 1;
161 break;
162
163 case 0:
164 len += 1;
165 scan += 1;
166 n -= 1;
167 break;
168
169 default:
170 // normal character
171 len += 1;
172 scan += mblen;
173 n -= mblen;
174 break;
175 }
176 }
177 }
178 else {
179 wchar_t* dst0 = dst;
180 for (const char* scan = src; n > 0; ++dst) {
181 int mblen = mbtowc(dst, scan, n);
182 switch (mblen) {
183 case -2:
184 // incomplete character. convert to unknown character.
185 *errors = true;
186 *dst = (wchar_t)0xfffd;
187 n = 0;
188 break;
189
190 case -1:
191 // invalid character. count one unknown character and
192 // start at the next byte.
193 *errors = true;
194 *dst = (wchar_t)0xfffd;
195 scan += 1;
196 n -= 1;
197 break;
198
199 case 0:
200 *dst = (wchar_t)0x0000;
201 scan += 1;
202 n -= 1;
203 break;
204
205 default:
206 // normal character
207 scan += mblen;
208 n -= mblen;
209 break;
210 }
211 }
212 len = (int)(dst - dst0);
213 }
214 ARCH->unlockMutex(s_mutex);
215
216 return len;
217}
218
219#endif
Note: See TracBrowser for help on using the repository browser.