Advertisement
kolbka_

Untitled

Feb 12th, 2022
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.50 KB | None | 0 0
  1. #include <boost/asio.hpp>
  2. #include <fstream>
  3. #include <functional>
  4. #include <iostream>
  5. #include <mutex>
  6. #include <set>
  7. #include <sstream>
  8. #include <thread>
  9. #include <utility>
  10. #include "bank.h"
  11. #include "boost/lexical_cast.hpp"
  12. using boost::asio::ip::tcp;
  13.  
  14. void transaction_command(tcp::iostream &client, const bank::user &user) {
  15.     int number = 0;
  16.     client >> number;
  17.     client << "CPTY\tBAL\tCOMM" << std::endl;
  18.     user.snapshot_transactions([&]([[maybe_unused]] auto &transactions,
  19.                                    [[maybe_unused]] int balance_xts) {
  20.         const int size = static_cast<int>(transactions.size());
  21.         auto start = std::max(0, size - number);
  22.         for (int i = start; i < size; i++) {
  23.             client << (transactions[i].counterparty == nullptr
  24.                            ? "-"
  25.                            : transactions[i].counterparty->name())
  26.                    << '\t' << transactions[i].balance_delta_xts << '\t'
  27.                    << transactions[i].comment << std::endl;
  28.         }
  29.         client << "===== BALANCE: " << balance_xts << " XTS =====" << std::endl;
  30.     });
  31.  
  32.     //    client << "OK" << std::endl;
  33. }
  34.  
  35. [[noreturn]] void monitor_command(tcp::iostream &client,
  36.                                   const bank::user &user) {
  37.     int number = 0;
  38.     client >> number;
  39.     client << "CPTY\tBAL\tCOMM" << std::endl;
  40.     bank::user_transactions_iterator a = user.snapshot_transactions(
  41.         [&](auto &transactions, [[maybe_unused]] int balance_xts) {
  42.             const int size = static_cast<int>(transactions.size());
  43.             auto start = std::max(0, size - number);
  44.             for (int i = start; i < size; i++) {
  45.                 client << ((transactions[i].counterparty == nullptr)
  46.                                ? "-"
  47.                                : transactions[i].counterparty->name())
  48.                        << '\t' << transactions[i].balance_delta_xts << '\t'
  49.                        << transactions[i].comment << std::endl;
  50.             }
  51.             client << "===== BALANCE: " << balance_xts
  52.                    << " XTS =====" << std::endl;
  53.         });
  54.     while (true) {
  55.         auto transaction_ = a.wait_next_transaction();
  56.         client << (transaction_.counterparty == nullptr
  57.                        ? "-"
  58.                        : transaction_.counterparty->name())
  59.                << '\t' << transaction_.balance_delta_xts << '\t'
  60.                << transaction_.comment << std::endl;
  61.     }
  62. }
  63.  
  64. void transfer_command(tcp::iostream &client,
  65.                       bank::user &user,
  66.                       bank::ledger &cur_ledger) {
  67.     std::string name_counterparty;
  68.     int amount = 0;
  69.     std::string comment;
  70.     client >> name_counterparty >> amount;
  71.     std::getline(client, comment);
  72.     comment = comment.substr(1);
  73.     try {
  74.         user.transfer(cur_ledger.get_or_create_user(name_counterparty), amount,
  75.                       comment);
  76.         client << "OK" << std::endl;
  77.     } catch (bank::not_enough_funds_error &e) {
  78.         client << e.what() << std::endl;
  79.     }
  80. }
  81.  
  82. // NOLINTNEXTLINE
  83. int main([[maybe_unused]] int argc, char *argv[]) {
  84.     bank::ledger cur_ledger;
  85.     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  86.     std::string file_name = static_cast<std::string>(argv[2]);
  87.     // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  88.     std::string port = static_cast<std::string>(argv[1]);
  89.     std::ofstream file(file_name);
  90.  
  91.     boost::asio::io_context io_context;
  92.     tcp::acceptor acceptor(
  93.         io_context,
  94.         tcp::endpoint(tcp::v4(), boost::lexical_cast<unsigned short>(port)));
  95.     std::cout << "Listening at " << acceptor.local_endpoint() << std::endl;
  96.     if (!file.is_open()) {
  97.         std::cerr << ("Unable to store port to file " + file_name) << std::endl;
  98.     } else {
  99.         file << acceptor.local_endpoint().port();
  100.     }
  101.     file.close();
  102.  
  103.     while (true) {
  104.         tcp::socket s = acceptor.accept();
  105.  
  106.         std::thread([socket = std::move(s), &cur_ledger]() mutable {
  107.             auto remote_endpoint =
  108.                 boost::lexical_cast<std::string>(socket.remote_endpoint());
  109.             auto local_endpoint =
  110.                 boost::lexical_cast<std::string>(socket.local_endpoint());
  111.             std::cout << "Connected " << remote_endpoint << " --> "
  112.                       << local_endpoint << std::endl;
  113.  
  114.             tcp::iostream client(std::move(socket));
  115.             client << "What is your name?" << std::endl;
  116.             std::string user_name;
  117.             client >> user_name;
  118.             bank::user &user = cur_ledger.get_or_create_user(user_name);
  119.             client << ("Hi " + user_name) << std::endl;
  120.             while (client) {
  121.                 std::string command;
  122.                 client >> command;
  123.                 if (command == "balance") {
  124.                     client << user.balance_xts() << std::endl;
  125.                 } else if (command == "transactions") {
  126.                     transaction_command(client, user);
  127.                 } else if (command == "monitor") {
  128.                     monitor_command(client, user);
  129.                 } else if (command == "transfer") {
  130.                     transfer_command(client, user, cur_ledger);
  131.                 } else {
  132.                     client << "Unknown command: '" + command + "'" << std::endl;
  133.                 }
  134.             }
  135.  
  136.             std::cout << "Disconnected " << remote_endpoint << " --> "
  137.                       << local_endpoint << std::endl;
  138.         }).detach();
  139.     }
  140. }
  141.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement