[yelp] [libyelp] Adding GIO decompressors for bz2, lzma, and magic



commit cd6e6383aba8e93f983e298e6044164e0fc19cab
Author: Shaun McCance <shaunm gnome org>
Date:   Mon Apr 26 11:24:17 2010 -0500

    [libyelp] Adding GIO decompressors for bz2, lzma, and magic

 libyelp/Makefile.am               |   14 ++-
 libyelp/yelp-bz2-decompressor.c   |  173 ++++++++++++++++++++++++++++++++++++
 libyelp/yelp-bz2-decompressor.h   |   53 +++++++++++
 libyelp/yelp-lzma-decompressor.c  |  174 +++++++++++++++++++++++++++++++++++++
 libyelp/yelp-lzma-decompressor.h  |   53 +++++++++++
 libyelp/yelp-magic-decompressor.c |  147 +++++++++++++++++++++++++++++++
 libyelp/yelp-magic-decompressor.h |   52 +++++++++++
 po/POTFILES.in                    |    3 +
 tests/Makefile.am                 |   12 +++
 tests/test-bz2.c                  |   60 +++++++++++++
 tests/test-lzma.c                 |   60 +++++++++++++
 tests/test-magic.c                |   60 +++++++++++++
 12 files changed, 857 insertions(+), 4 deletions(-)
---
diff --git a/libyelp/Makefile.am b/libyelp/Makefile.am
index 56a6595..770ce02 100644
--- a/libyelp/Makefile.am
+++ b/libyelp/Makefile.am
@@ -1,12 +1,15 @@
 lib_LTLIBRARIES = libyelp.la
 
 libyelp_la_SOURCES =				\
+	yelp-bz2-decompressor.c			\
 	yelp-debug.c				\
 	yelp-error.c				\
 	yelp-docbook-document.c			\
 	yelp-document.c				\
 	yelp-io-channel.c			\
 	yelp-location-entry.c			\
+	yelp-lzma-decompressor.c		\
+	yelp-magic-decompressor.c		\
 	yelp-mallard-document.c			\
 	yelp-marshal.c				\
 	yelp-settings.c				\
@@ -48,10 +51,13 @@ BUILT_SOURCES =			\
 	yelp-types.c		\
 	yelp-types.h
 
-EXTRA_DIST =			\
-	yelp-debug.h		\
-	yelp-error.h		\
-	yelp-io-channel.h	\
+EXTRA_DIST =				\
+	yelp-bz2-decompressor.h		\
+	yelp-debug.h			\
+	yelp-error.h			\
+	yelp-io-channel.h		\
+	yelp-lzma-decompressor.h	\
+	yelp-magic-decompressor.h	\
 	yelp-marshal.list
 
 yelp-marshal.h: stamp-yelp-marshal.h
