aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2016-08-26 15:53:51 +0200
committerLukas Larsson <[email protected]>2016-08-26 15:53:51 +0200
commit85234b4069c9b75e3ae5ddf643b981d7428fb81f (patch)
treeaa52443a80eecf23664cf56ed74cb395cab5a96c /erts
parentd017ade88b8fa39f57aee722dd2e2c5d82e8b262 (diff)
parent6fe89e38d40132e6acac2233d45ea44da49d1021 (diff)
downloadotp-85234b4069c9b75e3ae5ddf643b981d7428fb81f.tar.gz
otp-85234b4069c9b75e3ae5ddf643b981d7428fb81f.tar.bz2
otp-85234b4069c9b75e3ae5ddf643b981d7428fb81f.zip
Merge branch 'g-andrade/kernel/fetch_ztream_dictionary/PR-1139/OTP-13842'
* g-andrade/kernel/fetch_ztream_dictionary/PR-1139/OTP-13842: Update preloaded modules Specify min zlib ver on inflateGetDictionary doc Skip inflateGetDictionary test case if unsupported zlib: Only link inflateGetDictionary if available zlib: Add test case for inflateGetDictionary zlib: support extraction of inflation dictionary
Diffstat (limited to 'erts')
-rw-r--r--erts/configure.in7
-rw-r--r--erts/doc/src/zlib.xml12
-rw-r--r--erts/emulator/drivers/common/zlib_drv.c58
-rw-r--r--erts/preloaded/ebin/zlib.beambin14136 -> 14320 bytes
-rw-r--r--erts/preloaded/src/zlib.erl41
5 files changed, 87 insertions, 31 deletions
diff --git a/erts/configure.in b/erts/configure.in
index b1830979aa..9f3d267791 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -1359,6 +1359,8 @@ AC_ARG_ENABLE(builtin-zlib,
Z_LIB=
if test "x$enable_builtin_zlib" = "xyes"; then
+ AC_DEFINE(HAVE_ZLIB_INFLATEGETDICTIONARY, 1,
+ [Define if your zlib version defines inflateGetDictionary.])
AC_MSG_NOTICE([Using our own built-in zlib source])
else
AC_MSG_CHECKING(for zlib 1.2.5 or higher)
@@ -1385,6 +1387,11 @@ error
AC_MSG_RESULT(no)
])
LIBS=$zlib_save_LIBS
+
+AC_MSG_CHECKING(for zlib inflateGetDictionary presence)
+AC_SEARCH_LIBS(inflateGetDictionary, [z],
+ AC_DEFINE(HAVE_ZLIB_INFLATEGETDICTIONARY, 1,
+ [Define if your zlib version defines inflateGetDictionary.]))
fi
AC_SUBST(Z_LIB)
diff --git a/erts/doc/src/zlib.xml b/erts/doc/src/zlib.xml
index 138414a880..e1924fffee 100644
--- a/erts/doc/src/zlib.xml
+++ b/erts/doc/src/zlib.xml
@@ -576,6 +576,18 @@ unpack(Z, Compressed, Dict) ->
</func>
<func>
+ <name name="inflateGetDictionary" arity="1"/>
+ <fsummary>Return the decompression dictionary.</fsummary>
+ <desc>
+ <p>Returns the decompression dictionary currently in use
+ by the stream. This function must be called between
+ <seealso marker="#inflateInit/1"><c>inflateInit/1,2</c></seealso>
+ and <seealso marker="#inflateEnd/1"><c>inflateEnd</c></seealso>.</p>
+ <p>Only supported if ERTS was compiled with zlib >= 1.2.8.</p>
+ </desc>
+ </func>
+
+ <func>
<name name="open" arity="0"/>
<fsummary>Open a stream and return a stream reference.</fsummary>
<desc>
diff --git a/erts/emulator/drivers/common/zlib_drv.c b/erts/emulator/drivers/common/zlib_drv.c
index 440ba956d8..066cf87c9d 100644
--- a/erts/emulator/drivers/common/zlib_drv.c
+++ b/erts/emulator/drivers/common/zlib_drv.c
@@ -44,30 +44,34 @@
#define INFLATE_INIT 8
#define INFLATE_INIT2 9
#define INFLATE_SETDICT 10
-#define INFLATE_SYNC 11
-#define INFLATE_RESET 12
-#define INFLATE_END 13
-#define INFLATE 14
+#define INFLATE_GETDICT 11
+#define INFLATE_SYNC 12
+#define INFLATE_RESET 13
+#define INFLATE_END 14
+#define INFLATE 15
-#define CRC32_0 15
-#define CRC32_1 16
-#define CRC32_2 17
+#define CRC32_0 16
+#define CRC32_1 17
+#define CRC32_2 18
-#define SET_BUFSZ 18
-#define GET_BUFSZ 19
-#define GET_QSIZE 20
+#define SET_BUFSZ 19
+#define GET_BUFSZ 20
+#define GET_QSIZE 21
-#define ADLER32_1 21
-#define ADLER32_2 22
+#define ADLER32_1 22
+#define ADLER32_2 23
-#define CRC32_COMBINE 23
-#define ADLER32_COMBINE 24
+#define CRC32_COMBINE 24
+#define ADLER32_COMBINE 25
-#define INFLATE_CHUNK 25
+#define INFLATE_CHUNK 26
#define DEFAULT_BUFSZ 4000
+/* According to zlib documentation, it can never exceed this */
+#define INFL_DICT_SZ 32768
+
/* This flag is used in the same places, where zlib return codes
* (Z_OK, Z_STREAM_END, Z_NEED_DICT) are. So, we need to set it to
* relatively large value to avoid possible value clashes in future.
@@ -248,6 +252,20 @@ static int zlib_output(ZLibData* d)
return zlib_output_init(d);
}
+#ifdef HAVE_ZLIB_INFLATEGETDICTIONARY
+static int zlib_inflate_get_dictionary(ZLibData* d)
+{
+ ErlDrvBinary* dbin = driver_alloc_binary(INFL_DICT_SZ);
+ uInt dlen = 0;
+ int res = inflateGetDictionary(&d->s, (unsigned char*)dbin->orig_bytes, &dlen);
+ if ((res == Z_OK) && (driver_output_binary(d->port, NULL, 0, dbin, 0, dlen) < 0)) {
+ res = Z_ERRNO;
+ }
+ driver_free_binary(dbin);
+ return res;
+}
+#endif
+
static int zlib_inflate(ZLibData* d, int flush)
{
int res = Z_OK;
@@ -586,6 +604,16 @@ static ErlDrvSSizeT zlib_ctl(ErlDrvData drv_data, unsigned int command, char *bu
res = inflateSetDictionary(&d->s, (unsigned char*)buf, len);
return zlib_return(res, rbuf, rlen);
+ case INFLATE_GETDICT:
+#ifdef HAVE_ZLIB_INFLATEGETDICTIONARY
+ if (d->state != ST_INFLATE) goto badarg;
+ res = zlib_inflate_get_dictionary(d);
+ return zlib_return(res, rbuf, rlen);
+#else
+ errno = ENOTSUP;
+ return zlib_return(Z_ERRNO, rbuf, rlen);
+#endif
+
case INFLATE_SYNC:
if (d->state != ST_INFLATE) goto badarg;
if (len != 0) goto badarg;
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index 4c48742344..6a7ad9164f 100644
--- a/erts/preloaded/ebin/zlib.beam
+++ b/erts/preloaded/ebin/zlib.beam
Binary files differ
diff --git a/erts/preloaded/src/zlib.erl b/erts/preloaded/src/zlib.erl
index fa0f28c5c3..8cd3e39fd7 100644
--- a/erts/preloaded/src/zlib.erl
+++ b/erts/preloaded/src/zlib.erl
@@ -23,7 +23,8 @@
-export([open/0,close/1,deflateInit/1,deflateInit/2,deflateInit/6,
deflateSetDictionary/2,deflateReset/1,deflateParams/3,
deflate/2,deflate/3,deflateEnd/1,
- inflateInit/1,inflateInit/2,inflateSetDictionary/2,
+ inflateInit/1,inflateInit/2,
+ inflateSetDictionary/2,inflateGetDictionary/1,
inflateSync/1,inflateReset/1,inflate/2,inflateEnd/1,
inflateChunk/1, inflateChunk/2,
setBufSize/2,getBufSize/1,
@@ -98,25 +99,26 @@
-define(INFLATE_INIT, 8).
-define(INFLATE_INIT2, 9).
-define(INFLATE_SETDICT, 10).
--define(INFLATE_SYNC, 11).
--define(INFLATE_RESET, 12).
--define(INFLATE_END, 13).
--define(INFLATE, 14).
--define(INFLATE_CHUNK, 25).
+-define(INFLATE_GETDICT, 11).
+-define(INFLATE_SYNC, 12).
+-define(INFLATE_RESET, 13).
+-define(INFLATE_END, 14).
+-define(INFLATE, 15).
+-define(INFLATE_CHUNK, 26).
--define(CRC32_0, 15).
--define(CRC32_1, 16).
--define(CRC32_2, 17).
+-define(CRC32_0, 16).
+-define(CRC32_1, 17).
+-define(CRC32_2, 18).
--define(SET_BUFSZ, 18).
--define(GET_BUFSZ, 19).
--define(GET_QSIZE, 20).
+-define(SET_BUFSZ, 19).
+-define(GET_BUFSZ, 20).
+-define(GET_QSIZE, 21).
--define(ADLER32_1, 21).
--define(ADLER32_2, 22).
+-define(ADLER32_1, 22).
+-define(ADLER32_2, 23).
--define(CRC32_COMBINE, 23).
--define(ADLER32_COMBINE, 24).
+-define(CRC32_COMBINE, 24).
+-define(ADLER32_COMBINE, 25).
%%------------------------------------------------------------------------
@@ -242,6 +244,13 @@ inflateInit(Z, WindowBits) ->
inflateSetDictionary(Z, Dictionary) ->
call(Z, ?INFLATE_SETDICT, Dictionary).
+-spec inflateGetDictionary(Z) -> Dictionary when
+ Z :: zstream(),
+ Dictionary :: iolist().
+inflateGetDictionary(Z) ->
+ _ = call(Z, ?INFLATE_GETDICT, []),
+ collect(Z).
+
-spec inflateSync(zstream()) -> 'ok'.
inflateSync(Z) ->
call(Z, ?INFLATE_SYNC, []).