isomorfeus-ferret 0.17.1 → 0.17.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e6d632f920215dd3c9a1b8833a255c2001102baac820a88b322308b023600b1
4
- data.tar.gz: 571a40b2b445f52f3044b732eb9356d0e6f8dd9d7d32e40eaa50ef66cd92b054
3
+ metadata.gz: 9d39decdeae08fb0fa83f242e3162938e10a9a7549ba3efcc1f5fbb06238e695
4
+ data.tar.gz: 89679c3ca82432887764672840965ddcc7633ea64ee5e79c92fbd4a9615e6771
5
5
  SHA512:
6
- metadata.gz: 8ac4670e9bb4bc9e3019593d82901d6aa7a4112996f6c48cefd0b98f87822daac4306331f196e3be1a46189689ed8b02a3787f5568e00071ba5706e43a7bb6b5
7
- data.tar.gz: 86d921d0b200ae74b2b3d86867450d8ab02409e4aa56ddc3fa4f9ba3ae4cf336155202440accffb315996df4dfd89247743b951e4856037f736a36251ab7a724
6
+ metadata.gz: 84b855487d6c7c390be71b36398f38ef016459773f0bd0412b79953ed752acef3a8584a43c455721c145ca95e4f384bee070d20baa25b709ed641cbb8db9ba2d
7
+ data.tar.gz: a229b8f4d6e93ad9b98d8ea87bff6ae124cc75d789302609a2994149264dc1d28f28bde4a24e389b0ee28d935a6b42a7c8671ed2e75ea42db026bd01769ac817
@@ -1,4 +1,6 @@
1
1
  #include <string.h>
2
+ #include "frt_in_stream.h"
3
+ #include "frt_out_stream.h"
2
4
  #include "benchmark.h"
3
5
  #include "frt_config.h"
4
6
  #include "frt_store.h"
@@ -1258,40 +1258,6 @@ frb_iw_add_doc(VALUE self, VALUE rdoc) {
1258
1258
  return self;
1259
1259
  }
1260
1260
 
