diff options
Diffstat (limited to 'src/protocol-main.cc')
| -rw-r--r-- | src/protocol-main.cc | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/protocol-main.cc b/src/protocol-main.cc new file mode 100644 index 0000000..5f22f86 --- /dev/null +++ b/src/protocol-main.cc @@ -0,0 +1,119 @@ +// -*- mode: c++; c-basic-offset: 2; -*- + +#include "common.hh" + +#include <fstream> +#include <iostream> +#include <unistd.h> + +#include "args.hh" +#include "gui_attrtext.hh" +#include "gui_htmlattrtext.hh" +#include "gui_plainattrtext.hh" +#include "looper.hh" +#include "protocols.hh" + +namespace { + +std::ostream* g_out; +bool g_use_html; + +class Receiver : public Protocols::Listener { +public: + Receiver(Looper* looper) + : looper_(looper) { + } + + void text(Protocols*, size_t, std::string const&, + std::unique_ptr<AttributedText>&& text) { + if (g_out) { + if (g_use_html) { + *g_out << "<html><body>" + << static_cast<HtmlAttributedText*>(text.get())->html() + << "</body></html>" << std::endl; + } else { + *g_out << text->text() << std::endl; + } + } + looper_->quit(); + } + + void content(Protocols*, size_t, std::string const&, std::ostream*) { + looper_->quit(); + } + +private: + Looper* looper_; +}; + +bool run(std::istream& in, std::ostream& out, bool html, bool content) { + g_use_html = html; + std::unique_ptr<Looper> looper(Looper::create()); + std::unique_ptr<Receiver> receiver(new Receiver(looper.get())); + std::unique_ptr<Protocols> protocols( + Protocols::create(1, 65536, 1, looper.get(), receiver.get())); + char buffer[8192]; + std::string data; + in.read(buffer, 8192); + data.append(buffer, in.gcount()); + protocols->add(42, data.data(), data.size()); + while (in.good()) { + in.read(buffer, 8192); + if (in.gcount() == 0) break; + data.append(buffer, in.gcount()); + protocols->update(42, data.data(), data.size()); + } + if (content) { + protocols->content(42, &out); + } else { + g_out = &out; + protocols->text(42); + } + looper->run(); + protocols.reset(); + g_out = nullptr; + return true; +} + +} // namespace + +// static +AttributedText* AttributedText::create() { + if (g_use_html) return HtmlAttributedText::create(); + return PlainAttributedText::create(); +} + +int main(int argc, char** argv) { + std::unique_ptr<Args> args(Args::create()); + args->add('H', "html", "generate HTML output"); + args->add('C', "content", "print content if possible"); + args->add('h', "help", "display this text and exit."); + if (!args->run(argc, argv)) { + std::cerr << "Try `protocol --help` for usage." << std::endl; + return EXIT_FAILURE; + } + if (args->is_set('h')) { + std::cout << "Usage: `protocol [OPTIONS...] [INPUT]`\n" + << "Runs protocols on INPUT or STDIN and prints result.\n" + << '\n'; + args->print_help(); + return EXIT_SUCCESS; + } + switch (args->arguments().size()) { + case 0: + return run(std::cin, std::cout, args->is_set('H'), args->is_set('C')); + case 1: { + std::ifstream in(args->arguments().front()); + if (!in.good()) { + std::cerr << "Unable to open " << args->arguments().front() + << " for reading." << std::endl; + return EXIT_FAILURE; + } + return run(in, std::cout, args->is_set('H'), args->is_set('C')); + } + default: + std::cerr << "Too many arguments.\n" + << "Try `protocol --help` for usage." << std::endl; + return EXIT_FAILURE; + } +} |
