isomorfeus-ferret 0.17.1 → 0.17.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/isomorfeus_ferret_ext/benchmark.c +9 -20
- data/ext/isomorfeus_ferret_ext/benchmarks_all.h +1 -2
- data/ext/isomorfeus_ferret_ext/bm_hash.c +1 -2
- data/ext/isomorfeus_ferret_ext/bm_store.c +2 -0
- data/ext/isomorfeus_ferret_ext/brotli_dec_decode.c +4 -2
- data/ext/isomorfeus_ferret_ext/brotli_enc_encode.c +3 -2
- data/ext/isomorfeus_ferret_ext/frb_analysis.c +4 -5
- data/ext/isomorfeus_ferret_ext/frb_field_info.c +3 -4
- data/ext/isomorfeus_ferret_ext/frb_index.c +118 -160
- data/ext/isomorfeus_ferret_ext/frb_lazy_doc.c +14 -16
- data/ext/isomorfeus_ferret_ext/frb_search.c +31 -23
- data/ext/isomorfeus_ferret_ext/frb_store.c +27 -13
- data/ext/isomorfeus_ferret_ext/frb_utils.c +3 -6
- data/ext/isomorfeus_ferret_ext/frt_analysis.c +39 -46
- data/ext/isomorfeus_ferret_ext/frt_analysis.h +9 -9
- data/ext/isomorfeus_ferret_ext/frt_array.c +11 -22
- data/ext/isomorfeus_ferret_ext/frt_bitvector.h +3 -6
- data/ext/isomorfeus_ferret_ext/frt_doc_field.c +87 -0
- data/ext/isomorfeus_ferret_ext/frt_doc_field.h +26 -0
- data/ext/isomorfeus_ferret_ext/frt_document.c +4 -97
- data/ext/isomorfeus_ferret_ext/frt_document.h +2 -27
- data/ext/isomorfeus_ferret_ext/frt_except.c +50 -6
- data/ext/isomorfeus_ferret_ext/frt_except.h +3 -2
- data/ext/isomorfeus_ferret_ext/frt_field_index.c +13 -32
- data/ext/isomorfeus_ferret_ext/frt_field_index.h +0 -6
- data/ext/isomorfeus_ferret_ext/frt_field_info.c +69 -0
- data/ext/isomorfeus_ferret_ext/frt_field_info.h +49 -0
- data/ext/isomorfeus_ferret_ext/frt_field_infos.c +196 -0
- data/ext/isomorfeus_ferret_ext/frt_field_infos.h +35 -0
- data/ext/isomorfeus_ferret_ext/frt_global.c +10 -4
- data/ext/isomorfeus_ferret_ext/frt_global.h +11 -15
- data/ext/isomorfeus_ferret_ext/frt_hash.c +8 -8
- data/ext/isomorfeus_ferret_ext/frt_hash.h +1 -2
- data/ext/isomorfeus_ferret_ext/frt_hashset.c +20 -40
- data/ext/isomorfeus_ferret_ext/frt_hashset.h +1 -2
- data/ext/isomorfeus_ferret_ext/frt_helper.c +7 -15
- data/ext/isomorfeus_ferret_ext/frt_in_stream.c +482 -0
- data/ext/isomorfeus_ferret_ext/frt_in_stream.h +241 -0
- data/ext/isomorfeus_ferret_ext/frt_ind.c +20 -49
- data/ext/isomorfeus_ferret_ext/frt_ind.h +0 -1
- data/ext/isomorfeus_ferret_ext/frt_index.c +296 -1857
- data/ext/isomorfeus_ferret_ext/frt_index.h +2 -145
- data/ext/isomorfeus_ferret_ext/frt_lang.c +5 -10
- data/ext/isomorfeus_ferret_ext/frt_lazy_doc.c +29 -0
- data/ext/isomorfeus_ferret_ext/frt_lazy_doc.h +19 -0
- data/ext/isomorfeus_ferret_ext/frt_lazy_doc_field.c +93 -0
- data/ext/isomorfeus_ferret_ext/frt_lazy_doc_field.h +33 -0
- data/ext/isomorfeus_ferret_ext/frt_mdbx_store.c +102 -70
- data/ext/isomorfeus_ferret_ext/frt_mempool.c +8 -16
- data/ext/isomorfeus_ferret_ext/frt_multimapper.c +23 -46
- data/ext/isomorfeus_ferret_ext/frt_multimapper.h +4 -8
- data/ext/isomorfeus_ferret_ext/frt_out_stream.c +334 -0
- data/ext/isomorfeus_ferret_ext/frt_out_stream.h +198 -0
- data/ext/isomorfeus_ferret_ext/frt_posh.c +6 -819
- data/ext/isomorfeus_ferret_ext/frt_posh.h +0 -57
- data/ext/isomorfeus_ferret_ext/frt_priorityqueue.c +11 -22
- data/ext/isomorfeus_ferret_ext/frt_priorityqueue.h +1 -2
- data/ext/isomorfeus_ferret_ext/frt_q_boolean.c +85 -171
- data/ext/isomorfeus_ferret_ext/frt_q_match_all.c +8 -16
- data/ext/isomorfeus_ferret_ext/frt_q_multi_term.c +1 -2
- data/ext/isomorfeus_ferret_ext/frt_q_parser.c +49 -98
- data/ext/isomorfeus_ferret_ext/frt_q_phrase.c +52 -104
- data/ext/isomorfeus_ferret_ext/frt_q_range.c +6 -12
- data/ext/isomorfeus_ferret_ext/frt_q_span.c +113 -226
- data/ext/isomorfeus_ferret_ext/frt_q_wildcard.c +1 -2
- data/ext/isomorfeus_ferret_ext/frt_ram_store.c +134 -85
- data/ext/isomorfeus_ferret_ext/frt_ram_store.h +12 -0
- data/ext/isomorfeus_ferret_ext/frt_search.c +82 -164
- data/ext/isomorfeus_ferret_ext/frt_similarity.c +11 -22
- data/ext/isomorfeus_ferret_ext/frt_similarity.h +1 -2
- data/ext/isomorfeus_ferret_ext/frt_store.c +13 -536
- data/ext/isomorfeus_ferret_ext/frt_store.h +90 -495
- data/ext/isomorfeus_ferret_ext/frt_stream.h +18 -0
- data/ext/isomorfeus_ferret_ext/frt_term_vectors.c +8 -16
- data/ext/isomorfeus_ferret_ext/frt_win32.h +5 -10
- data/ext/isomorfeus_ferret_ext/isomorfeus_ferret.c +12 -11
- data/ext/isomorfeus_ferret_ext/isomorfeus_ferret.h +11 -13
- data/ext/isomorfeus_ferret_ext/lz4.c +422 -195
- data/ext/isomorfeus_ferret_ext/lz4.h +114 -46
- data/ext/isomorfeus_ferret_ext/lz4frame.c +421 -242
- data/ext/isomorfeus_ferret_ext/lz4frame.h +122 -53
- data/ext/isomorfeus_ferret_ext/lz4hc.c +127 -111
- data/ext/isomorfeus_ferret_ext/lz4hc.h +14 -14
- data/ext/isomorfeus_ferret_ext/lz4xxhash.h +1 -1
- data/ext/isomorfeus_ferret_ext/mdbx.c +3762 -2526
- data/ext/isomorfeus_ferret_ext/mdbx.h +115 -70
- data/ext/isomorfeus_ferret_ext/test.c +40 -87
- data/ext/isomorfeus_ferret_ext/test.h +3 -6
- data/ext/isomorfeus_ferret_ext/test_1710.c +11 -13
- data/ext/isomorfeus_ferret_ext/test_analysis.c +32 -64
- data/ext/isomorfeus_ferret_ext/test_array.c +6 -12
- data/ext/isomorfeus_ferret_ext/test_bitvector.c +12 -24
- data/ext/isomorfeus_ferret_ext/test_document.c +23 -33
- data/ext/isomorfeus_ferret_ext/test_except.c +10 -21
- data/ext/isomorfeus_ferret_ext/test_fields.c +62 -68
- data/ext/isomorfeus_ferret_ext/test_file_deleter.c +15 -24
- data/ext/isomorfeus_ferret_ext/test_filter.c +17 -27
- data/ext/isomorfeus_ferret_ext/test_global.c +14 -29
- data/ext/isomorfeus_ferret_ext/test_hash.c +19 -38
- data/ext/isomorfeus_ferret_ext/test_hashset.c +8 -16
- data/ext/isomorfeus_ferret_ext/test_helper.c +4 -8
- data/ext/isomorfeus_ferret_ext/test_highlighter.c +16 -28
- data/ext/isomorfeus_ferret_ext/test_index.c +277 -495
- data/ext/isomorfeus_ferret_ext/test_lang.c +7 -14
- data/ext/isomorfeus_ferret_ext/test_mdbx_store.c +2 -5
- data/ext/isomorfeus_ferret_ext/test_mempool.c +5 -10
- data/ext/isomorfeus_ferret_ext/test_multimapper.c +3 -6
- data/ext/isomorfeus_ferret_ext/test_priorityqueue.c +9 -18
- data/ext/isomorfeus_ferret_ext/test_q_const_score.c +4 -6
- data/ext/isomorfeus_ferret_ext/test_q_filtered.c +3 -4
- data/ext/isomorfeus_ferret_ext/test_q_fuzzy.c +9 -15
- data/ext/isomorfeus_ferret_ext/test_q_parser.c +8 -16
- data/ext/isomorfeus_ferret_ext/test_q_span.c +19 -35
- data/ext/isomorfeus_ferret_ext/test_ram_store.c +14 -13
- data/ext/isomorfeus_ferret_ext/test_search.c +60 -109
- data/ext/isomorfeus_ferret_ext/test_segments.c +8 -13
- data/ext/isomorfeus_ferret_ext/test_similarity.c +2 -4
- data/ext/isomorfeus_ferret_ext/test_sort.c +14 -24
- data/ext/isomorfeus_ferret_ext/test_store.c +96 -115
- data/ext/isomorfeus_ferret_ext/test_term.c +9 -15
- data/ext/isomorfeus_ferret_ext/test_term_vectors.c +9 -14
- data/ext/isomorfeus_ferret_ext/test_test.c +4 -8
- data/ext/isomorfeus_ferret_ext/test_threading.c +15 -30
- data/ext/isomorfeus_ferret_ext/testhelper.c +11 -21
- data/ext/isomorfeus_ferret_ext/testhelper.h +1 -1
- data/ext/isomorfeus_ferret_ext/tests_all.h +1 -2
- data/lib/isomorfeus/ferret/index/index.rb +1 -12
- data/lib/isomorfeus/ferret/version.rb +1 -1
- metadata +43 -4
@@ -6,13 +6,11 @@
|
|
6
6
|
#define St(state) ((FrtState *)(state))
|
7
7
|
#define UCtoI(val) ((int)(unsigned char)(val))
|
8
8
|
|
9
|
-
static void state_destroy(FrtState *state)
|
10
|
-
{
|
9
|
+
static void state_destroy(FrtState *state) {
|
11
10
|
state->destroy_i(state);
|
12
11
|
}
|
13
12
|
|
14
|
-
typedef struct LetterState
|
15
|
-
{
|
13
|
+
typedef struct LetterState {
|
16
14
|
FrtState super;
|
17
15
|
int c;
|
18
16
|
int val;
|
@@ -21,30 +19,25 @@ typedef struct LetterState
|
|
21
19
|
|
22
20
|
#define LSt(state) ((LetterState *)(state))
|
23
21
|
|
24
|
-
static int lstate_next(LetterState *self, int c, int *states)
|
25
|
-
{
|
22
|
+
static int lstate_next(LetterState *self, int c, int *states) {
|
26
23
|
if (c == self->c) {
|
27
24
|
states[0] = self->val;
|
28
25
|
return 1;
|
29
|
-
}
|
30
|
-
else {
|
26
|
+
} else {
|
31
27
|
return 0;
|
32
28
|
}
|
33
29
|
}
|
34
30
|
|
35
|
-
static int lstate_is_match(LetterState *self, char **mapping)
|
36
|
-
{
|
31
|
+
static int lstate_is_match(LetterState *self, char **mapping) {
|
37
32
|
if (self->val < 0) {
|
38
33
|
*mapping = self->mapping;
|
39
34
|
return self->val;
|
40
|
-
}
|
41
|
-
else {
|
35
|
+
} else {
|
42
36
|
return 0;
|
43
37
|
}
|
44
38
|
}
|
45
39
|
|
46
|
-
static LetterState *lstate_new(int c, int val)
|
47
|
-
{
|
40
|
+
static LetterState *lstate_new(int c, int val) {
|
48
41
|
LetterState *self = FRT_ALLOC(LetterState);
|
49
42
|
self->c = c;
|
50
43
|
self->val = val;
|
@@ -55,28 +48,24 @@ static LetterState *lstate_new(int c, int val)
|
|
55
48
|
return self;
|
56
49
|
}
|
57
50
|
|
58
|
-
typedef struct NonDeterministicState
|
59
|
-
{
|
51
|
+
typedef struct NonDeterministicState {
|
60
52
|
FrtState super;
|
61
53
|
int *states[256];
|
62
54
|
int size[256];
|
63
55
|
int capa[256];
|
64
56
|
} NonDeterministicState;
|
65
57
|
|
66
|
-
static int ndstate_next(NonDeterministicState *self, int c, int *states)
|
67
|
-
{
|
58
|
+
static int ndstate_next(NonDeterministicState *self, int c, int *states) {
|
68
59
|
int size = self->size[c];
|
69
60
|
memcpy(states, self->states[c], size * sizeof(int));
|
70
61
|
return size;
|
71
62
|
}
|
72
63
|
|
73
|
-
static void ndstate_add(NonDeterministicState *self, int c, int state)
|
74
|
-
{
|
64
|
+
static void ndstate_add(NonDeterministicState *self, int c, int state) {
|
75
65
|
if (self->capa[c] <= self->size[c]) {
|
76
66
|
if (self->capa[c] == 0) {
|
77
67
|
self->capa[c] = 4;
|
78
|
-
}
|
79
|
-
else {
|
68
|
+
} else {
|
80
69
|
self->capa[c] <<= 1;
|
81
70
|
}
|
82
71
|
FRT_REALLOC_N(self->states[c], int, self->capa[c]);
|
@@ -92,8 +81,7 @@ static void ndstate_destroy_i(NonDeterministicState *self) {
|
|
92
81
|
free(self);
|
93
82
|
}
|
94
83
|
|
95
|
-
static int ndstate_is_match(FrtState *self, char **mapping)
|
96
|
-
{
|
84
|
+
static int ndstate_is_match(FrtState *self, char **mapping) {
|
97
85
|
(void)self; (void)mapping;
|
98
86
|
return 0;
|
99
87
|
}
|
@@ -118,8 +106,7 @@ FrtMultiMapper *frt_mulmap_new(void) {
|
|
118
106
|
return self;
|
119
107
|
}
|
120
108
|
|
121
|
-
static void mulmap_free_dstates(FrtMultiMapper *self)
|
122
|
-
{
|
109
|
+
static void mulmap_free_dstates(FrtMultiMapper *self) {
|
123
110
|
if (self->d_size > 0) {
|
124
111
|
int i;
|
125
112
|
for (i = self->d_size - 1; i >= 0; i--) {
|
@@ -129,8 +116,7 @@ static void mulmap_free_dstates(FrtMultiMapper *self)
|
|
129
116
|
}
|
130
117
|
}
|
131
118
|
|
132
|
-
void frt_mulmap_add_mapping(FrtMultiMapper *self, const char *pattern, const char *rep)
|
133
|
-
{
|
119
|
+
void frt_mulmap_add_mapping(FrtMultiMapper *self, const char *pattern, const char *rep) {
|
134
120
|
if (pattern == NULL || pattern[0] == '\0') {
|
135
121
|
FRT_RAISE(FRT_ARG_ERROR, "Tried to add empty pattern to multi_mapper");
|
136
122
|
} else {
|
@@ -147,16 +133,14 @@ void frt_mulmap_add_mapping(FrtMultiMapper *self, const char *pattern, const cha
|
|
147
133
|
}
|
148
134
|
|
149
135
|
|
150
|
-
static void mulmap_bv_set_states(FrtBitVector *bv, int *states, int cnt)
|
151
|
-
{
|
136
|
+
static void mulmap_bv_set_states(FrtBitVector *bv, int *states, int cnt) {
|
152
137
|
int i;
|
153
138
|
for (i = cnt - 1; i >= 0; i--) {
|
154
139
|
frt_bv_set(bv, states[i]);
|
155
140
|
}
|
156
141
|
}
|
157
142
|
|
158
|
-
static FrtDeterministicState *mulmap_process_state(FrtMultiMapper *self, FrtBitVector *bv)
|
159
|
-
{
|
143
|
+
static FrtDeterministicState *mulmap_process_state(FrtMultiMapper *self, FrtBitVector *bv) {
|
160
144
|
FrtDeterministicState *current_state
|
161
145
|
= (FrtDeterministicState *)frt_h_get(self->dstates_map, bv);
|
162
146
|
if (current_state == NULL) {
|
@@ -197,15 +181,13 @@ static FrtDeterministicState *mulmap_process_state(FrtMultiMapper *self, FrtBitV
|
|
197
181
|
}
|
198
182
|
current_state->next[(int)c] = mulmap_process_state(self, nxt_bv);
|
199
183
|
}
|
200
|
-
}
|
201
|
-
else {
|
184
|
+
} else {
|
202
185
|
frt_bv_destroy(bv);
|
203
186
|
}
|
204
187
|
return current_state;
|
205
188
|
}
|
206
189
|
|
207
|
-
void frt_mulmap_compile(FrtMultiMapper *self)
|
208
|
-
{
|
190
|
+
void frt_mulmap_compile(FrtMultiMapper *self) {
|
209
191
|
NonDeterministicState *start = ndstate_new();
|
210
192
|
int i, j;
|
211
193
|
int size = 1;
|
@@ -254,8 +236,7 @@ void frt_mulmap_compile(FrtMultiMapper *self)
|
|
254
236
|
free(nstates);
|
255
237
|
}
|
256
238
|
|
257
|
-
int frt_mulmap_map_len(FrtMultiMapper *self, char *to, char *from, int capa)
|
258
|
-
{
|
239
|
+
int frt_mulmap_map_len(FrtMultiMapper *self, char *to, char *from, int capa) {
|
259
240
|
FrtDeterministicState *start = self->dstates[0];
|
260
241
|
FrtDeterministicState *state = start;
|
261
242
|
char *s = from, *d = to, *end = to + capa - 1;
|
@@ -273,8 +254,7 @@ int frt_mulmap_map_len(FrtMultiMapper *self, char *to, char *from, int capa)
|
|
273
254
|
memcpy(d, state->mapping, len);
|
274
255
|
d += len;
|
275
256
|
state = start;
|
276
|
-
}
|
277
|
-
else {
|
257
|
+
} else {
|
278
258
|
*(d++) = *s;
|
279
259
|
}
|
280
260
|
s++;
|
@@ -283,15 +263,13 @@ int frt_mulmap_map_len(FrtMultiMapper *self, char *to, char *from, int capa)
|
|
283
263
|
return d - to;
|
284
264
|
}
|
285
265
|
|
286
|
-
char *frt_mulmap_map(FrtMultiMapper *self, char *to, char *from, int capa)
|
287
|
-
{
|
266
|
+
char *frt_mulmap_map(FrtMultiMapper *self, char *to, char *from, int capa) {
|
288
267
|
frt_mulmap_map_len(self, to, from, capa);
|
289
268
|
return to;
|
290
269
|
}
|
291
270
|
|
292
271
|
/* Maps a string to a dynamically allocated string */
|
293
|
-
char *frt_mulmap_dynamic_map(FrtMultiMapper *self, char *from)
|
294
|
-
{
|
272
|
+
char *frt_mulmap_dynamic_map(FrtMultiMapper *self, char *from) {
|
295
273
|
FrtDeterministicState *start = self->dstates[0];
|
296
274
|
FrtDeterministicState *state = start;
|
297
275
|
int capa = strlen(from);
|
@@ -312,8 +290,7 @@ char *frt_mulmap_dynamic_map(FrtMultiMapper *self, char *from)
|
|
312
290
|
memcpy(d, state->mapping, len);
|
313
291
|
d += len;
|
314
292
|
state = start;
|
315
|
-
}
|
316
|
-
else {
|
293
|
+
} else {
|
317
294
|
*(d++) = *s;
|
318
295
|
}
|
319
296
|
s++;
|
@@ -3,29 +3,25 @@
|
|
3
3
|
|
4
4
|
#include "frt_hash.h"
|
5
5
|
|
6
|
-
typedef struct FrtState
|
7
|
-
{
|
6
|
+
typedef struct FrtState {
|
8
7
|
int (*next)(struct FrtState *self, int c, int *states);
|
9
8
|
void (*destroy_i)(struct FrtState *self);
|
10
9
|
int (*is_match)(struct FrtState *self, char **mapping);
|
11
10
|
} FrtState;
|
12
11
|
|
13
|
-
typedef struct FrtDeterministicState
|
14
|
-
{
|
12
|
+
typedef struct FrtDeterministicState {
|
15
13
|
struct FrtDeterministicState *next[256];
|
16
14
|
int longest_match;
|
17
15
|
char *mapping;
|
18
16
|
int mapping_len;
|
19
17
|
} FrtDeterministicState;
|
20
18
|
|
21
|
-
typedef struct FrtMapping
|
22
|
-
{
|
19
|
+
typedef struct FrtMapping {
|
23
20
|
char *pattern;
|
24
21
|
char *replacement;
|
25
22
|
} FrtMapping;
|
26
23
|
|
27
|
-
typedef struct FrtMultiMapper
|
28
|
-
{
|
24
|
+
typedef struct FrtMultiMapper {
|
29
25
|
FrtMapping **mappings;
|
30
26
|
int size;
|
31
27
|
int capa;
|
@@ -0,0 +1,334 @@
|
|
1
|
+
/* prevent warning: #warning Please include winsock2.h before windows.h [-Wcpp] */
|
2
|
+
#ifdef _WIN32
|
3
|
+
# include <winsock2.h>
|
4
|
+
#endif
|
5
|
+
|
6
|
+
#include "brotli_decode.h"
|
7
|
+
#include "brotli_encode.h"
|
8
|
+
#include "bzlib.h"
|
9
|
+
#include "lz4frame.h"
|
10
|
+
#include "frt_except.h"
|
11
|
+
#include "frt_stream.h"
|
12
|
+
#include "frt_out_stream.h"
|
13
|
+
|
14
|
+
#define FRT_BROTLI_COMPRESSION_LEVEL 4
|
15
|
+
#define FRT_BZIP_COMPRESSION_LEVEL 9
|
16
|
+
|
17
|
+
/**
|
18
|
+
* Create a newly allocated and initialized OutStream object
|
19
|
+
*
|
20
|
+
* @return a newly allocated and initialized OutStream object
|
21
|
+
*/
|
22
|
+
FrtOutStream *frt_os_new(void) {
|
23
|
+
FrtOutStream *os = FRT_ALLOC(FrtOutStream);
|
24
|
+
os->folder_name = NULL;
|
25
|
+
os->buf.start = 0;
|
26
|
+
os->buf.pos = 0;
|
27
|
+
os->buf.len = 0;
|
28
|
+
return os;
|
29
|
+
}
|
30
|
+
|
31
|
+
/**
|
32
|
+
* Flush the countents of the FrtOutStream's buffers
|
33
|
+
*
|
34
|
+
* @param the OutStream to flush
|
35
|
+
*/
|
36
|
+
void frt_os_flush(FrtOutStream *os) {
|
37
|
+
os->m->flush_i(os, os->buf.buf, os->buf.pos);
|
38
|
+
os->buf.start += os->buf.pos;
|
39
|
+
os->buf.pos = 0;
|
40
|
+
}
|
41
|
+
|
42
|
+
void frt_os_close(FrtOutStream *os) {
|
43
|
+
frt_os_flush(os);
|
44
|
+
os->m->close_i(os);
|
45
|
+
if (os->folder_name) {
|
46
|
+
free((void *)os->folder_name);
|
47
|
+
}
|
48
|
+
free(os);
|
49
|
+
}
|
50
|
+
|
51
|
+
off_t frt_os_pos(FrtOutStream *os) {
|
52
|
+
return os->buf.start + os->buf.pos;
|
53
|
+
}
|
54
|
+
|
55
|
+
void frt_os_seek(FrtOutStream *os, frt_off_t new_pos) {
|
56
|
+
frt_os_flush(os);
|
57
|
+
os->buf.start = new_pos;
|
58
|
+
os->m->seek_i(os, new_pos);
|
59
|
+
}
|
60
|
+
|
61
|
+
/**
|
62
|
+
* Unsafe alternative to os_write_byte. Only use this method if you know there
|
63
|
+
* is no chance of buffer overflow.
|
64
|
+
*/
|
65
|
+
#define write_byte(os, b) os->buf.buf[os->buf.pos++] = (frt_uchar)b
|
66
|
+
|
67
|
+
/**
|
68
|
+
* Write a single byte +b+ to the OutStream +os+
|
69
|
+
*
|
70
|
+
* @param os the OutStream to write to
|
71
|
+
* @param b the byte to write
|
72
|
+
* @raise FRT_IO_ERROR if there is an IO error writing to the filesystem
|
73
|
+
*/
|
74
|
+
void frt_os_write_byte(FrtOutStream *os, frt_uchar b) {
|
75
|
+
if (os->buf.pos >= (FRT_BUFFER_SIZE - 1)) {
|
76
|
+
frt_os_flush(os);
|
77
|
+
}
|
78
|
+
write_byte(os, b);
|
79
|
+
}
|
80
|
+
|
81
|
+
void frt_os_write_bytes(FrtOutStream *os, const frt_uchar *buf, int len) {
|
82
|
+
if (len < (FRT_BUFFER_SIZE - os->buf.pos)) {
|
83
|
+
memcpy(os->buf.buf + os->buf.pos, buf, len);
|
84
|
+
os->buf.pos += len;
|
85
|
+
} else {
|
86
|
+
frt_os_flush(os);
|
87
|
+
int pos = 0;
|
88
|
+
int size;
|
89
|
+
while (pos < len) {
|
90
|
+
if (len - pos < FRT_BUFFER_SIZE) {
|
91
|
+
size = len - pos;
|
92
|
+
} else {
|
93
|
+
size = FRT_BUFFER_SIZE;
|
94
|
+
}
|
95
|
+
os->m->flush_i(os, buf + pos, size);
|
96
|
+
pos += size;
|
97
|
+
os->buf.start += size;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
void frt_os_write_i32(FrtOutStream *os, frt_i32 num) {
|
103
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 24) & 0xFF));
|
104
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 16) & 0xFF));
|
105
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 8) & 0xFF));
|
106
|
+
frt_os_write_byte(os, (frt_uchar)(num & 0xFF));
|
107
|
+
}
|
108
|
+
|
109
|
+
void frt_os_write_i64(FrtOutStream *os, frt_i64 num) {
|
110
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 56) & 0xFF));
|
111
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 48) & 0xFF));
|
112
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 40) & 0xFF));
|
113
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 32) & 0xFF));
|
114
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 24) & 0xFF));
|
115
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 16) & 0xFF));
|
116
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 8) & 0xFF));
|
117
|
+
frt_os_write_byte(os, (frt_uchar)(num & 0xFF));
|
118
|
+
}
|
119
|
+
|
120
|
+
void frt_os_write_u32(FrtOutStream *os, frt_u32 num) {
|
121
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 24) & 0xFF));
|
122
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 16) & 0xFF));
|
123
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 8) & 0xFF));
|
124
|
+
frt_os_write_byte(os, (frt_uchar)(num & 0xFF));
|
125
|
+
}
|
126
|
+
|
127
|
+
void frt_os_write_u64(FrtOutStream *os, frt_u64 num) {
|
128
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 56) & 0xFF));
|
129
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 48) & 0xFF));
|
130
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 40) & 0xFF));
|
131
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 32) & 0xFF));
|
132
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 24) & 0xFF));
|
133
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 16) & 0xFF));
|
134
|
+
frt_os_write_byte(os, (frt_uchar)((num >> 8) & 0xFF));
|
135
|
+
frt_os_write_byte(os, (frt_uchar)(num & 0xFF));
|
136
|
+
}
|
137
|
+
|
138
|
+
/* optimized to use an unchecked write if there is space */
|
139
|
+
void frt_os_write_vint(FrtOutStream *os, register unsigned int num) {
|
140
|
+
if (os->buf.pos > VINT_END) {
|
141
|
+
while (num > 127) {
|
142
|
+
frt_os_write_byte(os, (frt_uchar)((num & 0x7f) | 0x80));
|
143
|
+
num >>= 7;
|
144
|
+
}
|
145
|
+
frt_os_write_byte(os, (frt_uchar)(num));
|
146
|
+
} else {
|
147
|
+
while (num > 127) {
|
148
|
+
write_byte(os, (frt_uchar)((num & 0x7f) | 0x80));
|
149
|
+
num >>= 7;
|
150
|
+
}
|
151
|
+
write_byte(os, (frt_uchar)(num));
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
/* optimized to use an unchecked write if there is space */
|
156
|
+
void frt_os_write_voff_t(FrtOutStream *os, register frt_off_t num) {
|
157
|
+
if (os->buf.pos > VINT_END) {
|
158
|
+
while (num > 127) {
|
159
|
+
frt_os_write_byte(os, (frt_uchar)((num & 0x7f) | 0x80));
|
160
|
+
num >>= 7;
|
161
|
+
}
|
162
|
+
frt_os_write_byte(os, (frt_uchar)num);
|
163
|
+
} else {
|
164
|
+
while (num > 127) {
|
165
|
+
write_byte(os, (frt_uchar)((num & 0x7f) | 0x80));
|
166
|
+
num >>= 7;
|
167
|
+
}
|
168
|
+
write_byte(os, (frt_uchar)num);
|
169
|
+
}
|
170
|
+
}
|
171
|
+
|
172
|
+
/* optimized to use an unchecked write if there is space */
|
173
|
+
void frt_os_write_vll(FrtOutStream *os, register frt_u64 num) {
|
174
|
+
if (os->buf.pos > VINT_END) {
|
175
|
+
while (num > 127) {
|
176
|
+
frt_os_write_byte(os, (frt_uchar)((num & 0x7f) | 0x80));
|
177
|
+
num >>= 7;
|
178
|
+
}
|
179
|
+
frt_os_write_byte(os, (frt_uchar)num);
|
180
|
+
} else {
|
181
|
+
while (num > 127) {
|
182
|
+
write_byte(os, (frt_uchar)((num & 0x7f) | 0x80));
|
183
|
+
num >>= 7;
|
184
|
+
}
|
185
|
+
write_byte(os, (frt_uchar)num);
|
186
|
+
}
|
187
|
+
}
|
188
|
+
|
189
|
+
void frt_os_write_string_len(FrtOutStream *os, const char *str, int len) {
|
190
|
+
frt_os_write_vint(os, len);
|
191
|
+
frt_os_write_bytes(os, (frt_uchar *)str, len);
|
192
|
+
}
|
193
|
+
|
194
|
+
void frt_os_write_string(FrtOutStream *os, const char *str) {
|
195
|
+
frt_os_write_string_len(os, str, (int)strlen(str));
|
196
|
+
}
|
197
|
+
|
198
|
+
static int frt_os_write_brotli_compressed_bytes(FrtOutStream* out_stream, frt_uchar *data, int length) {
|
199
|
+
size_t compressed_length = 0;
|
200
|
+
const frt_uchar *next_in = data;
|
201
|
+
size_t available_in = length;
|
202
|
+
size_t available_out;
|
203
|
+
frt_uchar compression_buffer[FRT_COMPRESSION_BUFFER_SIZE];
|
204
|
+
frt_uchar *next_out;
|
205
|
+
BrotliEncoderState *b_state = BrotliEncoderCreateInstance(NULL, NULL, NULL);
|
206
|
+
if (!b_state) { frt_comp_raise(); return -1; }
|
207
|
+
|
208
|
+
BrotliEncoderSetParameter(b_state, BROTLI_PARAM_QUALITY, FRT_BROTLI_COMPRESSION_LEVEL);
|
209
|
+
|
210
|
+
do {
|
211
|
+
available_out = FRT_COMPRESSION_BUFFER_SIZE;
|
212
|
+
next_out = compression_buffer;
|
213
|
+
if (!BrotliEncoderCompressStream(b_state, BROTLI_OPERATION_FINISH,
|
214
|
+
&available_in, &next_in,
|
215
|
+
&available_out, &next_out, &compressed_length)) {
|
216
|
+
BrotliEncoderDestroyInstance(b_state);
|
217
|
+
frt_comp_raise();
|
218
|
+
return -1;
|
219
|
+
}
|
220
|
+
frt_os_write_bytes(out_stream, compression_buffer, FRT_COMPRESSION_BUFFER_SIZE - available_out);
|
221
|
+
} while (!BrotliEncoderIsFinished(b_state));
|
222
|
+
|
223
|
+
BrotliEncoderDestroyInstance(b_state);
|
224
|
+
|
225
|
+
return (int)compressed_length;
|
226
|
+
}
|
227
|
+
|
228
|
+
static int frt_os_write_bz2_compressed_bytes(FrtOutStream* out_stream, frt_uchar *data, int length) {
|
229
|
+
int ret, buf_size, compressed_len = 0;
|
230
|
+
char out_buffer[FRT_COMPRESSION_BUFFER_SIZE];
|
231
|
+
bz_stream zstrm;
|
232
|
+
zstrm.bzalloc = NULL;
|
233
|
+
zstrm.bzfree = NULL;
|
234
|
+
zstrm.opaque = NULL;
|
235
|
+
if ((ret = BZ2_bzCompressInit(&zstrm, FRT_BZIP_COMPRESSION_LEVEL, 0, 0)) != BZ_OK) frt_zraise(ret);
|
236
|
+
|
237
|
+
zstrm.avail_in = length;
|
238
|
+
zstrm.next_in = (char *)data;
|
239
|
+
zstrm.avail_out = FRT_COMPRESSION_BUFFER_SIZE;
|
240
|
+
zstrm.next_out = out_buffer;
|
241
|
+
|
242
|
+
do {
|
243
|
+
ret = BZ2_bzCompress(&zstrm, BZ_FINISH); /* no bad return value */
|
244
|
+
assert(ret != BZ_SEQUENCE_ERROR); /* state not clobbered */
|
245
|
+
compressed_len += buf_size = FRT_COMPRESSION_BUFFER_SIZE - zstrm.avail_out;
|
246
|
+
frt_os_write_bytes(out_stream, (frt_uchar *)out_buffer, buf_size);
|
247
|
+
} while (zstrm.avail_out == 0);
|
248
|
+
assert(zstrm.avail_in == 0); /* all input will be used */
|
249
|
+
|
250
|
+
(void)BZ2_bzCompressEnd(&zstrm);
|
251
|
+
return compressed_len;
|
252
|
+
}
|
253
|
+
|
254
|
+
static const LZ4F_preferences_t lz4_prefs = {
|
255
|
+
{
|
256
|
+
LZ4F_default,
|
257
|
+
LZ4F_blockLinked,
|
258
|
+
LZ4F_noContentChecksum,
|
259
|
+
LZ4F_frame,
|
260
|
+
0, /* unknown content size */
|
261
|
+
0, /* no dictID */
|
262
|
+
LZ4F_noBlockChecksum
|
263
|
+
},
|
264
|
+
0,
|
265
|
+
1,
|
266
|
+
1,
|
267
|
+
{0,0,0}
|
268
|
+
};
|
269
|
+
|
270
|
+
static int frt_os_write_lz4_compressed_bytes(FrtOutStream* out_stream, frt_uchar *data, int length) {
|
271
|
+
int compressed_length = 0;
|
272
|
+
int remaining_length = length;
|
273
|
+
size_t ccmp_length = 0;
|
274
|
+
LZ4F_compressionContext_t ctx;
|
275
|
+
size_t out_buf_length = LZ4F_compressBound(FRT_COMPRESSION_BUFFER_SIZE, &lz4_prefs);
|
276
|
+
frt_uchar *out_buf = frt_ecalloc(out_buf_length);
|
277
|
+
|
278
|
+
size_t ctx_creation = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
|
279
|
+
if (LZ4F_isError(ctx_creation)) {
|
280
|
+
compressed_length = -1;
|
281
|
+
goto finish;
|
282
|
+
}
|
283
|
+
|
284
|
+
/* create header */
|
285
|
+
ccmp_length = LZ4F_compressBegin(ctx, out_buf, out_buf_length, &lz4_prefs);
|
286
|
+
if (LZ4F_isError(ccmp_length)) {
|
287
|
+
compressed_length = -1;
|
288
|
+
goto finish;
|
289
|
+
}
|
290
|
+
compressed_length = ccmp_length;
|
291
|
+
frt_os_write_bytes(out_stream, out_buf, ccmp_length);
|
292
|
+
|
293
|
+
/* compress data */
|
294
|
+
do {
|
295
|
+
int read_length = (FRT_COMPRESSION_BUFFER_SIZE > remaining_length) ? remaining_length : FRT_COMPRESSION_BUFFER_SIZE;
|
296
|
+
ccmp_length = LZ4F_compressUpdate(ctx, out_buf, out_buf_length, data + (length - remaining_length), read_length, NULL);
|
297
|
+
if (LZ4F_isError(ccmp_length)) {
|
298
|
+
compressed_length = -1;
|
299
|
+
goto finish;
|
300
|
+
}
|
301
|
+
frt_os_write_bytes(out_stream, out_buf, ccmp_length);
|
302
|
+
compressed_length += ccmp_length;
|
303
|
+
remaining_length -= read_length;
|
304
|
+
} while (remaining_length > 0);
|
305
|
+
|
306
|
+
/* finish up */
|
307
|
+
ccmp_length = LZ4F_compressEnd(ctx, out_buf, out_buf_length, NULL);
|
308
|
+
if (LZ4F_isError(ccmp_length)) {
|
309
|
+
compressed_length = -1;
|
310
|
+
goto finish;
|
311
|
+
}
|
312
|
+
|
313
|
+
frt_os_write_bytes(out_stream, out_buf, ccmp_length);
|
314
|
+
compressed_length += ccmp_length;
|
315
|
+
|
316
|
+
finish:
|
317
|
+
LZ4F_freeCompressionContext(ctx);
|
318
|
+
free(out_buf);
|
319
|
+
|
320
|
+
return compressed_length;
|
321
|
+
}
|
322
|
+
|
323
|
+
int frt_os_write_compressed_bytes(FrtOutStream* out_stream, frt_uchar *data, int length, FrtCompressionType compression_type) {
|
324
|
+
switch (compression_type) {
|
325
|
+
case FRT_COMPRESSION_BROTLI:
|
326
|
+
return frt_os_write_brotli_compressed_bytes(out_stream, data, length);
|
327
|
+
case FRT_COMPRESSION_BZ2:
|
328
|
+
return frt_os_write_bz2_compressed_bytes(out_stream, data, length);
|
329
|
+
case FRT_COMPRESSION_LZ4:
|
330
|
+
return frt_os_write_lz4_compressed_bytes(out_stream, data, length);
|
331
|
+
default:
|
332
|
+
return -1;
|
333
|
+
}
|
334
|
+
}
|