1261
- /*
1262
- * call-seq:
1263
- * iw.optimize -> iw
1264
- *
1265
- * Optimize the index for searching. This commits any unwritten data to the
1266
- * index and optimizes the index into a single segment to improve search
1267
- * performance. This is an expensive operation and should not be called too
1268
- * often. The best time to call this is at the end of a long batch indexing
1269
- * process. Note that calling the optimize method do not in any way effect
1270
- * indexing speed (except for the time taken to complete the optimization
1271
- * process).
1272
- */
1273
- static VALUE
1274
- frb_iw_optimize(VALUE self) {
1275
- int ex_code = 0;
1276
- const char *msg = NULL;
1277
-
1278
- FrtIndexWriter *iw = (FrtIndexWriter *)DATA_PTR(self);
1279
-
1280
- FRT_TRY
1281
- frt_iw_optimize(iw);
1282
- FRT_XCATCHALL
1283
- ex_code = xcontext.excode;
1284
- msg = xcontext.msg;
1285
- FRT_HANDLED();
1286
- FRT_XENDTRY
1287
-
1288
- if (ex_code && msg) {
1289
- frb_raise(ex_code, msg);
1290
- }
1291
-
1292
- return self;
1293
- }
1294
-
1295
1261
  /*
1296
1262
  * call-seq:
1297
1263
  * iw.commit -> iw
@@ -2811,7 +2777,6 @@ void Init_IndexWriter(void) {
2811
2777
  rb_define_method(cIndexWriter, "close", frb_iw_close, 0);
2812
2778
  rb_define_method(cIndexWriter, "add_document", frb_iw_add_doc, 1);
2813
2779
  rb_define_method(cIndexWriter, "<<", frb_iw_add_doc, 1);
2814
- rb_define_method(cIndexWriter, "optimize", frb_iw_optimize, 0);
2815
2780
  rb_define_method(cIndexWriter, "commit", frb_iw_commit, 0);
2816
2781
  rb_define_method(cIndexWriter, "add_readers", frb_iw_add_readers, 1);
2817
2782
  rb_define_method(cIndexWriter, "delete", frb_iw_delete, 2);
@@ -1,4 +1,5 @@
1
1
  #include <stdarg.h>
2
+ #include "bzlib.h"
2
3
  #include "frt_global.h"
3
4
  #include "frt_except.h"
4
5
  #include "frt_threading.h"
@@ -71,6 +72,47 @@ void frt_xraise(int excode, const char *const msg) {
71
72
  }
72
73
  }
73
74
 
75
+ void frt_comp_raise(void) {
76
+ FRT_RAISE(EXCEPTION, "Compression error");
77
+ }
78
+
79
+ void frt_zraise(int ret) {
80
+ switch (ret) {
81
+ case BZ_IO_ERROR:
82
+ if (ferror(stdin))
83
+ FRT_RAISE(FRT_IO_ERROR, "bzlib: error reading stdin");
84
+ if (ferror(stdout))
85
+ FRT_RAISE(FRT_IO_ERROR, "bzlib: error writing stdout");
86
+ break;
87
+ case BZ_CONFIG_ERROR:
88
+ FRT_RAISE(FRT_IO_ERROR, "bzlib: system configuration error");
89
+ break;
90
+ case BZ_SEQUENCE_ERROR: /* shouldn't occur if code is correct */
91
+ FRT_RAISE(FRT_IO_ERROR, "bzlib: !!BUG!! sequence error");
92
+ break;
93
+ case BZ_PARAM_ERROR: /* shouldn't occur if code is correct */
94
+ FRT_RAISE(FRT_IO_ERROR, "bzlib: !!BUG!! parameter error");
95
+ break;
96
+ case BZ_MEM_ERROR:
97
+ FRT_RAISE(FRT_IO_ERROR, "bzlib: memory error");
98
+ break;
99
+ case BZ_DATA_ERROR:
100
+ FRT_RAISE(FRT_IO_ERROR, "bzlib: data integrity check error");
101
+ break;
102
+ case BZ_DATA_ERROR_MAGIC:
103
+ FRT_RAISE(FRT_IO_ERROR, "bzlib: data integrity check - non-matching magic");
104
+ break;
105
+ case BZ_UNEXPECTED_EOF:
106
+ FRT_RAISE(FRT_IO_ERROR, "bzlib: unexpected end-of-file");
107
+ break;
108
+ case BZ_OUTBUFF_FULL:
109
+ FRT_RAISE(FRT_IO_ERROR, "bzlib: output buffer full");
110
+ break;
111
+ default:
112
+ FRT_RAISE(FRT_EXCEPTION, "bzlib: unknown error");
113
+ }
114
+ }
115
+
74
116
  void frt_xpop_context(void) {
75
117
  frt_xcontext_t *top_cxt, *context;
76
118
  pthread_once(&exception_stack_key_once, *exception_stack_alloc);
@@ -178,6 +178,8 @@ typedef struct frt_xcontext_t
178
178
  extern void FRT_RAISE(int excode, const char *fmt, ...);
179
179
  #endif
180
180
 
181
+ extern void frt_comp_raise(void);
182
+ extern void frt_zraise(int ret);
181
183
  extern void frt_xraise(int excode, const char *const msg);
182
184
  extern void frt_xpush_context(frt_xcontext_t *context);
183
185
  extern void frt_xpop_context();
@@ -0,0 +1,492 @@
1
+ #include "brotli_decode.h"
2
+ #include "brotli_encode.h"
3
+ #include "bzlib.h"
4
+ #include "lz4frame.h"
5
+ #include "frt_except.h"
6
+ #include "frt_in_stream.h"
7
+
8
+ /**
9
+ * Create a newly allocated and initialized InStream
10
+ *
11
+ * @return a newly allocated and initialized InStream
12
+ */
13
+ FrtInStream *frt_is_new(void) {
14
+ FrtInStream *is = FRT_ALLOC(FrtInStream);
15
+ is->f = FRT_ALLOC_AND_ZERO(FrtInStreamFile);
16
+ is->f->ref_cnt = 1;
17
+ is->buf.start = 0;
18
+ is->buf.pos = 0;
19
+ is->buf.len = 0;
20
+ is->ref_cnt = 1;
21
+ return is;
22
+ }
23
+
24
+ /**
25
+ * Refill the InStream's buffer from the store source (filesystem or memory).
26
+ *
27
+ * @param is the InStream to refill
28
+ * @raise FRT_IO_ERROR if there is a error reading from the filesystem
29
+ * @raise FRT_EOF_ERROR if there is an attempt to read past the end of the file
30
+ */
31
+ static void frt_is_refill(FrtInStream *is)
32
+ {
33
+ frt_off_t start = is->buf.start + is->buf.pos;
34
+ frt_off_t last = start + FRT_BUFFER_SIZE;
35
+ frt_off_t flen = is->m->length_i(is);
36
+
37
+ if (last > flen) { /* don't read past EOF */
38
+ last = flen;
39
+ }
40
+
41
+ is->buf.len = last - start;
42
+ if (is->buf.len <= 0) {
43
+ FRT_RAISE(FRT_EOF_ERROR, "current pos = %"FRT_OFF_T_PFX"d, "
44
+ "file length = %"FRT_OFF_T_PFX"d", start, flen);
45
+ }
46
+
47
+ is->m->read_i(is, is->buf.buf, is->buf.len);
48
+
49
+ is->buf.start = start;
50
+ is->buf.pos = 0;
51
+ }
52
+
53
+ /**
54
+ * Unsafe alternative to frt_is_read_byte. Only use this method when you know
55
+ * there is no chance that you will read past the end of the InStream's
56
+ * buffer.
57
+ */
58
+ #define read_byte(is) is->buf.buf[is->buf.pos++]
59
+
60
+ /**
61
+ * Read a singly byte (unsigned char) from the InStream +is+.
62
+ *
63
+ * @param is the Instream to read from
64
+ * @return a single unsigned char read from the InStream +is+
65
+ * @raise FRT_IO_ERROR if there is a error reading from the filesystem
66
+ * @raise FRT_EOF_ERROR if there is an attempt to read past the end of the file
67
+ */
68
+ frt_uchar frt_is_read_byte(FrtInStream *is)
69
+ {
70
+ if (is->buf.pos >= is->buf.len) {
71
+ frt_is_refill(is);
72
+ }
73
+
74
+ return read_byte(is);
75
+ }
76
+
77
+ off_t frt_is_pos(FrtInStream *is)
78
+ {
79
+ return is->buf.start + is->buf.pos;
80
+ }
81
+
82
+ frt_uchar *frt_is_read_bytes(FrtInStream *is, frt_uchar *buf, int len)
83
+ {
84
+ int i;
85
+ frt_off_t start;
86
+
87
+ if ((is->buf.pos + len) < is->buf.len) {
88
+ for (i = 0; i < len; i++) {
89
+ buf[i] = read_byte(is);
90
+ }
91
+ }
92
+ else { /* read all-at-once */
93
+ start = frt_is_pos(is);
94
+ is->m->seek_i(is, start);
95
+ is->m->read_i(is, buf, len);
96
+
97
+ is->buf.start = start + len; /* adjust stream variables */
98
+ is->buf.pos = 0;
99
+ is->buf.len = 0; /* trigger refill on read */
100
+ }
101
+ return buf;
102
+ }
103
+
104
+ void frt_is_seek(FrtInStream *is, frt_off_t pos) {
105
+ if (pos >= is->buf.start && pos < (is->buf.start + is->buf.len)) {
106
+ is->buf.pos = pos - is->buf.start; /* seek within buffer */
107
+ } else {
108
+ is->buf.start = pos;
109
+ is->buf.pos = 0;
110
+ is->buf.len = 0; /* trigger refill() on read() */
111
+ is->m->seek_i(is, pos);
112
+ }
113
+ }
114
+
115
+ void frt_is_close(FrtInStream *is) {
116
+ if (is->ref_cnt == 0) {
117
+ FRT_RAISE(FRT_STATE_ERROR, "is ref_cnt to low\n");
118
+ }
119
+
120
+ if (FRT_DEREF(is) == 0) {
121
+ if (FRT_DEREF(is->f) == 0) {
122
+ is->m->close_i(is);
123
+ free(is->f);
124
+ }
125
+ free(is);
126
+ }
127
+ }
128
+
129
+ FrtInStream *frt_is_clone(FrtInStream *is)
130
+ {
131
+ if (!(is->f))
132
+ return NULL;
133
+ FrtInStream *new_is = FRT_ALLOC(FrtInStream);
134
+ memcpy(new_is, is, sizeof(FrtInStream));
135
+ new_is->ref_cnt = 1;
136
+ FRT_REF(new_is->f);
137
+ return new_is;
138
+ }
139
+
140
+ frt_i32 frt_is_read_i32(FrtInStream *is)
141
+ {
142
+ return ((frt_i32)frt_is_read_byte(is) << 24) |
143
+ ((frt_i32)frt_is_read_byte(is) << 16) |
144
+ ((frt_i32)frt_is_read_byte(is) << 8) |
145
+ ((frt_i32)frt_is_read_byte(is));
146
+ }
147
+
148
+
149
+ frt_i64 frt_is_read_i64(FrtInStream *is)
150
+ {
151
+ return ((frt_i64)frt_is_read_byte(is) << 56) |
152
+ ((frt_i64)frt_is_read_byte(is) << 48) |
153
+ ((frt_i64)frt_is_read_byte(is) << 40) |
154
+ ((frt_i64)frt_is_read_byte(is) << 32) |
155
+ ((frt_i64)frt_is_read_byte(is) << 24) |
156
+ ((frt_i64)frt_is_read_byte(is) << 16) |
157
+ ((frt_i64)frt_is_read_byte(is) << 8) |
158
+ ((frt_i64)frt_is_read_byte(is));
159
+ }
160
+
161
+
162
+ frt_u32 frt_is_read_u32(FrtInStream *is)
163
+ {
164
+ return ((frt_u32)frt_is_read_byte(is) << 24) |
165
+ ((frt_u32)frt_is_read_byte(is) << 16) |
166
+ ((frt_u32)frt_is_read_byte(is) << 8) |
167
+ ((frt_u32)frt_is_read_byte(is));
168
+ }
169
+
170
+ frt_u64 frt_is_read_u64(FrtInStream *is)
171
+ {
172
+ return ((frt_u64)frt_is_read_byte(is) << 56) |
173
+ ((frt_u64)frt_is_read_byte(is) << 48) |
174
+ ((frt_u64)frt_is_read_byte(is) << 40) |
175
+ ((frt_u64)frt_is_read_byte(is) << 32) |
176
+ ((frt_u64)frt_is_read_byte(is) << 24) |
177
+ ((frt_u64)frt_is_read_byte(is) << 16) |
178
+ ((frt_u64)frt_is_read_byte(is) << 8) |
179
+ ((frt_u64)frt_is_read_byte(is));
180
+ }
181
+
182
+
183
+ /* optimized to use unchecked read_byte if there is definitely space */
184
+ unsigned int frt_is_read_vint(FrtInStream *is)
185
+ {
186
+ register unsigned int res, b;
187
+ register int shift = 7;
188
+
189
+ if (is->buf.pos > (is->buf.len - VINT_MAX_LEN)) {
190
+ b = frt_is_read_byte(is);
191
+ res = b & 0x7F; /* 0x7F = 0b01111111 */
192
+
193
+ while ((b & 0x80) != 0) { /* 0x80 = 0b10000000 */
194
+ b = frt_is_read_byte(is);
195
+ res |= (b & 0x7F) << shift;
196
+ shift += 7;
197
+ }
198
+ }
199
+ else { /* unchecked optimization */
200
+ b = read_byte(is);
201
+ res = b & 0x7F; /* 0x7F = 0b01111111 */
202
+
203
+ while ((b & 0x80) != 0) { /* 0x80 = 0b10000000 */
204
+ b = read_byte(is);
205
+ res |= (b & 0x7F) << shift;
206
+ shift += 7;
207
+ }
208
+ }
209
+
210
+ return res;
211
+ }
212
+
213
+
214
+ /* optimized to use unchecked read_byte if there is definitely space */
215
+ off_t frt_is_read_voff_t(FrtInStream *is)
216
+ {
217
+ register frt_off_t res, b;
218
+ register int shift = 7;
219
+
220
+ if (is->buf.pos > (is->buf.len - VINT_MAX_LEN)) {
221
+ b = frt_is_read_byte(is);
222
+ res = b & 0x7F; /* 0x7F = 0b01111111 */
223
+
224
+ while ((b & 0x80) != 0) { /* 0x80 = 0b10000000 */
225
+ b = frt_is_read_byte(is);
226
+ res |= (b & 0x7F) << shift;
227
+ shift += 7;
228
+ }
229
+ }
230
+ else { /* unchecked optimization */
231
+ b = read_byte(is);
232
+ res = b & 0x7F; /* 0x7F = 0b01111111 */
233
+
234
+ while ((b & 0x80) != 0) { /* 0x80 = 0b10000000 */
235
+ b = read_byte(is);
236
+ res |= (b & 0x7F) << shift;
237
+ shift += 7;
238
+ }
239
+ }
240
+
241
+ return res;
242
+ }
243
+
244
+ /* optimized to use unchecked read_byte if there is definitely space */
245
+ frt_u64 frt_is_read_vll(FrtInStream *is)
246
+ {
247
+ register frt_u64 res, b;
248
+ register int shift = 7;
249
+
250
+ if (is->buf.pos > (is->buf.len - VINT_MAX_LEN)) {
251
+ b = frt_is_read_byte(is);
252
+ res = b & 0x7F; /* 0x7F = 0b01111111 */
253
+
254
+ while ((b & 0x80) != 0) { /* 0x80 = 0b10000000 */
255
+ b = frt_is_read_byte(is);
256
+ res |= (b & 0x7F) << shift;
257
+ shift += 7;
258
+ }
259
+ }
260
+ else { /* unchecked optimization */
261
+ b = read_byte(is);
262
+ res = b & 0x7F; /* 0x7F = 0b01111111 */
263
+
264
+ while ((b & 0x80) != 0) { /* 0x80 = 0b10000000 */
265
+ b = read_byte(is);
266
+ res |= (b & 0x7F) << shift;
267
+ shift += 7;
268
+ }
269
+ }
270
+
271
+ return res;
272
+ }
273
+
274
+ void frt_is_skip_vints(FrtInStream *is, register int cnt)
275
+ {
276
+ for (; cnt > 0; cnt--) {
277
+ while ((frt_is_read_byte(is) & 0x80) != 0) {
278
+ }
279
+ }
280
+ }
281
+
282
+ char *frt_is_read_string(FrtInStream *is)
283
+ {
284
+ register int length = (int) frt_is_read_vint(is);
285
+ char *str = FRT_ALLOC_N(char, length + 1);
286
+ str[length] = '\0';
287
+
288
+ if (is->buf.pos > (is->buf.len - length)) {
289
+ register int i;
290
+ for (i = 0; i < length; i++) {
291
+ str[i] = frt_is_read_byte(is);
292
+ }
293
+ }
294
+ else { /* unchecked optimization */
295
+ memcpy(str, is->buf.buf + is->buf.pos, length);
296
+ is->buf.pos += length;
297
+ }
298
+
299
+ return str;
300
+ }
301
+
302
+ char *frt_is_read_string_safe(FrtInStream *is)
303
+ {
304
+ register int length = (int) frt_is_read_vint(is);
305
+ char *str = FRT_ALLOC_N(char, length + 1);
306
+ str[length] = '\0';
307
+
308
+ FRT_TRY
309
+ if (is->buf.pos > (is->buf.len - length)) {
310
+ register int i;
311
+ for (i = 0; i < length; i++) {
312
+ str[i] = frt_is_read_byte(is);
313
+ }
314
+ }
315
+ else { /* unchecked optimization */
316
+ memcpy(str, is->buf.buf + is->buf.pos, length);
317
+ is->buf.pos += length;
318
+ }
319
+ FRT_XCATCHALL
320
+ free(str);
321
+ FRT_XENDTRY
322
+
323
+ return str;
324
+ }
325
+
326
+ static char *frt_is_read_brotli_compressed_bytes(FrtInStream *is, int compressed_len, int *len) {
327
+ int buf_out_idx = 0;
328
+ int read_len;
329
+ frt_uchar buf_in[FRT_COMPRESSION_BUFFER_SIZE];
330
+ const frt_uchar *next_in;
331
+ size_t available_in;
332
+ frt_uchar *buf_out = NULL;
333
+ frt_uchar *next_out;
334
+ size_t available_out;
335
+
336
+ BrotliDecoderState *b_state = BrotliDecoderCreateInstance(NULL, NULL, NULL);
337
+ BrotliDecoderResult b_result = BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT;
338
+ if (!b_state) { frt_comp_raise(); return NULL; }
339
+
340
+ do {
341
+ read_len = (compressed_len > FRT_COMPRESSION_BUFFER_SIZE) ? FRT_COMPRESSION_BUFFER_SIZE : compressed_len;
342
+ frt_is_read_bytes(is, buf_in, read_len);
343
+ compressed_len -= read_len;
344
+ available_in = read_len;
345
+ next_in = buf_in;
346
+ available_out = FRT_COMPRESSION_BUFFER_SIZE;
347
+ do {
348
+ FRT_REALLOC_N(buf_out, frt_uchar, buf_out_idx + FRT_COMPRESSION_BUFFER_SIZE);
349
+ next_out = buf_out + buf_out_idx;
350
+ b_result = BrotliDecoderDecompressStream(b_state,
351
+ &available_in, &next_in,
352
+ &available_out, &next_out, NULL);
353
+ if (b_result == BROTLI_DECODER_RESULT_ERROR) { frt_comp_raise(); return NULL; }
354
+ buf_out_idx += FRT_COMPRESSION_BUFFER_SIZE - available_out;
355
+ } while (b_result == BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT);
356
+ } while (b_result != BROTLI_DECODER_RESULT_SUCCESS && compressed_len > 0);
357
+
358
+ BrotliDecoderDestroyInstance(b_state);
359
+
360
+ FRT_REALLOC_N(buf_out, frt_uchar, buf_out_idx + 1);
361
+ buf_out[buf_out_idx] = '\0';
362
+ *len = buf_out_idx;
363
+ return (char *)buf_out;
364
+ }
365
+
366
+ static char *frt_is_read_bz2_compressed_bytes(FrtInStream *is, int compressed_len, int *len) {
367
+ int buf_out_idx = 0, ret, read_len;
368
+ char *buf_out = NULL;
369
+ char buf_in[FRT_COMPRESSION_BUFFER_SIZE];
370
+ bz_stream zstrm;
371
+ zstrm.bzalloc = NULL;
372
+ zstrm.bzfree = NULL;
373
+ zstrm.opaque = NULL;
374
+ zstrm.next_in = NULL;
375
+ zstrm.avail_in = 0;
376
+ if ((ret = BZ2_bzDecompressInit(&zstrm, 0, 0)) != BZ_OK) frt_zraise(ret);
377
+
378
+ do {
379
+ read_len = (compressed_len > FRT_COMPRESSION_BUFFER_SIZE) ? FRT_COMPRESSION_BUFFER_SIZE : compressed_len;
380
+ frt_is_read_bytes(is, (frt_uchar *)buf_in, read_len);
381
+ compressed_len -= read_len;
382
+ zstrm.avail_in = read_len;
383
+ zstrm.next_in = buf_in;
384
+ zstrm.avail_out = FRT_COMPRESSION_BUFFER_SIZE;
385
+
386
+ do {
387
+ REALLOC_N(buf_out, char, buf_out_idx + FRT_COMPRESSION_BUFFER_SIZE);
388
+ zstrm.next_out = buf_out + buf_out_idx;
389
+ ret = BZ2_bzDecompress(&zstrm);
390
+ assert(ret != BZ_SEQUENCE_ERROR); /* state not clobbered */
391
+ if (ret != BZ_OK && ret != BZ_STREAM_END) {
392
+ (void)BZ2_bzDecompressEnd(&zstrm);
393
+ frt_zraise(ret);
394
+ }
395
+ buf_out_idx += FRT_COMPRESSION_BUFFER_SIZE - zstrm.avail_out;
396
+ } while (zstrm.avail_out == 0);
397
+ } while (ret != BZ_STREAM_END && compressed_len != 0);
398
+
399
+ (void)BZ2_bzDecompressEnd(&zstrm);
400
+
401
+ FRT_REALLOC_N(buf_out, char, buf_out_idx + 1);
402
+ buf_out[buf_out_idx] = '\0';
403
+
404
+ *len = buf_out_idx;
405
+ return (char *)buf_out;
406
+ }
407
+
408
+ static char *frt_is_read_lz4_compressed_bytes(FrtInStream *is, int compressed_len, int *length) {
409
+ frt_uchar buf_in[FRT_COMPRESSION_BUFFER_SIZE];
410
+ char *buf_out = NULL;
411
+ int dc_length = 0;
412
+ LZ4F_dctx *dctx;
413
+ LZ4F_frameInfo_t frame_info;
414
+ LZ4F_errorCode_t dctx_status = LZ4F_createDecompressionContext(&dctx, LZ4F_VERSION);
415
+ if (LZ4F_isError(dctx_status)) { *length = -1; return NULL; }
416
+
417
+ /* header and buffer */
418
+ int read_length = (compressed_len > FRT_COMPRESSION_BUFFER_SIZE) ? FRT_COMPRESSION_BUFFER_SIZE : compressed_len;
419
+ frt_is_read_bytes(is, buf_in, read_length);
420
+ compressed_len -= read_length;
421
+
422
+ size_t consumed_size = read_length;
423
+ size_t res = LZ4F_getFrameInfo(dctx, &frame_info, buf_in, &consumed_size);
424
+ if (LZ4F_isError(res)) { *length = -1; return NULL; }
425
+ size_t buf_out_length;
426
+ switch(frame_info.blockSizeID) {
427
+ case LZ4F_default:
428
+ case LZ4F_max64KB:
429
+ buf_out_length = 1 << 16;
430
+ break;
431
+ case LZ4F_max256KB:
432
+ buf_out_length = 1 << 18;
433
+ break;
434
+ case LZ4F_max1MB:
435
+ buf_out_length = 1 << 20;
436
+ break;
437
+ case LZ4F_max4MB:
438
+ buf_out_length = 1 << 22;
439
+ break;
440
+ default:
441
+ buf_out_length = 0;
442
+ }
443
+
444
+ res = 1;
445
+ int first_chunk = 1;
446
+
447
+ /* decompress data */
448
+ while (res != 0) {
449
+ if (!first_chunk) {
450
+ read_length = (compressed_len > FRT_COMPRESSION_BUFFER_SIZE) ? FRT_COMPRESSION_BUFFER_SIZE : compressed_len;
451
+ frt_is_read_bytes(is, buf_in, read_length);
452
+ compressed_len -= read_length;
453
+ consumed_size = 0;
454
+ }
455
+ first_chunk = 0;
456
+
457
+ char *src = (char *)(buf_in + consumed_size);
458
+ char *src_end = (char *)buf_in + read_length;
459
+
460
+ while (src < src_end && res != 0){
461
+ size_t dest_length = buf_out_length;
462
+ size_t consumed_size = read_length;
463
+ FRT_REALLOC_N(buf_out, char, dc_length + buf_out_length);
464
+ res = LZ4F_decompress(dctx, buf_out + dc_length, &dest_length, src, &consumed_size, NULL);
465
+ if (LZ4F_isError(res)) { *length = -1; return NULL; }
466
+ dc_length += dest_length;
467
+ src = src + consumed_size;
468
+ }
469
+ }
470
+
471
+ /* finish up */
472
+ LZ4F_freeDecompressionContext(dctx);
473
+
474
+ FRT_REALLOC_N(buf_out, char, dc_length + 1);
475
+ buf_out[dc_length] = '\0';
476
+
477
+ *length = dc_length;
478
+ return buf_out;
479
+ }
480
+
481
+ char *frt_is_read_compressed_bytes(FrtInStream *is, int compressed_len, int *len, FrtCompressionType compression) {
482
+ switch (compression) {
483
+ case FRT_COMPRESSION_BROTLI:
484
+ return frt_is_read_brotli_compressed_bytes(is, compressed_len, len);
485
+ case FRT_COMPRESSION_BZ2:
486
+ return frt_is_read_bz2_compressed_bytes(is, compressed_len, len);
487
+ case FRT_COMPRESSION_LZ4:
488
+ return frt_is_read_lz4_compressed_bytes(is, compressed_len, len);
489
+ default:
490
+ return NULL;
491
+ }
492
+ }