Botan 2.19.2
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#include <botan/mem_ops.h>
10#include <botan/internal/rounding.h>
11#include <botan/exceptn.h>
12
13namespace Botan {
14
15/*
16* Buffered_Filter Constructor
17*/
19 m_main_block_mod(b), m_final_minimum(f)
20 {
21 if(m_main_block_mod == 0)
22 throw Invalid_Argument("m_main_block_mod == 0");
23
24 if(m_final_minimum > m_main_block_mod)
25 throw Invalid_Argument("m_final_minimum > m_main_block_mod");
26
27 m_buffer.resize(2 * m_main_block_mod);
28 m_buffer_pos = 0;
29 }
30
31/*
32* Buffer input into blocks, trying to minimize copying
33*/
34void Buffered_Filter::write(const uint8_t input[], size_t input_size)
35 {
36 if(!input_size)
37 return;
38
39 if(m_buffer_pos + input_size >= m_main_block_mod + m_final_minimum)
40 {
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,
51 m_buffer_pos + input_size - m_final_minimum),
52 m_main_block_mod);
53
54 buffered_block(m_buffer.data(), total_to_consume);
55
56 m_buffer_pos -= total_to_consume;
57
58 copy_mem(m_buffer.data(), m_buffer.data() + total_to_consume, m_buffer_pos);
59 }
60
61 if(input_size >= m_final_minimum)
62 {
63 size_t full_blocks = (input_size - m_final_minimum) / m_main_block_mod;
64 size_t to_copy = full_blocks * m_main_block_mod;
65
66 if(to_copy)
67 {
68 buffered_block(input, to_copy);
69
70 input += to_copy;
71 input_size -= to_copy;
72 }
73 }
74
75 copy_mem(&m_buffer[m_buffer_pos], input, input_size);
76 m_buffer_pos += input_size;
77 }
78
79/*
80* Finish/flush operation
81*/
83 {
84 if(m_buffer_pos < m_final_minimum)
85 throw Invalid_State("Buffered filter end_msg without enough input");
86
87 size_t spare_blocks = (m_buffer_pos - m_final_minimum) / m_main_block_mod;
88
89 if(spare_blocks)
90 {
91 size_t spare_bytes = m_main_block_mod * spare_blocks;
92 buffered_block(m_buffer.data(), spare_bytes);
93 buffered_final(&m_buffer[spare_bytes], m_buffer_pos - spare_bytes);
94 }
95 else
96 {
97 buffered_final(m_buffer.data(), m_buffer_pos);
98 }
99
100 m_buffer_pos = 0;
101 }
102
103}
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:18
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:34
Definition: alg_id.cpp:13
constexpr T round_down(T n, T align_to)
Definition: rounding.h:37
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:133