/ src / ipc / libmultiprocess / example / calculator.cpp
calculator.cpp
 1  // Copyright (c) The Bitcoin Core developers
 2  // Distributed under the MIT software license, see the accompanying
 3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
 4  
 5  #include <calculator.h>
 6  #include <init.capnp.h>
 7  #include <init.capnp.proxy.h> // NOLINT(misc-include-cleaner) // IWYU pragma: keep
 8  
 9  #include <charconv>
10  #include <cstring>
11  #include <fstream>
12  #include <functional>
13  #include <iostream>
14  #include <kj/async.h>
15  #include <kj/common.h>
16  #include <kj/memory.h>
17  #include <memory>
18  #include <mp/proxy-io.h>
19  #include <stdexcept>
20  #include <string>
21  #include <system_error>
22  #include <utility>
23  
24  class CalculatorImpl : public Calculator
25  {
26  public:
27      CalculatorImpl(std::unique_ptr<Printer> printer) : m_printer(std::move(printer)) {}
28      void solveEquation(const std::string& eqn) override { m_printer->print("Wow " + eqn + ", that's a tough one.\n"); }
29      std::unique_ptr<Printer> m_printer;
30  };
31  
32  class InitImpl : public Init
33  {
34  public:
35      std::unique_ptr<Calculator> makeCalculator(std::unique_ptr<Printer> printer) override
36      {
37          return std::make_unique<CalculatorImpl>(std::move(printer));
38      }
39  };
40  
41  // Exercises deprecated log callback signature
42  static void LogPrint(bool raise, const std::string& message)
43  {
44      if (raise) throw std::runtime_error(message);
45      std::ofstream("debug.log", std::ios_base::app) << message << std::endl;
46  }
47  
48  int main(int argc, char** argv)
49  {
50      if (argc != 2) {
51          std::cout << "Usage: mpcalculator <fd>\n";
52          return 1;
53      }
54      int fd;
55      if (std::from_chars(argv[1], argv[1] + strlen(argv[1]), fd).ec != std::errc{}) {
56          std::cerr << argv[1] << " is not a number or is larger than an int\n";
57          return 1;
58      }
59      mp::EventLoop loop("mpcalculator", LogPrint);
60      std::unique_ptr<Init> init = std::make_unique<InitImpl>();
61      mp::ServeStream<InitInterface>(loop, fd, *init);
62      loop.loop();
63      return 0;
64  }