mirror of
https://github.com/xomboverlord/xomb-bare-bones.git
synced 2026-01-11 18:33:15 +01:00
164 lines
3.8 KiB
D
164 lines
3.8 KiB
D
// This module contains helpful functions found necessary by the runtime and gcc.
|
|
|
|
// contains: itoa, memcpy, memset, memmove, memcmp, strlen, isnan, toString
|
|
|
|
module kernel.runtime.util;
|
|
|
|
/**
|
|
This function converts an integer to a string, depending on the base passed in.
|
|
Params:
|
|
buf = The function will save the translated string into this character array.
|
|
base = The base of the integer value. If "d," it will be assumed to be decimal. If "x," the integer
|
|
will be hexadecimal.
|
|
d = The integer to translate.
|
|
Returns: The translated string in a character array.
|
|
*/
|
|
char[] itoa(char[] buf, char base, long d)
|
|
{
|
|
size_t p = buf.length - 1;
|
|
size_t startIdx = 0;
|
|
ulong ud = d;
|
|
bool negative = false;
|
|
|
|
int divisor = 10;
|
|
|
|
// If %d is specified and D is minus, put `-' in the head.
|
|
if(base == 'd' && d < 0)
|
|
{
|
|
negative = true;
|
|
ud = -d;
|
|
}
|
|
else if(base == 'x')
|
|
divisor = 16;
|
|
|
|
// Divide UD by DIVISOR until UD == 0.
|
|
do
|
|
{
|
|
int remainder = ud % divisor;
|
|
buf[p--] = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
|
|
}
|
|
while (ud /= divisor)
|
|
|
|
if(negative)
|
|
buf[p--] = '-';
|
|
|
|
return buf[p + 1 .. $];
|
|
}
|
|
|
|
/**
|
|
This function copies data from a source piece of memory to a destination piece of memory.
|
|
Params:
|
|
dest = A pointer to the piece of memory serving as the copy destination.
|
|
src = A pointer to the piece of memory serving as the copy source.
|
|
count = The number of bytes to copy form src to dest.
|
|
Returns: A void pointer to the start of the destination data (dest).
|
|
*/
|
|
extern(C) void* memcpy(void* dest, void* src, size_t count)
|
|
{
|
|
ubyte* d = cast(ubyte*)dest;
|
|
ubyte* s = cast(ubyte*)src;
|
|
|
|
for(size_t i = count; count; count--, d++, s++)
|
|
*d = *s;
|
|
|
|
return dest;
|
|
}
|
|
|
|
/**
|
|
Memcpy and memmove only really have differences at the user level, where they have slightly
|
|
different semantics. Here, they're pretty much the same.
|
|
*/
|
|
extern(C) void* memmove(void* dest, void* src, size_t count)
|
|
{
|
|
ubyte* d = cast(ubyte*)dest;
|
|
ubyte* s = cast(ubyte*)src;
|
|
|
|
for(size_t i = count; count; count--, d++, s++)
|
|
*d = *s;
|
|
|
|
return dest;
|
|
}
|
|
|
|
/**
|
|
Compare two blocks of memory.
|
|
|
|
Params:
|
|
a = Pointer to the first block.
|
|
b = Pointer to the second block.
|
|
n = The number of bytes to compare.
|
|
|
|
Returns:
|
|
0 if they are equal, < 0 if a is less than b, and > 0 if a is greater than b.
|
|
*/
|
|
long memcmp(void* a, void* b, size_t n)
|
|
{
|
|
ubyte* str_a = cast(ubyte*)a;
|
|
ubyte* str_b = cast(ubyte*)b;
|
|
|
|
for(size_t i = 0; i < n; i++)
|
|
{
|
|
if(*str_a != *str_b)
|
|
return *str_a - *str_b;
|
|
|
|
str_a++;
|
|
str_b++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
This function sets a particular piece of memory to a particular value.
|
|
Params:
|
|
addr = The address of the piece of memory you wish to write.
|
|
val = The value you wish to write to memory.
|
|
numBytes = The number of bytes you would like to write to memory.
|
|
*/
|
|
void memset(void *addr, ubyte val, uint numBytes){
|
|
ubyte *data = cast(ubyte*) addr;
|
|
|
|
for(int i = 0; i < numBytes; i++){
|
|
data[i] = val;
|
|
}
|
|
}
|
|
|
|
/**
|
|
This function determines the size of a passed-in string.
|
|
Params:
|
|
s = A pointer to the beginning of a character array, declaring a string.
|
|
Returns: The size of the string in size_t format.
|
|
*/
|
|
size_t strlen(char* s)
|
|
{
|
|
size_t i = 0;
|
|
for( ; *s != 0; i++, s++){}
|
|
return i;
|
|
}
|
|
|
|
/**
|
|
This function takes in a character pointer and returns a character array, or a string.
|
|
Params:
|
|
s = A pointer to the character(s) you wish to translate to a string.
|
|
Returns: A character array (string) containing the information.
|
|
*/
|
|
char[] toString(char* s)
|
|
{
|
|
return s[0 .. strlen(s)];
|
|
}
|
|
|
|
/**
|
|
This function checks to see if a floating point number is a NaN.
|
|
Params:
|
|
e = The value / piece of information you would like to check for number status.
|
|
Returns:
|
|
0 if it isn't a NaN, non-zero if it is.
|
|
*/
|
|
int isnan(real e)
|
|
{
|
|
ushort* pe = cast(ushort *)&e;
|
|
ulong* ps = cast(ulong *)&e;
|
|
|
|
return (pe[4] & 0x7FFF) == 0x7FFF &&
|
|
*ps & 0x7FFFFFFFFFFFFFFF;
|
|
}
|