libi2ncommon: (tomj) fix iso_to_html() function
[libi2ncommon] / src / stringfunc.cpp
1 /***************************************************************************
2                           escape.cpp  -  escaping of strings
3                              -------------------
4     begin                : Sun Nov 14 1999
5     copyright            : (C) 1999 by Intra2net AG
6     email                : info@intra2net.com
7  ***************************************************************************/
8
9 #include <iostream>
10 #include <string>
11 #include <sstream>
12 #include <stdexcept>
13
14 #include <stdlib.h>
15 #include <iconv.h>
16 #include <i18n.h>
17
18 #include <stringfunc.hxx>
19
20 using namespace std;
21
22 std::string iso_to_utf8(const std::string& isostring)
23 {
24     string result;
25     
26     iconv_t i2utf8 = iconv_open ("UTF-8", "ISO-8859-1");
27     
28     if (iso_to_utf8 == (iconv_t)-1)
29         throw runtime_error("iconv can't convert from ISO-8859-1 to UTF-8");
30         
31     size_t in_size=isostring.size();
32     size_t out_size=in_size*4;
33     
34     char *buf = (char *)malloc(out_size+1);
35     if (buf == NULL)
36         throw runtime_error("out of memory for iconv buffer");
37
38     const char *in = isostring.c_str();
39     char *out = buf;
40     iconv (i2utf8, &in, &in_size, &out, &out_size);
41             
42     buf[isostring.size()*4-out_size]=0;
43     
44     result=buf;
45                 
46     free(buf);
47     iconv_close (i2utf8);
48     
49     return result;
50 }
51
52 std::string utf8_to_iso(const std::string& utf8string)
53 {
54     string result;
55     
56     iconv_t utf82iso = iconv_open ("ISO-8859-1","UTF-8");
57     
58     if (utf82iso == (iconv_t)-1)
59         throw runtime_error("iconv can't convert from UTF-8 to ISO-8859-1");
60         
61     size_t in_size=utf8string.size();
62     size_t out_size=in_size;
63     
64     char *buf = (char *)malloc(out_size+1);
65     if (buf == NULL)
66         throw runtime_error("out of memory for iconv buffer");
67
68     const char *in = utf8string.c_str();
69     char *out = buf;
70     iconv (utf82iso, &in, &in_size, &out, &out_size);
71             
72     buf[utf8string.size()-out_size]=0;
73     
74     result=buf;
75                 
76     free(buf);
77     iconv_close (utf82iso);
78
79     return result;
80 }
81
82 std::string iso_to_html(const std::string& isostring, bool showerr_bug)
83 {
84     string result = isostring;
85
86     // TODO: This needs to be removed soon by a proper 
87     // HTML quoted chars engine. Then we can also remove &uuml; from i18n files.
88     if (!showerr_bug) {
89         replace_all (result, "\"", "&quot;");
90         replace_all (result, "&", "&amp;");
91         replace_all (result, "<", "&lt;");
92         replace_all (result, ">", "&gt;");
93     }
94     
95     replace_all (result, "ä", "&auml;");
96     replace_all (result, "ö", "&ouml;");
97     replace_all (result, "ü", "&uuml;");
98     replace_all (result, "Ä", "&Auml;");
99     replace_all (result, "Ö", "&Ouml;");
100     replace_all (result, "Ü", "&Uuml;");
101     replace_all (result, "ß", "&szlig;");
102     
103     return result;
104 }
105
106 bool replace_all(string &base, const char *ist, const char *soll)
107 {
108     string i=ist;
109     string s=soll;
110     return replace_all(base,&i,&s);
111 }
112
113 bool replace_all(string &base, const string &ist, const char *soll)
114 {
115     string s=soll;
116     return replace_all(base,&ist,&s);
117 }
118
119 bool replace_all(string &base, const string *ist, const string *soll)
120 {
121     return replace_all(base,*ist,*soll);
122 }
123
124 bool replace_all(string &base, const char *ist, const string *soll)
125 {
126     string i=ist;
127     return replace_all(base,&i,soll);
128 }
129
130 bool replace_all(string &base, const string &ist, const string &soll)
131 {
132     bool found_ist = false;
133     string::size_type a=0;
134
135     while((a=base.find(ist,a))!=string::npos)
136     {
137         base.replace(a,ist.size(),soll);
138         a=a+soll.size();
139         found_ist = true;
140     }
141     
142     return found_ist;
143 }
144
145 string to_lower(const string &src)
146 {
147     string dst = src;
148
149     string::size_type pos = 0, end = dst.size();
150     for (pos = 0; pos < end; pos++)
151         dst[pos] = tolower(dst[pos]);
152
153     return dst;
154 }
155
156 string to_upper(const string &src)
157 {
158     string dst = src;
159
160     string::size_type pos = 0, end = dst.size();
161     for (pos = 0; pos < end; pos++)
162         dst[pos] = toupper(dst[pos]);
163
164     return dst;
165 }
166
167 string nice_unit_format (int input) {
168     float size = input;
169     int sizecount = 0;
170
171     while (size > 1000) {
172         size = size / 1000;
173         sizecount++;
174     }
175
176     float tmp;                       // round
177     tmp = size*10;
178     tmp += 0.5;
179     tmp = int (tmp);
180     tmp = float(tmp)/float(10);
181     size = tmp;
182
183     ostringstream out;
184
185     out.setf (ios::fixed);
186     out.precision(2);
187     switch (sizecount) {
188     case 1:
189         out << size << i18n(" KBytes");
190         break;
191     case 2:
192         out << size << i18n(" MBytes");
193         break;
194     case 3:
195         out << size << i18n(" Gbytes");
196         break;
197     default:
198         out << size << i18n(" Bytes");
199         break;
200     }
201
202     return out.str();
203 }
204
205 string escape(const string &s)
206 {
207     string out(s);
208     string::size_type p;
209
210     p=0;
211     while ((p=out.find_first_of("\"\\",p))!=out.npos)
212     {
213         out.insert(p,"\\");
214         p+=2;
215     }
216
217     p=0;
218     while ((p=out.find_first_of("\r",p))!=out.npos)
219     {
220         out.replace(p,1,"\\r");
221         p+=2;
222     }
223
224     p=0;
225     while ((p=out.find_first_of("\n",p))!=out.npos)
226     {
227         out.replace(p,1,"\\n");
228         p+=2;
229     }
230
231     out='"'+out+'"';
232
233     return out;
234 }
235
236 string descape(const string &s, int startpos, int &endpos)
237 {
238     string out;
239
240     if (s.at(startpos) != '"')
241         throw out_of_range("value not type escaped string");
242
243     out=s.substr(startpos+1);
244     string::size_type p=0;
245
246     // search for the end of the string
247     while((p=out.find("\"",p))!=out.npos)
248     {
249         int e=p-1;
250         bool escaped=false;
251
252         // the " might be escaped with a backslash
253         while(e>=0 && out.at(e)=='\\')
254         {
255             if (escaped == false)
256                 escaped=true;
257             else
258                 escaped=false;
259
260             e--;
261         }
262
263         if (escaped==false)
264             break;
265         else
266             p++;
267     }
268
269     // we now have the end of the string
270     out=out.substr(0,p);
271
272     // tell calling prog about the endposition
273     endpos=startpos+p+1;
274
275     // descape all \ stuff inside the string now
276     p=0;
277     while((p=out.find_first_of("\\",p))!=out.npos)
278     {
279         switch(out.at(p+1))
280         {
281         case 'r':
282             out.replace(p,2,"\r");
283             break;
284         case 'n':
285             out.replace(p,2,"\n");
286             break;
287         default:
288             out.erase(p,1);
289         }
290         p++;
291     }
292
293     return out;
294 }
295
296 string escape_shellarg(const string &input)
297 {
298     if (!input.size())
299         return "";
300     
301     string output = "'";
302     string::const_iterator it, it_end = input.end();
303     for (it = input.begin(); it != it_end; it++) {
304         if ((*it) == '\'')
305             output += "'\\'";
306         
307         output += *it;
308     }
309     
310     output += "'";
311     return output;
312 }