00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef CMULTIBYTE_H
00016 #define CMULTIBYTE_H
00017
00018 #include "common.h"
00019 #include "CArch.h"
00020 #include <climits>
00021 #include <cstring>
00022 #include <cstdlib>
00023 #if HAVE_LOCALE_H
00024 # include <locale.h>
00025 #endif
00026 #if HAVE_WCHAR_H || defined(_MSC_VER)
00027 # include <wchar.h>
00028 #elif __APPLE__
00029
00030 # include <cstdlib>
00031 #else
00032
00033
00034
00035
00036 static inline
00037 int
00038 mbtowc(wchar_t* dst, const char* src, int n)
00039 {
00040 *dst = static_cast<wchar_t>(*src);
00041 return 1;
00042 }
00043
00044 static inline
00045 int
00046 wctomb(char* dst, wchar_t src)
00047 {
00048 *dst = static_cast<char>(src);
00049 return 1;
00050 }
00051
00052 #endif
00053
00054
00055
00056
00057
00058 static CArchMutex s_mutex = NULL;
00059
00060 ARCH_STRING::ARCH_STRING()
00061 {
00062 s_mutex = ARCH->newMutex();
00063
00064 #if HAVE_LOCALE_H
00065
00066 char mb[MB_LEN_MAX];
00067 if (wctomb(mb, 0xe3) == -1) {
00068
00069 setlocale(LC_CTYPE, "en_US");
00070 }
00071 #endif
00072 }
00073
00074 ARCH_STRING::~ARCH_STRING()
00075 {
00076 ARCH->closeMutex(s_mutex);
00077 s_mutex = NULL;
00078 }
00079
00080 int
00081 ARCH_STRING::convStringWCToMB(char* dst,
00082 const wchar_t* src, UInt32 n, bool* errors)
00083 {
00084 int len = 0;
00085
00086 bool dummyErrors;
00087 if (errors == NULL) {
00088 errors = &dummyErrors;
00089 }
00090
00091 ARCH->lockMutex(s_mutex);
00092 if (dst == NULL) {
00093 char dummy[MB_LEN_MAX];
00094 for (const wchar_t* scan = src; n > 0; ++scan, --n) {
00095 int mblen = wctomb(dummy, *scan);
00096 if (mblen == -1) {
00097 *errors = true;
00098 mblen = 1;
00099 }
00100 len += mblen;
00101 }
00102 int mblen = wctomb(dummy, L'\0');
00103 if (mblen != -1) {
00104 len += mblen - 1;
00105 }
00106 }
00107 else {
00108 char* dst0 = dst;
00109 for (const wchar_t* scan = src; n > 0; ++scan, --n) {
00110 int mblen = wctomb(dst, *scan);
00111 if (mblen == -1) {
00112 *errors = true;
00113 *dst++ = '?';
00114 }
00115 else {
00116 dst += mblen;
00117 }
00118 }
00119 int mblen = wctomb(dst, L'\0');
00120 if (mblen != -1) {
00121
00122 dst += mblen - 1;
00123 }
00124 len = (int)(dst - dst0);
00125 }
00126 ARCH->unlockMutex(s_mutex);
00127
00128 return len;
00129 }
00130
00131 int
00132 ARCH_STRING::convStringMBToWC(wchar_t* dst,
00133 const char* src, UInt32 n, bool* errors)
00134 {
00135 int len = 0;
00136 wchar_t dummy;
00137
00138 bool dummyErrors;
00139 if (errors == NULL) {
00140 errors = &dummyErrors;
00141 }
00142
00143 ARCH->lockMutex(s_mutex);
00144 if (dst == NULL) {
00145 for (const char* scan = src; n > 0; ) {
00146 int mblen = mbtowc(&dummy, scan, n);
00147 switch (mblen) {
00148 case -2:
00149
00150 *errors = true;
00151 len += 1;
00152 n = 0;
00153 break;
00154
00155 case -1:
00156
00157
00158 *errors = true;
00159 len += 1;
00160 scan += 1;
00161 n -= 1;
00162 break;
00163
00164 case 0:
00165 len += 1;
00166 scan += 1;
00167 n -= 1;
00168 break;
00169
00170 default:
00171
00172 len += 1;
00173 scan += mblen;
00174 n -= mblen;
00175 break;
00176 }
00177 }
00178 }
00179 else {
00180 wchar_t* dst0 = dst;
00181 for (const char* scan = src; n > 0; ++dst) {
00182 int mblen = mbtowc(dst, scan, n);
00183 switch (mblen) {
00184 case -2:
00185
00186 *errors = true;
00187 *dst = (wchar_t)0xfffd;
00188 n = 0;
00189 break;
00190
00191 case -1:
00192
00193
00194 *errors = true;
00195 *dst = (wchar_t)0xfffd;
00196 scan += 1;
00197 n -= 1;
00198 break;
00199
00200 case 0:
00201 *dst = (wchar_t)0x0000;
00202 scan += 1;
00203 n -= 1;
00204 break;
00205
00206 default:
00207
00208 scan += mblen;
00209 n -= mblen;
00210 break;
00211 }
00212 }
00213 len = (int)(dst - dst0);
00214 }
00215 ARCH->unlockMutex(s_mutex);
00216
00217 return len;
00218 }
00219
00220 #endif