aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/FbString.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/FbString.cc')
-rw-r--r--src/FbTk/FbString.cc207
1 files changed, 207 insertions, 0 deletions
diff --git a/src/FbTk/FbString.cc b/src/FbTk/FbString.cc
new file mode 100644
index 0000000..a88b237
--- /dev/null
+++ b/src/FbTk/FbString.cc
@@ -0,0 +1,207 @@
1// FbString.cc for fluxbox
2// Copyright (c) 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
3// Copyright (c) 2006 Simon Bowden (rathnor at fluxbox dot org)
4//
5// Permission is hereby granted, free of charge, to any person obtaining a
6// copy of this software and associated documentation files (the "Software"),
7// to deal in the Software without restriction, including without limitation
8// the rights to use, copy, modify, merge, publish, distribute, sublicense,
9// and/or sell copies of the Software, and to permit persons to whom the
10// Software is furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in
13// all copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21// DEALINGS IN THE SOFTWARE.
22
23// $Id$
24
25#ifdef HAVE_CERRNO
26 #include <cerrno>
27#else
28 #include <errno.h>
29#endif
30
31#include "FbString.hh"
32#include "config.h"
33
34#ifdef HAVE_ICONV
35#include <iconv.h>
36#endif // HAVE_ICONV
37#include <langinfo.h>
38#include <locale.h>
39
40#include <iostream>
41using namespace std;
42
43namespace FbTk {
44
45namespace FbStringUtil {
46
47enum ConvType { FB2X = 0, X2FB, LOCALE2FB, FB2LOCALE, CONVSIZE };
48
49#ifdef HAVE_ICONV
50static iconv_t *iconv_convs = 0;
51#else
52static int iconv_convs[CONVSIZE];
53#endif // HAVE_ICONV
54
55/// Initialise all of the iconv conversion descriptors
56void init() {
57 iconv_convs = new iconv_t[CONVSIZE];
58
59 setlocale(LC_CTYPE, "");
60
61#ifdef HAVE_ICONV
62#ifdef CODESET
63 std::string locale_codeset = nl_langinfo(CODESET);
64#else // openbsd doesnt have this (yet?)
65 std::string locale_codeset = "";
66 std::string locale = setlocale(LC_CTYPE, NULL);
67 size_t pos = locale.find('.');
68 if (pos != std::string::npos)
69 locale_codeset = locale.substr(pos);
70#endif // CODESET
71
72#ifdef DEBUG
73 cerr<<"FbTk::FbString: setup converts for local codeset = "<<locale_codeset<<endl;
74#endif // DEBUG
75
76 iconv_convs[FB2X] = iconv_open("ISO8859-1", "UTF-8");
77 iconv_convs[X2FB] = iconv_open("UTF-8", "ISO8859-1");
78 iconv_convs[FB2LOCALE] = iconv_open(locale_codeset.c_str(), "UTF-8");
79 iconv_convs[LOCALE2FB] = iconv_open("UTF-8", locale_codeset.c_str());
80#else
81 for (int i=0; i < CONVSIZE; ++i)
82 iconv_convs[i] = 0;
83#endif // HAVE_ICONV
84
85}
86
87void shutdown() {
88#ifdef HAVE_ICONV
89 for (int i=0; i < CONVSIZE; ++i)
90 if (iconv_convs[i] != (iconv_t)(-1))
91 iconv_close(iconv_convs[i]);
92#endif // HAVE_ICONV
93
94 delete[] iconv_convs;
95
96}
97
98
99
100
101#ifdef HAVE_ICONV
102/**
103 Recodes the text from one encoding to another
104 assuming cd is correct
105 @param cd the iconv type
106 @param msg text to be converted, **NOT** necessarily NULL terminated
107 @param size number of BYTES to convert
108 @return the recoded string, or 0 on failure
109*/
110std::string recode(iconv_t cd,
111 const std::string &in) {
112
113 // If empty message, yes this can happen, return
114 if (in.empty())
115 return "";
116
117 size_t insize = in.size();
118 size_t outsize = insize;
119 char * out = (char *) malloc(outsize * sizeof(char)); // need realloc
120 char * outptr = out;
121
122 size_t inbytesleft = insize;
123 size_t outbytesleft = outsize;
124
125 char * in_ptr = const_cast<char *>(in.data());
126 size_t result = (size_t)(-1);
127 bool again = true;
128
129 while (again) {
130 again = false;
131 result = iconv(cd, &in_ptr, &inbytesleft, &outptr, &outbytesleft);
132 if (result == (size_t)(-1)) {
133 switch(errno) {
134 case EILSEQ:
135 // Try skipping a byte
136 in_ptr++;
137 inbytesleft--;
138 again = true;
139 case EINVAL:
140 break;
141 case E2BIG:
142 // need more space!
143 outsize += insize;
144 out = (char *) realloc(out, outsize*sizeof(char));
145 if (out != NULL)
146 again = true;
147 outbytesleft += insize;
148 outptr = out + outsize - outbytesleft;
149 break;
150 default:
151 // something else broke
152 perror("iconv");
153 break;
154 }
155 }
156 }
157
158 // copy to our return string
159 std::string ret;
160 ret.append(out, outsize - outbytesleft);
161
162 // reset the conversion descriptor
163 iconv(cd, NULL, NULL, NULL, NULL);
164
165 if (out)
166 free(out);
167
168 return ret;
169}
170#else
171std::string recode(int cd,
172 const std::string &str) {
173 return str;
174}
175#endif // HAVE_ICONV
176
177FbString XStrToFb(const std::string &src) {
178 return recode(iconv_convs[X2FB], src);
179}
180
181std::string FbStrToX(const FbString &src) {
182 return recode(iconv_convs[FB2X], src);
183}
184
185
186/// Handle thislocale string encodings (strings coming from userspace)
187FbString LocaleStrToFb(const std::string &src) {
188 return recode(iconv_convs[LOCALE2FB], src);
189}
190
191std::string FbStrToLocale(const FbString &src) {
192 return recode(iconv_convs[FB2LOCALE], src);
193}
194
195bool haveUTF8() {
196#ifdef HAVE_ICONV
197 if (iconv_convs[LOCALE2FB] != ((iconv_t)(-1)))
198 return true;
199#endif // HAVE_ICONV
200
201 return false;
202}
203
204
205}; // end namespace StringUtil
206
207}; // end namespace FbTk