#pragma once /* #define VECTOR_UTILS #define BUFFER #define BIT_READER #define BIT_WRITER #define EXECUTE_COMAND */ #ifndef NIKOLA_UTILS #define NIKOLA_UTILS #include #include #include #include #include #include #include #include #include class Buffer { public: unsigned char *buffer = nullptr; size_t taken = 0; size_t size = 0; std::string file_path; Buffer(size_t size); Buffer(); ~Buffer(); bool resize(size_t new_size); int add_end(unsigned char *data, size_t data_size); int add_middle(unsigned char *data, size_t data_size, size_t index); void copy(Buffer &other); // Removes data from buffer without checking if it's in the buffer void remove_fast(unsigned char *data, size_t data_size); void remove(size_t index, size_t data_size); int find(unsigned char *data, size_t data_size); void remove(unsigned char *data, size_t data_size); void clear() { taken = 0; } bool save_to_file(); bool save_to_file(std::string file_path); bool load_from_file(); bool load_from_file(std::string file_path); }; class BitReader { public: int k = 8; Buffer buffer; char x = 0; size_t pos = 0; long readNBits(int n); float readFloat(); long readLong(); int readInt(); short readShort(); char readByte(); bool readBit(); }; class BitWriter { public: int k = 0; Buffer buffer; char x = 0; void writeNBits(long value, int n); void writeFloat(float v); void writeLong(long v); void writeInt(int v); void writeShort(short v); void writeByte(char v); void writeBit(bool b); void finish(); }; std::optional exec(const char *cmd); void print_vec(std::vector &vec, int wrap = 5); void print_matrix(std::vector> &vec); #ifdef NIKOLA_UTILS_IMPLEMENTATION Buffer::Buffer() { buffer = nullptr; size = 0; taken = 0; } Buffer::Buffer(size_t size) { this->size = size; this->buffer = new unsigned char[size]; } Buffer::~Buffer() { if (buffer) delete[] buffer; } bool Buffer::resize(size_t new_size) { if (size >= new_size) return true; if (new_size < size * 2) new_size = size * 2; unsigned char *new_buffer = (unsigned char *)realloc(buffer, new_size); if (!new_buffer) { printf("Error resizing buffer\n"); return false; } buffer = new_buffer; size = new_size; return true; } int Buffer::add_end(unsigned char *data, size_t data_size) { if (taken + data_size > size) if (!resize(size + data_size)) return -1; memcpy(buffer + taken, data, data_size); taken += data_size; return taken - data_size; } int Buffer::add_middle(unsigned char *data, size_t data_size, size_t index) { if (taken + data_size > size) if (!resize(size + data_size)) return -1; memmove(buffer + index + data_size, buffer + index, taken - index); memcpy(buffer + index, data, data_size); taken += data_size; return index; } void Buffer::copy(Buffer &other) { if (other.size > size) if (!resize(other.size)) return; memcpy(buffer, other.buffer, other.taken); taken = other.taken; } void Buffer::remove_fast(unsigned char *data, size_t data_size) { int64_t index = data - buffer; if (index < 0 || index > taken || index + data_size > taken) { printf("Error removing from buffer\n"); return; } memmove(buffer + index, buffer + index + data_size, taken - index - data_size); taken -= data_size; } void Buffer::remove(size_t index, size_t data_size) { if (index + data_size > taken) { printf("Error removing from buffer\n"); return; } memmove(buffer + index, buffer + index + data_size, taken - index - data_size); taken -= data_size; } int Buffer::find(unsigned char *data, size_t data_size) { for (int i = 0; i < taken; i++) if (memcmp(buffer + i, data, data_size) == 0) return i; return -1; } void Buffer::remove(unsigned char *data, size_t data_size) { int index = find(data, data_size); if (index == -1) { printf("Error removing from buffer\n"); return; } remove(index, data_size); } bool Buffer::save_to_file() { std::ofstream file(this->file_path, std::ios::binary | std::ios::out); if (!file.is_open()) { printf("Error saving file\n"); return false; } file.write((char *)this->buffer, this->taken); file.close(); return true; } bool Buffer::save_to_file(std::string file_path) { this->file_path = file_path; return save_to_file(); } bool Buffer::load_from_file() { std::ifstream file(this->file_path, std::ios::binary | std::ios::in); if (!file.is_open()) return false; file.seekg(0, std::ios::end); size_t file_size = file.tellg(); resize(file_size); file.seekg(0, std::ios::beg); file.read((char *)buffer, size); if (file) taken = file_size; else taken = file.gcount(); file.close(); return true; } bool Buffer::load_from_file(std::string file_path) { this->file_path = file_path; return load_from_file(); } long BitReader::readNBits(int n) { long ret = 0; for (int i = 0; i < n; i++) { ret |= readBit() << i; } return ret; } float BitReader::readFloat() { float ret = *(float *)&buffer.buffer[pos]; pos += sizeof(float); return ret; } long BitReader::readLong() { long ret = *(long *)&buffer.buffer[pos]; pos += sizeof(long); return ret; } int BitReader::readInt() { int ret = *(int *)&buffer.buffer[pos]; pos += sizeof(int); return ret; } short BitReader::readShort() { short ret = *(short *)&buffer.buffer[pos]; pos += sizeof(short); return ret; } char BitReader::readByte() { x = buffer.buffer[pos]; pos += sizeof(char); return x; } bool BitReader::readBit() { if (k == 8) { readByte(); k = 0; } bool b = (x >> k) & 1; k++; return b; } void BitWriter::writeByte(char v) { buffer.add_end((unsigned char *)&v, sizeof(v)); } void BitWriter::writeNBits(long value, int n) { for (int i = 0; i < n; i++) { writeBit(value & (1 << i)); } } void BitWriter::writeFloat(float v) { buffer.add_end((unsigned char *)&v, sizeof(v)); } void BitWriter::writeLong(long v) { buffer.add_end((unsigned char *)&v, sizeof(v)); } void BitWriter::writeInt(int v) { buffer.add_end((unsigned char *)&v, sizeof(v)); } void BitWriter::writeShort(short v) { buffer.add_end((unsigned char *)&v, sizeof(v)); } void BitWriter::writeBit(bool b) { if (k == 8) { writeByte(x); k = 0; x = 0; } x ^= (-b ^ x) & (1 << k); k++; } void BitWriter::finish() { if (k > 0) writeByte(x); } std::optional exec(const char *cmd) { char buffer[128]; std::string result = ""; FILE *pipe = popen(cmd, "r"); if (!pipe) return std::nullopt; try { while (fgets(buffer, sizeof buffer, pipe) != NULL) result += buffer; } catch (...) { pclose(pipe); return std::nullopt; } pclose(pipe); return result; } void print_vec(std::vector &vec, int wrap) { for (size_t i = 0; i < vec.size(); i++) { printf("%2d ", vec[i]); if (i % wrap == wrap - 1) printf("\n"); } printf("\n"); } void print_matrix(std::vector> &vec) { for (size_t i = 0; i < vec.size(); i++) { for (size_t j = 0; j < vec[i].size(); j++) { printf("%f ", vec[i][j]); } printf("\n"); } printf("\n"); } #endif // NIKOLA_UTILS_IMPLEMENTATION #endif // NIKOLA_UTILS