NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
lz4.c
Go to the documentation of this file.
1 
30 #include "config.h"
31 #include <stddef.h>
32 #include <lz4.h>
33 #include "private.h"
34 #include "mutt/lib.h"
35 #include "lib.h"
36 
37 #define MIN_COMP_LEVEL 1
38 #define MAX_COMP_LEVEL 12
39 
40 
44 {
45  void *buf;
46  short level;
47 };
48 
52 static void *compr_lz4_open(short level)
53 {
54  struct ComprLz4Ctx *ctx = mutt_mem_malloc(sizeof(struct ComprLz4Ctx));
55 
56  ctx->buf = mutt_mem_malloc(LZ4_compressBound(1024 * 32));
57 
58  if ((level < MIN_COMP_LEVEL) || (level > MAX_COMP_LEVEL))
59  {
60  mutt_debug(LL_DEBUG1, "The compression level for %s should be between %d and %d",
62  level = MIN_COMP_LEVEL;
63  }
64 
65  ctx->level = level;
66 
67  return ctx;
68 }
69 
73 static void *compr_lz4_compress(void *cctx, const char *data, size_t dlen, size_t *clen)
74 {
75  if (!cctx)
76  return NULL;
77 
78  struct ComprLz4Ctx *ctx = cctx;
79 
80  int datalen = dlen;
81  int len = LZ4_compressBound(dlen);
82  mutt_mem_realloc(&ctx->buf, len + 4);
83  char *cbuf = ctx->buf;
84 
85  len = LZ4_compress_fast(data, cbuf + 4, datalen, len, ctx->level);
86  if (len == 0)
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_lz4_decompress(void *cctx, const char *cbuf, size_t clen)
107 {
108  if (!cctx)
109  return NULL;
110 
111  struct ComprLz4Ctx *ctx = cctx;
112 
113  /* first 4 bytes store the size */
114  const unsigned char *cs = (const unsigned char *) cbuf;
115  size_t ulen = cs[0] + (cs[1] << 8) + (cs[2] << 16) + ((size_t) cs[3] << 24);
116  if (ulen == 0)
117  return (void *) cbuf;
118 
119  mutt_mem_realloc(&ctx->buf, ulen);
120  void *ubuf = ctx->buf;
121  const char *data = cbuf;
122  int ret = LZ4_decompress_safe(data + 4, ubuf, clen - 4, ulen);
123  if (ret < 0)
124  return NULL;
125 
126  return ubuf;
127 }
128 
132 static void compr_lz4_close(void **cctx)
133 {
134  if (!cctx || !*cctx)
135  return;
136 
137  struct ComprLz4Ctx *ctx = *cctx;
138 
139  FREE(&ctx->buf);
140  FREE(cctx);
141 }
142 
static void * compr_lz4_open(short level)
Implements ComprOps::open() -.
Definition: lz4.c:52
#define MIN_COMP_LEVEL
Minimum compression level for lz4.
Definition: lz4.c:37
#define COMPRESS_OPS(_name, _min_level, _max_level)
Definition: private.h:26
#define MAX_COMP_LEVEL
Maximum compression level for lz4.
Definition: lz4.c:38
const struct ComprOps compr_lz4_ops
const char * name
Compression name.
Definition: lib.h:61
Shared constants/structs that are private to Compression.
API for the header cache compression.
Private Lz4 Compression Context.
Definition: lz4.c:43
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
static void compr_lz4_close(void **cctx)
Implements ComprOps::close() -.
Definition: lz4.c:132
short level
Compression Level to be used.
Definition: lz4.c:46
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define mutt_debug(LEVEL,...)
Definition: logging.h:85
static void * compr_lz4_compress(void *cctx, const char *data, size_t dlen, size_t *clen)
Implements ComprOps::compress() -.
Definition: lz4.c:73
Log at debug level 1.
Definition: logging.h:40
#define FREE(x)
Definition: memory.h:40
static void * compr_lz4_decompress(void *cctx, const char *cbuf, size_t clen)
Implements ComprOps::decompress() -.
Definition: lz4.c:106
void * buf
Temporary buffer.
Definition: lz4.c:45
Convenience wrapper for the library headers.