]> wimlib.net Git - wimlib/blobdiff - src/compress_serial.c
Add WIMLIB_ERR_WIM_IS_INCOMPLETE
[wimlib] / src / compress_serial.c
index 0ae354834286b8e84db6987e7391df262f2df89e..6bac63ec8f9b2037bf720c82d69649264eddc006 100644 (file)
@@ -7,39 +7,39 @@
 /*
  * Copyright (C) 2013 Eric Biggers
  *
- * This file is part of wimlib, a library for working with WIM files.
+ * 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 3 of the License, or (at your option) any
+ * later version.
  *
- * wimlib 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 3 of the License, or (at your option) any later
- * version.
+ * This file 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.
  *
- * wimlib 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
- * wimlib; if not, see http://www.gnu.org/licenses/.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this file; if not, see http://www.gnu.org/licenses/.
  */
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
 #endif
 
+#include <string.h>
+
 #include "wimlib.h"
 #include "wimlib/assert.h"
 #include "wimlib/chunk_compressor.h"
 #include "wimlib/util.h"
 
-#include <string.h>
-
 struct serial_chunk_compressor {
        struct chunk_compressor base;
        struct wimlib_compressor *compressor;
        u8 *udata;
        u8 *cdata;
-       unsigned ulen;
-       unsigned clen;
+       u32 usize;
+       u8 *result_data;
+       u32 result_size;
 };
 
 static void
@@ -56,47 +56,52 @@ serial_chunk_compressor_destroy(struct chunk_compressor *_ctx)
        FREE(ctx);
 }
 
-static bool
-serial_chunk_compressor_submit_chunk(struct chunk_compressor *_ctx,
-                                    const void *chunk, size_t size)
+static void *
+serial_chunk_compressor_get_chunk_buffer(struct chunk_compressor *_ctx)
 {
        struct serial_chunk_compressor *ctx = (struct serial_chunk_compressor*)_ctx;
 
-       if (ctx->ulen != 0)
-               return false;
+       if (ctx->result_data)
+               return NULL;
+       return ctx->udata;
+}
 
-       wimlib_assert(size > 0);
-       wimlib_assert(size <= ctx->base.out_chunk_size);
+static void
+serial_chunk_compressor_signal_chunk_filled(struct chunk_compressor *_ctx, u32 usize)
+{
+       struct serial_chunk_compressor *ctx = (struct serial_chunk_compressor*)_ctx;
+       u32 csize;
 
-       memcpy(ctx->udata, chunk, size);
-       ctx->ulen = size;
-       return true;
+       wimlib_assert(usize > 0);
+       wimlib_assert(usize <= ctx->base.out_chunk_size);
+
+       ctx->usize = usize;
+       csize = wimlib_compress(ctx->udata, usize, ctx->cdata, usize - 1,
+                               ctx->compressor);
+       if (csize) {
+               ctx->result_data = ctx->cdata;
+               ctx->result_size = csize;
+       } else {
+               ctx->result_data = ctx->udata;
+               ctx->result_size = ctx->usize;
+       }
 }
 
 static bool
-serial_chunk_compressor_get_chunk(struct chunk_compressor *_ctx,
-                                 const void **cdata_ret, unsigned *csize_ret,
-                                 unsigned *usize_ret)
+serial_chunk_compressor_get_compression_result(struct chunk_compressor *_ctx,
+                                              const void **cdata_ret, u32 *csize_ret,
+                                              u32 *usize_ret)
 {
-       struct serial_chunk_compressor *ctx = (struct serial_chunk_compressor*)_ctx;
+       struct serial_chunk_compressor *ctx = (struct serial_chunk_compressor *)_ctx;
 
-       if (ctx->ulen == 0)
+       if (!ctx->result_data)
                return false;
 
-       ctx->clen = wimlib_compress(ctx->udata, ctx->ulen,
-                                   ctx->cdata, ctx->ulen - 1,
-                                   ctx->compressor);
+       *cdata_ret = ctx->result_data;
+       *csize_ret = ctx->result_size;
+       *usize_ret = ctx->usize;
 
-       if (ctx->clen) {
-               *cdata_ret = ctx->cdata;
-               *csize_ret = ctx->clen;
-       } else {
-               *cdata_ret = ctx->udata;
-               *csize_ret = ctx->ulen;
-       }
-       *usize_ret = ctx->ulen;
-
-       ctx->ulen = 0;
+       ctx->result_data = NULL;
        return true;
 }
 
@@ -107,6 +112,8 @@ new_serial_chunk_compressor(int out_ctype, u32 out_chunk_size,
        struct serial_chunk_compressor *ctx;
        int ret;
 
+       wimlib_assert(out_chunk_size > 0);
+
        ctx = CALLOC(1, sizeof(*ctx));
        if (ctx == NULL)
                return WIMLIB_ERR_NOMEM;
@@ -115,22 +122,23 @@ new_serial_chunk_compressor(int out_ctype, u32 out_chunk_size,
        ctx->base.out_chunk_size = out_chunk_size;
        ctx->base.num_threads = 1;
        ctx->base.destroy = serial_chunk_compressor_destroy;
-       ctx->base.submit_chunk = serial_chunk_compressor_submit_chunk;
-       ctx->base.get_chunk = serial_chunk_compressor_get_chunk;
-
+       ctx->base.get_chunk_buffer = serial_chunk_compressor_get_chunk_buffer;
+       ctx->base.signal_chunk_filled = serial_chunk_compressor_signal_chunk_filled;
+       ctx->base.get_compression_result = serial_chunk_compressor_get_compression_result;
 
        ret = wimlib_create_compressor(out_ctype, out_chunk_size,
-                                      NULL, &ctx->compressor);
+                                      WIMLIB_COMPRESSOR_FLAG_DESTRUCTIVE,
+                                      &ctx->compressor);
        if (ret)
                goto err;
 
        ctx->udata = MALLOC(out_chunk_size);
        ctx->cdata = MALLOC(out_chunk_size - 1);
-       ctx->ulen = 0;
        if (ctx->udata == NULL || ctx->cdata == NULL) {
                ret = WIMLIB_ERR_NOMEM;
                goto err;
        }
+       ctx->result_data = NULL;
 
        *compressor_ret = &ctx->base;
        return 0;