示例#1
0
文件: brotli.c 项目: Efreak/elinks
static unsigned char *
brotli_decode_buffer(struct stream_encoded *st, unsigned char *data, int len, int *new_len)
{
	struct br_enc_data *enc_data = (struct br_enc_data *)st->data;
	BrotliInput inp;
	BrotliOutput outp;
	BrotliState *stream = &enc_data->br_stream;
	int error;
	int finish = (len == 0);

	*new_len = 0;	  /* default, left there if an error occurs */
	enc_data->input = data;
	enc_data->input_length = len;
	enc_data->input_pos = 0;
	enc_data->output = NULL;
	enc_data->output_length = 0;
	enc_data->output_pos = 0;
	inp.data_ = enc_data;
	outp.data_ = enc_data;
	inp.cb_ = brotli_read_function;
	outp.cb_ = brotli_write_function;
	error = BrotliDecompressStreaming(inp, outp, finish, stream);

	switch (error) {
	case BROTLI_RESULT_ERROR:
		return NULL;
	case BROTLI_RESULT_SUCCESS:
		enc_data->after_end = 1;
	case BROTLI_RESULT_NEEDS_MORE_INPUT:
	default:
		*new_len = enc_data->output_length;
		return enc_data->output;
	}
}
示例#2
0
文件: brotli.c 项目: Efreak/elinks
static int
brotli_read(struct stream_encoded *stream, unsigned char *buf, int len)
{
	struct br_enc_data *enc_data = (struct br_enc_data *) stream->data;
	BrotliState *s;
	BrotliInput inp;
	BrotliOutput outp;
	size_t l;
	int error;

	if (!enc_data) return -1;
	s = &enc_data->br_stream;

	assert(len > 0);

	if (enc_data->after_end) {
		l = MIN(len, enc_data->output_length - enc_data->output_pos);
		memcpy(buf, enc_data->output + enc_data->output_pos, l);
		enc_data->output_pos += l;
		return l;
	}

	enc_data->input = NULL;
	enc_data->input_length = 0;
	enc_data->output = NULL;
	enc_data->output_length = 0;
	enc_data->output_pos = 0;
	inp.data_ = enc_data;
	outp.data_ = enc_data;
	inp.cb_ = brotli_read_function_fd;
	outp.cb_ = brotli_write_function;

	error = BrotliDecompressStreaming(inp, outp, 1, s);
	switch (error) {
	case BROTLI_RESULT_ERROR:
		return -1;
	case BROTLI_RESULT_SUCCESS:
		enc_data->after_end = 1;
	case BROTLI_RESULT_NEEDS_MORE_INPUT:
	default:
		enc_data->need_free = 1;
		l = MIN(len, enc_data->output_length - enc_data->output_pos);
		memcpy(buf, enc_data->output + enc_data->output_pos, l);
		enc_data->output_pos += l;
		return l;
	}
}
示例#3
0
void QBrotliDecoder::decode()
{
    if (m_pInputDevice == nullptr || m_pOutputDevice == nullptr)
    {
        emit onError("IO devices not set.");
        return;
    }

    if (!m_pInputDevice->isReadable())
    {
        emit onError("Input not readable.");
        return;
    }

    if (!m_pOutputDevice->isWritable())
    {
        emit onError("Output not writeable.");
        return;
    }


    BrotliState state;
    qint64 totalsize=-1;

    if (!m_pInputDevice->isSequential())
        totalsize = m_pInputDevice->size();

    BrotliStateInit(&state);

    int finish = 0;
    BrotliResult r;

    BrotliInput input = initInput(m_pInputDevice);
    BrotliOutput output = initOutput(m_pOutputDevice);

    for (;;)
    {
        r = BrotliDecompressStreaming(input,output,finish,&state);
        if (r==0)
        {
            //error
            emit onError("Decoding error.");
            break;
        }
        else if (r==1)
        {
            //done
            break;
        }

        if (totalsize!=-1)
            emit onProgress((double)m_pInputDevice->pos()/(double)totalsize);


        if (m_pInputDevice->atEnd())
            finish=1;
    }

    emit onProgress(1.0);
    emit onDone();

    BrotliStateCleanup(&state);
}