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