Botan 3.4.0
Crypto and TLS for C&
buf_filt.cpp
Go to the documentation of this file.
1/*
2* Buffered Filter
3* (C) 1999-2007 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#include <botan/filters.h>
9
10#include <botan/exceptn.h>
11#include <botan/mem_ops.h>
12#include <botan/internal/rounding.h>
13
14namespace Botan {
15
16/*
17* Buffered_Filter Constructor
18*/
19Buffered_Filter::Buffered_Filter(size_t b, size_t f) : m_main_block_mod(b), m_final_minimum(f) {
20 if(m_main_block_mod == 0) {
21 throw Invalid_Argument("m_main_block_mod == 0");
22 }
23
24 if(m_final_minimum > m_main_block_mod) {
25 throw Invalid_Argument("m_final_minimum > m_main_block_mod");
26 }
27
28 m_buffer.resize(2 * m_main_block_mod);
29 m_buffer_pos = 0;
30}
31
32/*
33* Buffer input into blocks, trying to minimize copying
34*/
35void Buffered_Filter::write(const uint8_t input[], size_t input_size) {
36 if(!input_size) {
37 return;
38 }
39
40 if(m_buffer_pos + input_size >= m_main_block_mod + m_final_minimum) {
41 size_t to_copy = std::min<size_t>(m_buffer.size() - m_buffer_pos, input_size);
42
43 copy_mem(&m_buffer[m_buffer_pos], input, to_copy);
44 m_buffer_pos += to_copy;
45
46 input += to_copy;
47 input_size -= to_copy;
48
49 size_t total_to_consume =
50 round_down(std::min(m_buffer_pos, m_buffer_pos + input_size - m_final_minimum), m_main_block_mod);
51
52 buffered_block(m_buffer.data(), total_to_consume);
53
54 m_buffer_pos -= total_to_consume;
55
56 copy_mem(m_buffer.data(), m_buffer.data() + total_to_consume, m_buffer_pos);
57 }
58
59 if(input_size >= m_final_minimum) {
60 size_t full_blocks = (input_size - m_final_minimum) / m_main_block_mod;
61 size_t to_copy = full_blocks * m_main_block_mod;
62
63 if(to_copy) {
64 buffered_block(input, to_copy);
65
66 input += to_copy;
67 input_size -= to_copy;
68 }
69 }
70
71 copy_mem(&m_buffer[m_buffer_pos], input, input_size);
72 m_buffer_pos += input_size;
73}
74
75/*
76* Finish/flush operation
77*/
79 if(m_buffer_pos < m_final_minimum) {
80 throw Invalid_State("Buffered filter end_msg without enough input");
81 }
82
83 size_t spare_blocks = (m_buffer_pos - m_final_minimum) / m_main_block_mod;
84
85 if(spare_blocks) {
86 size_t spare_bytes = m_main_block_mod * spare_blocks;
87 buffered_block(m_buffer.data(), spare_bytes);
88 buffered_final(&m_buffer[spare_bytes], m_buffer_pos - spare_bytes);
89 } else {
90 buffered_final(m_buffer.data(), m_buffer_pos);
91 }
92
93 m_buffer_pos = 0;
94}
95
96} // namespace Botan
virtual void buffered_block(const uint8_t input[], size_t length)=0
Buffered_Filter(size_t block_size, size_t final_minimum)
Definition buf_filt.cpp:19
virtual void buffered_final(const uint8_t input[], size_t length)=0
void write(const uint8_t in[], size_t length)
Definition buf_filt.cpp:35
constexpr T round_down(T n, T align_to)
Definition rounding.h:37
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:146