KLDR done (i think)
This commit is contained in:
parent
c3d4762213
commit
786460d41b
34
Makefile
Normal file
34
Makefile
Normal file
@ -0,0 +1,34 @@
|
||||
# libstadium makefile
|
||||
|
||||
CC = g++
|
||||
CFLAGS_DEFAULT = -Wall -Wpedantic -Wno-uninitialized -std=c++23 -static-libgcc -static-libstdc++ -static
|
||||
CFLAGS_DEBUG = -Og -fanalyzer -ggdb
|
||||
CFLAGS_RELEASE = -Ofast -fdevirtualize-speculatively -fdata-sections -ffunction-sections -Wl,-gc-sections -Wl,-strip-all -Wl,-strip-discarded -flto -s
|
||||
|
||||
SOURCES = src/stadium.hpp src/stadium.cpp src/kldr.hpp
|
||||
SOURCES_TEST = src/test.cpp
|
||||
#LINKED_LIBS = -l
|
||||
OUTPUT_LIB = libstadium.so
|
||||
OUTPUT_TEST_BIN = libstadiumtest
|
||||
|
||||
|
||||
default: clean debug_test
|
||||
|
||||
|
||||
debug_test: $(SOURCES) $(SOURCES_TEST)
|
||||
$(CC) $(CFLAGS_DEFAULT) $(CFLAGS_DEBUG) $(SOURCES) $(SOURCES_TEST) -o $(OUTPUT_TEST_BIN)
|
||||
#$(LINKED_LIBS)
|
||||
|
||||
debug: $(SOURCES)
|
||||
echo "NYI"
|
||||
|
||||
release_test: $(SOURCES)
|
||||
echo "NYI"
|
||||
|
||||
release: $(SOURCES)
|
||||
echo "NYI"
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(OUTPUT_LIB)
|
||||
rm -f $(OUTPUT_TEST_BIN)
|
@ -3,3 +3,8 @@
|
||||
_Эталонная имплементация библиотеки с реализацией протокола Stadium на языке C++._
|
||||
|
||||
**В процессе активной разработки!/Under active development!**
|
||||
|
||||
|
||||
## Пространства имён
|
||||
|
||||
`Stadium::Base`: базовые инструменты, не подлежащие принципиальному изменению в будущем.
|
102
src/_trash/kldr.cpp
Normal file
102
src/_trash/kldr.cpp
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* kldr.cpp
|
||||
* Copyright (c) 2023 Cyclone Team. Licensed under GNU GPLv3-only terms.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "kldr.hpp"
|
||||
|
||||
|
||||
|
||||
namespace Stadium {
|
||||
namespace Base {
|
||||
|
||||
// Destructor
|
||||
template <typename KeyT, typename LengthT>
|
||||
KLDRArray<KeyT, LengthT>::~KLDRArray () {
|
||||
// Freeing all pointers if vector is not empty
|
||||
for (size_t i = 0; i < this->Values.size(); i++) {
|
||||
operator delete(this->Values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Print all contents of array to stdout
|
||||
template <typename KeyT, typename LengthT>
|
||||
void KLDRArray<KeyT, LengthT>::Print () {
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
std::cout << "Key: " << std::hex << std::setw(sizeof(KeyT) * 2) << this->Keys[i] << "; ";
|
||||
std::cout << "Length: " << std::dec << this->Lengths[i] << "; ";
|
||||
std::cout << "Value: " << std::hex << std::setfill('0') << std::setw(2);
|
||||
for (LengthT j = 0; j < this->Lengths[i]; j++)
|
||||
std::cout << this->Values[j] << " ";
|
||||
std::cout << std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Add new cell to array
|
||||
template <typename KeyT, typename LengthT>
|
||||
void KLDRArray<KeyT, LengthT>::Add (KeyT key, LengthT length, void* data) {
|
||||
this->Keys.push_back(key);
|
||||
this->Lengths.push_back(length);
|
||||
void* newData = operator new(length); // Yes, allocating memory for void pointer really looks like this
|
||||
std::copy(data, data + length, newData); // ATTENTION: may be we should not copy, but rather use pointer to already allocated mem
|
||||
this->Values.push_back(std::move(newData)); // NOTICE: move or not to move...
|
||||
// NOTICE: there is `std::is_pod<SomeType>()`, so may be we can use one more template to make this a little more safe
|
||||
}
|
||||
|
||||
// Get just value from array by key
|
||||
template <typename KeyT, typename LengthT>
|
||||
void* KLDRArray<KeyT, LengthT>::Get (KeyT key) {
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
if (this->Keys[i] == key) {
|
||||
return this->Values[i];
|
||||
}
|
||||
}
|
||||
throw std::invalid_argument("invalid KLDRArray key");
|
||||
}
|
||||
|
||||
// Get value and length from array by key
|
||||
template <typename KeyT, typename LengthT>
|
||||
void* KLDRArray<KeyT, LengthT>::Get (KeyT key, LengthT* length) {
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
if (this->Keys[i] == key) {
|
||||
*length = this->Lengths[i];
|
||||
return this->Values[i];
|
||||
}
|
||||
}
|
||||
throw std::invalid_argument("invalid KLDRArray key");
|
||||
}
|
||||
|
||||
// Delete cell from array by key
|
||||
template <typename KeyT, typename LengthT>
|
||||
void KLDRArray<KeyT, LengthT>::Del (KeyT key) {
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
if (this->Keys[i] == key) {
|
||||
this->Keys.erase(this->Keys.begin() + i);
|
||||
this->Lengths.erase(this->Lengths.begin() + i);
|
||||
this->Values.erase(this->Values.begin() + i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw std::invalid_argument("invalid KLDRArray key");
|
||||
}
|
||||
|
||||
// Shuffle array
|
||||
template <typename KeyT, typename LengthT>
|
||||
void KLDRArray<KeyT, LengthT>::Shuffle () {
|
||||
std::random_device seed;
|
||||
std::mt19937 gen{seed()};
|
||||
std::uniform_int_distribution<size_t> dist{0, this->Keys.size()};
|
||||
size_t pickedIndex = 0;
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
do
|
||||
pickedIndex = dist(gen);
|
||||
while (pickedIndex == i);
|
||||
std::swap(this->Keys[i], this->Keys[pickedIndex]);
|
||||
std::swap(this->Lengths[i], this->Length[pickedIndex]);
|
||||
std::swap(this->Values[i], this->Values[pickedIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
128
src/_trash/kldr.hpp
Normal file
128
src/_trash/kldr.hpp
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* kldr.hpp
|
||||
* Copyright (c) 2023 Cyclone Team. Licensed under GNU GPLv3-only terms.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBSTADIUM_KLDR_HPP
|
||||
#define LIBSTADIUM_KLDR_HPP
|
||||
|
||||
|
||||
|
||||
#include <cstdio>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <random>
|
||||
#include <exception>
|
||||
|
||||
|
||||
|
||||
namespace Stadium {
|
||||
namespace Base {
|
||||
|
||||
// NOTICE: This can be more optimized
|
||||
template <typename KeyT = uint8_t, typename LengthT = uint16_t>
|
||||
class KLDRArray {
|
||||
protected:
|
||||
std::vector<KeyT> Keys;
|
||||
std::vector<LengthT> Lengths;
|
||||
std::vector<void*> Values; // We should use void* as it is more abstract, BUT! Then we need to deal with schizophrenical errors, like segfault when valid void pointer is freed
|
||||
|
||||
public:
|
||||
//KLDRArray (); // TODO: check used types
|
||||
|
||||
// Destructor
|
||||
~KLDRArray () {
|
||||
// Freeing all pointers if vector is not empty
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
operator delete(this->Values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Print all contents of array to stdout
|
||||
void Print () {
|
||||
printf("Elements amount: %lu\n", this->Keys.size());
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
printf("Key: 0x%.2X; ", (KeyT)this->Keys[i]);
|
||||
printf("Length: %u; ", (LengthT)this->Lengths[i]);
|
||||
printf("Value: ");
|
||||
for (LengthT j = 0; j < this->Lengths[i]; j++)
|
||||
printf("%.2X ", ((uint8_t*)this->Values[i])[j]);
|
||||
printf("\n");
|
||||
// std::cout << "Key: " << std::hex << std::setw(sizeof(KeyT) * 2) << this->Keys[i] << "; ";
|
||||
// std::cout << "Length: " << std::dec << this->Lengths[i] << "; ";
|
||||
// std::cout << "Value: " << std::hex;
|
||||
// for (LengthT j = 0; j < this->Lengths[i]; j++)
|
||||
// std::cout << std::setfill('0') << std::setw(2) << this->Values[j] << " ";
|
||||
// std::cout << std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Add new cell to array
|
||||
// WARNING: pointer supplied as "data" may be invalid after this function call
|
||||
void Add (KeyT key, LengthT length, void* data) {
|
||||
this->Keys.push_back(key);
|
||||
this->Lengths.push_back(length);
|
||||
//void* newData = operator new(length); // Yes, allocating memory for void pointer really looks like this
|
||||
//std::copy(data, data + length, newData);
|
||||
this->Values.push_back(std::move(data)); // NOTICE: move or not to move...
|
||||
// NOTICE: there is `std::is_pod<SomeType>()`, so may be we can use one more template to make this a little more safe
|
||||
}
|
||||
|
||||
// Get just value from array by key
|
||||
void* Get (KeyT key) {
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
if (this->Keys[i] == key) {
|
||||
return this->Values[i];
|
||||
}
|
||||
}
|
||||
throw std::invalid_argument("invalid KLDRArray key");
|
||||
}
|
||||
|
||||
// Get value and length from array by key
|
||||
void* Get (KeyT key, LengthT* length) {
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
if (this->Keys[i] == key) {
|
||||
*length = this->Lengths[i];
|
||||
return this->Values[i];
|
||||
}
|
||||
}
|
||||
throw std::invalid_argument("invalid KLDRArray key");
|
||||
}
|
||||
|
||||
// Delete cell from array by key
|
||||
void Del (KeyT key) {
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
if (this->Keys[i] == key) {
|
||||
this->Keys.erase(this->Keys.begin() + i);
|
||||
this->Lengths.erase(this->Lengths.begin() + i);
|
||||
this->Values.erase(this->Values.begin() + i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw std::invalid_argument("invalid KLDRArray key");
|
||||
}
|
||||
|
||||
// Shuffle array
|
||||
void Shuffle () {
|
||||
std::random_device seed;
|
||||
std::mt19937 gen{seed()};
|
||||
std::uniform_int_distribution<size_t> dist{0, this->Keys.size()};
|
||||
size_t pickedIndex = 0;
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
do
|
||||
pickedIndex = dist(gen);
|
||||
while (pickedIndex == i);
|
||||
std::swap(this->Keys[i], this->Keys[pickedIndex]);
|
||||
std::swap(this->Lengths[i], this->Length[pickedIndex]);
|
||||
std::swap(this->Values[i], this->Values[pickedIndex]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
10
src/event.cpp
Normal file
10
src/event.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* event.cpp
|
||||
* Copyright (c) 2023 Cyclone Team. Licensed under GNU GPLv3-only terms.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "event.hpp"
|
||||
|
||||
|
||||
|
32
src/event.hpp
Normal file
32
src/event.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* event.hpp
|
||||
* Copyright (c) 2023 Cyclone Team. Licensed under GNU GPLv3-only terms.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBSTADIUM_EVENT_HPP
|
||||
#define LIBSTADIUM_EVENT_HPP
|
||||
|
||||
|
||||
|
||||
namespace Stadium {
|
||||
namespace Base {
|
||||
|
||||
template <typename CategoryT = uint8_t, typename SubcategoryT = uint8_t>
|
||||
class Event {
|
||||
public:
|
||||
struct {
|
||||
CategoryT Category;
|
||||
SubcategoryT Subcategory;
|
||||
} Type; // ???
|
||||
uint32_t ServerSession;
|
||||
// TODO: payload hash
|
||||
// TODO: payload
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
131
src/kldr.hpp
Normal file
131
src/kldr.hpp
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* kldr.hpp
|
||||
* Copyright (c) 2023 Cyclone Team. Licensed under GNU GPLv3-only terms.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBSTADIUM_KLDR_HPP
|
||||
#define LIBSTADIUM_KLDR_HPP
|
||||
|
||||
|
||||
|
||||
#include <cstdio>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include <random>
|
||||
#include <exception>
|
||||
|
||||
|
||||
|
||||
namespace Stadium {
|
||||
namespace Base {
|
||||
|
||||
// NOTICE: This can be more optimized
|
||||
template <typename KeyT = uint8_t, typename LengthT = uint16_t>
|
||||
class KLDRArray {
|
||||
protected:
|
||||
std::vector<KeyT> Keys;
|
||||
std::vector<LengthT> Lengths;
|
||||
std::vector<void*> Values;
|
||||
|
||||
public:
|
||||
//KLDRArray (); // TODO: check used types
|
||||
|
||||
// Destructor
|
||||
~KLDRArray () {
|
||||
// Freeing all pointers if vector is not empty
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
operator delete(this->Values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Print all contents of array to stdout
|
||||
void Print () {
|
||||
printf("Elements amount: %lu\n", this->Keys.size());
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
printf("Key: 0x%.2X; ", (KeyT)this->Keys[i]);
|
||||
printf("Length: %u; ", (LengthT)this->Lengths[i]);
|
||||
printf("Value: ");
|
||||
for (LengthT j = 0; j < this->Lengths[i]; j++)
|
||||
printf("%.2X ", ((uint8_t*)this->Values[i])[j]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Add new cell to array, fast version without keys check
|
||||
void AddF (KeyT key, LengthT length, void* data) {
|
||||
this->Keys.push_back(key);
|
||||
this->Lengths.push_back(length);
|
||||
void* newData = operator new(length); // Yes, allocating memory for void pointer really looks like this
|
||||
std::copy((uint8_t*)data, (uint8_t*)data + length, (uint8_t*)newData); // Dirty hacks, YES!
|
||||
this->Values.push_back(newData);
|
||||
// NOTICE: there is `std::is_pod<SomeType>()`, so may be we can use one more template to make this a little more safe (may be)
|
||||
}
|
||||
|
||||
void Add (KeyT key, LengthT length, void* data) {
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
if (this->Keys[i] == key) {
|
||||
throw std::invalid_argument("supplied key already exist");
|
||||
}
|
||||
}
|
||||
this->AddF(key, length, data);
|
||||
}
|
||||
|
||||
// Get just value from array by key
|
||||
void* Get (KeyT key) {
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
if (this->Keys[i] == key) {
|
||||
return this->Values[i];
|
||||
}
|
||||
}
|
||||
throw std::invalid_argument("invalid KLDRArray key");
|
||||
}
|
||||
|
||||
// Get value and length from array by key
|
||||
void* Get (KeyT key, LengthT* length) {
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
if (this->Keys[i] == key) {
|
||||
*length = this->Lengths[i];
|
||||
return this->Values[i];
|
||||
}
|
||||
}
|
||||
throw std::invalid_argument("invalid KLDRArray key");
|
||||
}
|
||||
|
||||
// Delete cell from array by key
|
||||
void Del (KeyT key) {
|
||||
for (size_t i = 0; i < this->Keys.size(); i++) {
|
||||
if (this->Keys[i] == key) {
|
||||
this->Keys.erase(this->Keys.begin() + i);
|
||||
this->Lengths.erase(this->Lengths.begin() + i);
|
||||
this->Values.erase(this->Values.begin() + i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw std::invalid_argument("invalid KLDRArray key");
|
||||
}
|
||||
|
||||
// Shuffle array
|
||||
void Shuffle () {
|
||||
size_t elements = this->Keys.size();
|
||||
std::random_device seed;
|
||||
std::mt19937 gen{seed()};
|
||||
std::uniform_int_distribution<size_t> dist{0, elements-1};
|
||||
size_t pickedIndex = 0;
|
||||
for (size_t i = 0; i < elements; i++) {
|
||||
do
|
||||
pickedIndex = dist(gen);
|
||||
while (pickedIndex == i);
|
||||
std::swap(this->Keys[i], this->Keys[pickedIndex]);
|
||||
std::swap(this->Lengths[i], this->Lengths[pickedIndex]);
|
||||
std::swap(this->Values[i], this->Values[pickedIndex]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
17
src/stadium.cpp
Normal file
17
src/stadium.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* stadium.cpp
|
||||
* Copyright (c) 2023 Cyclone Team. Licensed under GNU GPLv3-only terms.
|
||||
*
|
||||
* -> [ Incoming Events Queue ] --> [ Base Event Handlers ]
|
||||
* / \-> [ Custom Event Handlers ]
|
||||
* [ Transport ] <-> [ StadiumCrypto (optional) ] <- -> [ Expected Event Handlers ]
|
||||
* \
|
||||
* <- [ Outcoming Events Queue ] <--- [ Base Methods ]
|
||||
* \
|
||||
* <- [ Custom Methods ]
|
||||
*/
|
||||
|
||||
#include "stadium.hpp"
|
||||
|
||||
|
||||
|
30
src/stadium.hpp
Normal file
30
src/stadium.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* stadium.hpp
|
||||
* Copyright (c) 2023 Cyclone Team. Licensed under GNU GPLv3-only terms.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBSTADIUM_HPP
|
||||
#define LIBSTADIUM_HPP
|
||||
|
||||
|
||||
|
||||
#include "kldr.hpp"
|
||||
|
||||
|
||||
|
||||
namespace Stadium {
|
||||
namespace v1 {
|
||||
|
||||
// class EventsQueue {
|
||||
// public:
|
||||
// void Add (); // TODO
|
||||
// void Pop (); // TODO
|
||||
// };
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
22
src/test.cpp
Normal file
22
src/test.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include <cstdio>
|
||||
#include "stadium.hpp"
|
||||
|
||||
|
||||
int main () {
|
||||
Stadium::Base::KLDRArray<> arr;
|
||||
char str1[] = "goodbye, var?\n";
|
||||
char str2[] = "hello, world!\n";
|
||||
char str3[] = "fisting\n";
|
||||
char str4[] = "IS 300$!!!!!!!!!!!!!!!!!!\n";
|
||||
char str5[] = "a)\n";
|
||||
arr.Add(0x01, sizeof(str1), (void*)&str1);
|
||||
arr.Add(0x02, sizeof(str2), (void*)&str2);
|
||||
arr.Add(0xF4, sizeof(str3), (void*)&str3);
|
||||
arr.Add(0x6a, sizeof(str4), (void*)&str4);
|
||||
arr.Add(0x6c, sizeof(str5), (void*)&str5);
|
||||
arr.Print();
|
||||
arr.Shuffle();
|
||||
arr.Print();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user