/* * Main file containing the program entry point. I really want to name all this all femboy themed * Copyright (C) 2023 Brett Terpstra * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include constexpr size_t PACKET_SIZE = 512; class packet { private: std::uint8_t* buffer = new std::uint8_t[PACKET_SIZE]; public: size_t used = 0; packet() = default; packet(const packet& copy) { for (size_t i = 0; i < PACKET_SIZE; i++) buffer[i] = copy[i]; used = copy.used; } packet(packet&& move) noexcept { delete[] buffer; buffer = move.buffer; used = move.used; move.buffer = nullptr; } packet& operator=(const packet& copy) { if (© == this) return *this; for (size_t i = 0; i < PACKET_SIZE; i++) buffer[i] = copy[i]; used = copy.used; return *this; } packet& operator=(packet&& move) noexcept { delete[] buffer; buffer = move.buffer; move.buffer = nullptr; used = move.used; return *this; } std::uint8_t* data() { return buffer; } std::uint8_t& operator[](size_t index) { BLT_ASSERT(index < PACKET_SIZE); return buffer[index]; } [[nodiscard]] const std::uint8_t& operator[](size_t index) const { BLT_ASSERT(index < PACKET_SIZE); return buffer[index]; } [[nodiscard]] size_t size() const { return used; } ~packet() { delete[] buffer; } }; void mangle(packet& packet) { static std::random_device dev; static std::mt19937_64 engine(dev()); static std::uniform_real_distribution dist(0.0, 1.0); static std::uniform_int_distribution randomizer(0, 7); // 50% chance to mangle 10% of the data. if (dist(engine) < 0.5) { for (size_t i = 0; i < PACKET_SIZE; i++) if (dist(engine) < 0.1) { // this is bad auto pos = static_cast(exp2(randomizer(engine))); // flip the bit auto bit = ~(packet[i] & pos); // extra everything but the bit auto data = packet[i] & ~pos; // recombine bit packet[i] = data | bit; } } } class pipe { private: std::random_device dev{}; std::mt19937_64 engine{dev()}; std::uniform_real_distribution dist{0.0, 1.0}; packet buffer; std::atomic is_written{false}; public: pipe() = default; void send(packet packet) { while (is_written.load(std::memory_order::memory_order_acquire)) std::this_thread::sleep_for(std::chrono::milliseconds(1)); // 10% chance to drop the packet all together if (dist(engine) < 0.1) return; buffer = std::move(packet); is_written.store(true, std::memory_order::memory_order_release); } void receive(packet& out) { while (!is_written.load(std::memory_order::memory_order_acquire)) std::this_thread::sleep_for(std::chrono::milliseconds(1)); out = packet(buffer); mangle(out); is_written.store(false, std::memory_order::memory_order_release); } }; void process_packets(const std::vector& packets) { } int main(int argc, const char** argv) { blt::arg_parse parser; parser.addArgument( blt::arg_builder{"-f", "--file"}.setNArgs(1).setHelp("Specify a file to read from instead of cin").setAction(blt::arg_action_t::STORE) .build()); auto args = parser.parse_args(argc, argv); std::vector packets; if (args.contains("--file")) { auto& path = blt::arg_parse::get(args.data["file"]); std::ifstream file(path); file.seekg(0, std::ifstream::end); size_t length = file.tellg(); file.seekg(0, std::ifstream::beg); blt::scoped_buffer data(length); file.read(reinterpret_cast(data.data()), static_cast(length)); if (file) BLT_INFO("All bytes have been read from the file, parsing into packets"); else BLT_WARN("Only read %d characters, expected %d", file.gcount(), length); file.close(); size_t rp = 0; while (rp < length) { packet p; if (rp + PACKET_SIZE < length) p.used = PACKET_SIZE; else p.used = length - rp; std::memcpy(p.data(), &data[rp], p.used); rp += PACKET_SIZE; packets.push_back(std::move(p)); } } else { do { packet p; std::cin.read(reinterpret_cast(p.data()), PACKET_SIZE); packets.push_back(std::move(p)); } while (!std::cin.eof() && !std::cin.fail()); } process_packets(packets); return 0; }