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