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