Lots of CString clean up; attempt #1 at implementing int to string conversion
Long (64-bit) ints are hard to do on 32-bit...
This commit is contained in:
parent
d8b05620cc
commit
d2d7fac4df
2 changed files with 169 additions and 16 deletions
|
@ -13,10 +13,11 @@ namespace kstd {
|
||||||
namespace CString {
|
namespace CString {
|
||||||
|
|
||||||
usize
|
usize
|
||||||
length(char* str)
|
length(const char* str,
|
||||||
|
usize max)
|
||||||
{
|
{
|
||||||
usize i;
|
usize i;
|
||||||
for (i = 0; str[i] != '\0'; i++);
|
for (i = 0; str[i] != '\0' && i < max; i++);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,9 +25,10 @@ length(char* str)
|
||||||
char*
|
char*
|
||||||
copy(char* dst,
|
copy(char* dst,
|
||||||
const char* src,
|
const char* src,
|
||||||
usize length)
|
usize max)
|
||||||
{
|
{
|
||||||
for (usize i = 0; i < length; i++) {
|
usize len = length(src, max);
|
||||||
|
for (usize i = 0; i < len; i++) {
|
||||||
dst[i] = src[i];
|
dst[i] = src[i];
|
||||||
if (src[i] == '\0') {
|
if (src[i] == '\0') {
|
||||||
break;
|
break;
|
||||||
|
@ -36,8 +38,25 @@ copy(char* dst,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char*
|
||||||
|
reverse(char* str,
|
||||||
|
usize max)
|
||||||
|
{
|
||||||
|
max = length(str, max);
|
||||||
|
char* p = str;
|
||||||
|
char* t = str + max - 1;
|
||||||
|
char c;
|
||||||
|
while (t > p) {
|
||||||
|
c = *p;
|
||||||
|
*p++ = *t;
|
||||||
|
*t-- = c;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
uppercase(char *str)
|
uppercase(char* str)
|
||||||
{
|
{
|
||||||
for (char *p = str; *p != '\0'; p++) {
|
for (char *p = str; *p != '\0'; p++) {
|
||||||
if (Char::isLower(*p)) {
|
if (Char::isLower(*p)) {
|
||||||
|
@ -50,12 +69,124 @@ uppercase(char *str)
|
||||||
* Converters
|
* Converters
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char*
|
/**
|
||||||
fromInteger(int value,
|
* Converts `value` to an un-reversed CString without a null terminator. It is
|
||||||
char* str,
|
* expected that callers of this function will append a null terminator and
|
||||||
usize length)
|
* reverse `str` at the appropriate time.
|
||||||
|
*
|
||||||
|
* @return A pointer to the character *after* all converted characters, such
|
||||||
|
* that `p - buffer` is the number of characters converted.
|
||||||
|
*/
|
||||||
|
static usize
|
||||||
|
_doConvertFromInteger(u32 value,
|
||||||
|
char* buffer,
|
||||||
|
usize length,
|
||||||
|
u8 base,
|
||||||
|
bool capitalized)
|
||||||
{
|
{
|
||||||
return 0;
|
char* p = buffer;
|
||||||
|
int place;
|
||||||
|
do {
|
||||||
|
if (usize(p - buffer) >= length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
place = value % base;
|
||||||
|
value /= base;
|
||||||
|
*p++ = (place < 10) ? place + '0' : (place - 10) + (capitalized ? 'A' : 'a');
|
||||||
|
} while (value != 0);
|
||||||
|
|
||||||
|
return p - buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
fromInteger(i32 value,
|
||||||
|
char* buffer,
|
||||||
|
usize length,
|
||||||
|
u8 base,
|
||||||
|
bool capitalized)
|
||||||
|
{
|
||||||
|
const bool negative = base == 10 && value < 0;
|
||||||
|
if (negative) {
|
||||||
|
value *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
usize convertedLength = _doConvertFromInteger(u32(value), buffer, length, base, capitalized);
|
||||||
|
|
||||||
|
if (convertedLength < length && negative) {
|
||||||
|
buffer[convertedLength++] = '-';
|
||||||
|
}
|
||||||
|
if (convertedLength < length) {
|
||||||
|
buffer[convertedLength] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse(buffer, convertedLength);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char*
|
||||||
|
fromUnsignedInteger(u32 value,
|
||||||
|
char* buffer,
|
||||||
|
usize length,
|
||||||
|
u8 base,
|
||||||
|
bool capitalized)
|
||||||
|
{
|
||||||
|
usize convertedLength = _doConvertFromInteger(u32(value), buffer, length, base, capitalized);
|
||||||
|
if (convertedLength < length) {
|
||||||
|
buffer[convertedLength] = '\0';
|
||||||
|
}
|
||||||
|
reverse(buffer, convertedLength);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char*
|
||||||
|
fromLongInteger(i64 value,
|
||||||
|
char* buffer,
|
||||||
|
usize length,
|
||||||
|
u8 base,
|
||||||
|
bool capitalized)
|
||||||
|
{
|
||||||
|
const bool negative = base == 10 && value < 0;
|
||||||
|
if (negative) {
|
||||||
|
value *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do large ints in two passes. First do the high-order bits, then the lower order bits.
|
||||||
|
usize convertedLength;
|
||||||
|
convertedLength = _doConvertFromInteger(u32(value >> 32), buffer, length, base, capitalized);
|
||||||
|
convertedLength += _doConvertFromInteger(u32(value), &buffer[convertedLength], length - convertedLength, base, capitalized);
|
||||||
|
|
||||||
|
if (convertedLength < length && negative) {
|
||||||
|
buffer[convertedLength++] = '-';
|
||||||
|
}
|
||||||
|
if (convertedLength < length) {
|
||||||
|
buffer[convertedLength] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse(buffer, convertedLength);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char*
|
||||||
|
fromUnsignedLongInteger(u64 value,
|
||||||
|
char* buffer,
|
||||||
|
usize length,
|
||||||
|
u8 base,
|
||||||
|
bool capitalized)
|
||||||
|
{
|
||||||
|
// Do large ints in two passes. First do the high-order bits, then the lower order bits.
|
||||||
|
usize convertedLength;
|
||||||
|
convertedLength = _doConvertFromInteger(u32(value >> 32), buffer, length, base, capitalized);
|
||||||
|
convertedLength += _doConvertFromInteger(u32(value), &buffer[convertedLength], length - convertedLength, base, capitalized);
|
||||||
|
if (convertedLength < length) {
|
||||||
|
buffer[convertedLength] = '\0';
|
||||||
|
}
|
||||||
|
reverse(buffer, convertedLength);
|
||||||
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,11 +11,20 @@
|
||||||
namespace kstd {
|
namespace kstd {
|
||||||
namespace CString {
|
namespace CString {
|
||||||
|
|
||||||
/** Find the length of a C string. */
|
/**
|
||||||
usize length(char *str);
|
* Find the length of a C string.
|
||||||
|
*
|
||||||
|
* @param [in] str The string whose length we should find
|
||||||
|
* @param [in] max Maximum number of characters to search
|
||||||
|
* @return Length of the string
|
||||||
|
*/
|
||||||
|
usize length(const char *str, usize max = -1);
|
||||||
|
|
||||||
/** Copy a string. */
|
/** Copy a string. */
|
||||||
char* copy(char* dst, const char* src, usize length);
|
char* copy(char* dst, const char* src, usize max);
|
||||||
|
|
||||||
|
/** Reverse a string. */
|
||||||
|
char* reverse(char* str, usize max);
|
||||||
|
|
||||||
/** Destructively convert an ASCII C String to uppercase. */
|
/** Destructively convert an ASCII C String to uppercase. */
|
||||||
void uppercase(char *str);
|
void uppercase(char *str);
|
||||||
|
@ -24,11 +33,24 @@ void uppercase(char *str);
|
||||||
* @defgroup To-String Converters
|
* @defgroup To-String Converters
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Convert an integer to a string. */
|
/**
|
||||||
char* fromInteger(int value, char *str, usize length);
|
* Convert a signed integer to a string.
|
||||||
|
*
|
||||||
|
* @param [in] value The value to convert
|
||||||
|
* @param [in,out] buffer Buffer to write to
|
||||||
|
* @param [in] length Length of the buffer
|
||||||
|
* @param [in] base Base to convert to. Default is base 10.
|
||||||
|
* @param [in] capitalized Should the alphabetic digits be capitalized? Default is false.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
char* fromInteger(i32 value, char* buffer, usize length, u8 base = 10, bool capitalized = false);
|
||||||
|
char* fromUnsignedInteger(u32 value, char* buffer, usize length, u8 base = 10, bool capitalized = false);
|
||||||
|
char* fromLongInteger(i64 value, char* buffer, usize length, u8 base = 10, bool capitalized = false);
|
||||||
|
char* fromUnsignedLongInteger(u64 value, char* buffer, usize length, u8 base = 10, bool capitalized = false);
|
||||||
|
/** @} */
|
||||||
|
|
||||||
/** Convert a bool to a string. */
|
/** Convert a bool to a string. */
|
||||||
char* fromBool(bool value, char *str, usize length);
|
char* fromBool(bool value, char* str, usize length);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue