summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun McCance <shaunm@gnome.org>2010-04-26 11:24:17 -0500
committerShaun McCance <shaunm@gnome.org>2010-04-26 11:24:17 -0500
commitcd6e6383aba8e93f983e298e6044164e0fc19cab (patch)
tree9db9a546bcbd705f69d3df6cd3912a616d8d1594
parentfeed213d5298125b026bc0c74d4b3be922b65e0e (diff)
downloadyelp-cd6e6383aba8e93f983e298e6044164e0fc19cab.tar.gz
[libyelp] Adding GIO decompressors for bz2, lzma, and magic
-rw-r--r--libyelp/Makefile.am14
-rw-r--r--libyelp/yelp-bz2-decompressor.c173
-rw-r--r--libyelp/yelp-bz2-decompressor.h53
-rw-r--r--libyelp/yelp-lzma-decompressor.c174
-rw-r--r--libyelp/yelp-lzma-decompressor.h53
-rw-r--r--libyelp/yelp-magic-decompressor.c147
-rw-r--r--libyelp/yelp-magic-decompressor.h52
-rw-r--r--po/POTFILES.in3
-rw-r--r--tests/Makefile.am12
-rw-r--r--tests/test-bz2.c60
-rw-r--r--tests/test-lzma.c60
-rw-r--r--tests/test-magic.c60
12 files changed, 857 insertions, 4 deletions
diff --git a/libyelp/Makefile.am b/libyelp/Makefile.am
index 56a6595d..770ce02d 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 00000000..98802cee
--- /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 00000000..e067f26e
--- /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 00000000..1bd38ef6
--- /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 00000000..f47cf2b3
--- /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 00000000..cf1b09bc
--- /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 00000000..15c09bbd
--- /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 1f862023..3c4440b7 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 02f1d98a..c4b9c543 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 00000000..a2da96cb
--- /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 00000000..76af37d8
--- /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 00000000..9a937991
--- /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;
+}