Exemple #1
0
/*
 * Return a block of data from the decompression buffer.  Decompress more
 * as necessary.
 */
static ssize_t
compress_filter_read(struct archive_read_filter *self, const void **pblock)
{
    struct private_data *state;
    unsigned char *p, *start, *end;
    int ret;

    state = (struct private_data *)self->data;
    if (state->end_of_stream) {
        *pblock = NULL;
        return (0);
    }
    p = start = (unsigned char *)state->out_block;
    end = start + state->out_block_size;

    while (p < end && !state->end_of_stream) {
        if (state->stackp > state->stack) {
            *p++ = *--state->stackp;
        } else {
            ret = next_code(self);
            if (ret == -1)
                state->end_of_stream = ret;
            else if (ret != ARCHIVE_OK)
                return (ret);
        }
    }

    *pblock = start;
    return (p - start);
}
Exemple #2
0
/*
 * Setup the callbacks.
 */
static int
compress_bidder_init(struct archive_read_filter *self)
{
    struct private_data *state;
    static const size_t out_block_size = 64 * 1024;
    void *out_block;
    int code;

    self->code = ARCHIVE_FILTER_COMPRESS;
    self->name = "compress (.Z)";

    state = (struct private_data *)calloc(sizeof(*state), 1);
    out_block = malloc(out_block_size);
    if (state == NULL || out_block == NULL) {
        free(out_block);
        free(state);
        archive_set_error(&self->archive->archive, ENOMEM,
                          "Can't allocate data for %s decompression",
                          self->name);
        return (ARCHIVE_FATAL);
    }

    self->data = state;
    state->out_block_size = out_block_size;
    state->out_block = out_block;
    self->read = compress_filter_read;
    self->skip = NULL; /* not supported */
    self->close = compress_filter_close;

    /* XXX MOVE THE FOLLOWING OUT OF INIT() XXX */

    (void)getbits(self, 8); /* Skip first signature byte. */
    (void)getbits(self, 8); /* Skip second signature byte. */

    code = getbits(self, 8);
    state->maxcode_bits = code & 0x1f;
    state->maxcode = (1 << state->maxcode_bits);
    state->use_reset_code = code & 0x80;

    /* Initialize decompressor. */
    state->free_ent = 256;
    state->stackp = state->stack;
    if (state->use_reset_code)
        state->free_ent++;
    state->bits = 9;
    state->section_end_code = (1<<state->bits) - 1;
    state->oldcode = -1;
    for (code = 255; code >= 0; code--) {
        state->prefix[code] = 0;
        state->suffix[code] = code;
    }
    next_code(self);

    return (ARCHIVE_OK);
}
Exemple #3
0
int main() {
	uint64_t first_code = 20151125LL;
	int row = 1;
	int col = 1;

	while (row != 2947 || col != 3029) {
		first_code = next_code(first_code);

		if (row == 1) {
			row = col + 1;
			col = 1;
		}	else {
			row--;
			col++;
		}
	}

	printf("%d %d %llu\n", row, col, first_code);
}
Exemple #4
0
/*
 * Process the next code and fill the stack with the expansion
 * of the code.  Returns ARCHIVE_FATAL if there is a fatal I/O or
 * format error, ARCHIVE_EOF if we hit end of data, ARCHIVE_OK otherwise.
 */
static int
next_code(struct archive_read_filter *self)
{
    struct private_data *state = (struct private_data *)self->data;
    int code, newcode;

    static int debug_buff[1024];
    static unsigned debug_index;

    code = newcode = getbits(self, state->bits);
    if (code < 0)
        return (code);

    debug_buff[debug_index++] = code;
    if (debug_index >= sizeof(debug_buff)/sizeof(debug_buff[0]))
        debug_index = 0;

    /* If it's a reset code, reset the dictionary. */
    if ((code == 256) && state->use_reset_code) {
        /*
         * The original 'compress' implementation blocked its
         * I/O in a manner that resulted in junk bytes being
         * inserted after every reset.  The next section skips
         * this junk.  (Yes, the number of *bytes* to skip is
         * a function of the current *bit* length.)
         */
        int skip_bytes =  state->bits -
                          (state->bytes_in_section % state->bits);
        skip_bytes %= state->bits;
        state->bits_avail = 0; /* Discard rest of this byte. */
        while (skip_bytes-- > 0) {
            code = getbits(self, 8);
            if (code < 0)
                return (code);
        }
        /* Now, actually do the reset. */
        state->bytes_in_section = 0;
        state->bits = 9;
        state->section_end_code = (1 << state->bits) - 1;
        state->free_ent = 257;
        state->oldcode = -1;
        return (next_code(self));
    }

    if (code > state->free_ent) {
        /* An invalid code is a fatal error. */
        archive_set_error(&(self->archive->archive), -1,
                          "Invalid compressed data");
        return (ARCHIVE_FATAL);
    }

    /* Special case for KwKwK string. */
    if (code >= state->free_ent) {
        *state->stackp++ = state->finbyte;
        code = state->oldcode;
    }

    /* Generate output characters in reverse order. */
    while (code >= 256) {
        *state->stackp++ = state->suffix[code];
        code = state->prefix[code];
    }
    *state->stackp++ = state->finbyte = code;

    /* Generate the new entry. */
    code = state->free_ent;
    if (code < state->maxcode && state->oldcode >= 0) {
        state->prefix[code] = state->oldcode;
        state->suffix[code] = state->finbyte;
        ++state->free_ent;
    }
    if (state->free_ent > state->section_end_code) {
        state->bits++;
        state->bytes_in_section = 0;
        if (state->bits == state->maxcode_bits)
            state->section_end_code = state->maxcode;
        else
            state->section_end_code = (1 << state->bits) - 1;
    }

    /* Remember previous code. */
    state->oldcode = newcode;
    return (ARCHIVE_OK);
}