Botan 3.6.1
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
13namespace Botan {
14
15/*
16* Buffered_Filter Constructor
17*/
18Buffered_Filter::Buffered_Filter(size_t b, size_t f) : m_main_block_mod(b), m_final_minimum(f) {
19 if(m_main_block_mod == 0) {
20 throw Invalid_Argument("m_main_block_mod == 0");
21 }
22
23 if(m_final_minimum > m_main_block_mod) {
24 throw Invalid_Argument("m_final_minimum > m_main_block_mod");
25 }
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 if(!input_size) {
36 return;
37 }
38
39 if(m_buffer_pos + input_size >= m_main_block_mod + m_final_minimum) {
40 size_t to_copy = std::min<size_t>(m_buffer.size() - m_buffer_pos, input_size);
41
42 copy_mem(&m_buffer[m_buffer_pos], input, to_copy);
43 m_buffer_pos += to_copy;
44
45 input += to_copy;
46 input_size -= to_copy;
47
48 const size_t available = std::min(m_buffer_pos, m_buffer_pos + input_size - m_final_minimum);
49
50 // Size down to available block size
51 const size_t total_to_consume = available - (available % m_main_block_mod);
52
53 buffered_block(m_buffer.data(), total_to_consume);
54
55 m_buffer_pos -= total_to_consume;
56
57 copy_mem(m_buffer.data(), m_buffer.data() + total_to_consume, m_buffer_pos);
58 }
59
60 if(input_size >= m_final_minimum) {
61 size_t full_blocks = (input_size - m_final_minimum) / m_main_block_mod;
62 size_t to_copy = full_blocks * m_main_block_mod;
63
64 if(to_copy) {
65 buffered_block(input, to_copy);
66
67 input += to_copy;
68 input_size -= to_copy;
69 }
70 }
71
72 copy_mem(&m_buffer[m_buffer_pos], input, input_size);
73 m_buffer_pos += input_size;
74}
75
76/*
77* Finish/flush operation
78*/
80 if(m_buffer_pos < m_final_minimum) {
81 throw Invalid_State("Buffered filter end_msg without enough input");
82 }
83
84 size_t spare_blocks = (m_buffer_pos - m_final_minimum) / m_main_block_mod;
85
86 if(spare_blocks) {
87 size_t spare_bytes = m_main_block_mod * spare_blocks;
88 buffered_block(m_buffer.data(), spare_bytes);
89 buffered_final(&m_buffer[spare_bytes], m_buffer_pos - spare_bytes);
90 } else {
91 buffered_final(m_buffer.data(), m_buffer_pos);
92 }
93
94 m_buffer_pos = 0;
95}
96
97} // 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: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
const SIMD_8x32 & b
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:146