X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/53b64418c20b6288e0e3a589b61db47861a575b6..84254bbdf069f0386f188d0e2bc5be795a9272bb:/src/decompress.c diff --git a/src/decompress.c b/src/decompress.c index b7cd8a6c40..cd8a3d1e96 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -1,5 +1,5 @@ /* Interface to zlib. - Copyright (C) 2013 Free Software Foundation, Inc. + Copyright (C) 2013-2014 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -85,7 +85,7 @@ init_zlib_functions (void) struct decompress_unwind_data { - ptrdiff_t old_point, start; + ptrdiff_t old_point, start, nbytes; z_stream *stream; }; @@ -95,12 +95,14 @@ unwind_decompress (void *ddata) struct decompress_unwind_data *data = ddata; fn_inflateEnd (data->stream); - /* Delete any uncompressed data already inserted and restore point. */ + /* Delete any uncompressed data already inserted on error. */ if (data->start) - { - del_range (data->start, PT); - SET_PT (data->old_point); - } + del_range (data->start, data->start + data->nbytes); + + /* Put point where it was, or if the buffer has shrunk because the + compressed data is bigger than the uncompressed, at + point-max. */ + SET_PT (min (data->old_point, ZV)); } DEFUN ("zlib-available-p", Fzlib_available_p, Szlib_available_p, 0, 0, 0, @@ -114,7 +116,8 @@ DEFUN ("zlib-available-p", Fzlib_available_p, Szlib_available_p, 0, 0, 0, else { Lisp_Object status; - status = init_zlib_functions () ? Qt : Qnil; + zlib_initialized = init_zlib_functions (); + status = zlib_initialized ? Qt : Qnil; Vlibrary_cache = Fcons (Fcons (Qzlib_dll, status), Vlibrary_cache); return status; } @@ -146,6 +149,8 @@ This function can be called only in unibyte buffers. */) #ifdef WINDOWSNT if (!zlib_initialized) zlib_initialized = init_zlib_functions (); + if (!zlib_initialized) + return Qnil; #endif /* This is a unibyte buffer, so character positions and bytes are @@ -160,7 +165,7 @@ This function can be called only in unibyte buffers. */) stream.avail_in = 0; stream.next_in = Z_NULL; - /* The magic number 32 apparently means "autodect both the gzip and + /* The magic number 32 apparently means "autodetect both the gzip and zlib formats" according to zlib.h. */ if (fn_inflateInit2 (&stream, MAX_WBITS + 32) != Z_OK) return Qnil; @@ -168,7 +173,7 @@ This function can be called only in unibyte buffers. */) unwind_data.start = iend; unwind_data.stream = &stream; unwind_data.old_point = PT; - + unwind_data.nbytes = 0; record_unwind_protect_ptr (unwind_decompress, &unwind_data); /* Insert the decompressed data at the end of the compressed data. */ @@ -181,12 +186,10 @@ This function can be called only in unibyte buffers. */) { /* Maximum number of bytes that one 'inflate' call should read and write. Do not make avail_out too large, as that might unduly delay C-g. - In any case zlib requires that these values not exceed UINT_MAX. */ + zlib requires that avail_in and avail_out not exceed UINT_MAX. */ ptrdiff_t avail_in = min (iend - pos_byte, UINT_MAX); - enum { avail_out = 1 << 14 }; - verify (avail_out <= UINT_MAX); - - ptrdiff_t decompressed; + int avail_out = 16 * 1024; + int decompressed; if (GAP_SIZE < avail_out) make_gap (avail_out - GAP_SIZE); @@ -198,6 +201,7 @@ This function can be called only in unibyte buffers. */) pos_byte += avail_in - stream.avail_in; decompressed = avail_out - stream.avail_out; insert_from_gap (decompressed, decompressed, 0); + unwind_data.nbytes += decompressed; QUIT; } while (inflate_status == Z_OK);