]> git.donarmstrong.com Git - lilypond.git/blob - flower/string-convert.cc
release: 1.1.52
[lilypond.git] / flower / string-convert.cc
1 /*
2   PROJECT: FlowerSoft C++ library
3   FILE   : string-convert.cc
4
5 --*/
6
7 #include <stdio.h>
8 #include <assert.h>
9 #include <limits.h>
10 #include "libc-extension.hh"
11 #include "string.hh"
12 #include "string-convert.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_str (bool b)
31 {
32   return String (b ? "true" : "false");
33 }
34
35 String
36 String_convert::bin2hex_str (String bin_str)
37 {
38   String str;
39   Byte const* byte_C = bin_str.byte_C();
40   for (int i = 0; i < bin_str.length_i(); i++) 
41     {
42       str += to_str ((char)nibble2hex_byte (*byte_C >> 4));
43       str += to_str ((char)nibble2hex_byte (*byte_C++));
44     }
45   return str;
46 }
47
48 int
49 String_convert::bin2_i (String bin_str)
50 {
51   return bin2_u (bin_str);
52 }
53
54 unsigned
55 String_convert::bin2_u (String bin_str)
56 {
57   assert (bin_str.length_i() <= (int)sizeof(unsigned));
58
59   unsigned result_u = 0;
60   for (int i = 0; i < bin_str.length_i(); i++) 
61     {
62       result_u <<= 8;
63       result_u += (Byte)bin_str[ i ];
64     }
65   return result_u;
66 }
67
68 // breendet imp from String
69 int
70 String_convert::dec2_i (String dec_str)
71 {
72   if (!dec_str.length_i())
73     return 0;
74
75   long l = 0;
76   int conv = sscanf (dec_str.ch_C(), "%ld", &l);
77   assert (conv);
78
79   return (int)l;
80 }
81
82 String
83 String_convert::i64_str (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::dec2_f (String dec_str)
94 {
95   if (!dec_str.length_i())
96     return 0;
97   double d = 0;
98   int conv = sscanf (dec_str.ch_C(), "%lf", &d);
99   assert (conv);
100   return d;
101 }
102
103 int
104 String_convert::hex2bin_i (String hex_str, String& bin_str_r)
105 {
106   if (hex_str.length_i() % 2)
107     hex_str = "0" + hex_str;
108
109   bin_str_r = "";
110   Byte const* byte_C= hex_str.byte_C();
111   int i = 0;
112   while (i < hex_str.length_i()) 
113     {
114       int high_i = hex2nibble_i (*byte_C++);
115       int low_i = hex2nibble_i (*byte_C++);
116       if (high_i < 0 || low_i < 0)
117         return 1; // illegal char
118       bin_str_r += to_str ((char)(high_i << 4 | low_i), 1 );
119       i += 2;
120     }
121   return 0;
122 }
123
124 String 
125 String_convert::hex2bin_str (String hex_str)
126 {
127   String str;
128   //  silly, asserts should alway be "on"!
129   //    assert (!hex2bin_i (hex_str, str) );
130   int error_i = hex2bin_i (hex_str, str);
131   assert (!error_i);
132   return str;
133 }
134
135 int 
136 String_convert::hex2nibble_i (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_str()
148 String 
149 String_convert::i2dec_str (int i, int length_i, char ch)
150 {
151   char fill_ch = ch;
152   if (fill_ch)
153     fill_ch = '0';
154
155   // ugh
156   String dec_str = to_str (i);
157   
158   // ugh
159   return to_str (fill_ch, length_i - dec_str.length_i()) + dec_str;
160 }
161
162
163 // stupido.  Should use int_str()
164 String 
165 String_convert::u2hex_str (unsigned u, int length_i, char fill_ch)
166 {
167   String str;
168   if (!u)
169     str = "0";
170
171 #if 1 // both go...
172   while (u) 
173     {
174       str = to_str ((char)((u % 16)["0123456789abcdef"] ) ) + str;
175       u /= 16;
176     }
177 #else
178   str += int_str (u, "%x");     // hmm. %lx vs. %x -> portability?
179 #endif
180
181   str = to_str (fill_ch, length_i - str.length_i()) + str;
182   while ((str.length_i() > length_i) &&  (str[ 0 ] == 'f' ) )
183     str = str.cut_str (2, INT_MAX);
184
185   return str;
186 }
187
188 String 
189 String_convert::i2hex_str (int i, int length_i, char fill_ch)
190 {
191   return u2hex_str ((unsigned)i, length_i, fill_ch);
192 }
193
194 Byte
195 String_convert::nibble2hex_byte (Byte byte)
196 {
197   if ((byte & 0x0f) <= 9 )
198     return (byte & 0x0f) + '0';
199   else
200     return (byte & 0x0f) - 10 + 'a';
201 }
202 /**
203   Convert an integer to a string
204
205   @param
206   #fmt# is a printf style format, default assumes "%d" as format. 
207   */
208 String
209 String_convert::int_str (int i, char const* fmt)
210 {
211   char buffer[STRING_BUFFER_LEN];
212   snprintf (buffer, STRING_BUFFER_LEN,
213             (fmt ? fmt : "%d"), i);     // assume radix 10
214   return String (buffer);
215 }
216
217 String
218 String_convert::form_str (char const* format, ...)
219 {
220   va_list args;
221   va_start (args, format);
222   char buffer[STRING_BUFFER_LEN];
223   vsnprintf (buffer, STRING_BUFFER_LEN, format, args);
224   va_end (args);
225   return String (buffer);
226 }
227
228 String 
229 String_convert::vform_str (char const* format, va_list args)
230 {
231   char buffer[STRING_BUFFER_LEN];
232   vsnprintf (buffer, STRING_BUFFER_LEN, format, args);
233   return String (buffer);
234 }
235
236 /**
237   Convert a double to a string.
238
239   @param #fmt# is a printf style format, default assumes "%lf" as format
240  */
241 String
242 String_convert::double_str (double f, char const* fmt)
243 {
244   char buf[STRING_BUFFER_LEN]; 
245
246   snprintf (buf, STRING_BUFFER_LEN, fmt ? fmt : "%f", f);
247   return String (buf);
248 }
249
250 /**
251 Make a string from a single character.
252
253   @param
254   #n# is a repetition count, default value is 1
255  */
256 String
257 String_convert::char_str (char c, int n)
258 {
259   n = n >= 0 ? n : 0;
260   char* ch_p = new char[ n ];
261   memset (ch_p, c, n);
262   String s ((Byte*)ch_p, n);
263   delete[] ch_p;
264   return s;
265 }
266
267 String
268 String_convert::rational_str (Rational r)
269 {
270         return r.str ();
271 }
272
273 String
274 String_convert::pointer_str (void const *l)
275 {
276   char buffer[STRING_BUFFER_LEN];
277   snprintf (buffer, STRING_BUFFER_LEN, "%p", l);     // assume radix 10
278   return String (buffer);
279 }
280
281 /**
282   Convert a double to a string.
283
284   @param
285   #n# is the number of nonzero digits
286  */
287 String
288 String_convert::precision_str (double x, int n)
289 {
290   String format = "%." + to_str (0 >? n - 1) + "e";
291   String str = double_str (abs (x), format.ch_C ());
292
293   int exp = str.right_str (3).value_i ();
294   str = str.left_str (str.length_i () - 4);
295
296   while (str[str.length_i () - 1] == '0')
297     str = str.left_str (str.length_i () - 1);
298   if (str[str.length_i () - 1] == '.')
299     str = str.left_str (str.length_i () - 1);
300
301   if (exp == 0)
302     return (sign (x) > 0 ? str : "-" + str);
303
304   str = str.left_str (1) + str.cut_str (2, INT_MAX);
305   int dot = 1 + exp;
306   if (dot <= 0)
307     str = "0." + to_str ('0', -dot) + str;
308   else if (dot >= str.length_i ())
309     str += to_str ('0', dot - str.length_i ());
310   else if (( dot > 0) && (dot < str.length_i ()))
311     str = str.left_str (dot) + "." + str.cut_str (dot, INT_MAX);
312   else
313     assert (0);
314
315   return (sign (x) > 0 ? str : "-" + str);
316 }
317
318 Array<String>
319 String_convert::split_arr (String str, char c)
320 {
321   Array<String> a;
322   int i = str.index_i (c);
323   while (i >=0)
324     {
325       String s = str.left_str (i);
326       a.push (s);
327       while (str[++i] == c)
328         ;
329       str = str.cut_str (i, INT_MAX);
330       i = str.index_i (c);
331     }
332   if (str.length_i ())
333     a.push (str);
334   return a;
335 }
336
337
338 String
339 String_convert::long_str (long l)
340 {
341   char s[STRING_BUFFER_LEN];
342   sprintf (s,"%ld", l);
343   return s;
344 }