Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <boost/asio.hpp>
- #include <fstream>
- #include <functional>
- #include <iostream>
- #include <mutex>
- #include <set>
- #include <sstream>
- #include <thread>
- #include <utility>
- #include "bank.h"
- #include "boost/lexical_cast.hpp"
- using boost::asio::ip::tcp;
- void transaction_command(tcp::iostream &client, const bank::user &user) {
- int number = 0;
- client >> number;
- client << "CPTY\tBAL\tCOMM" << std::endl;
- user.snapshot_transactions([&]([[maybe_unused]] auto &transactions,
- [[maybe_unused]] int balance_xts) {
- const int size = static_cast<int>(transactions.size());
- auto start = std::max(0, size - number);
- for (int i = start; i < size; i++) {
- client << (transactions[i].counterparty == nullptr
- ? "-"
- : transactions[i].counterparty->name())
- << '\t' << transactions[i].balance_delta_xts << '\t'
- << transactions[i].comment << std::endl;
- }
- client << "===== BALANCE: " << balance_xts << " XTS =====" << std::endl;
- });
- // client << "OK" << std::endl;
- }
- [[noreturn]] void monitor_command(tcp::iostream &client,
- const bank::user &user) {
- int number = 0;
- client >> number;
- client << "CPTY\tBAL\tCOMM" << std::endl;
- bank::user_transactions_iterator a = user.snapshot_transactions(
- [&](auto &transactions, [[maybe_unused]] int balance_xts) {
- const int size = static_cast<int>(transactions.size());
- auto start = std::max(0, size - number);
- for (int i = start; i < size; i++) {
- client << ((transactions[i].counterparty == nullptr)
- ? "-"
- : transactions[i].counterparty->name())
- << '\t' << transactions[i].balance_delta_xts << '\t'
- << transactions[i].comment << std::endl;
- }
- client << "===== BALANCE: " << balance_xts
- << " XTS =====" << std::endl;
- });
- while (true) {
- auto transaction_ = a.wait_next_transaction();
- client << (transaction_.counterparty == nullptr
- ? "-"
- : transaction_.counterparty->name())
- << '\t' << transaction_.balance_delta_xts << '\t'
- << transaction_.comment << std::endl;
- }
- }
- void transfer_command(tcp::iostream &client,
- bank::user &user,
- bank::ledger &cur_ledger) {
- std::string name_counterparty;
- int amount = 0;
- std::string comment;
- client >> name_counterparty >> amount;
- std::getline(client, comment);
- comment = comment.substr(1);
- try {
- user.transfer(cur_ledger.get_or_create_user(name_counterparty), amount,
- comment);
- client << "OK" << std::endl;
- } catch (bank::not_enough_funds_error &e) {
- client << e.what() << std::endl;
- }
- }
- // NOLINTNEXTLINE
- int main([[maybe_unused]] int argc, char *argv[]) {
- bank::ledger cur_ledger;
- // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
- std::string file_name = static_cast<std::string>(argv[2]);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
- std::string port = static_cast<std::string>(argv[1]);
- std::ofstream file(file_name);
- boost::asio::io_context io_context;
- tcp::acceptor acceptor(
- io_context,
- tcp::endpoint(tcp::v4(), boost::lexical_cast<unsigned short>(port)));
- std::cout << "Listening at " << acceptor.local_endpoint() << std::endl;
- if (!file.is_open()) {
- std::cerr << ("Unable to store port to file " + file_name) << std::endl;
- } else {
- file << acceptor.local_endpoint().port();
- }
- file.close();
- while (true) {
- tcp::socket s = acceptor.accept();
- std::thread([socket = std::move(s), &cur_ledger]() mutable {
- auto remote_endpoint =
- boost::lexical_cast<std::string>(socket.remote_endpoint());
- auto local_endpoint =
- boost::lexical_cast<std::string>(socket.local_endpoint());
- std::cout << "Connected " << remote_endpoint << " --> "
- << local_endpoint << std::endl;
- tcp::iostream client(std::move(socket));
- client << "What is your name?" << std::endl;
- std::string user_name;
- client >> user_name;
- bank::user &user = cur_ledger.get_or_create_user(user_name);
- client << ("Hi " + user_name) << std::endl;
- while (client) {
- std::string command;
- client >> command;
- if (command == "balance") {
- client << user.balance_xts() << std::endl;
- } else if (command == "transactions") {
- transaction_command(client, user);
- } else if (command == "monitor") {
- monitor_command(client, user);
- } else if (command == "transfer") {
- transfer_command(client, user, cur_ledger);
- } else {
- client << "Unknown command: '" + command + "'" << std::endl;
- }
- }
- std::cout << "Disconnected " << remote_endpoint << " --> "
- << local_endpoint << std::endl;
- }).detach();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement