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 std::string (b
? "true" : "false");
37 String_convert::bin2hex (std::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 (std::string bin_string
)
52 return bin2unsigned (bin_string
);
56 String_convert::bin2unsigned (std::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
];
69 // breendet imp from std::string
71 String_convert::dec2int (std::string dec_string
)
73 if (!dec_string
.length ())
77 int conv
= sscanf (dec_string
.c_str (), "%ld", &l
);
84 String_convert::i64_string (I64 i64
, char const *fmt
)
86 char buffer
[STRING_BUFFER_LEN
];
87 snprintf (buffer
, STRING_BUFFER_LEN
,
88 (fmt
? fmt
: "%Ld"), i64
); // assume radix 10
89 return std::string (buffer
);
91 // breendet imp from std::string
93 String_convert::dec2double (std::string dec_string
)
95 if (!dec_string
.length ())
98 int conv
= sscanf (dec_string
.c_str (), "%lf", &d
);
104 String_convert::hex2bin (std::string hex_string
, std::string
&bin_string_r
)
106 if (hex_string
.length () % 2)
107 hex_string
= "0" + hex_string
;
110 Byte
const *byte
= (Byte
const*) hex_string
.data ();
112 while (i
< hex_string
.length ())
114 int high_i
= hex2nibble (*byte
++);
115 int low_i
= hex2nibble (*byte
++);
116 if (high_i
< 0 || low_i
< 0)
117 return 1; // illegal char
118 bin_string_r
+= to_string ((char) (high_i
<< 4 | low_i
), 1);
125 String_convert::hex2bin (std::string hex_string
)
128 // silly, asserts should alway be "on"!
129 // assert (!hex2bin (hex_string, str) );
130 int error_i
= hex2bin (hex_string
, str
);
136 String_convert::hex2nibble (Byte byte
)
138 if (byte
>= '0' && byte
<= '9')
140 if (byte
>= 'A' && byte
<= 'F')
141 return byte
- 'A' + 10;
142 if (byte
>= 'a' && byte
<= 'f')
143 return byte
- 'a' + 10;
147 // stupido. Should use int_string ()
149 String_convert::int2dec (int i
, int length_i
, char ch
)
156 std::string dec_string
= to_string (i
);
159 return to_string (fill_char
, length_i
- dec_string
.length ()) + dec_string
;
162 // stupido. Should use int_string ()
164 String_convert::unsigned2hex (unsigned u
, ssize length
, char fill_char
)
173 str
= to_string ((char) ((u
% 16)["0123456789abcdef"])) + str
;
177 str
+= int_string (u
, "%x"); // hmm. %lx vs. %x -> portability?
180 str
= to_string (fill_char
, length
- str
.length ()) + str
;
181 while ((str
.length () > length
) && (str
[ 0 ] == 'f'))
182 str
= str
.substr (2);
188 String_convert::int2hex (int i
, int length_i
, char fill_char
)
190 return unsigned2hex ((unsigned)i
, length_i
, fill_char
);
194 String_convert::nibble2hex_byte (Byte byte
)
196 if ((byte
& 0x0f) <= 9)
197 return (byte
& 0x0f) + '0';
199 return (byte
& 0x0f) - 10 + 'a';
202 Convert an integer to a string
205 #fmt# is a printf style format, default assumes "%d" as format.
208 String_convert::int_string (int i
, char const *fmt
)
210 char buffer
[STRING_BUFFER_LEN
];
211 snprintf (buffer
, STRING_BUFFER_LEN
,
212 (fmt
? fmt
: "%d"), i
); // assume radix 10
213 return std::string (buffer
);
217 String_convert::form_string (char const *format
, ...)
220 va_start (args
, format
);
221 char buffer
[STRING_BUFFER_LEN
];
222 vsnprintf (buffer
, STRING_BUFFER_LEN
, format
, args
);
224 return std::string (buffer
);
228 String_convert::vform_string (char const *format
, va_list args
)
230 char buffer
[STRING_BUFFER_LEN
];
231 vsnprintf (buffer
, STRING_BUFFER_LEN
, format
, args
);
232 return std::string (buffer
);
236 Convert a double to a string.
238 @param #fmt# is a printf style format, default assumes "%lf" as format
241 String_convert::double_string (double f
, char const *fmt
)
243 char buf
[STRING_BUFFER_LEN
];
245 snprintf (buf
, STRING_BUFFER_LEN
, fmt
? fmt
: "%f", f
);
246 return std::string (buf
);
250 Make a string from a single character.
253 #n# is a repetition count, default value is 1
256 String_convert::char_string (char c
, int n
)
259 char *ch
= new char[ n
];
262 std::string
s (ch
, n
);
264 std::string
s (ch
, 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 std::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 std::string format
= "%." + to_string (max (0, n
- 1)) + "e";
294 std::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
);
321 std::vector
<std::string
>
322 String_convert::split (std::string str
, char c
)
324 std::vector
<std::string
> a
;
325 ssize i
= str
.find (c
);
328 std::string s
= str
.substr (0, i
);
330 while (str
[++i
] == c
)
332 str
= str
.substr (i
);
341 String_convert::long_string (long l
)
343 char s
[STRING_BUFFER_LEN
];
344 sprintf (s
, "%ld", l
);
349 String_convert::unsigned_string (unsigned u
)
351 char s
[STRING_BUFFER_LEN
];
352 sprintf (s
, "%u", u
);
357 String_convert::pad_to (std::string s
, int n
)
359 return s
+ std::string (max (int(n
- s
.length ()), 0), ' ');
363 String_convert::to_upper (std::string s
)
365 return strnupr ((char *)s
.c_str (), s
.length ());
369 String_convert::to_lower (std::string s
)
371 return strnlwr ((char *)s
.c_str (), s
.length ());
375 String_convert::reverse (std::string s
)
377 return (char*) memrev ((unsigned char *)s
.data (), s
.length ());