]> git.donarmstrong.com Git - lilypond.git/blob - flower/string-convert.cc
* flower/*.cc: remove <? and >?
[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 // breendet imp from String
91 double
92 String_convert::dec2double (String dec_string)
93 {
94   if (!dec_string.length ())
95     return 0;
96   double d = 0;
97   int conv = sscanf (dec_string.to_str0 (), "%lf", &d);
98   assert (conv);
99   return d;
100 }
101
102 int
103 String_convert::hex2bin (String hex_string, String &bin_string_r)
104 {
105   if (hex_string.length () % 2)
106     hex_string = "0" + hex_string;
107
108   bin_string_r = "";
109   Byte const *byte = hex_string.to_bytes ();
110   int i = 0;
111   while (i < hex_string.length ())
112     {
113       int high_i = hex2nibble (*byte++);
114       int low_i = hex2nibble (*byte++);
115       if (high_i < 0 || low_i < 0)
116         return 1; // illegal char
117       bin_string_r += to_string ((char) (high_i << 4 | low_i), 1);
118       i += 2;
119     }
120   return 0;
121 }
122
123 String
124 String_convert::hex2bin (String hex_string)
125 {
126   String str;
127   //  silly, asserts should alway be "on"!
128   //    assert (!hex2bin (hex_string, str) );
129   int error_i = hex2bin (hex_string, str);
130   assert (!error_i);
131   return str;
132 }
133
134 int
135 String_convert::hex2nibble (Byte byte)
136 {
137   if (byte >= '0' && byte <= '9')
138     return byte - '0';
139   if (byte >= 'A' && byte <= 'F')
140     return byte - 'A' + 10;
141   if (byte >= 'a' && byte <= 'f')
142     return byte - 'a' + 10;
143   return -1;
144 }
145
146 // stupido.  Should use int_string ()
147 String
148 String_convert::int2dec (int i, int length_i, char ch)
149 {
150   char fill_char = ch;
151   if (fill_char)
152     fill_char = '0';
153
154   // ugh
155   String dec_string = to_string (i);
156
157   // ugh
158   return to_string (fill_char, length_i - dec_string.length ()) + dec_string;
159 }
160
161 // stupido.  Should use int_string ()
162 String
163 String_convert::unsigned2hex (unsigned u, int length_i, char fill_char)
164 {
165   String str;
166   if (!u)
167     str = "0";
168
169 #if 1 // both go...
170   while (u)
171     {
172       str = to_string ((char) ((u % 16)["0123456789abcdef"])) + str;
173       u /= 16;
174     }
175 #else
176   str += int_string (u, "%x");  // hmm. %lx vs. %x -> portability?
177 #endif
178
179   str = to_string (fill_char, length_i - str.length ()) + str;
180   while ((str.length () > length_i) && (str[ 0 ] == 'f' ) )
181     str = str.cut_string (2, INT_MAX);
182
183   return str;
184 }
185
186 String 
187 String_convert::int2hex (int i, int length_i, char fill_char)
188 {
189   return unsigned2hex ((unsigned)i, length_i, fill_char);
190 }
191
192 Byte
193 String_convert::nibble2hex_byte (Byte byte)
194 {
195   if ((byte & 0x0f) <= 9 )
196     return (byte & 0x0f) + '0';
197   else
198     return (byte & 0x0f) - 10 + 'a';
199 }
200 /**
201    Convert an integer to a string
202
203    @param
204    #fmt# is a printf style format, default assumes "%d" as format.
205 */
206 String
207 String_convert::int_string (int i, char const *fmt)
208 {
209   char buffer[STRING_BUFFER_LEN];
210   snprintf (buffer, STRING_BUFFER_LEN,
211             (fmt ? fmt : "%d"), i); // assume radix 10
212   return String (buffer);
213 }
214
215 String
216 String_convert::form_string (char const *format, ...)
217 {
218   va_list args;
219   va_start (args, format);
220   char buffer[STRING_BUFFER_LEN];
221   vsnprintf (buffer, STRING_BUFFER_LEN, format, args);
222   va_end (args);
223   return String (buffer);
224 }
225
226 String
227 String_convert::vform_string (char const *format, va_list args)
228 {
229   char buffer[STRING_BUFFER_LEN];
230   vsnprintf (buffer, STRING_BUFFER_LEN, format, args);
231   return String (buffer);
232 }
233
234 /**
235    Convert a double to a string.
236
237    @param #fmt# is a printf style format, default assumes "%lf" as format
238 */
239 String
240 String_convert::double_string (double f, char const *fmt)
241 {
242   char buf[STRING_BUFFER_LEN];
243
244   snprintf (buf, STRING_BUFFER_LEN, fmt ? fmt : "%f", f);
245   return String (buf);
246 }
247
248 /**
249    Make a string from a single character.
250
251    @param
252    #n# is a repetition count, default value is 1
253 */
254 String
255 String_convert::char_string (char c, int n)
256 {
257   n = n >= 0 ? n : 0;
258   char *ch = new char[ n ];
259   memset (ch, c, n);
260   String s ((Byte *)ch, n);
261   delete[] ch;
262   return s;
263 }
264
265 String
266 String_convert::rational_string (Rational r)
267 {
268   return r.to_string ();
269 }
270
271 String
272 String_convert::pointer_string (void const *l)
273 {
274   char buffer[STRING_BUFFER_LEN];
275   snprintf (buffer, STRING_BUFFER_LEN, "%p", l); // assume radix 10
276   return String (buffer);
277 }
278
279 /**
280    Convert a double to a string.
281
282    @param
283    #n# is the number of nonzero digits
284 */
285 String
286 String_convert::precision_string (double x, int n)
287 {
288   String format = "%." + to_string (0 >? n - 1) + "e";
289   String str = double_string (abs (x), format.to_str0 ());
290
291   int exp = str.right_string (3).to_int ();
292   str = str.left_string (str.length () - 4);
293
294   while (str[str.length () - 1] == '0')
295     str = str.left_string (str.length () - 1);
296   if (str[str.length () - 1] == '.')
297     str = str.left_string (str.length () - 1);
298
299   if (exp == 0)
300     return (sign (x) > 0 ? str : "-" + str);
301
302   str = str.left_string (1) + str.cut_string (2, INT_MAX);
303   int dot = 1 + exp;
304   if (dot <= 0)
305     str = "0." + to_string ('0', -dot) + str;
306   else if (dot >= str.length ())
307     str += to_string ('0', dot - str.length ());
308   else if (( dot > 0) && (dot < str.length ()))
309     str = str.left_string (dot) + "." + str.cut_string (dot, INT_MAX);
310   else
311     assert (0);
312
313   return (sign (x) > 0 ? str : "-" + str);
314 }
315
316 Array<String>
317 String_convert::split (String str, char c)
318 {
319   Array<String> a;
320   int i = str.index (c);
321   while (i >= 0)
322     {
323       String s = str.left_string (i);
324       a.push (s);
325       while (str[++i] == c)
326         ;
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 (' ' , max (n - s.length (), 0));
347 }