feat: formatter and oslog()
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
#include <Lib/String.h>
|
||||
#include <Lib/VAArgs.h>
|
||||
|
||||
static void BufferAdd(ASCII* buffer, Size bufferSize, Size* written, ASCII character) {
|
||||
if (*written + 1 < bufferSize) {
|
||||
buffer[*written] = character;
|
||||
}
|
||||
(*written)++;
|
||||
}
|
||||
|
||||
void* StringSet(BytePointer destination, ASCII value, Size count) {
|
||||
BytePointer savedDestination = destination;
|
||||
while (count--) {
|
||||
*destination++ = (UInt8) value;
|
||||
}
|
||||
return savedDestination;
|
||||
}
|
||||
|
||||
void* MemoryCopy(void* destination, const void* source, Size count) {
|
||||
BytePointer destinationBuffer = (BytePointer) destination;
|
||||
const UInt8* sourceBuffer = (const UInt8*) source;
|
||||
|
||||
while (count >= 8) {
|
||||
*(UInt64*) destinationBuffer = *(const UInt64*) sourceBuffer;
|
||||
destinationBuffer += 8;
|
||||
sourceBuffer += 8;
|
||||
count -= 8;
|
||||
}
|
||||
|
||||
while (count > 0) {
|
||||
*destinationBuffer++ = *sourceBuffer++;
|
||||
count--;
|
||||
}
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
Int32 StringCompare(const ASCII* firstString, const ASCII* secondString) {
|
||||
while (*firstString && (*firstString == *secondString)) {
|
||||
firstString++;
|
||||
secondString++;
|
||||
}
|
||||
return *(const UInt8*) firstString - *(const UInt8*) secondString;
|
||||
}
|
||||
|
||||
Int32 StringCompareWithLimit(const ASCII* firstString, const ASCII* secondString, Size limit) {
|
||||
while (limit > 0) {
|
||||
if (*firstString != *secondString) return *(const UInt8*) firstString - *(const UInt8*) secondString;
|
||||
if (*firstString == '\0') return 0;
|
||||
firstString++;
|
||||
secondString++;
|
||||
limit--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ASCII* StringCopy(ASCII* destination, const ASCII* source) {
|
||||
ASCII* saved = destination;
|
||||
while (*source) *destination++ = *source++;
|
||||
*destination = 0;
|
||||
return saved;
|
||||
}
|
||||
|
||||
ASCII* StringCopyWithLimit(ASCII* destination, const ASCII* source, Size limit) {
|
||||
ASCII* saved = destination;
|
||||
while (*source && limit > 0) {
|
||||
*destination++ = *source++;
|
||||
limit--;
|
||||
}
|
||||
while (limit > 0) {
|
||||
*destination++ = 0;
|
||||
limit--;
|
||||
}
|
||||
return saved;
|
||||
}
|
||||
|
||||
Size StringGetLength(const ASCII* string) {
|
||||
Size result = 0;
|
||||
for (result = 0; string[result]; result++);
|
||||
return result;
|
||||
}
|
||||
|
||||
const ASCII* StringFindLastOccurrenceOfCharacter(const ASCII* string, ASCII separator) {
|
||||
const ASCII* lastSeparator = 0;
|
||||
do {
|
||||
if (*string == separator) lastSeparator = string;
|
||||
} while (*string++);
|
||||
|
||||
return lastSeparator;
|
||||
}
|
||||
|
||||
Int32 StringFormatVariadic(ASCII* string, Size size, const ASCII* format, va_list args) {
|
||||
Size written = 0;
|
||||
for (Size i = 0; format[i] != '\0'; i++) {
|
||||
if (format[i] == '%') {
|
||||
i++;
|
||||
if (format[i] == '\0') break;
|
||||
switch (format[i]) {
|
||||
case 's': {
|
||||
const ASCII* vaArgString = va_arg(args, const ASCII*);
|
||||
if (!vaArgString) vaArgString = "(null)";
|
||||
while (*vaArgString) BufferAdd(string, size, &written, *vaArgString++);
|
||||
break;
|
||||
}
|
||||
case 'c': {
|
||||
ASCII character = (ASCII)va_arg(args, Int);
|
||||
BufferAdd(string, size, &written, character);
|
||||
break;
|
||||
}
|
||||
case 'd': {
|
||||
Int64 number = va_arg(args, Int);
|
||||
if (number < 0) {
|
||||
BufferAdd(string, size, &written, '-');
|
||||
number = -number;
|
||||
}
|
||||
|
||||
UInt64 unsignedNumber = (UInt64)number;
|
||||
ASCII tempBuffer[32];
|
||||
Size position = 0;
|
||||
|
||||
if (unsignedNumber == 0) tempBuffer[position++] = '0';
|
||||
while (unsignedNumber > 0) {
|
||||
tempBuffer[position++] = (ASCII)((unsignedNumber % 10) + '0');
|
||||
unsignedNumber /= 10;
|
||||
}
|
||||
|
||||
while (position > 0) BufferAdd(string, size, &written, tempBuffer[--position]);
|
||||
break;
|
||||
}
|
||||
case 'x':
|
||||
case 'X': {
|
||||
UInt64 unsignedNumber = va_arg(args, UInt64);
|
||||
UInt8 padding = (format[i] == 'X') ? 16 : 0;
|
||||
|
||||
ASCII tempBuffer[32];
|
||||
Size position = 0;
|
||||
static const ASCII kHexDigits[] = "0123456789ABCDEF";
|
||||
|
||||
if (unsignedNumber == 0 && padding == 0) tempBuffer[position++] = '0';
|
||||
while (unsignedNumber > 0) {
|
||||
tempBuffer[position++] = kHexDigits[unsignedNumber % 16];
|
||||
unsignedNumber /= 16;
|
||||
}
|
||||
|
||||
while (position < (Size)padding) tempBuffer[position++] = '0';
|
||||
while (position > 0) BufferAdd(string, size, &written, tempBuffer[--position]);
|
||||
break;
|
||||
}
|
||||
case '%': {
|
||||
BufferAdd(string, size, &written, '%');
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
BufferAdd(string, size, &written, '%');
|
||||
BufferAdd(string, size, &written, format[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BufferAdd(string, size, &written, format[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (size > 0) {
|
||||
if (written < size) string[written] = '\0';
|
||||
else string[size - 1] = '\0';
|
||||
}
|
||||
|
||||
return (Int32)written;
|
||||
}
|
||||
|
||||
Int32 StringFormat(ASCII* destination, UInt64 size, const ASCII* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
Int32 returnValue = StringFormatVariadic(destination, size, format, args);
|
||||
va_end(args);
|
||||
return returnValue;
|
||||
}
|
||||
Reference in New Issue
Block a user