|
@ -20,37 +20,38 @@ |
|
|
#include "INIConfig.h" |
|
|
#include "INIConfig.h" |
|
|
#include "Socket.h" |
|
|
#include "Socket.h" |
|
|
|
|
|
|
|
|
void Jupiter::INIConfig::write_helper(FILE *in_file, const Jupiter::Config *in_section, size_t in_depth) |
|
|
void Jupiter::INIConfig::write_helper(FILE *in_file, const Jupiter::Config *in_section, size_t in_depth) { |
|
|
{ |
|
|
|
|
|
size_t index; |
|
|
size_t index; |
|
|
|
|
|
|
|
|
if (in_depth != 0) |
|
|
if (in_depth != 0) { |
|
|
{ |
|
|
|
|
|
// Write header
|
|
|
// Write header
|
|
|
|
|
|
|
|
|
fputs("\r\n", in_file); |
|
|
fputs("\r\n", in_file); |
|
|
|
|
|
|
|
|
// Tabs
|
|
|
// Tabs
|
|
|
for (index = 1; index < in_depth; ++index) |
|
|
for (index = 1; index < in_depth; ++index) { |
|
|
fputc('\t', in_file); |
|
|
fputc('\t', in_file); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
for (index = 0; index != in_depth; ++index) |
|
|
for (index = 0; index != in_depth; ++index) { |
|
|
fputc('[', in_file); |
|
|
fputc('[', in_file); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
fputs(in_section->getName().c_str(), in_file); |
|
|
fputs(in_section->getName().c_str(), in_file); |
|
|
|
|
|
|
|
|
for (index = 0; index != in_depth; ++index) |
|
|
for (index = 0; index != in_depth; ++index) { |
|
|
fputc(']', in_file); |
|
|
fputc(']', in_file); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
fputs("\r\n", in_file); |
|
|
fputs("\r\n", in_file); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Write table entries
|
|
|
// Write table entries
|
|
|
for (auto& table_entry : in_section->getTable()) |
|
|
for (auto& table_entry : in_section->getTable()) { |
|
|
{ |
|
|
|
|
|
// Tabs
|
|
|
// Tabs
|
|
|
for (index = 1; index < in_depth; ++index) |
|
|
for (index = 1; index < in_depth; ++index) { |
|
|
fputc('\t', in_file); |
|
|
fputc('\t', in_file); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Write entry
|
|
|
// Write entry
|
|
|
fwrite(table_entry.first.data(), sizeof(char), table_entry.first.size(), in_file); |
|
|
fwrite(table_entry.first.data(), sizeof(char), table_entry.first.size(), in_file); |
|
@ -70,8 +71,9 @@ bool Jupiter::INIConfig::write_internal(const char *in_filename) |
|
|
// Open file
|
|
|
// Open file
|
|
|
FILE *file = fopen(in_filename, "wb"); |
|
|
FILE *file = fopen(in_filename, "wb"); |
|
|
|
|
|
|
|
|
if (file == nullptr) |
|
|
if (file == nullptr) { |
|
|
return false; |
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Iterate through table and sections
|
|
|
// Iterate through table and sections
|
|
|
write_helper(file, this, 0); |
|
|
write_helper(file, this, 0); |
|
@ -97,25 +99,24 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) { |
|
|
|
|
|
|
|
|
line.remove_prefix(itr - line.data()); |
|
|
line.remove_prefix(itr - line.data()); |
|
|
|
|
|
|
|
|
if (*itr == ';') |
|
|
if (*itr == ';') { |
|
|
return; // Comment
|
|
|
return; // Comment
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (*itr == '[') |
|
|
if (*itr == '[') { |
|
|
{ |
|
|
|
|
|
// Parse header
|
|
|
// Parse header
|
|
|
|
|
|
|
|
|
size_t depth = 1; |
|
|
size_t depth = 1; |
|
|
|
|
|
|
|
|
for (++itr; itr != end && *itr == '['; ++itr) |
|
|
for (++itr; itr != end && *itr == '['; ++itr) { |
|
|
++depth; |
|
|
++depth; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
line.remove_prefix(itr - line.data()); |
|
|
line.remove_prefix(itr - line.data()); |
|
|
|
|
|
|
|
|
while (end != itr) |
|
|
while (end != itr) { |
|
|
{ |
|
|
|
|
|
--end; |
|
|
--end; |
|
|
if (*end != ']' && isspace(*end) == 0) |
|
|
if (*end != ']' && isspace(*end) == 0) { |
|
|
{ |
|
|
|
|
|
++end; |
|
|
++end; |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
@ -125,21 +126,23 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) { |
|
|
|
|
|
|
|
|
// Add section to stack; pop sections or push blanks as necessary
|
|
|
// Add section to stack; pop sections or push blanks as necessary
|
|
|
|
|
|
|
|
|
while (depth < section_stack.size()) |
|
|
while (depth < section_stack.size()) { |
|
|
section_stack.pop(); |
|
|
section_stack.pop(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
while (depth > section_stack.size()) |
|
|
while (depth > section_stack.size()) { |
|
|
section_stack.push(std::addressof(section_stack.top()->getSectionReference({}))); |
|
|
section_stack.push(std::addressof(section_stack.top()->getSectionReference({}))); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
section_stack.push(§ion_stack.top()->getSectionReference(line)); |
|
|
section_stack.push(§ion_stack.top()->getSectionReference(line)); |
|
|
} |
|
|
} |
|
|
else |
|
|
else { |
|
|
{ |
|
|
|
|
|
// Truncate spaces
|
|
|
// Truncate spaces
|
|
|
--end; |
|
|
--end; |
|
|
|
|
|
|
|
|
while (isspace(static_cast<unsigned char>(*end))) |
|
|
while (isspace(static_cast<unsigned char>(*end))) { |
|
|
--end; // don't need a safety check since we know there is at least 1 non-space character
|
|
|
--end; // don't need a safety check since we know there is at least 1 non-space character
|
|
|
|
|
|
} |
|
|
// end now points to a non-space character within the bounds
|
|
|
// end now points to a non-space character within the bounds
|
|
|
|
|
|
|
|
|
++end; |
|
|
++end; |
|
@ -147,19 +150,21 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) { |
|
|
|
|
|
|
|
|
// Parse key (can be empty)
|
|
|
// Parse key (can be empty)
|
|
|
|
|
|
|
|
|
while (*itr != '=') |
|
|
while (*itr != '=') { |
|
|
if (++itr == end) |
|
|
if (++itr == end) { |
|
|
return; // Error: no assignment exists; ignore line
|
|
|
return; // Error: no assignment exists; ignore line
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
std::string_view key; |
|
|
std::string_view key; |
|
|
|
|
|
|
|
|
if (itr != line.data()) |
|
|
if (itr != line.data()) { |
|
|
{ |
|
|
|
|
|
// Truncate spaces from key; a non-space character is guaranteed
|
|
|
// Truncate spaces from key; a non-space character is guaranteed
|
|
|
end = itr - 1; |
|
|
end = itr - 1; |
|
|
|
|
|
|
|
|
while (isspace(*end)) |
|
|
while (isspace(*end)) { |
|
|
--end; |
|
|
--end; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
key = line.substr(size_t{ 0 }, end + 1 - line.data()); |
|
|
key = line.substr(size_t{ 0 }, end + 1 - line.data()); |
|
|
|
|
|
|
|
@ -168,16 +173,17 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) { |
|
|
|
|
|
|
|
|
// Parse value (can be empty)
|
|
|
// Parse value (can be empty)
|
|
|
|
|
|
|
|
|
if (++itr != end) |
|
|
if (++itr != end) { |
|
|
{ |
|
|
|
|
|
// Shift to right of spaces; a non-space character is guaranteed
|
|
|
// Shift to right of spaces; a non-space character is guaranteed
|
|
|
while (isspace(*itr)) |
|
|
while (isspace(*itr)) { |
|
|
++itr; |
|
|
++itr; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
line.remove_prefix(itr - line.data()); |
|
|
line.remove_prefix(itr - line.data()); |
|
|
} |
|
|
} |
|
|
else |
|
|
else { |
|
|
line = std::string_view{}; |
|
|
line = std::string_view{}; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Add entry to current table on stack
|
|
|
// Add entry to current table on stack
|
|
|
section_stack.top()->set(std::string{key}, static_cast<std::string>(line)); |
|
|
section_stack.top()->set(std::string{key}, static_cast<std::string>(line)); |
|
@ -193,8 +199,9 @@ bool Jupiter::INIConfig::read_internal(const char *in_filename) { |
|
|
// Open file
|
|
|
// Open file
|
|
|
FILE *file = fopen(in_filename, "rb"); |
|
|
FILE *file = fopen(in_filename, "rb"); |
|
|
|
|
|
|
|
|
if (file == nullptr) |
|
|
if (file == nullptr) { |
|
|
return false; |
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Parse file contents
|
|
|
// Parse file contents
|
|
|
char buffer[READ_CHUNK_SIZE]; |
|
|
char buffer[READ_CHUNK_SIZE]; |
|
|