ACTIVE ABILITY: WOOMED

This commit is contained in:
malloc 2018-11-08 17:34:56 -06:00
parent 6092bb9f66
commit 045db422a0
6 changed files with 163 additions and 62 deletions

View file

@ -0,0 +1,5 @@
; test ini file
[Test Section]
TEST = ARE YOU SQWOOBIN
ANSWER = TRUE

View file

@ -1,6 +1,29 @@
#include "ini.hpp"
using namespace sosc::ini;
bool Field::Test() const {
try {
switch(type) {
case INT32:
(int32_t)File::Proxy(name);
break;
case UINT32:
(uint32_t)File::Proxy(name);
break;
case DOUBLE:
(double)File::Proxy(name);
break;
case BOOL:
(bool)File::Proxy(name);
break;
}
return true;
} catch(...) {
return false;
}
}
File* File::Open
(const std::string& filename, const std::vector<Rule>& rules)
{
@ -54,7 +77,7 @@ File* File::Open
str::tolower(str::trim(&(parts[0])));
str::trim(&(parts[1]));
if(parts[0] == "" || active_section->values.count(parts[0]) == 0)
if(parts[0] == "" || active_section->values.count(parts[0]) > 0)
throw LoadError(ini, line_number,
"Duplicate key-value pair field in section."
);
@ -69,16 +92,15 @@ File* File::Open
"Required section '", rule.name, "' not found."
}));
if(!rule.allow_multiple && ini[rule.name].sections.size() > 1)
if(!rule.allow_multiple && (*ini)[rule.name].sections.size() > 1)
throw LoadError(ini, -1, str::join({
"Multiple instances of '", rule.name, "' section "
"when explicitely not allowed."
}));
for(auto& section : ini[rule.name].sections) {
for(auto& section : (*ini)[rule.name].sections) {
for(auto &field : rule.required_fields) {
str::tolower(&field.name);
if(section.values.count(field.name) == 0)
if(section.values.count(str::tolower(field.name)) == 0)
throw LoadError(ini, -1, str::join({
"Required field '", field.name, "' in section '",
rule.name, "' not found."
@ -115,12 +137,20 @@ const File::SectionList&
{
str::tolower(&name);
if(this->section_lists.count(name) > 0)
return this->section_lists[name];
return this->section_lists.at(name);
else
throw std::range_error("Section name not found.");
}
const std::string&
bool File::SectionList::HasKey(std::string name) const {
return this->sections[0].HasKey(name);
}
int File::SectionList::SectionCount() const {
return this->sections.size();
}
const File::Proxy&
File::SectionList::operator[] (std::string key) const
{
return this->sections[0][key];
@ -135,12 +165,17 @@ const File::SectionList::Section&
throw std::range_error("Section index out-of-bounds.");
}
const std::string&
bool File::SectionList::Section::HasKey(std::string name) const {
str::tolower(&name);
return this->values.count(name) == 1;
}
const File::Proxy&
File::SectionList::Section::operator[] (std::string key) const
{
str::tolower(&key);
if(this->values.count(key) > 0)
return this->values[key];
return Proxy(this->values.at(key));
else
throw std::range_error("Key not found in section.");
}

View file

@ -11,11 +11,46 @@
namespace sosc {
namespace ini {
struct Field {
enum kType {
STRING,
INT32,
UINT32,
DOUBLE,
BOOL
};
explicit Field
(const std::string& name, kType type = STRING)
: name(name), type(type) {}
bool Test() const;
std::string name;
kType type;
};
struct Rule {
Rule() = delete;
Rule(
const std::string& name,
bool required,
bool allow_multiple,
const std::vector<Field>& required_fields
) : name(name),
required(required),
allow_multiple(allow_multiple),
required_fields(required_fields) {};
std::string name;
bool required;
bool allow_multiple;
std::vector<Field> required_fields;
};
class File {
public:
struct Proxy {
std::string value;
Proxy(const std::string& value) : value(value) {};
explicit Proxy(const std::string& value) : value(value) {};
explicit operator bool() const {
if(this->value == "1" || this->value == "true")
@ -34,7 +69,7 @@ public:
&& !std::is_same<std::allocator<char>, Decayed>::value
&& !std::is_same<std::initializer_list<char>, Decayed>::value
>::type
> explicit operator T() {
> explicit operator T() const {
std::stringstream ss;
ss << this->value;
@ -44,58 +79,27 @@ public:
else
return retval;
}
};
struct Rule {
template<typename T = std::string>
struct Field {
Field(const std::string& name) : name(name) {}
bool Test() {
try {
(T)Proxy(this->name);
return true;
} catch(...) {
return false;
}
}
std::string name;
};
Rule() = delete;
Rule(
const std::string& name,
bool required,
bool allow_multiple,
const std::vector<Field>& required_fields
) : name(name),
required(required),
allow_multiple(allow_multiple),
required_fields(required_fields) {};
std::string name;
bool required;
bool allow_multiple;
std::vector<Field> required_fields;
std::string value;
};
class SectionList {
public:
class Section {
public:
const std::string& operator[] (std::string key) const;
bool HasKey(std::string name) const;
const Proxy& operator[] (std::string key) const;
private:
Section() = default;
std::map<std::string, std::string> values;
friend class File;
};
const std::string& operator[] (std::string key) const;
bool HasKey(std::string name) const;
int SectionCount() const;
const Proxy& operator[] (std::string key) const;
const Section& operator[] (int index) const;
private:
SectionList() = default;
std::vector<Section> sections;
friend class File;
};
@ -103,6 +107,8 @@ public:
File(const File&) = delete;
static File* Open
(const std::string& filename, const std::vector<Rule>& rules = {});
bool HasSection(std::string name) const;
void Close();
const SectionList& operator[] (std::string name) const;

View file

@ -1,6 +1,7 @@
#ifndef SOSC_UTIL_STRING_H
#define SOSC_UTIL_STRING_H
#include <cstring>
#include <vector>
#include <string>
#include <sstream>

View file

@ -88,6 +88,16 @@ bool sosc::MasterClient::ProcessLogin(Packet &pck) {
return true;
}
bool sosc::MasterClient::ProcessRegistration(Packet &pck) {
return true;
}
bool sosc::MasterClient::ListServers(Packet &pck) {
return true;
}
bool sosc::MasterClient::Close() {
this->sock.Close();
return false;

View file

@ -2,6 +2,7 @@
#include <string>
#include <ctime>
#include <thread>
#include <sock/pool.hpp>
#include "db/database.hpp"
#include "hosts/master.hpp"
@ -43,26 +44,69 @@ int main(int argc, char **argv) {
if(argc < 2)
return -1;
auto test = ini::File::Open("test.ini", {
ini::File::Rule("test section", true, false, {
ini::File::Rule::Field<bool>("test")
}),
});
ini::File* config;
try {
config = ini::File::Open(SOSC_RESC("config.ini"), {
ini::Rule("general", true, false, {
ini::Field("run master", ini::Field::BOOL),
ini::Field("master host", ini::Field::STRING),
ini::Field("master port", ini::Field::UINT32),
}),
ini::Rule("defaults", true, false, {
ini::Field("initial count", ini::Field::UINT32),
ini::Field("initial size", ini::Field::UINT32),
ini::Field("size growth", ini::Field::UINT32),
if(argv[1][0] == 'm') {
ini::Field("max size", ini::Field::INT32),
ini::Field("max count", ini::Field::INT32),
ini::Field("max total", ini::Field::INT32),
ini::Field("tolerance", ini::Field::INT32),
}),
ini::Rule("master", true, false, {
ini::Field("client port", ini::Field::UINT32),
ini::Field("intra port", ini::Field::UINT32),
}),
ini::Rule("slave", false, true, {
ini::Field("port", ini::Field::UINT32),
ini::Field("name", ini::Field::STRING),
})
});
} catch(const std::exception& e) {
std::cout << e.what() << std::endl;
return -1;
}
poolinfo_t info = poolinfo_t();
info.initial_count =
if((*config)["master"]["run master"]) {
if(!db::init_databases(nullptr))
return -1;
_ctx.master_intra = new master_intra_ctx;
master_intra_start(1234, poolinfo_t());
master_intra_start(
(uint16_t)(*config)["master"]["intra port"],
poolinfo_t()
);
_ctx.master_client = new master_client_ctx;
master_client_start(8008, poolinfo_t());
} else {
_ctx.slave_count = 1;
master_client_start(
(uint16_t)(*config)["master"]["client port"],
poolinfo_t()
);
}
if(config->HasSection("slave")) {
_ctx.slave_count = (*config)["slave"].SectionCount();
_ctx.slaves = new slave_ctx[_ctx.slave_count];
for(int i = 0; i < _ctx.slave_count; ++i)
slave_start(1234, poolinfo_t(), _ctx.slaves + i);
for(int i = 0; i < _ctx.slave_count; ++i) {
slave_start(
(uint16_t)(*config)["slave"][i]["port"],
poolinfo_t(),
_ctx.slaves + i
);
}
}
std::cout << "Server threads started. Type STOP to cancel." << std::endl;