Kernel: Split number-parsing code into a separate file

This commit is contained in:
apio 2022-11-05 10:50:58 +01:00
parent d0efc106b0
commit 67f536cf91
3 changed files with 59 additions and 15 deletions

View File

@ -0,0 +1,4 @@
#pragma once
long parse_decimal(const char* str);
long parse_octal(const char* str);

View File

@ -10,6 +10,7 @@
#include "std/errno.h"
#include "std/stdlib.h"
#include "std/string.h"
#include "utils/StringParsing.h"
extern BOOTBOOT bootboot;
@ -54,24 +55,14 @@ uint64_t InitRD::get_file_physical_address(InitRD::File& file)
InitRD::File InitRD::get_file(TarHeader* header)
{
File result;
result.size = 0;
char null_terminated_size[13];
memcpy(null_terminated_size, header->size, 12);
null_terminated_size[12] = 0;
result.size = parse_octal(null_terminated_size);
memcpy(result.name, header->name, 100);
long multiplier =
1; // why they decided to store the size as an octal-encoded string instead of an integer is beyond me
for (int i = 10; i >= 0; i--)
{
result.size += (multiplier * (header->size[i] - 48));
multiplier *= 8;
}
result.addr = (void*)((uint64_t)header + TAR_BLOCKSIZE);
result.size_in_blocks = Utilities::get_blocks_from_size(TAR_BLOCKSIZE, result.size);
result.mode = 0;
multiplier = 1;
for (int i = 6; i >= 0; i--)
{
result.mode += (mode_t)(multiplier * (header->mode[i] - 48));
multiplier *= 8;
}
result.mode = (mode_t)parse_octal(header->mode);
return result;
}

View File

@ -0,0 +1,49 @@
#include "utils/StringParsing.h"
int isdigit(int c)
{
return c >= '0' && c < ':';
}
int isodigit(int c)
{
return c >= '0' && c < '8';
}
int isxdigit(int c)
{
return isdigit(c) || ((unsigned int)c | 32) - 'a' < 6;
}
template <typename T, typename ValidDigitChecker, typename Converter>
static T string_to_integer_type(const char* str, int base, ValidDigitChecker checker, Converter converter)
{
bool neg = false;
T val = 0;
switch (*str)
{
case '-':
neg = true;
str++;
break;
case '+': str++; break;
default: break;
}
while (checker(*str)) { val = (base * val) + converter(*str++); }
return (neg ? -val : val);
}
long parse_decimal(const char* str)
{
return string_to_integer_type<long>(
str, 10, [](char c) { return isdigit(c); }, [](char c) { return c - '0'; });
}
long parse_octal(const char* str)
{
return string_to_integer_type<long>(
str, 8, [](char c) { return isodigit(c); }, [](char c) { return c - '0'; });
}