in Release/src/http/common/http_compression.cpp [322:398]
size_t compress(const uint8_t* input,
size_t input_size,
uint8_t* output,
size_t output_size,
operation_hint hint,
size_t& input_bytes_processed,
bool& done)
{
if (m_done || (hint != operation_hint::is_last && !input_size))
{
input_bytes_processed = 0;
done = m_done;
return 0;
}
if (m_state != BROTLI_TRUE)
{
throw std::runtime_error("Prior unrecoverable compression stream error");
}
const uint8_t* next_in = input;
size_t avail_in = 0;
uint8_t* next_out = output;
size_t avail_out = output_size;
size_t total_out;
if (BrotliEncoderHasMoreOutput(m_stream) == BROTLI_TRUE)
{
// Drain any compressed bytes remaining from a prior call
do
{
m_state = BrotliEncoderCompressStream(
m_stream, BROTLI_OPERATION_FLUSH, &avail_in, &next_in, &avail_out, &next_out, &total_out);
} while (m_state == BROTLI_TRUE && avail_out && BrotliEncoderHasMoreOutput(m_stream) == BROTLI_TRUE);
}
if (m_state == BROTLI_TRUE && avail_out && input_size)
{
// Compress the caller-supplied buffer
avail_in = input_size;
do
{
m_state = BrotliEncoderCompressStream(
m_stream, BROTLI_OPERATION_FLUSH, &avail_in, &next_in, &avail_out, &next_out, &total_out);
} while (m_state == BROTLI_TRUE && avail_out && BrotliEncoderHasMoreOutput(m_stream) == BROTLI_TRUE);
}
else
{
// We're not compressing any new data; ensure calculation sanity
input_size = 0;
}
if (m_state != BROTLI_TRUE)
{
throw std::runtime_error("Unrecoverable compression stream error");
}
if (hint == operation_hint::is_last)
{
if (avail_out)
{
// Make one more pass to finalize the compressed stream
_ASSERTE(!avail_in);
m_state = BrotliEncoderCompressStream(
m_stream, BROTLI_OPERATION_FINISH, &avail_in, &next_in, &avail_out, &next_out, &total_out);
if (m_state != BROTLI_TRUE)
{
throw std::runtime_error("Unrecoverable error finalizing compression stream");
}
m_done = (BrotliEncoderIsFinished(m_stream) == BROTLI_TRUE);
}
}
input_bytes_processed = input_size - avail_in;
done = m_done;
return output_size - avail_out;
}