diff --git a/libyelp/yelp-bz2-decompressor.c b/libyelp/yelp-bz2-decompressor.c
new file mode 100644
index 0000000..98802ce
--- /dev/null
+++ b/libyelp/yelp-bz2-decompressor.c
@@ -0,0 +1,173 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 Shaun McCance <shaunm gnome org>
+ *
+ * This library 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 library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <string.h>
+
+#include <glib/gi18n.h>
+
+#include "yelp-bz2-decompressor.h"
+
+static void yelp_bz2_decompressor_iface_init          (GConverterIface *iface);
+
+struct _YelpBz2Decompressor
+{
+    GObject parent_instance;
+
+    bz_stream bzstream;
+};
+
+G_DEFINE_TYPE_WITH_CODE (YelpBz2Decompressor, yelp_bz2_decompressor, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
+                                                yelp_bz2_decompressor_iface_init))
+
+static void
+yelp_bz2_decompressor_finalize (GObject *object)
+{
+    YelpBz2Decompressor *decompressor;
+
+    decompressor = YELP_BZ2_DECOMPRESSOR (object);
+
+    BZ2_bzDecompressEnd (&decompressor->bzstream);
+
+    G_OBJECT_CLASS (yelp_bz2_decompressor_parent_class)->finalize (object);
+}
+
+static void
+yelp_bz2_decompressor_init (YelpBz2Decompressor *decompressor)
+{
+}
+
+static void
+yelp_bz2_decompressor_constructed (GObject *object)
+{
+    YelpBz2Decompressor *decompressor;
+    int res;
+
+    decompressor = YELP_BZ2_DECOMPRESSOR (object);
+
+    res = BZ2_bzDecompressInit (&decompressor->bzstream, 0, FALSE);
+
+    if (res == BZ_MEM_ERROR )
+        g_error ("YelpBz2Decompressor: Not enough memory for bzip2 use");
+
+    if (res != BZ_OK)
+        g_error ("YelpBz2Decompressor: Unexpected bzip2 error");
+}
+
+static void
+yelp_bz2_decompressor_class_init (YelpBz2DecompressorClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+    gobject_class->finalize = yelp_bz2_decompressor_finalize;
+    gobject_class->constructed = yelp_bz2_decompressor_constructed;
+}
+
+YelpBz2Decompressor *
+yelp_bz2_decompressor_new (void)
+{
+    YelpBz2Decompressor *decompressor;
+
+    decompressor = g_object_new (YELP_TYPE_BZ2_DECOMPRESSOR, NULL);
+
+    return decompressor;
+}
+
+static void
+yelp_bz2_decompressor_reset (GConverter *converter)
+{
+    YelpBz2Decompressor *decompressor = YELP_BZ2_DECOMPRESSOR (converter);
+    int res;
+
+    /* libbzip2 doesn't have a reset function.  Ending and reiniting
+     * might do the trick.  But this is untested.  If reset matters
+     * to you, test this.
+     */
+    BZ2_bzDecompressEnd (&decompressor->bzstream);
+    res = BZ2_bzDecompressInit (&decompressor->bzstream, 0, FALSE);
+
+    if (res == BZ_MEM_ERROR )
+        g_error ("YelpBz2Decompressor: Not enough memory for bzip2 use");
+
+    if (res != BZ_OK)
+        g_error ("YelpBz2Decompressor: Unexpected bzip2 error");
+}
+
+static GConverterResult
+yelp_bz2_decompressor_convert (GConverter *converter,
+                               const void *inbuf,
+                               gsize       inbuf_size,
+                               void       *outbuf,
+                               gsize       outbuf_size,
+                               GConverterFlags flags,
+                               gsize      *bytes_read,
+                               gsize      *bytes_written,
+                               GError    **error)
+{
+    YelpBz2Decompressor *decompressor;
+    gsize header_size;
+    int res;
+
+    decompressor = YELP_BZ2_DECOMPRESSOR (converter);
+
+    decompressor->bzstream.next_in = (void *)inbuf;
+    decompressor->bzstream.avail_in = inbuf_size;
+
+    decompressor->bzstream.next_out = outbuf;
+    decompressor->bzstream.avail_out = outbuf_size;
+
+    res = BZ2_bzDecompress (&decompressor->bzstream);
+
+    if (res == BZ_DATA_ERROR || res == BZ_DATA_ERROR_MAGIC) {
+        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
+                             _("Invalid compressed data"));
+        return G_CONVERTER_ERROR;
+    }
+
+    if (res == BZ_MEM_ERROR) {
+        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                             _("Not enough memory"));
+        return G_CONVERTER_ERROR;
+    }
+
+    if (res == BZ_OK || res == BZ_STREAM_END) {
+        *bytes_read = inbuf_size - decompressor->bzstream.avail_in;
+        *bytes_written = outbuf_size - decompressor->bzstream.avail_out;
+
+        if (res == BZ_STREAM_END)
+            return G_CONVERTER_FINISHED;
+        return G_CONVERTER_CONVERTED;
+    }
+
+    g_assert_not_reached ();
+}
+
+static void
+yelp_bz2_decompressor_iface_init (GConverterIface *iface)
+{
+  iface->convert = yelp_bz2_decompressor_convert;
+  iface->reset = yelp_bz2_decompressor_reset;
+}
diff --git a/libyelp/yelp-bz2-decompressor.h b/libyelp/yelp-bz2-decompressor.h
new file mode 100644
index 0000000..e067f26
--- /dev/null
+++ b/libyelp/yelp-bz2-decompressor.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 Shaun McCance <shaunm gnome org>
+ *
+ * This library 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 library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#ifndef __YELP_BZ2_DECOMPRESSOR_H__
+#define __YELP_BZ2_DECOMPRESSOR_H__
+
+#include <gio/gio.h>
+#include <bzlib.h>
+
+G_BEGIN_DECLS
+
+#define YELP_TYPE_BZ2_DECOMPRESSOR         (yelp_bz2_decompressor_get_type ())
+#define YELP_BZ2_DECOMPRESSOR(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_BZ2_DECOMPRESSOR, YelpBz2Decompressor))
+#define YELP_BZ2_DECOMPRESSOR_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), YELP_TYPE_BZ2_DECOMPRESSOR, YelpBz2DecompressorClass))
+#define YELP_IS_BZ2_DECOMPRESSOR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_BZ2_DECOMPRESSOR))
+#define YELP_IS_BZ2_DECOMPRESSOR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_BZ2_DECOMPRESSOR))
+#define YELP_BZ2_DECOMPRESSOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_BZ2_DECOMPRESSOR, YelpBz2DecompressorClass))
+
+typedef struct _YelpBz2Decompressor        YelpBz2Decompressor;
+typedef struct _YelpBz2DecompressorClass   YelpBz2DecompressorClass;
+
+struct _YelpBz2DecompressorClass
+{
+    GObjectClass parent_class;
+};
+
+GType               yelp_bz2_decompressor_get_type (void);
+
+YelpBz2Decompressor *yelp_bz2_decompressor_new (void);
+
+G_END_DECLS
+
+#endif /* __YELP_BZ2_DECOMPRESSOR_H__ */
diff --git a/libyelp/yelp-lzma-decompressor.c b/libyelp/yelp-lzma-decompressor.c
new file mode 100644
index 0000000..1bd38ef
--- /dev/null
+++ b/libyelp/yelp-lzma-decompressor.c
@@ -0,0 +1,174 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 Shaun McCance <shaunm gnome org>
+ *
+ * This library 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 library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <string.h>
+
+#include <glib/gi18n.h>
+
+#include "yelp-lzma-decompressor.h"
+
+static void yelp_lzma_decompressor_iface_init          (GConverterIface *iface);
+
+struct _YelpLzmaDecompressor
+{
+    GObject parent_instance;
+
+    lzmadec_stream lzmastream;
+};
+
+G_DEFINE_TYPE_WITH_CODE (YelpLzmaDecompressor, yelp_lzma_decompressor, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
+                                                yelp_lzma_decompressor_iface_init))
+
+static void
+yelp_lzma_decompressor_finalize (GObject *object)
+{
+    YelpLzmaDecompressor *decompressor;
+
+    decompressor = YELP_LZMA_DECOMPRESSOR (object);
+
+    lzmadec_end (&decompressor->lzmastream);
+
+    G_OBJECT_CLASS (yelp_lzma_decompressor_parent_class)->finalize (object);
+}
+
+static void
+yelp_lzma_decompressor_init (YelpLzmaDecompressor *decompressor)
+{
+}
+
+static void
+yelp_lzma_decompressor_constructed (GObject *object)
+{
+    YelpLzmaDecompressor *decompressor;
+    int res;
+
+    decompressor = YELP_LZMA_DECOMPRESSOR (object);
+
+    res = lzmadec_init (&decompressor->lzmastream);
+
+    if (res == LZMADEC_MEM_ERROR )
+        g_error ("YelpLzmaDecompressor: Not enough memory for lzma use");
+
+    if (res != LZMADEC_OK)
+        g_error ("YelpLzmaDecompressor: Unexpected lzma error");
+}
+
+static void
+yelp_lzma_decompressor_class_init (YelpLzmaDecompressorClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+    gobject_class->finalize = yelp_lzma_decompressor_finalize;
+    gobject_class->constructed = yelp_lzma_decompressor_constructed;
+}
+
+YelpLzmaDecompressor *
+yelp_lzma_decompressor_new (void)
+{
+    YelpLzmaDecompressor *decompressor;
+
+    decompressor = g_object_new (YELP_TYPE_LZMA_DECOMPRESSOR, NULL);
+
+    return decompressor;
+}
+
+static void
+yelp_lzma_decompressor_reset (GConverter *converter)
+{
+    YelpLzmaDecompressor *decompressor = YELP_LZMA_DECOMPRESSOR (converter);
+    int res;
+
+    /* lzmadec doesn't have a reset function.  Ending and reiniting
+     * might do the trick.  But this is untested.  If reset matters
+     * to you, test this.
+     */
+    lzmadec_end (&decompressor->lzmastream);
+    res = lzmadec_init (&decompressor->lzmastream);
+
+    if (res == LZMADEC_MEM_ERROR )
+        g_error ("YelpLzmaDecompressor: Not enough memory for lzma use");
+
+    if (res != LZMADEC_OK)
+        g_error ("YelpLzmaDecompressor: Unexpected lzma error");
+}
+
+static GConverterResult
+yelp_lzma_decompressor_convert (GConverter *converter,
+                                const void *inbuf,
+                                gsize       inbuf_size,
+                                void       *outbuf,
+                                gsize       outbuf_size,
+                                GConverterFlags flags,
+                                gsize      *bytes_read,
+                                gsize      *bytes_written,
+                                GError    **error)
+{
+    YelpLzmaDecompressor *decompressor;
+    gsize header_size;
+    int res;
+
+    decompressor = YELP_LZMA_DECOMPRESSOR (converter);
+
+    decompressor->lzmastream.next_in = (void *)inbuf;
+    decompressor->lzmastream.avail_in = inbuf_size;
+
+    decompressor->lzmastream.next_out = outbuf;
+    decompressor->lzmastream.avail_out = outbuf_size;
+
+    res = lzmadec_decode (&decompressor->lzmastream,
+                          flags & G_CONVERTER_INPUT_AT_END);
+
+    if (res == LZMADEC_DATA_ERROR || res == LZMADEC_HEADER_ERROR) {
+        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
+                             _("Invalid compressed data"));
+        return G_CONVERTER_ERROR;
+    }
+
+    if (res == LZMADEC_MEM_ERROR) {
+        g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                             _("Not enough memory"));
+        return G_CONVERTER_ERROR;
+    }
+
+    if (res == LZMADEC_OK || res == LZMADEC_STREAM_END) {
+        *bytes_read = inbuf_size - decompressor->lzmastream.avail_in;
+        *bytes_written = outbuf_size - decompressor->lzmastream.avail_out;
+
+        if (res == LZMADEC_STREAM_END)
+            return G_CONVERTER_FINISHED;
+        return G_CONVERTER_CONVERTED;
+    }
+
+    g_assert_not_reached ();
+}
+
+static void
+yelp_lzma_decompressor_iface_init (GConverterIface *iface)
+{
+  iface->convert = yelp_lzma_decompressor_convert;
+  iface->reset = yelp_lzma_decompressor_reset;
+}
diff --git a/libyelp/yelp-lzma-decompressor.h b/libyelp/yelp-lzma-decompressor.h
new file mode 100644
index 0000000..f47cf2b
--- /dev/null
+++ b/libyelp/yelp-lzma-decompressor.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 Shaun McCance <shaunm gnome org>
+ *
+ * This library 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 library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#ifndef __YELP_LZMA_DECOMPRESSOR_H__
+#define __YELP_LZMA_DECOMPRESSOR_H__
+
+#include <gio/gio.h>
+#include <lzmadec.h>
+
+G_BEGIN_DECLS
+
+#define YELP_TYPE_LZMA_DECOMPRESSOR         (yelp_lzma_decompressor_get_type ())
+#define YELP_LZMA_DECOMPRESSOR(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_LZMA_DECOMPRESSOR, YelpLzmaDecompressor))
+#define YELP_LZMA_DECOMPRESSOR_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), YELP_TYPE_LZMA_DECOMPRESSOR, YelpLzmaDecompressorClass))
+#define YELP_IS_LZMA_DECOMPRESSOR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_LZMA_DECOMPRESSOR))
+#define YELP_IS_LZMA_DECOMPRESSOR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_LZMA_DECOMPRESSOR))
+#define YELP_LZMA_DECOMPRESSOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_LZMA_DECOMPRESSOR, YelpLzmaDecompressorClass))
+
+typedef struct _YelpLzmaDecompressor        YelpLzmaDecompressor;
+typedef struct _YelpLzmaDecompressorClass   YelpLzmaDecompressorClass;
+
+struct _YelpLzmaDecompressorClass
+{
+    GObjectClass parent_class;
+};
+
+GType                 yelp_lzma_decompressor_get_type (void);
+
+YelpLzmaDecompressor *yelp_lzma_decompressor_new (void);
+
+G_END_DECLS
+
+#endif /* __YELP_LZMA_DECOMPRESSOR_H__ */
diff --git a/libyelp/yelp-magic-decompressor.c b/libyelp/yelp-magic-decompressor.c
new file mode 100644
index 0000000..cf1b09b
--- /dev/null
+++ b/libyelp/yelp-magic-decompressor.c
@@ -0,0 +1,147 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 Shaun McCance <shaunm gnome org>
+ *
+ * This library 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 library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+
+#include "yelp-bz2-decompressor.h"
+#include "yelp-lzma-decompressor.h"
+#include "yelp-magic-decompressor.h"
+
+static void yelp_magic_decompressor_iface_init          (GConverterIface *iface);
+
+struct _YelpMagicDecompressor
+{
+    GObject parent_instance;
+
+    GConverter *magic_decoder_ring;
+
+    gboolean first;
+};
+
+G_DEFINE_TYPE_WITH_CODE (YelpMagicDecompressor, yelp_magic_decompressor, G_TYPE_OBJECT,
+                         G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
+                                                yelp_magic_decompressor_iface_init))
+
+static void
+yelp_magic_decompressor_dispose (GObject *object)
+{
+    YelpMagicDecompressor *decompressor;
+
+    g_object_unref (decompressor->magic_decoder_ring);
+
+    G_OBJECT_CLASS (yelp_magic_decompressor_parent_class)->dispose (object);
+}
+
+static void
+yelp_magic_decompressor_init (YelpMagicDecompressor *decompressor)
+{
+    decompressor->magic_decoder_ring = NULL;
+    decompressor->first = TRUE;
+}
+
+static void
+yelp_magic_decompressor_class_init (YelpMagicDecompressorClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+    gobject_class->dispose = yelp_magic_decompressor_dispose;
+}
+
+YelpMagicDecompressor *
+yelp_magic_decompressor_new (void)
+{
+    YelpMagicDecompressor *decompressor;
+
+    decompressor = g_object_new (YELP_TYPE_MAGIC_DECOMPRESSOR, NULL);
+
+    return decompressor;
+}
+
+static void
+yelp_magic_decompressor_reset (GConverter *converter)
+{
+    YelpMagicDecompressor *decompressor = YELP_MAGIC_DECOMPRESSOR (converter);
+
+    if (decompressor->magic_decoder_ring)
+        g_converter_reset (decompressor->magic_decoder_ring);
+}
+
+static GConverterResult
+yelp_magic_decompressor_convert (GConverter *converter,
+                                 const void *inbuf,
+                                 gsize       inbuf_size,
+                                 void       *outbuf,
+                                 gsize       outbuf_size,
+                                 GConverterFlags flags,
+                                 gsize      *bytes_read,
+                                 gsize      *bytes_written,
+                                 GError    **error)
+{
+    YelpMagicDecompressor *decompressor;
+
+    decompressor = YELP_MAGIC_DECOMPRESSOR (converter);
+
+    if (decompressor->first) {
+        decompressor->first = FALSE;
+        /* If input_size is less than two the first time, we end up
+         * not getting detection.  Might be worth addressing.  Not
+         * sure I care.
+         *
+         * The two-byte magic we're doing here is not sufficient in
+         * the general case.  It is sufficient for the specific data
+         * Yelp deals with.
+         */
+        if (inbuf_size <= 2)
+            ;
+        else if (((gchar *) inbuf)[0] == 'B' &&
+                 ((gchar *) inbuf)[1] == 'Z') {
+            decompressor->magic_decoder_ring = (GConverter *) yelp_bz2_decompressor_new ();
+        }
+        else if (((gchar *) inbuf)[0] == ']' &&
+                 ((gchar *) inbuf)[1] == '\0') {
+            decompressor->magic_decoder_ring = (GConverter *) yelp_lzma_decompressor_new ();
+        }
+        else {
+            decompressor->magic_decoder_ring =
+                (GConverter *) g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
+        }
+    }
+
+    return g_converter_convert (decompressor->magic_decoder_ring,
+                                inbuf, inbuf_size,
+                                outbuf, outbuf_size,
+                                flags,
+                                bytes_read, bytes_written,
+                                error);
+
+    g_assert_not_reached ();
+}
+
+static void
+yelp_magic_decompressor_iface_init (GConverterIface *iface)
+{
+  iface->convert = yelp_magic_decompressor_convert;
+  iface->reset = yelp_magic_decompressor_reset;
+}
diff --git a/libyelp/yelp-magic-decompressor.h b/libyelp/yelp-magic-decompressor.h
new file mode 100644
index 0000000..15c09bb
--- /dev/null
+++ b/libyelp/yelp-magic-decompressor.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009 Shaun McCance <shaunm gnome org>
+ *
+ * This library 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 library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#ifndef __YELP_MAGIC_DECOMPRESSOR_H__
+#define __YELP_MAGIC_DECOMPRESSOR_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define YELP_TYPE_MAGIC_DECOMPRESSOR         (yelp_magic_decompressor_get_type ())
+#define YELP_MAGIC_DECOMPRESSOR(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_MAGIC_DECOMPRESSOR, YelpMagicDecompressor))
+#define YELP_MAGIC_DECOMPRESSOR_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), YELP_TYPE_MAGIC_DECOMPRESSOR, YelpMagicDecompressorClass))
+#define YELP_IS_MAGIC_DECOMPRESSOR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_MAGIC_DECOMPRESSOR))
+#define YELP_IS_MAGIC_DECOMPRESSOR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_MAGIC_DECOMPRESSOR))
+#define YELP_MAGIC_DECOMPRESSOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_MAGIC_DECOMPRESSOR, YelpMagicDecompressorClass))
+
+typedef struct _YelpMagicDecompressor        YelpMagicDecompressor;
+typedef struct _YelpMagicDecompressorClass   YelpMagicDecompressorClass;
+
+struct _YelpMagicDecompressorClass
+{
+    GObjectClass parent_class;
+};
+
+GType                 yelp_magic_decompressor_get_type (void);
+
+YelpMagicDecompressor *yelp_magic_decompressor_new (void);
+
+G_END_DECLS
+
+#endif /* __YELP_MAGIC_DECOMPRESSOR_H__ */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 1f86202..3c4440b 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,12 +4,15 @@
 data/info.xml.in
 data/man.xml.in
 data/toc.xml.in
