COPASI API  4.16.103
CLocaleString.cpp
Go to the documentation of this file.
1 // Copyright (C) 2011 - 2015 by Pedro Mendes, Virginia Tech Intellectual
2 // Properties, Inc., University of Heidelberg, and The University
3 // of Manchester.
4 // All rights reserved.
5 
6 #include "CLocaleString.h"
7 
8 #include <stdlib.h>
9 #include <string.h>
10 
11 #ifdef WIN32
12 # include <windows.h>
13 # define strdup _wcsdup
14 #endif // WIN32
15 
16 #if (defined SunOS || defined Linux)
17 # include <errno.h>
18 # include <iconv.h>
19 # include <langinfo.h>
20 #endif // SunOS || Linux
21 
22 #if (defined SunOS || defined Linux)
23 const char * findLocale()
24 {
25  static char * Locale = NULL;
26 
27  if (Locale == NULL)
28  Locale = strdup(nl_langinfo(CODESET));
29 
30 #ifdef SunOS
31 
32  if (strcmp(Locale, "646") == 0)
33  pfree(Locale);
34 
35  if (Locale == NULL)
36  Locale = strdup("8859-1");
37 
38 #else
39 
40  if (Locale == NULL)
41  Locale = strdup("ISO-8859-1");
42 
43 #endif
44 
45  return Locale;
46 }
47 #endif // SunOS || Linux
48 
49 // static
50 CLocaleString CLocaleString::fromUtf8(const std::string & utf8)
51 {
52 #ifdef WIN32
53  int size;
54 
55  size = MultiByteToWideChar(CP_UTF8, // code page
56  MB_ERR_INVALID_CHARS, // character-type options
57  utf8.c_str(), // address of string to map
58  -1, // NULL terminated
59  NULL, // address of wide-character buffer
60  0) + 1; // size of buffer
61 
62  WCHAR * pWideChar = new WCHAR[size];
63 
64  MultiByteToWideChar(CP_UTF8, // code page
65  MB_ERR_INVALID_CHARS, // character-type options
66  utf8.c_str(), // address of string to map
67  -1, // NULL terminated
68  pWideChar, // address of wide-character buffer
69  size); // size of buffer
70 
71  CLocaleString Locale(pWideChar);
72  delete [] pWideChar;
73 
74  return Locale;
75 #endif // WIN32
76 
77 #if (defined SunOS || defined Linux)
78  static iconv_t Converter = NULL;
79 
80  if (Converter == NULL)
81  {
82  char From[] = "UTF-8";
83  const char * To = findLocale();
84 
85  Converter = iconv_open(To, From);
86  }
87 
88  if (Converter == (iconv_t)(-1))
89  return CLocaleString(utf8.c_str());
90 
91  size_t Utf8Length = utf8.length();
92  char * Utf8 = strdup(utf8.c_str());
93 #if (defined COPASI_ICONV_CONST_CHAR) // non standard iconv declaration :(
94  const char * pUtf8 = Utf8;
95 #else
96  char * pUtf8 = Utf8;
97 #endif
98 
99  size_t LocaleLength = Utf8Length + 1;
100  size_t SpaceLeft = Utf8Length;
101  char * Locale = new char[LocaleLength];
102  char * pLocale = Locale;
103 
104  while (Utf8Length)
105  if ((size_t)(-1) ==
106  iconv(Converter, &pUtf8, &Utf8Length, &pLocale, &SpaceLeft))
107  {
108  switch (errno)
109  {
110  case EILSEQ:
111  pUtf8 = Utf8;
112  LocaleLength = 0;
113  break;
114 
115  case EINVAL:
116  pLocale = Locale;
117  Utf8Length = 0;
118  break;
119 
120  case E2BIG:
121  char * pTmp = Locale;
122  size_t OldLength = LocaleLength;
123  LocaleLength += 2 * Utf8Length;
124 
125  Locale = new char[LocaleLength];
126  memcpy(Locale, pTmp,
127  sizeof(char) * (OldLength - SpaceLeft - 1));
128  pLocale = Locale + OldLength - SpaceLeft - 1;
129  SpaceLeft += 2 * Utf8Length;
130  delete [] pTmp;
131 
132  break;
133  }
134 
135  continue;
136  }
137 
138  *pLocale = 0x00; // NULL terminate the string.
139  CLocaleString Result(Locale);
140 
141  // Reset the Converter
142  iconv(Converter, NULL, &Utf8Length, NULL, &LocaleLength);
143 
144  // Release memory
145  free(Utf8);
146  delete [] Locale;
147 
148  return Result;
149 #endif // SunOS || Linux
150 
151 #ifdef Darwin
152  return CLocaleString(utf8.c_str());
153 #endif
154 }
155 
157  mpStr(NULL)
158 {}
159 
161  mpStr((str != NULL) ? strdup(str) : NULL)
162 {}
163 
165  mpStr((src.mpStr != NULL) ? strdup(src.mpStr) : NULL)
166 {}
167 
169 {
170  if (mpStr != NULL)
171  {
172  free(mpStr);
173  mpStr = NULL;
174  }
175 }
176 
178 {
179  if (mpStr != NULL)
180  {
181  free(mpStr);
182  mpStr = NULL;
183  }
184 
185  mpStr = (rhs.mpStr != NULL) ? strdup(rhs.mpStr) : NULL;
186 
187  return *this;
188 }
189 
191 {
192  if (mpStr != NULL)
193  {
194  free(mpStr);
195  mpStr = NULL;
196  }
197 
198  mpStr = (rhs != NULL) ? strdup(rhs) : NULL;
199 
200  return *this;
201 }
202 
203 std::string CLocaleString::toUtf8() const
204 {
205  if (mpStr == NULL)
206  {
207  return "";
208  }
209 
210 #ifdef WIN32
211  int size;
212 
213  size = WideCharToMultiByte(CP_UTF8, // code page
214  0, // performance and mapping flags
215  mpStr, // address of wide-character string
216  -1, // NULL terminated
217  NULL, // address of buffer for new string
218  0, // size of buffer
219  NULL, // address of default for unmappable characters
220  NULL) + 1; // address of flag set when default char used
221 
222  char * pUtf8 = new char[size];
223 
224  WideCharToMultiByte(CP_UTF8, // code page
225  0, // address of wide-character string
226  mpStr, // address of wide-character string
227  -1, // NULL terminated
228  pUtf8, // address of buffer for new string
229  size, // size of buffer
230  NULL, // address of default for unmappable characters
231  NULL); // address of flag set when default char used
232 
233  std::string Utf8 = pUtf8;
234  delete [] pUtf8;
235 
236  return Utf8;
237 #endif // WIN32
238 
239 #if (defined SunOS || defined Linux)
240  static iconv_t Converter = NULL;
241 
242  if (Converter == NULL)
243  {
244  char To[] = "UTF-8";
245  const char * From = findLocale();
246 
247  Converter = iconv_open(To, From);
248  }
249 
250  if (Converter == (iconv_t)(-1))
251  return mpStr;
252 
253  size_t LocaleLength = strlen(mpStr);
254  char * Locale = strdup(mpStr);
255 #if (COPASI_ICONV_CONST_CHAR) // non standard iconv declaration :(
256  const char * pLocale = Locale;
257 #else
258  char * pLocale = Locale;
259 #endif
260 
261  size_t Utf8Length = LocaleLength + 1;
262  size_t SpaceLeft = LocaleLength;
263  char * Utf8 = new char[Utf8Length];
264  char * pUtf8 = Utf8;
265 
266  while (LocaleLength)
267  if ((size_t)(-1) ==
268  iconv(Converter, &pLocale, &LocaleLength, &pUtf8, &SpaceLeft))
269  {
270  switch (errno)
271  {
272  case EILSEQ:
273  pUtf8 = Utf8;
274  LocaleLength = 0;
275  break;
276 
277  case EINVAL:
278  pUtf8 = Utf8;
279  LocaleLength = 0;
280  break;
281 
282  case E2BIG:
283  char * pTmp = Utf8;
284  size_t OldLength = Utf8Length;
285  Utf8Length += 2 * LocaleLength;
286 
287  Utf8 = new char[Utf8Length];
288  memcpy(Utf8, pTmp,
289  sizeof(char) * (OldLength - SpaceLeft - 1));
290  pUtf8 = Utf8 + OldLength - SpaceLeft - 1;
291  SpaceLeft += 2 * LocaleLength;
292  delete [] pTmp;
293 
294  break;
295  }
296 
297  continue;
298  }
299 
300  *pUtf8 = 0x00; // NULL terminate the string.
301  std::string Result = Utf8;
302 
303  // Reset the Converter
304  iconv(Converter, NULL, &LocaleLength, NULL, &Utf8Length);
305 
306  // Release memory
307  free(Locale);
308  delete [] Utf8;
309 
310  return Result;
311 #endif // SunOS || Linux
312 
313 #ifdef Darwin
314  std::string Result = mpStr;
315  return Result;
316 #endif // Darwin
317 }
318 
320 {
321  return mpStr;
322 }
#define pfree(p)
Definition: copasi.h:214
CLocaleString & operator=(const CLocaleString &rhs)
const lchar * c_str() const
std::string toUtf8() const
static CLocaleString fromUtf8(const std::string &utf8)