2 PROJECT: FlowerSoft C++ library
3 FILE : string-convert.cc
7 #include "string-convert.hh"
13 #include "libc-extension.hh"
14 #include "rational.hh"
15 #include "std-vector.hh"
18 A safe length for stringconversion buffers.
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.
23 Should enlarge buff dynamically.
28 static const int STRING_BUFFER_LEN
= 1024;
31 String_convert::bool_string (bool b
)
33 return string (b
? "true" : "false");
37 String_convert::bin2hex (Byte bin_char
)
40 str
+= to_string ((char) nibble2hex_byte (bin_char
>> 4));
41 str
+= to_string ((char) nibble2hex_byte (bin_char
++));
46 String_convert::bin2hex (string bin_string
)
49 Byte
const *byte
= (Byte
const*)bin_string
.data ();
50 for (ssize i
= 0; i
< bin_string
.length (); i
++)
52 str
+= to_string ((char)nibble2hex_byte (*byte
>> 4));
53 str
+= to_string ((char)nibble2hex_byte (*byte
++));
59 String_convert::bin2int (string bin_string
)
61 return bin2unsigned (bin_string
);
65 String_convert::bin2unsigned (string bin_string
)
67 assert (bin_string
.length () <= (int)sizeof (unsigned));
69 unsigned result_u
= 0;
70 for (ssize i
= 0; i
< bin_string
.length (); i
++)
73 result_u
+= (Byte
)bin_string
[ i
];
79 String_convert::dec2int (string dec_string
)
81 if (!dec_string
.length ())
85 if (!sscanf (dec_string
.c_str (), "%ld", &l
))
88 assert (form_string ("%ld", l
) == dec_string
);
94 String_convert::i64_string (I64 i64
, char const *fmt
)
96 char buffer
[STRING_BUFFER_LEN
];
97 snprintf (buffer
, STRING_BUFFER_LEN
,
98 (fmt
? fmt
: "%Ld"), i64
); // assume radix 10
99 return string (buffer
);
101 // breendet imp from string
103 String_convert::dec2double (string dec_string
)
105 if (!dec_string
.length ())
109 if (!sscanf (dec_string
.c_str (), "%lf", &d
))
116 String_convert::hex2bin (string hex_string
, string
&bin_string_r
)
118 if (hex_string
.length () % 2)
119 hex_string
= "0" + hex_string
;
122 Byte
const *byte
= (Byte
const*) hex_string
.data ();
124 while (i
< hex_string
.length ())
126 int high_i
= hex2nibble (*byte
++);
127 int low_i
= hex2nibble (*byte
++);
128 if (high_i
< 0 || low_i
< 0)
129 return 1; // invalid char
130 bin_string_r
+= to_string ((char) (high_i
<< 4 | low_i
), 1);
137 String_convert::hex2bin (string hex_string
)
141 if (hex2bin (hex_string
, str
))
148 String_convert::hex2nibble (Byte byte
)
150 if (byte
>= '0' && byte
<= '9')
152 if (byte
>= 'A' && byte
<= 'F')
153 return byte
- 'A' + 10;
154 if (byte
>= 'a' && byte
<= 'f')
155 return byte
- 'a' + 10;
159 // stupido. Should use int_string ()
161 String_convert::int2dec (int i
, int length_i
, char ch
)
168 string dec_string
= to_string (i
);
171 return to_string (fill_char
, length_i
- dec_string
.length ()) + dec_string
;
174 // stupido. Should use int_string ()
176 String_convert::unsigned2hex (unsigned u
, ssize length
, char fill_char
)
185 str
= to_string ((char) ((u
% 16)["0123456789abcdef"])) + str
;
189 str
+= int_string (u
, "%x"); // hmm. %lx vs. %x -> portability?
192 str
= to_string (fill_char
, length
- str
.length ()) + str
;
193 while ((str
.length () > length
) && (str
[ 0 ] == 'f'))
194 str
= str
.substr (2);
200 String_convert::int2hex (int i
, int length_i
, char fill_char
)
202 return unsigned2hex ((unsigned)i
, length_i
, fill_char
);
206 String_convert::nibble2hex_byte (Byte byte
)
208 if ((byte
& 0x0f) <= 9)
209 return (byte
& 0x0f) + '0';
211 return (byte
& 0x0f) - 10 + 'a';
214 Convert an integer to a string
217 #fmt# is a printf style format, default assumes "%d" as format.
220 String_convert::int_string (int i
, char const *fmt
)
222 char buffer
[STRING_BUFFER_LEN
];
223 snprintf (buffer
, STRING_BUFFER_LEN
,
224 (fmt
? fmt
: "%d"), i
); // assume radix 10
225 return string (buffer
);
229 String_convert::form_string (char const *format
, ...)
232 va_start (args
, format
);
233 char buffer
[STRING_BUFFER_LEN
];
234 vsnprintf (buffer
, STRING_BUFFER_LEN
, format
, args
);
236 return string (buffer
);
240 String_convert::vform_string (char const *format
, va_list args
)
242 char buffer
[STRING_BUFFER_LEN
];
243 vsnprintf (buffer
, STRING_BUFFER_LEN
, format
, args
);
244 return string (buffer
);
248 Convert a double to a string.
250 @param #fmt# is a printf style format, default assumes "%lf" as format
253 String_convert::double_string (double f
, char const *fmt
)
255 char buf
[STRING_BUFFER_LEN
];
257 snprintf (buf
, STRING_BUFFER_LEN
, fmt
? fmt
: "%f", f
);
262 Make a string from a single character.
265 #n# is a repetition count, default value is 1
268 String_convert::char_string (char c
, int n
)
271 char *ch
= new char[ n
];
280 String_convert::rational_string (Rational r
)
282 return r
.to_string ();
286 String_convert::pointer_string (void const *l
)
288 char buffer
[STRING_BUFFER_LEN
];
289 snprintf (buffer
, STRING_BUFFER_LEN
, "%p", l
); // assume radix 10
290 return string (buffer
);
294 Convert a double to a string.
297 #n# is the number of nonzero digits
300 String_convert::precision_string (double x
, int n
)
302 string format
= "%." + to_string (max (0, n
- 1)) + "e";
303 string str
= double_string (abs (x
), format
.c_str ());
305 int exp
= dec2int (str
.substr (str
.length () - 3));
306 str
= str
.substr (0, str
.length () - 4);
308 while (str
[str
.length () - 1] == '0')
309 str
= str
.substr (0, str
.length () - 1);
310 if (str
[str
.length () - 1] == '.')
311 str
= str
.substr (0, str
.length () - 1);
314 return (sign (x
) > 0 ? str
: "-" + str
);
316 str
= str
.substr (0, 1) + str
.substr (2);
319 str
= "0." + to_string ('0', -dot
) + str
;
320 else if (dot
>= str
.length ())
321 str
+= to_string ('0', dot
- str
.length ());
322 else if ((dot
> 0) && (dot
< str
.length ()))
323 str
= str
.substr (0, dot
) + "." + str
.substr (dot
);
327 return (sign (x
) > 0 ? str
: "-" + str
);
332 String_convert::long_string (long l
)
334 char s
[STRING_BUFFER_LEN
];
335 sprintf (s
, "%ld", l
);
340 String_convert::unsigned_string (unsigned u
)
342 char s
[STRING_BUFFER_LEN
];
343 sprintf (s
, "%u", u
);
348 String_convert::pad_to (string s
, int n
)
350 return s
+ string (max (int(n
- s
.length ()), 0), ' ');
354 String_convert::to_upper (string s
)
356 return strnupr ((char *)s
.c_str (), s
.length ());
360 String_convert::to_lower (string s
)
362 return strnlwr ((char *)s
.c_str (), s
.length ());
366 String_convert::reverse (string s
)
368 return (char*) memrev ((unsigned char *)s
.data (), s
.length ());