[yelp] Allow the possibility of no compression for info files.



commit e56c8638a8d872c85646fa27bdcb8b743f7c4236
Author: Rupert Swarbrick <rswarbrick gmail com>
Date:   Thu Jun 10 11:35:46 2010 +0100

    Allow the possibility of no compression for info files.
    
    At the moment, the info parser uses YelpMagicDecompressor. If it
    didn't recognize a stream as BZ2 or LZMA, the decompressor assumed it
    was GZip. This didn't work if the file is uncompressed... Since GZip
    decompression certainly won't work if the file is not GZip compressed,
    this patch changes YelpMagicDecompressor to fall back to a
    pass-through converter if it doesn't recognise the compression format
    (which might mean the file is uncompressed!).

 libyelp/yelp-magic-decompressor.c |   86 ++++++++++++++++++++++--------------
 1 files changed, 52 insertions(+), 34 deletions(-)
---
diff --git a/libyelp/yelp-magic-decompressor.c b/libyelp/yelp-magic-decompressor.c
index 89fa2be..6b3a83c 100644
--- a/libyelp/yelp-magic-decompressor.c
+++ b/libyelp/yelp-magic-decompressor.c
@@ -24,6 +24,7 @@
 #include "config.h"
 
 #include <glib/gi18n.h>
+#include <string.h>
 
 #include "yelp-magic-decompressor.h"
 
@@ -54,7 +55,7 @@ G_DEFINE_TYPE_WITH_CODE (YelpMagicDecompressor, yelp_magic_decompressor, G_TYPE_
 static void
 yelp_magic_decompressor_dispose (GObject *object)
 {
-    YelpMagicDecompressor *decompressor;
+    YelpMagicDecompressor *decompressor = YELP_MAGIC_DECOMPRESSOR (object);
 
     if (decompressor->magic_decoder_ring) {
         g_object_unref (decompressor->magic_decoder_ring);
@@ -98,6 +99,37 @@ yelp_magic_decompressor_reset (GConverter *converter)
         g_converter_reset (decompressor->magic_decoder_ring);
 }
 
+static GConverter*
+yelp_magic_decompressor_choose (const void *inbuf, gsize inbuf_size)
+{
+    /* 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)
+        return NULL;
+
+#ifdef ENABLE_BZ2
+    if (((gchar *) inbuf)[0] == 'B' && ((gchar *) inbuf)[1] == 'Z') {
+        return (GConverter *) yelp_bz2_decompressor_new ();
+    }
+#endif
+#ifdef ENABLE_LZMA
+    if (((gchar *) inbuf)[0] == ']' && ((gchar *) inbuf)[1] == '\0') {
+        return (GConverter *) yelp_lzma_decompressor_new ();
+    }
+#endif
+    if (((guint8*) inbuf)[0] == 0x1F && ((guint8*) inbuf)[1] == 0x8B) {
+        return (GConverter *) g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
+    }
+
+    return NULL;
+}
+
 static GConverterResult
 yelp_magic_decompressor_convert (GConverter *converter,
                                  const void *inbuf,
@@ -110,47 +142,33 @@ yelp_magic_decompressor_convert (GConverter *converter,
                                  GError    **error)
 {
     YelpMagicDecompressor *decompressor;
+    gsize txfer_size;
 
     decompressor = YELP_MAGIC_DECOMPRESSOR (converter);
 
     if (decompressor->first) {
+        decompressor->magic_decoder_ring =
+            yelp_magic_decompressor_choose (inbuf, inbuf_size);
         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)
-            ;
-#ifdef ENABLE_BZ2
-        else if (((gchar *) inbuf)[0] == 'B' &&
-                 ((gchar *) inbuf)[1] == 'Z') {
-            decompressor->magic_decoder_ring = (GConverter *) yelp_bz2_decompressor_new ();
-        }
-#endif
-#ifdef ENABLE_LZMA
-        else if (((gchar *) inbuf)[0] == ']' &&
-                 ((gchar *) inbuf)[1] == '\0') {
-            decompressor->magic_decoder_ring = (GConverter *) yelp_lzma_decompressor_new ();
-        }
-#endif
-        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);
+    if (decompressor->magic_decoder_ring) {
+        return g_converter_convert (decompressor->magic_decoder_ring,
+                                    inbuf, inbuf_size,
+                                    outbuf, outbuf_size,
+                                    flags,
+                                    bytes_read, bytes_written,
+                                    error);
+    }
 
-    g_assert_not_reached ();
+    /* If there's no magic_decoder_ring, we just copy the data
+     * straight through. */
+    txfer_size = MIN (inbuf_size, outbuf_size);
+    memcpy (outbuf, inbuf, txfer_size);
+    *bytes_read = txfer_size;
+    *bytes_written = txfer_size;
+    
+    return G_CONVERTER_CONVERTED;
 }
 
 static void



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