summaryrefslogtreecommitdiff
path: root/src/protocol-main.cc
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@yahoo.com>2017-08-06 22:23:41 +0200
committerJoel Klinghed <the_jk@yahoo.com>2017-08-06 22:25:44 +0200
commit178bb3a1ceab88f29aa7d0ceb453e76de172fd27 (patch)
tree09f830338d5490552ae878152de0f104cb7f6e5b /src/protocol-main.cc
parent9d586aec3a5615377e389318e97e7d756c970c96 (diff)
Add protools, used for getting content out of packages
Only HTTP protocol implemented yet, but with gzip, deflate and bzip2 suport
Diffstat (limited to 'src/protocol-main.cc')
-rw-r--r--src/protocol-main.cc119
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;
+ }
+}