Add macro REDUCE_DATA_PREFIX.  Use it to add a title to the compressed
data.
Functions reduce_do/reduce_undo are the only interface functions.
- Format of compressed data: elements*, zero byte, 8-byte check hash in little endian form
+ Format of compressed data: "MIR", elements*, zero byte, 8-byte check hash in little endian form
Format of element:
o 8 bits tag
(N bits for symbol length; 0 means no sym, 2^N -1 means symbol length as uint present;
#define FALSE 0
#define TRUE 1
+#define REDUCE_DATA_PREFIX "MIR" /* first chars of compressed data */
#define REDUCE_SYMB_TAG_LEN 3 /* for some application could be 4 */
#define REDUCE_SYMB_TAG_LONG ((1 << REDUCE_SYMB_TAG_LEN) - 1) /* should be not changed */
#define REDUCE_REF_TAG_LEN (8 - REDUCE_SYMB_TAG_LEN)
@@ -255,10 +256,15 @@ static inline int reduce_do (reader_t reader, writer_t writer) {
uint64_t check_hash = REDUCE_CHECK_HASH_SEED;
uint32_t dict_len, dict_pos, base;
struct reduce_data *data = malloc (sizeof (struct reduce_data));
+ char prefix[] = REDUCE_DATA_PREFIX;
+ size_t prefix_size = strlen (prefix);
data->reader = reader;
data->writer = writer;
data->err_p = FALSE;
+ if (writer (prefix, prefix_size) != prefix_size) {
+ err_p = TRUE;
+ } else {
for (;;) {
data->buf_bound = reader (&data->buf, REDUCE_BUF_LEN);
if (data->buf_bound == 0) break;
@@ -282,28 +288,33 @@ static inline int reduce_do (reader_t reader, writer_t writer) {
}
reduce_hash_write (data, check_hash);
err_p = data->err_p;
+ }
free (data);
return !err_p;
}
static inline int reduce_undo (reader_t reader, writer_t writer) {
- uint8_t tag, s[sizeof (uint64_t)];
+ uint8_t tag, hash_str[sizeof (uint64_t)];
uint32_t sym_len, ref_len, ref_ind, sym_pos, pos = 0, curr_ind = 0;
uint64_t r, check_hash = REDUCE_CHECK_HASH_SEED;
int ret = FALSE;
struct reduce_data *data = malloc (sizeof (struct reduce_data));
+ char prefix[] = REDUCE_DATA_PREFIX, str[sizeof (prefix)];
+ size_t prefix_size = strlen (prefix);
data->reader = reader;
data->writer = writer;
+ if (reader (str, prefix_size) == prefix_size && memcmp (prefix, str, prefix_size) == 0) {
for (;;) {
if (reader (&tag, 1) == 0) break;
if (tag == 0) { /* check hash */
- if (reader (s, sizeof (s)) != sizeof (s) || reader (&tag, 1) != 0) break;
+ if (reader (hash_str, sizeof (hash_str)) != sizeof (hash_str) || reader (&tag, 1) != 0)
+ break;
if (pos != 0) {
check_hash = mir_hash_strict (data->buf, pos, check_hash);
writer (&data->buf[0], pos);
}
- if (reduce_str2hash (s) != check_hash) break;
+ if (reduce_str2hash (hash_str) != check_hash) break;
ret = TRUE;
break;
}
@@ -340,6 +351,7 @@ static inline int reduce_undo (reader_t reader, writer_t writer) {
pos = curr_ind = 0;
}
}
+ }
free (data);
return ret;
}
