diff options
Diffstat (limited to 'erts/emulator/drivers/common')
| -rw-r--r-- | erts/emulator/drivers/common/zlib_drv.c | 58 | 
1 files changed, 43 insertions, 15 deletions
| 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; | 
