Some minor changes

This commit is contained in:
WolverinDEV 2019-10-13 17:12:50 +02:00
parent cb73d9df32
commit e30c03029f
6 changed files with 121 additions and 224 deletions

View File

@ -237,6 +237,11 @@ namespace ts {
details_ptr->extra_properties["extra_msg"] = message;
}
command_result(error::type error, const std::map<std::string, std::string>& properties) : command_result{error, ""} {
assert(this->is_detailed());
this->details()->extra_properties = properties;
}
#ifndef _NDEBUG
/* if we're not using any debug we dont have to use a deconstructor. A deconstructor prevent a direct uint64_t return as described above */
~command_result() {
@ -259,7 +264,6 @@ namespace ts {
ErrorType(const uint16_t errorId, const std::string &name, const std::string &message) : errorId(errorId), name(name), message(message) {}
ErrorType(const ErrorType& ref) : errorId(ref.errorId), name(ref.name), message(ref.message) {}
ErrorType(ErrorType& ref) : errorId(ref.errorId), name(ref.name), message(ref.message) {}
ErrorType(ErrorType&& ref) : errorId(ref.errorId), name(std::move(ref.name)), message(std::move(ref.message)) {}
uint16_t errorId;

View File

@ -53,7 +53,7 @@ namespace license {
struct LicenseKey {
bool privateKey = false;
uint8_t privateKeyData[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t publicKeyData[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t publicKeyData[32] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
};
typedef uint8_t LicensePublicKey[32];

View File

@ -53,23 +53,23 @@ namespace ts {
typedef uint32_t flag_type;
enum flag : flag_type {
FLAG_BEGIN = 0b1,
FLAG_INTERNAL = FLAG_BEGIN << 1, //Just for internal usage
FLAG_GLOBAL = FLAG_INTERNAL << 1, //Not server bound
FLAG_SNAPSHOT = FLAG_GLOBAL << 1, //Saved within snapshots
FLAG_SAVE = FLAG_SNAPSHOT << 1, //Saved to database
FLAG_SAVE_MUSIC = FLAG_SAVE << 1, //Saved to database
FLAG_NEW = FLAG_SAVE_MUSIC << 1, //Its a non TeamSpeak property
FLAG_SERVER_VARIABLE = FLAG_NEW << 1,
FLAG_SERVER_VIEW = FLAG_SERVER_VARIABLE << 1,
FLAG_CLIENT_VARIABLE = FLAG_SERVER_VIEW << 1,
FLAG_CLIENT_VIEW = FLAG_CLIENT_VARIABLE << 1,
FLAG_CLIENT_INFO = FLAG_CLIENT_VIEW << 1,
FLAG_CHANNEL_VARIABLE = FLAG_CLIENT_INFO << 1,
FLAG_CHANNEL_VIEW = FLAG_CHANNEL_VARIABLE << 1,
FLAG_GROUP_VIEW = FLAG_CHANNEL_VIEW << 1,
FLAG_INSTANCE_VARIABLE = FLAG_GROUP_VIEW << 1,
FLAG_USER_EDITABLE = FLAG_INSTANCE_VARIABLE << 1,
FLAG_PLAYLIST_VARIABLE = FLAG_USER_EDITABLE << 1,
FLAG_INTERNAL = FLAG_BEGIN << 1UL, //Just for internal usage
FLAG_GLOBAL = FLAG_INTERNAL << 1UL, //Not server bound
FLAG_SNAPSHOT = FLAG_GLOBAL << 1UL, //Saved within snapshots
FLAG_SAVE = FLAG_SNAPSHOT << 1UL, //Saved to database
FLAG_SAVE_MUSIC = FLAG_SAVE << 1UL, //Saved to database
FLAG_NEW = FLAG_SAVE_MUSIC << 1UL, //Its a non TeamSpeak property
FLAG_SERVER_VARIABLE = FLAG_NEW << 1UL,
FLAG_SERVER_VIEW = FLAG_SERVER_VARIABLE << 1UL,
FLAG_CLIENT_VARIABLE = FLAG_SERVER_VIEW << 1UL,
FLAG_CLIENT_VIEW = FLAG_CLIENT_VARIABLE << 1UL,
FLAG_CLIENT_INFO = FLAG_CLIENT_VIEW << 1UL,
FLAG_CHANNEL_VARIABLE = FLAG_CLIENT_INFO << 1UL,
FLAG_CHANNEL_VIEW = FLAG_CHANNEL_VARIABLE << 1UL,
FLAG_GROUP_VIEW = FLAG_CHANNEL_VIEW << 1UL,
FLAG_INSTANCE_VARIABLE = FLAG_GROUP_VIEW << 1UL,
FLAG_USER_EDITABLE = FLAG_INSTANCE_VARIABLE << 1UL,
FLAG_PLAYLIST_VARIABLE = FLAG_USER_EDITABLE << 1UL,
};
static constexpr const char *flag_names[sizeof(flag) * 8] =
{"UNDEFINED", "FLAG_INTERNAL", "FLAG_GLOBAL", "FLAG_SNAPSHOT", "FLAG_SAVE", "FLAG_SAVE_MUSIC", "FLAG_NEW",
@ -773,12 +773,8 @@ namespace ts {
Properties(const Properties&) = delete;
Properties(Properties&&) = delete;
std::vector<PropertyWrapper> list_properties(property::flag_type flagMask = ~0, property::flag_type negatedFlagMask = 0);
std::vector<PropertyWrapper> list_properties(property::flag_type flagMask = (property::flag_type) ~0UL, property::flag_type negatedFlagMask = 0);
std::vector<PropertyWrapper> all_properties();
/*
std::deque<std::shared_ptr<Property>> listProperties(property::flag_type flagMask = ~0, property::flag_type negatedFlagMask = 0);
std::deque<std::shared_ptr<Property>> allProperties();
*/
template <typename Type>
bool register_property_type() {
@ -786,25 +782,6 @@ namespace ts {
return this->register_property_type(type, property::impl::length(type), property::impl::offset(type));
}
/*
template <typename PT>
std::shared_ptr<Property> registerProperty(PT property){
auto info = property::impl::info<PT>(property);
{
threads::MutexLock lock(this->propsLock);
for(const auto& elm : this->properties) {
if(*info == elm->type()){
std::cerr << "Double registration of " << elm->type().name << "\n";
return this->find(property::impl::type<PT>(), property);
}
}
properties.push_back(std::make_shared<Property>(this, info));
}
return this->find(property::impl::type<PT>(), property);
}
*/
template <typename T>
bool hasProperty(T type) { return this->has(property::impl::type<T>(), type); }
@ -846,11 +823,9 @@ namespace ts {
bool save = true;
std::vector<std::function<void(PropertyWrapper&)>> notifyFunctions{};
std::recursive_mutex propsLock{};
//std::deque<std::shared_ptr<Property>> properties{};
size_t properties_count = 0;
std::deque<std::shared_ptr<PropertyBundle>> properties;
std::vector<std::shared_ptr<PropertyBundle>> properties;
};
};

View File

@ -42,7 +42,7 @@ CONVERTER_ST(const_char__ , return str.c_str();, return std::string(std::any_cas
command::command(const std::string& command, bool editable) {
this->handle = make_shared<impl::command_data>();
this->handle->editiable = editable;
this->handle->editable = editable;
this->handle->command = command;
}
@ -56,7 +56,7 @@ void command::set_identifier(const std::string &command) {
command_bulk command::bulk(size_t index) {
if(this->handle->bulks.size() <= index) {
if(!this->handle->editiable)
if(!this->handle->editable)
throw command_bulk_exceed_index_exception();
while(this->handle->bulks.size() <= index) {
@ -229,7 +229,7 @@ command_entry command_bulk::value(const std::string &key) {
auto& values = this->handle->values;
auto index = values.find(key);
if(index == values.end()) {
if(!this->handle->handle->editiable)
if(!this->handle->handle->editable)
throw command_value_missing_exception(this->bulk_index, key);
auto result = make_shared<impl::command_value>();

View File

@ -38,7 +38,7 @@ namespace ts {
struct command_data {
std::string command;
bool editiable;
bool editable;
std::deque<std::shared_ptr<command_bulk>> bulks;
std::deque<std::string> triggers;
};
@ -136,7 +136,7 @@ namespace ts {
return this->string();
}
template <typename T, std::enable_if_t<!std::is_same<T, std::string>::value && !std::is_same<T, std::string>::value, int> = 0>
template <typename T, std::enable_if_t<!std::is_same<T, std::string>::value, int> = 0>
T as() {
static_assert(converter<T>::supported, "Target type isn't supported!");
static_assert(!converter<T>::supported || converter<T>::from_string, "Target type dosn't support parsing");
@ -308,13 +308,20 @@ namespace ts {
};
using default_options = options<false, false>;
struct base { };
struct base {
virtual ~base() = default;
};
struct base_data {
int type; /* 1 = field | 2 = switch | 3 = command handle */
option_data options;
};
struct field_base : public base {
virtual std::vector<command_entry>& ref_values() = 0;
virtual const std::vector<command_entry>& ref_values() const = 0;
};
struct field_data : public base_data {
const char* key;
const std::type_info& field_type;
@ -323,19 +330,12 @@ namespace ts {
void* to_string;
};
struct field_base {
typedef std::vector<command_entry>&(*ref_values_fn)();
static inline std::vector<command_entry>& ref_values(const void* _this) {
void** vtable = *(void***) _this;
return ((ref_values_fn) vtable[0])();
}
};
template <class key_t, typename value_type_t, class options, class... extends>
struct field : public base, public options, public extends... {
struct field : public field_base, public options, public extends... {
friend struct command_parser<field<key_t, value_type_t, options, extends...>>;
static_assert(converter<value_type_t>::supported, "Target type isn't supported!");
static_assert(!converter<value_type_t>::supported || converter<value_type_t>::from_string, "Target type dosn't support parsing");
static_assert(impl::templates::_or_<!std::is_empty<extends>::value...>::value == false, "Extensions could not have data members");
protected:
using object_t = field_data;
@ -344,7 +344,6 @@ namespace ts {
static constexpr auto from_string = converter<value_type_t>::from_string;
public:
template <bool flag = true /*, std::enable_if_t<!templates::_or_<std::is_same<extends, optional_extend>::value...>::value, int> = 0 */>
using as_optional = field<key_t, value_type_t, impl::options<options::is_bulked, flag>, optional_extend, extends...>;
@ -391,27 +390,32 @@ namespace ts {
return this->as<T>();
}
std::vector<command_entry>& ref_values() final { return this->values; }
const std::vector<command_entry>& ref_values() const final { return this->values; }
protected:
/* ATTENTION: This must be placed at index 0 within the VTable */
virtual __attribute__used std::vector<command_entry>& _v_ref_values() {
return this->values;
}
std::vector<command_entry> values;
};
struct optional_extend {
public:
inline bool has_value() const {
auto& values = field_base::ref_values(this);
auto base = dynamic_cast<field_base*>((struct base*) this);
assert(base);
const auto& values = base->ref_values();
return !values.empty() && !values[0].is_empty();
}
template <typename T>
inline T get_or(T&& value = T{}) const {
if(this->has_value())
return field_base::ref_values(this).front().as<T>();
return value;
auto base = dynamic_cast<field_base*>((struct base*) this);
assert(base);
auto& values = base->ref_values();
if(values.empty() || values[0].is_empty())
return value;
return values.front().as<T>();
}
};
@ -421,10 +425,18 @@ namespace ts {
return !this->at(index).is_empty();
}
inline size_t length() const { return field_base::ref_values(this).size(); }
inline size_t length() const {
auto base = dynamic_cast<field_base*>((struct base*) this);
assert(base);
return base->ref_values().size();
}
inline command_entry at(size_t index) const {
auto& values = field_base::ref_values(this);
auto base = dynamic_cast<field_base*>((struct base*) this);
assert(base);
auto& values = base->ref_values();
if(index > values.size())
throw command_bulk_exceed_index_exception();
@ -436,16 +448,12 @@ namespace ts {
}
};
struct trigger_data : public base_data {
const char* key;
struct trigger_base : public base {
virtual bool& ref_flag() = 0;
};
struct trigger_base : public base {
typedef bool&(*ref_flag_fn)();
static inline bool& ref_flag(void* _this) {
void** vtable = *(void***) _this;
return ((ref_flag_fn) vtable[0])();
}
struct trigger_data : public base_data {
const char* key;
};
template <class key_t, class options>
@ -468,109 +476,14 @@ namespace ts {
inline bool is_set() const { return this->flag_set; }
operator bool() const { return this->flag_set; }
private:
/* ATTENTION: This must be placed at index 0 within the VTable */
virtual __attribute__used bool& _v_ref_values() {
bool& ref_flag() override {
return this->flag_set;
}
bool flag_set;
};
struct command_handle_data : public base_data { };
struct command_handle_base : public base {
typedef command&(*ref_flag_fn)();
static inline command& ref_command(void* _this) {
void** vtable = *(void***) _this;
return ((ref_flag_fn) vtable[0])();
}
};
template <class options>
struct command_handle : public command_handle_base, public options {
public:
using object_t = command_handle_data;
inline static std::shared_ptr<object_t> describe() {
return std::make_shared<object_t>(
command_handle_data {
3,
options::options_object()
}
);
}
inline command get_command() { return this->_command; }
operator command() { return this->_command; }
inline command* operator->() const noexcept {
return (command*) &_command;
}
/*
template<class Arg>
auto operator[](Arg &&arg) -> decltype(get_command()[std::forward<Arg>(arg)]) {
return _command[std::forward<Arg>(arg)];
}
*/
template<class Arg>
decltype(std::declval<command>()[std::forward<Arg>(Arg{})]) operator[](Arg &&arg) {
return _command[std::forward<Arg>(arg)];
}
private:
/* ATTENTION: This must be placed at index 0 within the VTable */
virtual __attribute__used class command& _v_ref_values() {
return this->_command;
}
command _command;
bool flag_set = false;
};
typedef std::vector<std::shared_ptr<impl::base_data>> function_descriptors_t;
template <typename...>
struct describe {
inline static void apply(function_descriptors_t& result) {}
};
template <typename T, typename... Args>
struct describe<T, Args...> {
inline static void apply(function_descriptors_t& result) {
result.push_back(T::describe());
describe<Args...>::apply(result);
}
};
inline void parse_field(const std::shared_ptr<field_data>& description, void* field, command& cmd) {
//if(!description->options.optional && !cmd.has_value(description->key))
// throw command_value_missing_exception();
auto& values = field_base::ref_values(field);
values.clear();
if(description->options.bulked) {
values.resize(cmd.bulk_count());
for(size_t bulk_index = 0; bulk_index < cmd.bulk_count(); bulk_index++) {
if(!cmd[bulk_index].has(description->key)) {
if(!description->options.optional)
throw command_value_missing_exception(bulk_index, description->key);
else
values[bulk_index] = command_entry::empty;
} else {
values[bulk_index] = cmd[bulk_index][description->key];
}
}
} else {
if(!cmd.has_value(description->key)) {
if(!description->options.optional)
throw command_value_missing_exception(0, description->key);
else
values.push_back(command_entry::empty);
} else
values.push_back(cmd[description->key]);
}
}
template <class key_t, class options, class... extends>
struct command_parser<field<key_t, options, extends...>> {
constexpr static bool supported = true;
@ -586,7 +499,33 @@ namespace ts {
assert(descriptor->type == 1);
field_t result{};
parse_field(descriptor, (void*) &result, cmd);
//if(!description->options.optional && !cmd.has_value(description->key))
// throw command_value_missing_exception();
auto& values = result.ref_values();
values.clear();
if(descriptor->options.bulked) {
values.resize(cmd.bulk_count());
for(size_t bulk_index = 0; bulk_index < cmd.bulk_count(); bulk_index++) {
if(!cmd[bulk_index].has(descriptor->key)) {
if(!descriptor->options.optional)
throw command_value_missing_exception(bulk_index, descriptor->key);
else
values[bulk_index] = command_entry::empty;
} else {
values[bulk_index] = cmd[bulk_index][descriptor->key];
}
}
} else {
if(!cmd.has_value(descriptor->key)) {
if(!descriptor->options.optional)
throw command_value_missing_exception(0, descriptor->key);
else
values.push_back(command_entry::empty);
} else
values.push_back(cmd[descriptor->key]);
}
return result;
}
@ -607,37 +546,32 @@ namespace ts {
assert(descriptor->type == 2);
trigger_t result{};
trigger_base::ref_flag(&result) = cmd.has_trigger(descriptor->key);
result.ref_flag() = cmd.has_trigger(descriptor->key);
return result;
}
};
template <class options>
struct command_parser<command_handle<options>> {
struct command_data : public base_data { };
template <>
struct command_parser<command&> {
constexpr static bool supported = true;
typedef command_handle<options> command_handle_t;
using descriptor_t = std::shared_ptr<typename command_handle_t::object_t>;
using descriptor_t = std::shared_ptr<command_data>;
inline static descriptor_t describe() {
return command_handle_t::describe();
}
inline static descriptor_t describe() { return std::make_shared<command_data>(command_data{{3, {false, false}}}); }
inline static command_handle_t apply(descriptor_t& descriptor, command& cmd) {
inline static command& apply(descriptor_t& descriptor, command& cmd) {
assert(descriptor->type == 3);
command_handle_t result{};
command_handle_base::ref_command(&result) = cmd;
return result;
return cmd;
}
};
template <typename C>
struct command_parser<C> {
constexpr static bool supported = std::is_same<typename std::remove_reference<typename std::remove_cv<C>::type>::type, command>::value;
static_assert(supported, "This type isn't supported!");
constexpr static bool supported = false;
using descriptor_t = std::shared_ptr<void>;
using descriptor_t = std::shared_ptr<nullptr_t>;
inline static descriptor_t describe() {
return nullptr;
@ -649,9 +583,6 @@ namespace ts {
};
}
/* direct use of command is possible as well! */
using command_handle = impl::command_handle<impl::default_options>;
template <class key_t, typename value_type_t>
using field = impl::field<key_t, value_type_t, impl::default_options>;
@ -659,16 +590,13 @@ namespace ts {
using trigger = impl::trigger<key_t, impl::default_options>;
template <typename... args_t>
inline impl::function_descriptors_t describe_function() {
impl::function_descriptors_t result;
impl::describe<args_t...>::apply(result);
return result;
inline std::array<std::shared_ptr<struct impl::base_data>, sizeof...(args_t)> describe_function(void(*)(args_t...)) {
static_assert(!impl::templates::_or_<!impl::command_parser<typename impl::templates::remove_cr<args_t>::type>::supported...>::value, "Not any function argument type is supported");
return {impl::command_parser<typename impl::templates::remove_cr<args_t>::type>::describe()...};
}
struct invocable_function {
void operator()(command& command) {
this->invoke(command);
}
void operator()(command& command) { this->invoke(command); }
virtual void invoke(command& command) = 0;
};
@ -684,7 +612,7 @@ namespace ts {
void(*function)(args_t...);
void invoke(command& command) override {
function(command_parser_t<args_t>::apply(std::get<impl::templates::tuple_index<args_t, args_tuple_t>::value>(descriptors), command)...);
this->function(command_parser_t<args_t>::apply(std::get<impl::templates::tuple_index<args_t, args_tuple_t>::value>(descriptors), command)...);
}
};

View File

@ -23,11 +23,11 @@ using trigger = ts::descriptor::trigger<key_t>;
void handleCommand(
ts::command& _cmd,
cconstants::return_code::optional return_code,
field<tl("key_a"), int> key_a,
field<tl("key_b"), string>::optional key_b,
field<tl("key_c"), uint64_t>::optional::bulked key_c,
trigger<tl("test")> switch_test
const cconstants::return_code::optional& return_code,
const field<tl("key_a"), int>& key_a,
const field<tl("key_b"), string>::optional& key_b,
const field<tl("key_c"), uint64_t>::optional::bulked& key_c,
const trigger<tl("test")>& switch_test
) {
if(key_a.value() < 10)
cout << "ERROR" << endl;
@ -67,18 +67,6 @@ void eval_test(command_result x) {
int main() {
//for(const auto& error : avariableErrors)
// cout << error.name << " = " << hex << "0x" << error.errorId << "," << endl;
#if false
{
string error;
istringstream is(base64::decode("AQCvbHFTQDY/terPeilrp/ECU9xCH5U3xC92lYTNaY/0KQAJFueAazbsgAAAACVUZWFtU3BlYWsgU3lzdGVtcyBHbWJIAADCxw83PomiAdX11jLso/hdMVov4e8N79iq2NRhwkIjqgAKSyfbMFu6mwAAACRUZWFtU3BlYWsgc3lzdGVtcyBHbWJIAAA+kiuhufX/V96lZzq4MICxnYxFPkV/mG03Pu+VYgUISwIKU0+AC1RkAAQAAAIASmFuLU5pa2xhcyBLZXR0ZW5idXJnAADlcwyCViOfHJKYvWHHqyL9R1Ba5ZP+cL7MQ5nI7s1R2yAKnICdCp0pXQ=="));
auto chain = LicenseChain::parse(is, error);
chain->print();
cout << base64::encode(chain->generatePublicKey(public_root)) << endl;
cout << base64::encode(chain->generatePublicKey(public_root, 1)) << endl;
cout << base64::encode(chain->generatePublicKey(public_root, 2)) << endl;
cout << base64::encode(chain->generatePublicKey(public_root, 3)) << endl;
}
#endif
eval_test(test());
eval_test(test2());
@ -127,7 +115,7 @@ int main() {
cout << ts::command::parse("a=c", false).build(ts::command::format::BRACE_ESCAPED_QUERY) << endl;
cout << ts::command::parse("a=c | a=c -x", false).build(ts::command::format::BRACE_ESCAPED_QUERY) << endl;
cout << ts::command::parse("a a=c|a=c").build(ts::command::format::BRACE_ESCAPED_QUERY) << endl;
cout << ts::command::parse("a a=c a=c2 -z | a=c").build(ts::command::format::BRACE_ESCAPED_QUERY) << endl;
cout << ts::command::parse("a a=c a=c2 -z | -? a=c").build(ts::command::format::BRACE_ESCAPED_QUERY) << endl;
/*
*
@ -147,6 +135,8 @@ int main() {
cmd[1]["key_c"] = "key_c_value_1";
cmd.set_trigger("test");
auto result = ts::descriptor::describe_function(handleCommand);
auto cmd_handler = ts::descriptor::parse_function(handleCommand);
cmd_handler->invoke(cmd);
cout << cmd.build() << endl;