Update copyright year to 2015
[emacs.git] / src / decompress.c
blob3c0ef10cea5a36fd6aec1e5432c02e614f87ac0a
1 /* Interface to zlib.
2 Copyright (C) 2013-2015 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
19 #include <config.h>
21 #ifdef HAVE_ZLIB
23 #include <zlib.h>
25 #include "lisp.h"
26 #include "character.h"
27 #include "buffer.h"
29 #include <verify.h>
31 static Lisp_Object Qzlib_dll;
33 #ifdef WINDOWSNT
34 # include <windows.h>
35 # include "w32.h"
37 DEF_DLL_FN (int, inflateInit2_,
38 (z_streamp strm, int windowBits, const char *version,
39 int stream_size));
40 DEF_DLL_FN (int, inflate, (z_streamp strm, int flush));
41 DEF_DLL_FN (int, inflateEnd, (z_streamp strm));
43 static bool zlib_initialized;
45 static bool
46 init_zlib_functions (void)
48 HMODULE library = w32_delayed_load (Qzlib_dll);
50 if (!library)
51 return false;
53 LOAD_DLL_FN (library, inflateInit2_);
54 LOAD_DLL_FN (library, inflate);
55 LOAD_DLL_FN (library, inflateEnd);
56 return true;
59 # undef inflate
60 # undef inflateEnd
61 # undef inflateInit2_
63 # define inflate fn_inflate
64 # define inflateEnd fn_inflateEnd
65 # define inflateInit2_ fn_inflateInit2_
67 #endif /* WINDOWSNT */
70 struct decompress_unwind_data
72 ptrdiff_t old_point, start, nbytes;
73 z_stream *stream;
76 static void
77 unwind_decompress (void *ddata)
79 struct decompress_unwind_data *data = ddata;
80 inflateEnd (data->stream);
82 /* Delete any uncompressed data already inserted on error. */
83 if (data->start)
84 del_range (data->start, data->start + data->nbytes);
86 /* Put point where it was, or if the buffer has shrunk because the
87 compressed data is bigger than the uncompressed, at
88 point-max. */
89 SET_PT (min (data->old_point, ZV));
92 DEFUN ("zlib-available-p", Fzlib_available_p, Szlib_available_p, 0, 0, 0,
93 doc: /* Return t if zlib decompression is available in this instance of Emacs. */)
94 (void)
96 #ifdef WINDOWSNT
97 Lisp_Object found = Fassq (Qzlib_dll, Vlibrary_cache);
98 if (CONSP (found))
99 return XCDR (found);
100 else
102 Lisp_Object status;
103 zlib_initialized = init_zlib_functions ();
104 status = zlib_initialized ? Qt : Qnil;
105 Vlibrary_cache = Fcons (Fcons (Qzlib_dll, status), Vlibrary_cache);
106 return status;
108 #else
109 return Qt;
110 #endif
113 DEFUN ("zlib-decompress-region", Fzlib_decompress_region,
114 Szlib_decompress_region,
115 2, 2, 0,
116 doc: /* Decompress a gzip- or zlib-compressed region.
117 Replace the text in the region by the decompressed data.
118 On failure, return nil and leave the data in place.
119 This function can be called only in unibyte buffers. */)
120 (Lisp_Object start, Lisp_Object end)
122 ptrdiff_t istart, iend, pos_byte;
123 z_stream stream;
124 int inflate_status;
125 struct decompress_unwind_data unwind_data;
126 ptrdiff_t count = SPECPDL_INDEX ();
128 validate_region (&start, &end);
130 if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
131 error ("This function can be called only in unibyte buffers");
133 #ifdef WINDOWSNT
134 if (!zlib_initialized)
135 zlib_initialized = init_zlib_functions ();
136 if (!zlib_initialized)
138 message1 ("zlib library not found");
139 return Qnil;
141 #endif
143 /* This is a unibyte buffer, so character positions and bytes are
144 the same. */
145 istart = XINT (start);
146 iend = XINT (end);
147 move_gap_both (iend, iend);
149 stream.zalloc = Z_NULL;
150 stream.zfree = Z_NULL;
151 stream.opaque = Z_NULL;
152 stream.avail_in = 0;
153 stream.next_in = Z_NULL;
155 /* The magic number 32 apparently means "autodetect both the gzip and
156 zlib formats" according to zlib.h. */
157 if (inflateInit2 (&stream, MAX_WBITS + 32) != Z_OK)
158 return Qnil;
160 unwind_data.start = iend;
161 unwind_data.stream = &stream;
162 unwind_data.old_point = PT;
163 unwind_data.nbytes = 0;
164 record_unwind_protect_ptr (unwind_decompress, &unwind_data);
166 /* Insert the decompressed data at the end of the compressed data. */
167 SET_PT (iend);
169 pos_byte = istart;
171 /* Keep calling 'inflate' until it reports an error or end-of-input. */
174 /* Maximum number of bytes that one 'inflate' call should read and write.
175 Do not make avail_out too large, as that might unduly delay C-g.
176 zlib requires that avail_in and avail_out not exceed UINT_MAX. */
177 ptrdiff_t avail_in = min (iend - pos_byte, UINT_MAX);
178 int avail_out = 16 * 1024;
179 int decompressed;
181 if (GAP_SIZE < avail_out)
182 make_gap (avail_out - GAP_SIZE);
183 stream.next_in = BYTE_POS_ADDR (pos_byte);
184 stream.avail_in = avail_in;
185 stream.next_out = GPT_ADDR;
186 stream.avail_out = avail_out;
187 inflate_status = inflate (&stream, Z_NO_FLUSH);
188 pos_byte += avail_in - stream.avail_in;
189 decompressed = avail_out - stream.avail_out;
190 insert_from_gap (decompressed, decompressed, 0);
191 unwind_data.nbytes += decompressed;
192 QUIT;
194 while (inflate_status == Z_OK);
196 if (inflate_status != Z_STREAM_END)
197 return unbind_to (count, Qnil);
199 unwind_data.start = 0;
201 /* Delete the compressed data. */
202 del_range (istart, iend);
204 return unbind_to (count, Qt);
208 /***********************************************************************
209 Initialization
210 ***********************************************************************/
211 void
212 syms_of_decompress (void)
214 DEFSYM (Qzlib_dll, "zlib");
215 defsubr (&Szlib_decompress_region);
216 defsubr (&Szlib_available_p);
219 #endif /* HAVE_ZLIB */