#include #include #include #include #include #include #include #include #include #include #include struct Credentail { int cert_; }; struct Download { enum ConnectionType { Telnet, Ssh }; std::string url_; Credentail credentail_; int maxMbps_; bool cache_; ConnectionType type_; }; struct Upload { enum ConnectionType { Telnet, Ssh }; std::string url_; Credentail credentail_; int maxMbps_; int size_; ConnectionType type_; }; struct RemoveFromCache { std::string url_; }; struct ClearCache { }; struct Image { std::vector bitmap_; }; class Server { public: void handle(const Download& request, void (*callback)(bool, Image)) { Image image; for (const auto& pair : cache_) { if (pair.second == request.url_) { image = pair.first; callback(true, image); return; } } if (download(request, &image)) { if (request.cache_) { cache_.push_back(std::pair(image, request.url_)); } callback(true, image); return; } callback(false, Image{}); } void handle(const Upload& request, void (*callback)(bool, Image)) { if (request.size_ > 100) { callback(false, Image{}); return; } Image image; bool succes = upload(request, &image); callback(succes, Image{}); } void handle(const RemoveFromCache& request, void (*callback)(bool, Image)) { for (auto it = cache_.begin(); it != cache_.end(); ++it) { if (it->second == request.url_) { cache_.erase(it); callback(true, Image{}); return; } } callback(false, Image{}); } void handle(const ClearCache& request, void (*callback)(bool, Image)) { cache_.clear(); callback(true, Image{}); } private: bool download(const Download& request, Image* image) { if (request.type_ == Download::Ssh && request.credentail_.cert_ != 123) { return false; } if (request.type_ == Download::Telnet && request.credentail_.cert_ != 231) { return false; } // Simulate some other error if (request.maxMbps_ % 2) { return false; } image->bitmap_ = {97, 98, 99, 100, 101, 102}; return true; } bool upload(const Upload& request, const Image* image) { if (request.type_ == Upload::Ssh && request.credentail_.cert_ != 1234) { return false; } if (request.type_ == Upload::Telnet && request.credentail_.cert_ != 5432) { return false; } // Simulate some other error if (!request.maxMbps_ % 2) { return false; } return true; } std::vector> cache_; }; class RequestHandler { public: enum RequestType { Download, Upload, Remove, Clear }; void start(Server* server) { std::thread(&RequestHandler::run, this, server).detach(); } void stop() { stop_ = true; } void pushRequest(void* request, RequestType type, void (*callback)(bool, Image)) { requests_.push(std::tuple(request, type, callback)); } private: void run(Server* server) { while (!stop_) { auto tuple = waitForRequest(); switch (std::get<1>(tuple)) { case Download: server->handle(*((::Download*)(std::get<0>(tuple))), std::get<2>(tuple)); break; case Upload: server->handle(*((::Upload*)(std::get<0>(tuple))), std::get<2>(tuple)); break; case Remove: server->handle(*((RemoveFromCache*)(std::get<0>(tuple))), std::get<2>(tuple)); break; case Clear: server->handle(*((ClearCache*)(std::get<0>(tuple))), std::get<2>(tuple)); break; } } } std::tuple waitForRequest() { while (requests_.empty() || !stop_) { } auto pair = requests_.front(); requests_.pop(); return pair; } bool stop_; std::queue> requests_; }; int main() { Server server; RequestHandler handler; handler.start(&server); Download d{"sth.png", 123, 100, true, Download::Ssh}; handler.pushRequest((void*)(&d), RequestHandler::Download, [](bool succes, Image image) { if (succes) { for (auto el : image.bitmap_) { std::cout << el << ' '; } std::cout << '\n'; } else { std::cout << "FAILED!\n"; } }); std::this_thread::sleep_for(std::chrono::seconds(1)); handler.stop(); }