NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
zlib.c
Go to the documentation of this file.
1 
30 #include "config.h"
31 #include <stddef.h>
32 #include <zconf.h>
33 #include <zlib.h>
34 #include "private.h"
35 #include "mutt/lib.h"
36 #include "lib.h"
37 
38 #define MIN_COMP_LEVEL 1
39 #define MAX_COMP_LEVEL 9
40 
41 
45 {
46  void *buf;
47  short level;
48 };
49 
53 static void *compr_zlib_open(short level)
54 {
55  struct ComprZlibCtx *ctx = mutt_mem_malloc(sizeof(struct ComprZlibCtx));
56 
57  ctx->buf = mutt_mem_malloc(compressBound(1024 * 32));
58 
59  if ((level < MIN_COMP_LEVEL) || (level > MAX_COMP_LEVEL))
60  {
61  mutt_debug(LL_DEBUG1, "The compression level for %s should be between %d and %d",
63  level = MIN_COMP_LEVEL;
64  }
65 
66  ctx->level = level;
67 
68  return ctx;
69 }
70 
74 static void *compr_zlib_compress(void *cctx, const char *data, size_t dlen, size_t *clen)
75 {
76  if (!cctx)
77  return NULL;
78 
79  struct ComprZlibCtx *ctx = cctx;
80 
81  uLong len = compressBound(dlen);
82  mutt_mem_realloc(&ctx->buf, len + 4);
83  Bytef *cbuf = (unsigned char *) ctx->buf + 4;
84  const void *ubuf = data;
85  int rc = compress2(cbuf, &len, ubuf, dlen, ctx->level);
86  if (rc != Z_OK)
87  return NULL; // LCOV_EXCL_LINE
88  *clen = len + 4;
89 
90  /* save ulen to first 4 bytes */
91  unsigned char *cs = ctx->buf;
92  cs[0] = dlen & 0xff;
93  dlen >>= 8;
94  cs[1] = dlen & 0xff;
95  dlen >>= 8;
96  cs[2] = dlen & 0xff;
97  dlen >>= 8;
98  cs[3] = dlen & 0xff;
99 
100  return ctx->buf;
101 }
102 
106 static void *compr_zlib_decompress(void *cctx, const char *cbuf, size_t clen)
107 {
108  if (!cctx)
109  return NULL;
110 
111  struct ComprZlibCtx *ctx = cctx;
112 
113  /* first 4 bytes store the size */
114  const unsigned char *cs = (const unsigned char *) cbuf;
115  uLong ulen = cs[0] + (cs[1] << 8) + (cs[2] << 16) + ((uLong) cs[3] << 24);
116  if (ulen == 0)
117  return NULL;
118 
119  mutt_mem_realloc(&ctx->buf, ulen);
120  Bytef *ubuf = ctx->buf;
121  cs = (const unsigned char *) cbuf;
122  int ret = uncompress(ubuf, &ulen, cs + 4, clen - 4);
123  if (ret != Z_OK)
124  return NULL;
125 
126  return ubuf;
127 }
128 
132 static void compr_zlib_close(void **cctx)
133 {
134  if (!cctx || !*cctx)
135  return;
136 
137  struct ComprZlibCtx *ctx = *cctx;
138 
139  FREE(&ctx->buf);
140  FREE(cctx);
141 }
142 
Private Zlib Compression Context.
Definition: zlib.c:44
#define COMPRESS_OPS(_name, _min_level, _max_level)
Definition: private.h:26
#define MIN_COMP_LEVEL
Minimum compression level for zlib.
Definition: zlib.c:38
const char * name
Compression name.
Definition: lib.h:61
static void * compr_zlib_decompress(void *cctx, const char *cbuf, size_t clen)
Implements ComprOps::decompress() -.
Definition: zlib.c:106
Shared constants/structs that are private to Compression.
API for the header cache compression.
static void compr_zlib_close(void **cctx)
Implements ComprOps::close() -.
Definition: zlib.c:132
#define MAX_COMP_LEVEL
Maximum compression level for zlib.
Definition: zlib.c:39
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
static void * compr_zlib_open(short level)
Implements ComprOps::open() -.
Definition: zlib.c:53
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
const struct ComprOps compr_zlib_ops
Log at debug level 1.
Definition: logging.h:40
short level
Compression Level to be used.
Definition: zlib.c:47
#define FREE(x)
Definition: memory.h:40
Convenience wrapper for the library headers.
void * buf
Temporary buffer.
Definition: zlib.c:46
static void * compr_zlib_compress(void *cctx, const char *data, size_t dlen, size_t *clen)
Implements ComprOps::compress() -.
Definition: zlib.c:74