gctf2023/pwn/flipper/dist/common/source/util/kstring.cpp
2023-11-24 13:11:34 -05:00

565 lines
9.1 KiB
C++

#include "kstring.h"
#include "kmalloc.h"
#include "assert.h"
#include "ArchMemory.h"
extern "C" size_t strlen(const char *str)
{
const char *pos = str;
while (*pos)
{
++pos;
}
return (pos - str);
}
extern "C" void *memcpy(void *dest, const void *src, size_t length)
{
size_t i;
size_t* s = (size_t*) src;
size_t* d = (size_t*) dest;
size_t num_large_copies = length / sizeof(size_t);
size_t num_rest_copies = length % sizeof(size_t);
for (size_t i = 0; i < num_large_copies; ++i)
{
*d++ = *s++;
}
uint8* s8 = (uint8*) s;
uint8* d8 = (uint8*) d;
for (i = 0; i < num_rest_copies; ++i)
{
*d8++ = *s8++;
}
return dest;
}
extern "C" void *memmove(void *dest, const void *src, size_t length)
{
uint8* dest8 = (uint8*) dest;
const uint8* src8 = (const uint8*) src;
if (length == 0 || src == dest)
{
return dest;
}
if (src > dest)
{
// if src is _not_ before dest we can do a forward copy
while (length--)
{
*dest8++ = *src8++;
}
}
else
{
// if src is before dest we have to do a backward copy
src8 += length - 1;
dest8 += length - 1;
while (length--)
{
*dest8-- = *src8--;
}
}
return dest;
}
void *memccpy(void *dest, const void *src, uint8 c, size_t length)
{
uint8 *dest8 = (uint8*) dest;
const uint8 *src8 = (const uint8*) src;
if (length == 0)
{
return (void*) 0;
}
while (length--)
{
if ((*dest8++ = *src8++) == c)
{
return (void*) dest8;
}
}
return (void *) 0;
}
extern "C" void *memset(void *block, uint8 c, size_t size)
{
if (size)
{
size_t i;
size_t* d = (size_t*) block;
size_t large_c = c;
for (i = 0; i < sizeof(size_t); i++)
{
large_c = (large_c << 8) | c;
}
size_t num_large_copies = size / sizeof(size_t);
size_t num_rest_copies = size % sizeof(size_t);
for (i = 0; i < num_large_copies; ++i)
{
*d++ = large_c;
}
uint8* d8 = (uint8*) d;
for (i = 0; i < num_rest_copies; ++i)
{
*d8++ = c;
}
}
return block;
}
extern "C" char *strcpy(char *dest, const char* src)
{
//assert("don't use strcpy" == 0);
char *start = dest;
for (; (*dest = *src); ++src, ++dest)
;
return start;
}
extern "C" char *strncpy(char *dest, const char* src, size_t size)
{
char *start = dest;
int8 fill = 0;
while (size--)
{
if (fill)
{
*dest = 0;
}
else if ((*dest = *src) == 0)
{
fill = 1;
}
src++;
dest++;
}
return start;
}
extern "C" char *strdup(const char *src)
{
size_t size = strlen(src) + 1;
char *dest = 0;
if ((dest = (char*) kmalloc((size) * sizeof(char))) == (char*) 0)
{
return (char*) 0;
}
return (char*) memcpy(dest, src, size);
}
extern "C" char *strcat(char *dest, const char*append)
{
char *start = dest + strlen(dest);
strcpy(start, append);
return dest;
}
extern "C" char *strncat(char *dest, const char*append, size_t size)
{
char* save = dest;
if (size == 0)
{
return save;
}
while (*dest)
{
++dest;
}
while (size--)
{
if ((*dest = *append++) == '\0')
{
break;
}
++dest;
}
*dest = '\0';
return save;
}
extern "C" size_t strlcat(char *dest, const char*append, size_t size)
{
size_t count = size;
const char*append_start = append;
size_t done = 0;
while (count != 0 && *dest != '\0')
{
--count;
++dest;
}
done = size - count;
if (count == 0)
{
return done + strlen(append);
}
while (count--)
{
if ((*dest++ = *append) == '\0')
{
break;
}
++append;
}
return done + (append - append_start) - 1;
}
extern "C" void bcopy(void *src, void* dest, size_t length)
{
uint8* dest8 = (uint8*) dest;
const uint8* src8 = (const uint8*) src;
if (length == 0 || src == dest)
{
return;
}
if (src < dest)
{
// if src is before dest we can do a forward copy
while (length--)
{
*dest8++ = *src8++;
}
}
else
{
// if src is _not_ before dest we can do a forward copy
src8 += length;
dest8 += length;
while (length--)
{
*dest8-- = *src8--;
}
}
}
extern "C" int32 memcmp(const void *region1, const void *region2, size_t size)
{
const uint8* b1 = (const uint8*)region1;
const uint8* b2 = (const uint8*)region2;
if (size == 0)
{
return 0;
}
while (size--)
{
if (*b1++ != *b2++)
{
return (*--b1 - *--b2);
}
}
return 0;
}
extern "C" int32 strcmp(const char *str1, const char *str2)
{
assert(str1);
assert(str2);
if (str1 == str2)
{
return 0;
}
while ((*str1) && (*str2))
{
if (*str1 != *str2)
{
break;
}
++str1;
++str2;
}
return (*(uint8 *) str1 - *(uint8 *) str2);
}
extern "C" int32 strncmp(const char *str1, const char *str2, size_t n)
{
while (n && (*str1) && (*str2))
{
if (*str1 != *str2)
{
break;
}
++str1;
++str2;
--n;
}
if (n == 0)
return 0;
else
return (*(uint8 *) str1 - *(uint8 *) str2);
}
extern "C" int32 bcmp(const void *region1, const void *region2, size_t size)
{
const uint8* b1 = (const uint8*)region1;
const uint8* b2 = (const uint8*)region2;
if (size == 0)
{
return 0;
}
while (size--)
{
if (*b1++ != *b2++)
{
return (*--b1 - *--b2);
}
}
return 0;
}
extern "C" void *memnotchr(const void *block, uint8 c, size_t size)
{
const uint8 *b = (const uint8*) block;
while (size--)
{
if (*b != c)
{
return (void *) b;
}
++b;
}
return (void *) 0;
}
extern "C" void *memchr(const void *block, uint8 c, size_t size)
{
const uint8 *b = (const uint8*) block;
while (size--)
{
if (*b == c)
{
return (void *) b;
}
++b;
}
return (void *) 0;
}
extern "C" void *memrchr(const void *block, uint8 c, size_t size)
{
const uint8 *b = ((const uint8*) block + size - 1);
while (size--)
{
if (*b == c)
{
return (void *) b;
}
--b;
}
return (void *) 0;
}
extern "C" char *strchr(const char* str, char c)
{
do
{
if (*str == c)
{
return (char *) str;
}
} while (*++str);
return (char *) 0;
}
extern "C" char *strrchr(const char* str, char c)
{
uint32 len = strlen(str);
const char *pos = str + len; // goes to '\0'
do
{
if (*--pos == c)
{
return (char *) pos;
}
} while (--len);
return (char *) 0;
}
extern "C" char* strtok(char* str, const char* delimiters)
{
static char* str_to_tok = 0;
if (str != 0)
str_to_tok = str;
// no delimiters, so just return the rest-string
if (delimiters == 0)
return str_to_tok;
if (str_to_tok == 0)
return 0;
// determine token start and end
uint32 tok_start = 0;
uint32 tok_end = -1;
// find first char which is not one of the delimiters
uint32 str_pos = 0;
for (str_pos = 0; str_to_tok[str_pos] != '\0'; str_pos++)
{
uint8 char_is_delimiter = 0;
uint32 del_pos = 0;
for (del_pos = 0; delimiters[del_pos] != '\0'; del_pos++)
{
if (str_to_tok[str_pos] == delimiters[del_pos])
{
char_is_delimiter = 1;
break;
}
}
if (char_is_delimiter == 0)
{
// this is the start char of the token
tok_start = str_pos;
break;
}
}
// find next delimiter in the string
for (str_pos = tok_start; str_to_tok[str_pos] != '\0'; str_pos++)
{
uint32 del_pos = 0;
for (; delimiters[del_pos] != '\0'; del_pos++)
{
if (str_to_tok[str_pos] == delimiters[del_pos])
{
// delimiter found!
tok_end = str_pos;
break;
}
}
if (tok_end != -1U)
break;
}
// create and return token:
char* token = str_to_tok + tok_start;
// update string
if (tok_end == -1U)
{
// finished, no next token
str_to_tok = 0;
}
else
{
str_to_tok[tok_end] = '\0';
str_to_tok += tok_end + 1;
}
return token;
}
// converts a single digit into an
extern "C" char numToASCIIChar(uint8 number)
{
if (number <= 9)
return 0x30 + number;
if (number >= 0xa && number <= 0xf)
return 0x61 + number - 0xa;
// default value
return '?';
}
extern "C" char* itoa(int value, char* str, int base)
{
if (!str)
return 0;
int div = value;
int mod;
unsigned int str_pos = 0;
while (div >= base)
{
mod = div % base;
div /= base;
str[str_pos++] = numToASCIIChar(mod);
}
str[str_pos++] = numToASCIIChar(div);
if (value < 0)
str[str_pos++] = '-';
str[str_pos] = '\0';
if (str_pos > 1)
{
uint32 str_len = strlen(str);
uint32 i = 0;
// switching the string
for (i = 0; i < str_len / 2; i++)
{
char temp = str[str_len - 1 - i];
str[str_len - 1 - i] = str[i];
str[i] = temp;
}
}
return str;
}
extern "C" uint32 checksum(uint32* src, uint32 nbytes)
{
nbytes /= sizeof(uint32);
uint32 poly = 0xEDB88320;
int bit = 0, nbits = 32;
uint32 res = 0xFFFFFFFF;
for (uint32 i = 0; i < nbytes; ++i)
for (bit = nbits - 1; bit >= 0; --bit)
if ((res & 1) != ((src[i] >> bit) & 1))
res = (res >> 1) ^ poly;
else
res = (res >> 1) + 7;
res ^= 0xFFFFFFFF;
return res;
}