[pan2/download-meter] bla
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2/download-meter] bla
- Date: Tue, 25 Sep 2012 15:48:20 +0000 (UTC)
commit b29259cb810797b84c74d56938dc59dfc6559d41
Author: Heinrich MÃller <henmull src gnome org>
Date: Tue Sep 25 17:48:05 2012 +0200
bla
pan/gui/dl-prefs.cc | 198 +++++++++++++++++++++++++++
pan/gui/dl-prefs.h | 58 ++++++++
pan/gui/download-meter.h | 87 ++++++++++++
pan/tasks/xzver-decoder.cc | 325 ++++++++++++++++++++++++++++++++++++++++++++
pan/tasks/xzver-decoder.h | 102 ++++++++++++++
5 files changed, 770 insertions(+), 0 deletions(-)
---
diff --git a/pan/gui/dl-prefs.cc b/pan/gui/dl-prefs.cc
new file mode 100644
index 0000000..647c6c7
--- /dev/null
+++ b/pan/gui/dl-prefs.cc
@@ -0,0 +1,198 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2006 Charles Kerr <charles rebelbase com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <config.h>
+extern "C" {
+ #include <glib/gi18n.h>
+ #include "gtk-compat.h"
+}
+#include <pan/general/debug.h>
+#include <pan/general/macros.h>
+#include <pan/icons/pan-pixbufs.h>
+#include "hig.h"
+#include "pad.h"
+#include "pan-file-entry.h"
+#include "dl-prefs.h"
+#include "url.h"
+#include "gtk-compat.h"
+
+using namespace pan;
+
+namespace pan
+{
+
+ namespace
+ {
+ #define PREFS_KEY "prefs-key"
+ #define PREFS_VAL "prefs-val"
+
+ void toggled_cb (GtkToggleButton * toggle, gpointer prefs_gpointer)
+ {
+ const char * key = (const char*) g_object_get_data (G_OBJECT(toggle), PREFS_KEY);
+ if (key)
+ static_cast<Prefs*>(prefs_gpointer)->set_flag (key, gtk_toggle_button_get_active(toggle));
+ }
+
+
+
+ GtkWidget* new_check_button (const char* mnemonic, const char* key, bool fallback, Prefs& prefs)
+ {
+ GtkWidget * t = gtk_check_button_new_with_mnemonic (mnemonic);
+ g_object_set_data_full (G_OBJECT(t), PREFS_KEY, g_strdup(key), g_free);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(t), prefs.get_flag (key, fallback));
+ g_signal_connect (t, "toggled", G_CALLBACK(toggled_cb), &prefs);
+ return t;
+ }
+
+ void response_cb (GtkDialog * dialog, int, gpointer)
+ {
+ gtk_widget_destroy (GTK_WIDGET(dialog));
+ }
+
+ void delete_dialog (gpointer castme)
+ {
+ DLMeterDialog* meterdialog(static_cast<DLMeterDialog*>(castme));
+ const bool enabled (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(meterdialog->get_enable())));
+ meterdialog->meter().set_enabled(enabled);
+
+ delete meterdialog;
+ }
+
+ void spin_value_changed_cb( GtkSpinButton *spin, gpointer data)
+ {
+ const char * key = (const char*) g_object_get_data (G_OBJECT(spin), PREFS_KEY);
+ Prefs *prefs = static_cast<Prefs*>(data);
+ prefs->set_int(key, gtk_spin_button_get_value_as_int(spin));
+ }
+
+ GtkWidget* new_spin_button (const char *key, int low, int high, Prefs &prefs)
+ {
+ guint tm = prefs.get_int(key, 5 );
+ GtkAdjustment *adj = (GtkAdjustment*) gtk_adjustment_new(tm, low, high, 1.0, 1.0, 0.0);
+ GtkWidget *w = gtk_spin_button_new( adj, 1.0, 0);
+ g_object_set_data_full(G_OBJECT(w), PREFS_KEY, g_strdup(key), g_free);
+ g_signal_connect (w, "value_changed", G_CALLBACK(spin_value_changed_cb), &prefs);
+ return w;
+ }
+
+ void set_prefs_string_from_combobox (GtkComboBox * c, gpointer user_data)
+ {
+ Prefs * prefs (static_cast<Prefs*>(user_data));
+ const char * key = (const char*) g_object_get_data (G_OBJECT(c), PREFS_KEY);
+
+ const int column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(c), "column"));
+ const int row (gtk_combo_box_get_active (c));
+ GtkTreeModel * m = gtk_combo_box_get_model (c);
+ GtkTreeIter i;
+ if (gtk_tree_model_iter_nth_child (m, &i, 0, row)) {
+ char * val (0);
+ gtk_tree_model_get (m, &i, column, &val, -1);
+ prefs->set_string (key, val);
+ g_free (val);
+ }
+ }
+
+ GtkWidget* new_bytes_combo_box (Prefs& prefs,
+ const char * mode_key)
+ {
+
+ const char* strings[2][2] =
+ {
+ {N_("MB"), "mb"},
+ {N_("GB"), "gb"}
+ };
+
+ const std::string mode (prefs.get_string (mode_key, "mb"));
+ GtkListStore * store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+
+ int sel_index (0);
+ for (size_t i=0; i<G_N_ELEMENTS(strings); ++i) {
+ GtkTreeIter iter;
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, strings[i][0], 1, strings[i][1], -1);
+ if (mode == strings[i][1])
+ sel_index = i;
+ }
+
+ GtkWidget * c = gtk_combo_box_new_with_model (GTK_TREE_MODEL(store));
+ GtkCellRenderer * renderer (gtk_cell_renderer_text_new ());
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (c), renderer, true);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (c), renderer, "text", 0, NULL);
+ gtk_combo_box_set_active (GTK_COMBO_BOX(c), sel_index);
+ g_object_set_data_full (G_OBJECT(c), PREFS_KEY, g_strdup(mode_key), g_free);
+ g_object_set_data (G_OBJECT(c), "column", GINT_TO_POINTER(1));
+ g_signal_connect (c, "changed", G_CALLBACK(set_prefs_string_from_combobox), &prefs);
+
+ gtk_widget_show_all(c);
+
+ return c;
+ }
+
+ void reset_dl_limit_cb (GtkButton *, gpointer user_data)
+ {
+ DLMeterDialog* pd (static_cast<DLMeterDialog*>(user_data));
+ pd->meter().reset();
+ }
+ }
+
+ DLMeterDialog :: DLMeterDialog (Prefs& prefs, DownloadMeter& meter, GtkWindow* parent):
+ _prefs (prefs), _meter(meter)
+ {
+
+ GtkWidget * dialog = gtk_dialog_new_with_buttons (_("Pan: Download Meter Preferences"), parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_window_set_role (GTK_WINDOW(dialog), "pan-dl-preferences-dialog");
+ g_signal_connect (dialog, "response", G_CALLBACK(response_cb), this);
+ g_signal_connect_swapped (dialog, "destroy", G_CALLBACK(delete_dialog), this);
+
+ // Behavior
+ int row (0);
+ GtkWidget *h, *w, *l, *b, *t;
+ t = HIG :: workarea_create ();
+ HIG::workarea_add_section_title (t, &row, _("Download Limit reached"));
+
+ HIG :: workarea_add_section_spacer (t, row, 2);
+ w = _enable = new_check_button (_("Enable"), "dl-limit-enable", true, prefs);
+ HIG :: workarea_add_wide_control (t, &row, w);
+ w = new_check_button (_("Warn"), "warn-dl-limit-reached", true, prefs);
+ HIG :: workarea_add_wide_control (t, &row, w);
+ w = new_check_button (_("Disconnect from server"), "disconnect-on-dl-limit-reached", true, prefs);
+ HIG :: workarea_add_wide_control (t, &row, w);
+ w = new_spin_button ("dl-limit", 1, 1024, prefs);
+ HIG :: workarea_add_wide_control (t, &row, w);
+ w = new_bytes_combo_box(prefs, "dl-limit-type");
+ g_signal_connect (w, "changed", G_CALLBACK(reset_dl_limit_cb), this);
+ HIG :: workarea_add_wide_control (t, &row, w);
+ w = gtk_button_new_with_label (_("Reset"));
+ g_signal_connect (w, "clicked", G_CALLBACK(reset_dl_limit_cb), this);
+ HIG :: workarea_add_wide_control (t, &row, w);
+
+ HIG :: workarea_finish (t, &row);
+
+ gtk_widget_show_all(t);
+
+ gtk_box_pack_start (GTK_BOX(gtk_dialog_get_content_area( GTK_DIALOG(dialog))), t, true, true, 0);
+
+ _root = dialog;
+
+ }
+
+}
diff --git a/pan/gui/dl-prefs.h b/pan/gui/dl-prefs.h
new file mode 100644
index 0000000..1068976
--- /dev/null
+++ b/pan/gui/dl-prefs.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2006 Charles Kerr <charles rebelbase com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DL_PREFS_UI_H
+#define DL_PREFS_UI_H
+
+#include "gtk-compat.h"
+#include <pan/gui/prefs.h>
+#include <pan/gui/download-meter.h>
+
+namespace pan
+{
+
+ class DLMeterDialog
+ {
+
+ public:
+
+ public:
+ DLMeterDialog (Prefs&, DownloadMeter&, GtkWindow*) ;
+ ~DLMeterDialog () { }
+
+ Prefs& prefs () { return _prefs; }
+
+ DownloadMeter& meter () { return _meter; }
+
+ GtkWidget* root() { return _root; }
+
+ uint64_t get_limit () { return _meter.get_limit(); }
+
+ GtkWidget* get_enable () { return _enable; }
+
+ private:
+ Prefs& _prefs;
+ GtkWidget* _root;
+ DownloadMeter& _meter;
+ GtkWidget* _enable;
+
+ };
+}
+
+#endif
diff --git a/pan/gui/download-meter.h b/pan/gui/download-meter.h
new file mode 100644
index 0000000..8cb5281
--- /dev/null
+++ b/pan/gui/download-meter.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2006 Charles Kerr <charles rebelbase com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _DOWNLOAD_METER_H_
+#define _DOWNLOAD_METER_H_
+
+#include <pan/gui/prefs.h>
+#include <pan/gui/progress-view.h>
+#include <pan/general/progress.h>
+#include <pan/data/data.h>
+
+namespace pan
+{
+
+ class DownloadMeter
+ {
+
+ public:
+
+ DownloadMeter (Prefs&, Data&);
+ virtual ~DownloadMeter() {}
+
+
+ void add (uint64_t bytes);
+ void reset ();
+ void set_enabled ( bool val) { _enabled = val; }
+
+ struct Listener {
+ Listener () {}
+ virtual ~Listener () {}
+ virtual void on_xfer_bytes (uint64_t&) {}
+ virtual void on_reset_xfer_bytes () {}
+ };
+
+ private:
+
+ typedef std::set<Listener*> listeners_t;
+ typedef DownloadMeter::listeners_t::const_iterator lit;
+ listeners_t _listeners;
+
+ uint64_t _val[5];// byte, kb, mb, gb, tb
+
+ ProgressView* _view;
+ Progress* _progress;
+ int _limit;
+ GtkWidget* _widget;
+ GtkWidget* _button;
+ bool _enabled;
+
+ public:
+
+ void add_listener (Listener * l) { _listeners.insert(l); }
+ void remove_listener (Listener * l) { _listeners.erase(l); }
+
+ ProgressView* get_view() { return _view; }
+
+ GtkWidget* get_widget () { return _widget; }
+
+ GtkWidget* get_button () { return _button; }
+
+ int get_limit() { return _limit; }
+ void set_limit (int& l) { _limit = l; }
+
+ virtual void fire_xfer_bytes (uint64_t bytes);
+
+ virtual void fire_reset_xfer_bytes ();
+
+ };
+
+}
+#endif
diff --git a/pan/tasks/xzver-decoder.cc b/pan/tasks/xzver-decoder.cc
new file mode 100644
index 0000000..9271501
--- /dev/null
+++ b/pan/tasks/xzver-decoder.cc
@@ -0,0 +1,325 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2007 Charles Kerr <charles rebelbase com>
+ *
+ * This file
+ * Copyright (C) 2007 Calin Culianu <calin ajvar org>
+ * Copyright (C) 2007 Charles Kerr <charles rebelbase com>
+ *
+ * This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <config.h>
+#include <cerrno>
+#include <ostream>
+#include <fstream>
+extern "C" {
+# define PROTOTYPES
+# include <uulib/uudeview.h>
+# include <glib/gi18n.h>
+};
+#include <pan/general/worker-pool.h>
+#include <pan/general/debug.h>
+#include <pan/general/file-util.h>
+#include <pan/general/macros.h>
+#include <pan/general/utf8-utils.h>
+#include "xzver-decoder.h"
+
+using namespace pan;
+
+/***
+****
+***/
+
+using namespace pan;
+
+XZVERDecoder :: XZVERDecoder (WorkerPool& pool) :
+ Decoder(pool)
+{
+ _cnt = 0;
+}
+
+XZVERDecoder :: ~XZVERDecoder()
+{
+ disable_progress_update();
+}
+
+void
+XZVERDecoder :: enqueue (TaskXOver * task, TaskXOver::DataStream* stream, Data* data)
+{
+
+ _cnt = 0;
+
+ disable_progress_update ();
+
+ this->xtask = task;
+ this->stream = stream;
+ this->data = data;
+ this->nntp = new NNTP(stream->server, "", "", 0);
+ this->nntp->_group = stream->group;
+
+ log_infos.clear();
+ log_errors.clear();
+
+ // gentlemen, start your saving...
+ _worker_pool.push_work (this, task, false);
+}
+
+namespace
+{
+ char* build_cachename (char* buf, size_t len, const char* name)
+ {
+ const char * home(file::get_pan_home().c_str());
+ g_snprintf(buf,len,"%s%c%s%c%s",home, G_DIR_SEPARATOR, "encode-cache", G_DIR_SEPARATOR, name);
+ return buf;
+ }
+}
+
+namespace
+{
+ unsigned long view_to_ul (const StringView& view)
+ {
+ unsigned long ul = 0ul;
+
+ if (!view.empty()) {
+ errno = 0;
+ ul = strtoul (view.str, 0, 10);
+ if (errno)
+ ul = 0ul;
+ }
+
+ return ul;
+ }
+ uint64_t view_to_ull (const StringView& view)
+ {
+ uint64_t ul = 0ul;
+
+ if (!view.empty()) {
+ errno = 0;
+ ul = g_ascii_strtoull (view.str, 0, 10);
+ if (errno)
+ ul = 0ul;
+ }
+
+ return ul;
+ }
+
+ bool header_is_nonencoded_utf8 (const StringView& in)
+ {
+ const bool is_nonencoded (!in.strstr("=?"));
+ const bool is_utf8 (g_utf8_validate (in.str, in.len, 0));
+ return is_nonencoded && is_utf8;
+ }
+}
+
+void
+XZVERDecoder :: on_nntp_batch_process (StringView & line)
+{
+ unsigned int lines=0u;
+ unsigned long bytes=0ul;
+ uint64_t number=0;
+
+ StringView subj, author, date, mid, tmp, xref;
+ StringView& l = line;
+ std::string ref;
+
+ bool ok = !l.empty();
+ ok = ok && l.pop_token (tmp, '\t'); if (ok) number = view_to_ull (tmp); tmp.clear();
+ ok = ok && l.pop_token (subj, '\t'); if (ok) subj.trim ();
+ ok = ok && l.pop_token (author, '\t'); if (ok) author.trim ();
+ ok = ok && l.pop_token (date, '\t'); if (ok) date.trim ();
+ ok = ok && l.pop_token (mid, '\t'); if (ok) mid.trim ();
+
+ //handle multiple "References:"-message-ids correctly.
+ ok = ok && l.pop_token (tmp, '\t');
+ do
+ {
+ if (tmp.empty()) continue;
+ if (tmp.front() == '<')
+ {
+ tmp.trim();
+ ref += tmp;
+ tmp.clear();
+ } else break;
+ } while ((ok = ok && l.pop_token (tmp, '\t'))) ;
+
+ if (ok) bytes = view_to_ul (tmp); tmp.clear();
+ ok = ok && l.pop_token (tmp, '\t'); if (ok) lines = view_to_ul (tmp);
+ ok = ok && l.pop_token (xref, '\t'); if (ok) xref.trim ();
+
+ if (xref.len>6 && !strncmp(xref.str,"Xref: ", 6)) {
+ xref = xref.substr (xref.str+6, 0);
+ xref.trim ();
+ }
+
+ // is this header corrupt?
+ if (!number // missing number
+ || subj.empty() // missing subject
+ || author.empty() // missing author
+ || date.empty() // missing date
+ || mid.empty() // missing mid
+ || mid.front()!='<') // corrupt mid
+ /// Concerning bug : https://bugzilla.gnome.org/show_bug.cgi?id=650042
+ /// Even if we didn't get a proper reference here, continue.
+ //|| (!ref.empty() && ref.front()!='<'))
+ return;
+
+ // if news server doesn't provide an xref, fake one
+ char * buf (0);
+ if (xref.empty())
+ xref = buf = g_strdup_printf ("%s %s:%"G_GUINT64_FORMAT,
+ nntp->_server.c_str(),
+ nntp->_group.c_str(),
+ number);
+
+ const char * fallback_charset = NULL; // FIXME
+ const time_t time_posted = g_mime_utils_header_decode_date (date.str, NULL);
+
+ data->xover_add (
+ nntp->_server, nntp->_group,
+ (header_is_nonencoded_utf8(subj) ? subj : header_to_utf8(subj,fallback_charset).c_str()),
+ (header_is_nonencoded_utf8(author) ? author : header_to_utf8(author,fallback_charset).c_str()),
+ time_posted, mid, StringView(ref), bytes, lines, xref);
+
+ high = std::max (high, number);
+
+ g_free (buf);
+}
+
+void
+XZVERDecoder :: find_lines()
+{
+ StringView ret;
+
+ while(!s_stream.eof())
+ {
+ std::string out;
+ getline(s_stream, out);
+ ret.assign(out);
+ xtask->on_nntp_line_process(nntp, ret);
+ _cnt++;
+ }
+
+}
+
+
+// save article IN A WORKER THREAD to avoid network stalls
+void
+XZVERDecoder :: do_work()
+{
+
+ const int bufsz = 4096;
+ char buf[bufsz];
+
+ disable_progress_update();
+
+ int res;
+ if (((res = UUInitialize())) != UURET_OK)
+ log_errors.push_back(_("Error initializing uulib")); // log error
+ else
+ {
+ build_cachename(buf,sizeof(buf), "xzver_test");
+ std::ofstream test (buf);
+ test << stream->stream->str();
+ test.close();
+
+ // TODO mod uulib to use streams!
+
+ UUSetOption (UUOPT_DESPERATE, 0, NULL);
+ UUSetOption (UUOPT_IGNMODE, 1, NULL); // don't save file as executable
+ UULoadFile (buf, 0, 0);
+ UUDecodeFile (UUGetFileListItem (0), build_cachename(buf,sizeof(buf), "xzver_decoded"));
+ UUCleanUp ();
+ }
+
+// disable_progress_update();
+
+ _strm.zalloc = Z_NULL;
+ _strm.zfree = Z_NULL;
+ _strm.opaque = Z_NULL;
+ _strm.avail_in = 0;
+ _strm.next_in = Z_NULL;
+
+ _zret = inflateInit2(&_strm,-MAX_WBITS); //raw inflate
+ if (_zret != Z_OK)
+ {
+ log_errors.push_back(_("Error initializing zlib deflate"));
+ return;
+ }
+
+ std::ifstream headers;
+ FILE * in = fopen(build_cachename(buf,sizeof(buf), "xzver_decoded"), "rb");
+
+ if (!in)
+ {
+ char tmpbuf[2048];
+ g_snprintf(tmpbuf, sizeof(tmpbuf), _("Error opening header file %s"), buf);
+ log_errors.push_back(tmpbuf);
+ return;
+ }
+
+ int ret;
+ char fbuf[CHUNK];
+ StringView line;
+
+ do
+ {
+ size_t len = fread(fbuf, sizeof(char), CHUNK, in);
+ if (len==0 || ferror(in)) break;
+ ret = inflate_xzver (len, fbuf);
+ } while (!feof(in) && _zret == Z_OK);
+
+ find_lines();
+
+ if (in) fclose(in);
+ (void)inflateEnd(&_strm);
+
+ xtask->setHigh(nntp->_server, high);
+
+}
+
+int
+XZVERDecoder :: inflate_xzver (size_t len, char* buf)
+{
+
+ InflateChunk ret;
+
+ _strm.avail_in = len;
+ _strm.next_in = (unsigned char*)buf;
+
+ /* run inflate() on input until output buffer not full */
+ do {
+ _strm.avail_out = CHUNK;
+ _strm.next_out = ret.tmpbuf;
+ _zret = inflate(&_strm, Z_NO_FLUSH);
+ assert(_zret != Z_STREAM_ERROR); /* state not clobbered */
+ switch (_zret) {
+ case Z_NEED_DICT:
+ _zret = Z_DATA_ERROR; /* and fall through */
+ case Z_DATA_ERROR:
+ case Z_MEM_ERROR:
+ (void)inflateEnd(&_strm);
+ return _zret;
+ }
+
+ s_stream<<ret.tmpbuf;
+
+ } while (_strm.avail_out == 0);
+
+ return _zret == Z_STREAM_END ? Z_OK : Z_STREAM_ERROR;
+
+}
+
+
diff --git a/pan/tasks/xzver-decoder.h b/pan/tasks/xzver-decoder.h
new file mode 100644
index 0000000..4515f0f
--- /dev/null
+++ b/pan/tasks/xzver-decoder.h
@@ -0,0 +1,102 @@
+
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * Pan - A Newsreader for Gtk+
+ * Copyright (C) 2002-2007 Charles Kerr <charles rebelbase com>
+ *
+ * This file
+ * Copyright (C) 2007 Calin Culianu <calin ajvar org>
+ * Copyright (C) 2007 Charles Kerr <charles rebelbase com>
+ *
+ * This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _XZVERDecoder_H_
+#define _XZVERDecoder_H_
+
+#include <list>
+#include <string>
+#include <sstream>
+#include <vector>
+
+#include <fstream>
+
+#include <pan/general/locking.h>
+#include <pan/general/worker-pool.h>
+#include <pan/tasks/task-xover.h>
+#include <pan/tasks/decoder.h>
+extern "C" {
+# define PROTOTYPES
+# include <uulib/uudeview.h>
+};
+
+namespace pan
+{
+ #define CHUNK 16384
+
+ class Decoder;
+
+ /**
+ * Decodes XZVER yenc-encoded and zlib-deflated
+ * headers to process with TaskXOver
+ * @author Heinrich Mueller <heinrich mueller82 gmail com>
+ * @author Calin Culianu <calin ajvar org>
+ * @author Charles Kerr <charles rebelbase com>
+ * @ingroup tasks
+ * @see Queue
+ * @see TaskXOver
+ */
+ class XZVERDecoder: public Decoder
+ {
+ public:
+
+ struct InflateChunk
+ {
+ int ret;
+ unsigned char tmpbuf[CHUNK]; // dbg
+ };
+
+ XZVERDecoder (WorkerPool&);
+
+ ~XZVERDecoder ();
+
+ typedef std::vector<std::string> strings_t;
+
+ void enqueue (TaskXOver * task, TaskXOver::DataStream*, Data*);
+
+ protected: // inherited from WorkerPool::Worker
+
+ void do_work();
+ TaskXOver * xtask;
+ TaskXOver::DataStream* stream;
+
+ z_stream _strm;
+ int _zret;
+ NNTP* nntp;
+ int _cnt;
+ Data* data;
+ uint64_t high;
+ GString * out;
+ unsigned char outbuf[4096];
+
+ int inflate_xzver (size_t len, char* buf);
+ void on_nntp_batch_process (StringView&);
+ void find_lines();
+
+ std::stringstream s_stream; // output for inflate
+
+ };
+}
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]