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 (string bin_string
)
40 Byte
const *byte
= (Byte
const*)bin_string
.data ();
41 for (ssize i
= 0; i
< bin_string
.length (); i
++)
43 str
+= to_string ((char)nibble2hex_byte (*byte
>> 4));
44 str
+= to_string ((char)nibble2hex_byte (*byte
++));
50 String_convert::bin2int (string bin_string
)
52 return bin2unsigned (bin_string
);
56 String_convert::bin2unsigned (string bin_string
)
58 assert (bin_string
.length () <= (int)sizeof (unsigned));
60 unsigned result_u
= 0;
61 for (ssize i
= 0; i
< bin_string
.length (); i
++)
64 result_u
+= (Byte
)bin_string
[ i
];
70 String_convert::dec2int (string dec_string
)
72 if (!dec_string
.length ())
76 if (!sscanf (dec_string
.c_str (), "%ld", &l
))
79 assert (form_string ("%ld", l
) == dec_string
);
85 String_convert::i64_string (I64 i64
, char const *fmt
)
87 char buffer
[STRING_BUFFER_LEN
];
88 snprintf (buffer
, STRING_BUFFER_LEN
,
89 (fmt
? fmt
: "%Ld"), i64
); // assume radix 10
90 return string (buffer
);
92 // breendet imp from string
94 String_convert::dec2double (string dec_string
)
96 if (!dec_string
.length ())
100 if (!sscanf (dec_string
.c_str (), "%lf", &d
))
107 String_convert::hex2bin (string hex_string
, string
&bin_string_r
)
109 if (hex_string
.length () % 2)
110 hex_string
= "0" + hex_string
;
113 Byte
const *byte
= (Byte
const*) hex_string
.data ();
115 while (i
< hex_string
.length ())
117 int high_i
= hex2nibble (*byte
++);
118 int low_i
= hex2nibble (*byte
++);
119 if (high_i
< 0 || low_i
< 0)
120 return 1; // invalid char
121 bin_string_r
+= to_string ((char) (high_i
<< 4 | low_i
), 1);
128 String_convert::hex2bin (string hex_string
)
132 if (hex2bin (hex_string
, str
))
139 String_convert::hex2nibble (Byte byte
)
141 if (byte
>= '0' && byte
<= '9')
143 if (byte
>= 'A' && byte
<= 'F')
144 return byte
- 'A' + 10;
145 if (byte
>= 'a' && byte
<= 'f')
146 return byte
- 'a' + 10;
150 // stupido. Should use int_string ()
152 String_convert::int2dec (int i
, int length_i
, char ch
)
159 string dec_string
= to_string (i
);
162 return to_string (fill_char
, length_i
- dec_string
.length ()) + dec_string
;
165 // stupido. Should use int_string ()
167 String_convert::unsigned2hex (unsigned u
, ssize length
, char fill_char
)
176 str
= to_string ((char) ((u
% 16)["0123456789abcdef"])) + str
;
180 str
+= int_string (u
, "%x"); // hmm. %lx vs. %x -> portability?
183 str
= to_string (fill_char
, length
- str
.length ()) + str
;
184 while ((str
.length () > length
) && (str
[ 0 ] == 'f'))
185 str
= str
.substr (2);
191 String_convert::int2hex (int i
, int length_i
, char fill_char
)
193 return unsigned2hex ((unsigned)i
, length_i
, fill_char
);
197 String_convert::nibble2hex_byte (Byte byte
)
199 if ((byte
& 0x0f) <= 9)
200 return (byte
& 0x0f) + '0';
202 return (byte
& 0x0f) - 10 + 'a';
205 Convert an integer to a string
208 #fmt# is a printf style format, default assumes "%d" as format.
211 String_convert::int_string (int i
, char const *fmt
)
213 char buffer
[STRING_BUFFER_LEN
];
214 snprintf (buffer
, STRING_BUFFER_LEN
,
215 (fmt
? fmt
: "%d"), i
); // assume radix 10
216 return string (buffer
);
220 String_convert::form_string (char const *format
, ...)
223 va_start (args
, format
);
224 char buffer
[STRING_BUFFER_LEN
];
225 vsnprintf (buffer
, STRING_BUFFER_LEN
, format
, args
);
227 return string (buffer
);
231 String_convert::vform_string (char const *format
, va_list args
)
233 char buffer
[STRING_BUFFER_LEN
];
234 vsnprintf (buffer
, STRING_BUFFER_LEN
, format
, args
);
235 return string (buffer
);
239 Convert a double to a string.
241 @param #fmt# is a printf style format, default assumes "%lf" as format
244 String_convert::double_string (double f
, char const *fmt
)
246 char buf
[STRING_BUFFER_LEN
];
248 snprintf (buf
, STRING_BUFFER_LEN
, fmt
? fmt
: "%f", f
);
253 Make a string from a single character.
256 #n# is a repetition count, default value is 1
259 String_convert::char_string (char c
, int n
)
262 char *ch
= new char[ n
];
271 String_convert::rational_string (Rational r
)
273 return r
.to_string ();
277 String_convert::pointer_string (void const *l
)
279 char buffer
[STRING_BUFFER_LEN
];
280 snprintf (buffer
, STRING_BUFFER_LEN
, "%p", l
); // assume radix 10
281 return string (buffer
);
285 Convert a double to a string.
288 #n# is the number of nonzero digits
291 String_convert::precision_string (double x
, int n
)
293 string format
= "%." + to_string (max (0, n
- 1)) + "e";
294 string str
= double_string (abs (x
), format
.c_str ());
296 int exp
= dec2int (str
.substr (str
.length () - 3));
297 str
= str
.substr (0, str
.length () - 4);
299 while (str
[str
.length () - 1] == '0')
300 str
= str
.substr (0, str
.length () - 1);
301 if (str
[str
.length () - 1] == '.')
302 str
= str
.substr (0, str
.length () - 1);
305 return (sign (x
) > 0 ? str
: "-" + str
);
307 str
= str
.substr (0, 1) + str
.substr (2);
310 str
= "0." + to_string ('0', -dot
) + str
;
311 else if (dot
>= str
.length ())
312 str
+= to_string ('0', dot
- str
.length ());
313 else if ((dot
> 0) && (dot
< str
.length ()))
314 str
= str
.substr (0, dot
) + "." + str
.substr (dot
);
318 return (sign (x
) > 0 ? str
: "-" + str
);
323 String_convert::long_string (long l
)
325 char s
[STRING_BUFFER_LEN
];
326 sprintf (s
, "%ld", l
);
331 String_convert::unsigned_string (unsigned u
)
333 char s
[STRING_BUFFER_LEN
];
334 sprintf (s
, "%u", u
);
339 String_convert::pad_to (string s
, int n
)
341 return s
+ string (max (int(n
- s
.length ()), 0), ' ');
345 String_convert::to_upper (string s
)
347 return strnupr ((char *)s
.c_str (), s
.length ());
351 String_convert::to_lower (string s
)
353 return strnlwr ((char *)s
.c_str (), s
.length ());
357 String_convert::reverse (string s
)
359 return (char*) memrev ((unsigned char *)s
.data (), s
.length ());