+libyelp/yelp-bz2-decompressor.c
 libyelp/yelp-debug.c
 libyelp/yelp-docbook-document.c
 libyelp/yelp-document.c
 libyelp/yelp-error.c
 libyelp/yelp-io-channel.c
 libyelp/yelp-location-entry.c
+libyelp/yelp-lzma-decompressor.c
+libyelp/yelp-magic-decompressor.c
 libyelp/yelp-mallard-document.c
 libyelp/yelp-marshal.c
 libyelp/yelp-settings.c
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 02f1d98..c4b9c54 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -12,19 +12,31 @@ YELP_COMMON_LDADD =				\
 	$(top_builddir)/libyelp/libyelp.la
 
 check_PROGRAMS =				\
+	test-bz2				\
 	test-io-channel				\
 	test-location-entry			\
+	test-lzma				\
+	test-magic				\
 	test-settings				\
 	test-transform				\
 	test-uri				\
 	test-view
 
+test_bz2_CFLAGS = $(YELP_COMMON_CFLAGS)
+test_bz2_LDADD = $(YELP_COMMON_LDADD)
+
 test_io_channel_CFLAGS = $(YELP_COMMON_CFLAGS)
 test_io_channel_LDADD = $(YELP_COMMON_LDADD)
 
 test_location_entry_CFLAGS = $(YELP_COMMON_CFLAGS)
 test_location_entry_LDADD = $(YELP_COMMON_LDADD)
 
