Kernel: Split number-parsing code into a separate file
This commit is contained in:
parent
d0efc106b0
commit
67f536cf91
4
kernel/include/utils/StringParsing.h
Normal file
4
kernel/include/utils/StringParsing.h
Normal file
@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
long parse_decimal(const char* str);
|
||||
long parse_octal(const char* str);
|
@ -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;
|
||||
}
|
||||
|
||||
|
49
kernel/src/utils/StringParsing.cpp
Normal file
49
kernel/src/utils/StringParsing.cpp
Normal 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'; });
|
||||
}
|
Loading…
Reference in New Issue
Block a user