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