+test_lzma_CFLAGS = $(YELP_COMMON_CFLAGS)
+test_lzma_LDADD = $(YELP_COMMON_LDADD)
+
+test_magic_CFLAGS = $(YELP_COMMON_CFLAGS)
+test_magic_LDADD = $(YELP_COMMON_LDADD)
+
 test_settings_CFLAGS = $(YELP_COMMON_CFLAGS)
 test_settings_LDADD = $(YELP_COMMON_LDADD)
 
diff --git a/tests/test-bz2.c b/tests/test-bz2.c
new file mode 100644
index 0000000..a2da96c
--- /dev/null
+++ b/tests/test-bz2.c
@@ -0,0 +1,60 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2009  Shaun McCance  <shaunm gnome org
+ *
+ * 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; 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.
+ *
+ * Author: Shaun McCance <shaunm gnome org
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <gio/gio.h>
+
+#include "yelp-bz2-decompressor.h"
+
+int
+main (int argc, char **argv)
+{
+    GConverter *converter;
+    GFile *file;
+    GFileInputStream *file_stream;
+    GInputStream *stream;
+    gchar buf[1024];
+    gssize bytes;
+        
+    if (argc < 2) {
+        g_printerr ("Usage: test-bz2 FILE\n");
+        return 1;
+    }
+
+    g_type_init ();
+
+    file = g_file_new_for_path (argv[1]);
+    file_stream = g_file_read (file, NULL, NULL);
+    converter = yelp_bz2_decompressor_new ();
+    stream = g_converter_input_stream_new (file_stream, converter);
+
+    while ((bytes = g_input_stream_read (stream, buf, 1024, NULL, NULL)) > 0) {
+        gchar *out = g_strndup (buf, bytes);
+        puts (out);
+        g_free (out);
+    }
+
+    return 0;
+}
diff --git a/tests/test-lzma.c b/tests/test-lzma.c
new file mode 100644
index 0000000..76af37d
--- /dev/null
+++ b/tests/test-lzma.c
@@ -0,0 +1,60 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2009  Shaun McCance  <shaunm gnome org
+ *
+ * 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; 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.
+ *
+ * Author: Shaun McCance <shaunm gnome org
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <gio/gio.h>
+
+#include "yelp-lzma-decompressor.h"
+
+int
+main (int argc, char **argv)
+{
+    GConverter *converter;
+    GFile *file;
+    GFileInputStream *file_stream;
+    GInputStream *stream;
+    gchar buf[1024];
+    gssize bytes;
+        
+    if (argc < 2) {
+        g_printerr ("Usage: test-lzma FILE\n");
+        return 1;
+    }
+
+    g_type_init ();
+
+    file = g_file_new_for_path (argv[1]);
+    file_stream = g_file_read (file, NULL, NULL);
+    converter = yelp_lzma_decompressor_new ();
+    stream = g_converter_input_stream_new (file_stream, converter);
+
+    while ((bytes = g_input_stream_read (stream, buf, 1024, NULL, NULL)) > 0) {
+        gchar *out = g_strndup (buf, bytes);
+        puts (out);
+        g_free (out);
+    }
+
+    return 0;
+}
diff --git a/tests/test-magic.c b/tests/test-magic.c
new file mode 100644
index 0000000..9a93799
--- /dev/null
+++ b/tests/test-magic.c
@@ -0,0 +1,60 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2009  Shaun McCance  <shaunm gnome org
+ *
+ * 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; 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.
+ *
+ * Author: Shaun McCance <shaunm gnome org
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <gio/gio.h>
+
+#include "yelp-magic-decompressor.h"
+
+int
+main (int argc, char **argv)
+{
+    GConverter *converter;
+    GFile *file;
+    GFileInputStream *file_stream;
+    GInputStream *stream;
+    gchar buf[1024];
+    gssize bytes;
+        
+    if (argc < 2) {
+        g_printerr ("Usage: test-magic FILE\n");
+        return 1;
+    }
+
+    g_type_init ();
+
+    file = g_file_new_for_path (argv[1]);
+    file_stream = g_file_read (file, NULL, NULL);
+    converter = yelp_magic_decompressor_new ();
+    stream = g_converter_input_stream_new (file_stream, converter);
+
+    while ((bytes = g_input_stream_read (stream, buf, 1024, NULL, NULL)) > 0) {
+        gchar *out = g_strndup (buf, bytes);
+        puts (out);
+        g_free (out);
+    }
+
+    return 0;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]