]> git.donarmstrong.com Git - lilypond.git/blob - flower/string-convert.cc
Issue 4550 (2/2) Avoid "using namespace std;" in included files
[lilypond.git] / flower / string-convert.cc
1 /*
2   PROJECT: FlowerSoft C++ library
3   FILE   : string-convert.cc
4
5   --*/
6
7 #include "string-convert.hh"
8
9 #include <cstring>
10 #include <cstdio>
11
12 #include "libc-extension.hh"
13 #include "rational.hh"
14 #include "std-vector.hh"
15
16 using std::string;
17
18 /**
19    A safe length for stringconversion buffers.
20
21    worst case would be %f printing HUGE (or 1/HUGE), which is approx
22    2e318, this number would have approx 318 zero's in its string.
23
24    Should enlarge buff dynamically.
25
26    @see
27    man 3 snprintf
28 */
29 static const int STRING_BUFFER_LEN = 1024;
30
31 string
32 String_convert::bool_string (bool b)
33 {
34   return string (b ? "true" : "false");
35 }
36
37 string
38 String_convert::bin2hex (Byte bin_char)
39 {
40   string str;
41   str += ::to_string ((char) nibble2hex_byte ((Byte) (bin_char >> 4)));
42   str += ::to_string ((char) nibble2hex_byte (bin_char++));
43   return str;
44 }
45
46 string
47 String_convert::bin2hex (const string &bin_string)
48 {
49   string str;
50   Byte const *byte = (Byte const *)bin_string.data ();
51   for (ssize i = 0; i < bin_string.length (); i++)
52     {
53       str += ::to_string ((char)nibble2hex_byte ((Byte) (*byte >> 4)));
54       str += ::to_string ((char)nibble2hex_byte (*byte++));
55     }
56   return str;
57 }
58
59 int
60 String_convert::bin2int (const string &bin_string)
61 {
62   return bin2unsigned (bin_string);
63 }
64
65 unsigned
66 String_convert::bin2unsigned (const string &bin_string)
67 {
68   assert (bin_string.length () <= (int)sizeof (unsigned));
69
70   unsigned result_u = 0;
71   for (ssize i = 0; i < bin_string.length (); i++)
72     {
73       result_u <<= 8;
74       result_u += (Byte)bin_string[ i ];
75     }
76   return result_u;
77 }
78
79 int
80 String_convert::dec2int (const string &dec_string)
81 {
82   if (!dec_string.length ())
83     return 0;
84
85   long l = 0;
86   if (!sscanf (dec_string.c_str (), "%ld", &l))
87     assert (false);
88
89   return (int)l;
90 }
91
92 string
93 String_convert::i64_string (I64 i64, char const *fmt)
94 {
95   char buffer[STRING_BUFFER_LEN];
96   snprintf (buffer, STRING_BUFFER_LEN,
97             (fmt ? fmt : "%Ld"), i64); // assume radix 10
98   return string (buffer);
99 }
100 // breendet imp from string
101 double
102 String_convert::dec2double (const string &dec_string)
103 {
104   if (!dec_string.length ())
105     return 0;
106
107   double d = 0.0;
108   if (!sscanf (dec_string.c_str (), "%lf", &d))
109     assert (false);
110
111   return d;
112 }
113
114 int
115 String_convert::hex2bin (string hex_string, string &bin_string_r)
116 {
117   if (hex_string.length () % 2)
118     hex_string = "0" + hex_string;
119
120   bin_string_r = "";
121   Byte const *byte = (Byte const *) hex_string.data ();
122   ssize i = 0;
123   while (i < hex_string.length ())
124     {
125       int high_i = hex2nibble (*byte++);
126       int low_i = hex2nibble (*byte++);
127       if (high_i < 0 || low_i < 0)
128         return 1; // invalid char
129       bin_string_r += ::to_string ((char) (high_i << 4 | low_i), 1);
130       i += 2;
131     }
132   return 0;
133 }
134
135 string
136 String_convert::hex2bin (const string &hex_string)
137 {
138   string str;
139
140   if (hex2bin (hex_string, str))
141     assert (false);
142
143   return str;
144 }
145
146 int
147 String_convert::hex2nibble (Byte byte)
148 {
149   if (byte >= '0' && byte <= '9')
150     return byte - '0';
151   if (byte >= 'A' && byte <= 'F')
152     return byte - 'A' + 10;
153   if (byte >= 'a' && byte <= 'f')
154     return byte - 'a' + 10;
155   return -1;
156 }
157
158 // stupido.  Should use int_string ()
159 string
160 String_convert::int2dec (int i, size_t length_i, char ch)
161 {
162   char fill_char = ch;
163   if (fill_char)
164     fill_char = '0';
165
166   // ugh
167   string dec_string = ::to_string (i);
168
169   // ugh
170   return ::to_string (fill_char, ssize_t (length_i - dec_string.length ())) + dec_string;
171 }
172
173 // stupido.  Should use int_string ()
174 string
175 String_convert::unsigned2hex (unsigned u, size_t length, char fill_char)
176 {
177   string str;
178   if (!u)
179     str = "0";
180
181 #if 1 // both go...
182   while (u)
183     {
184       str = ::to_string ((char) ((u % 16)["0123456789abcdef"])) + str;
185       u /= 16;
186     }
187 #else
188   str += int_string (u, "%x");  // hmm. %lx vs. %x -> portability?
189 #endif
190
191   str = ::to_string (fill_char, ssize_t (length - str.length ())) + str;
192   while ((str.length () > length) && (str[ 0 ] == 'f'))
193     str = str.substr (2);
194
195   return str;
196 }
197
198 string
199 String_convert::int2hex (int i, size_t length_i, char fill_char)
200 {
201   return unsigned2hex ((unsigned)i, length_i, fill_char);
202 }
203
204 Byte
205 String_convert::nibble2hex_byte (Byte byte)
206 {
207   if ((byte & 0x0f) <= 9)
208     return (Byte) ((byte & 0x0f) + '0');
209   else
210     return (Byte) ((byte & 0x0f) - 10 + 'a');
211 }
212 /**
213    Convert an integer to a string
214
215    @param
216    #fmt# is a printf style format, default assumes "%d" as format.
217 */
218 string
219 String_convert::int_string (int i, char const *fmt)
220 {
221   char buffer[STRING_BUFFER_LEN];
222   snprintf (buffer, STRING_BUFFER_LEN,
223             (fmt ? fmt : "%d"), i); // assume radix 10
224   return string (buffer);
225 }
226
227 string
228 String_convert::form_string (char const *format, ...)
229 {
230   va_list args;
231   va_start (args, format);
232   char buffer[STRING_BUFFER_LEN];
233   vsnprintf (buffer, STRING_BUFFER_LEN, format, args);
234   va_end (args);
235   return string (buffer);
236 }
237
238 string
239 String_convert::vform_string (char const *format, va_list args)
240 {
241   char buffer[STRING_BUFFER_LEN];
242   vsnprintf (buffer, STRING_BUFFER_LEN, format, args);
243   return string (buffer);
244 }
245
246 /**
247    Convert a double to a string.
248
249    @param #fmt# is a printf style format, default assumes "%lf" as format
250 */
251 string
252 String_convert::double_string (double f, char const *fmt)
253 {
254   char buf[STRING_BUFFER_LEN];
255
256   snprintf (buf, STRING_BUFFER_LEN, fmt ? fmt : "%f", f);
257   return string (buf);
258 }
259
260 /**
261    Make a string from a single character.
262
263    @param
264    #n# is a repetition count, default value is 1
265 */
266 string
267 String_convert::char_string (char c, int n)
268 {
269   n = n >= 0 ? n : 0;
270   char *ch = new char[ n ];
271   memset (ch, c, n);
272   string s (ch, n);
273
274   delete[] ch;
275   return s;
276 }
277
278 string
279 String_convert::rational_string (Rational r)
280 {
281   return r.to_string ();
282 }
283
284 string
285 String_convert::pointer_string (void const *l)
286 {
287   char buffer[STRING_BUFFER_LEN];
288   snprintf (buffer, STRING_BUFFER_LEN, "%p", l); // assume radix 10
289   return string (buffer);
290 }
291
292 /**
293    Convert a double to a string.
294
295    @param
296    #n# is the number of nonzero digits
297 */
298 string
299 String_convert::precision_string (double x, int n)
300 {
301   string format = "%." + ::to_string (std::max (0, n - 1)) + "e";
302   string str = double_string (abs (x), format.c_str ());
303
304   int exp = dec2int (str.substr (str.length () - 3));
305   str = str.substr (0, str.length () - 4);
306
307   while (str[str.length () - 1] == '0')
308     str = str.substr (0, str.length () - 1);
309   if (str[str.length () - 1] == '.')
310     str = str.substr (0, str.length () - 1);
311
312   if (exp == 0)
313     return (sign (x) > 0 ? str : "-" + str);
314
315   str = str.substr (0, 1) + str.substr (2);
316   ssize dot = 1 + exp;
317   if (dot <= 0)
318     str = "0." + ::to_string ('0', -dot) + str;
319   else if (dot >= str.length ())
320     str += ::to_string ('0', dot - str.length ());
321   else if ((dot > 0) && (dot < str.length ()))
322     str = str.substr (0, dot) + "." + str.substr (dot);
323   else
324     assert (0);
325
326   return (sign (x) > 0 ? str : "-" + str);
327 }
328
329 string
330 String_convert::long_string (long l)
331 {
332   char s[STRING_BUFFER_LEN];
333   sprintf (s, "%ld", l);
334   return s;
335 }
336
337 string
338 String_convert::unsigned_string (unsigned u)
339 {
340   char s[STRING_BUFFER_LEN];
341   sprintf (s, "%u", u);
342   return s;
343 }
344
345 string
346 String_convert::unsigned_long_string (unsigned long ul)
347 {
348   char s[STRING_BUFFER_LEN];
349   sprintf (s, "%lu", ul);
350   return s;
351 }
352
353 string
354 String_convert::pad_to (const string &s, size_t n)
355 {
356   return s + string (std::max (int (n - s.length ()), 0), ' ');
357 }
358
359 string
360 String_convert::to_upper (string s)
361 {
362   return strnupr (const_cast<char*>(s.c_str ()), s.length ());
363 }
364
365 string
366 String_convert::to_lower (string s)
367 {
368   return strnlwr (const_cast<char*>(s.c_str ()), s.length ());
369 }
370
371 string
372 String_convert::reverse (string s)
373 {
374   return (char *) memrev ((unsigned char *)s.data (), s.length ());
375 }