8#include <botan/internal/compress_utils.h>
10#include <botan/exceptn.h>
11#include <botan/mem_ops.h>
12#include <botan/internal/fmt.h>
13#include <botan/internal/int_utils.h>
19 Exception(
fmt(
"Compression API {} failed with return code {}", func_name, rc)), m_type(type), m_rc(rc) {}
21void* Compression_Alloc_Info::do_malloc(
size_t n,
size_t size)
noexcept {
28 void* ptr = std::calloc(n, size);
44 m_current_allocs[ptr] = n * size;
53void Compression_Alloc_Info::do_free(
void* ptr)
noexcept {
55 auto i = m_current_allocs.find(ptr);
57 if(i == m_current_allocs.end()) {
79 m_current_allocs.erase(i);
87void Stream_Compression::start(
size_t level) {
88 m_stream = make_stream(level);
96 if(buf.size() == offset && flags == m_stream->run_flag()) {
100 const size_t buffer_needed =
add_or_throw(buf.size(), offset,
"Compression input too large");
101 if(m_buffer.size() < buffer_needed) {
102 m_buffer.resize(buffer_needed);
110 if(m_buffer.empty()) {
114 m_stream->next_in(buf.data() + offset, buf.size() - offset);
115 m_stream->next_out(m_buffer.data() + offset, m_buffer.size() - offset);
118 const bool stream_end = m_stream->run(flags);
121 BOTAN_ASSERT(m_stream->avail_in() == 0,
"After stream is done, no input remains to be processed");
122 m_buffer.resize(m_buffer.size() - m_stream->avail_out());
124 }
else if(m_stream->avail_out() == 0) {
126 const size_t new_size =
add_or_throw(m_buffer.size(), added,
"Compression output too large");
127 m_buffer.resize(new_size);
128 m_stream->next_out(m_buffer.data() + m_buffer.size() - added, added);
129 }
else if(m_stream->avail_in() == 0) {
130 m_buffer.resize(m_buffer.size() - m_stream->avail_out());
135 copy_mem(m_buffer.data(), buf.data(), offset);
141 process(buf, offset, flush ? m_stream->flush_flag() : m_stream->run_flag());
146 process(buf, offset, m_stream->finish_flag());
155 m_stream = make_stream();
162 const size_t buffer_needed =
add_or_throw(buf.size(), offset,
"Compression input too large");
163 if(m_buffer.size() < buffer_needed) {
164 m_buffer.resize(buffer_needed);
167 m_stream->next_in(buf.data() + offset, buf.size() - offset);
168 m_stream->next_out(m_buffer.data() + offset, m_buffer.size() - offset);
171 const bool stream_end = m_stream->run(flags);
174 if(m_stream->avail_in() == 0) {
176 m_buffer.resize(m_buffer.size() - m_stream->avail_out());
184 m_buffer.resize(m_buffer.size() - m_stream->avail_out());
185 const size_t read = (buf.size() - offset) - m_stream->avail_in();
187 m_stream->next_in(buf.data() + offset + read, buf.size() - offset - read);
190 if(m_stream->avail_out() == 0) {
192 const size_t new_size =
add_or_throw(m_buffer.size(), added,
"Compression output too large");
193 m_buffer.resize(new_size);
194 m_stream->next_out(m_buffer.data() + m_buffer.size() - added, added);
195 }
else if(m_stream->avail_in() == 0) {
196 m_buffer.resize(m_buffer.size() - m_stream->avail_out());
201 copy_mem(m_buffer.data(), buf.data(), offset);
207 if(buf.size() == offset) {
213 process(buf, offset, m_stream->run_flag());
218 if(buf.size() == offset) {
225 process(buf, offset, m_stream->finish_flag());
#define BOTAN_ASSERT(expr, assertion_made)
Compression_Error(const char *func_name, ErrorType type, int rc)
virtual std::string name() const =0
Exception(std::string_view msg)
void update(secure_vector< uint8_t > &buf, size_t offset, bool flush) final
void finish(secure_vector< uint8_t > &buf, size_t offset) final
void update(secure_vector< uint8_t > &buf, size_t offset) final
void finish(secure_vector< uint8_t > &buf, size_t offset) final
constexpr T add_or_throw(T a, T b, std::string_view msg)
std::string fmt(std::string_view format, const T &... args)
constexpr void copy_mem(T *out, const T *in, size_t n)
void secure_scrub_memory(void *ptr, size_t n)
constexpr std::optional< T > checked_mul(T a, T b)
std::vector< T, secure_allocator< T > > secure_vector