Botan 1.10.17
buf_filt.cpp
Go to the documentation of this file.
1/*
2* Buffered Filter
3* (C) 1999-2007 Jack Lloyd
4*
5* Distributed under the terms of the Botan license
6*/
7
8#include <botan/buf_filt.h>
9#include <botan/mem_ops.h>
10#include <botan/internal/rounding.h>
11#include <stdexcept>
12
13namespace Botan {
14
15/*
16* Buffered_Filter Constructor
17*/
19 main_block_mod(b), final_minimum(f)
20 {
21 if(main_block_mod == 0)
22 throw std::invalid_argument("main_block_mod == 0");
23
24 if(final_minimum > main_block_mod)
25 throw std::invalid_argument("final_minimum > main_block_mod");
26
27 buffer.resize(2 * main_block_mod);
28 buffer_pos = 0;
29 }
30
31/*
32* Buffer input into blocks, trying to minimize copying
33*/
34void Buffered_Filter::write(const byte input[], size_t input_size)
35 {
36 if(!input_size)
37 return;
38
39 if(buffer_pos + input_size >= main_block_mod + final_minimum)
40 {
41 size_t to_copy = std::min<size_t>(buffer.size() - buffer_pos, input_size);
42
43 copy_mem(&buffer[buffer_pos], input, to_copy);
44 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(buffer_pos,
51 buffer_pos + input_size - final_minimum),
52 main_block_mod);
53
54 buffered_block(&buffer[0], total_to_consume);
55
56 buffer_pos -= total_to_consume;
57
58 copy_mem(&buffer[0], &buffer[total_to_consume], buffer_pos);
59 }
60
61 if(input_size >= final_minimum)
62 {
63 size_t full_blocks = (input_size - final_minimum) / main_block_mod;
64 size_t to_copy = full_blocks * 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(&buffer[buffer_pos], input, input_size);
76 buffer_pos += input_size;
77 }
78
79/*
80* Finish/flush operation
81*/
83 {
84 if(buffer_pos < final_minimum)
85 throw std::runtime_error("Buffered filter end_msg without enough input");
86
87 size_t spare_blocks = (buffer_pos - final_minimum) / main_block_mod;
88
89 if(spare_blocks)
90 {
91 size_t spare_bytes = main_block_mod * spare_blocks;
92 buffered_block(&buffer[0], spare_bytes);
93 buffered_final(&buffer[spare_bytes], buffer_pos - spare_bytes);
94 }
95 else
96 {
97 buffered_final(&buffer[0], buffer_pos);
98 }
99
100 buffer_pos = 0;
101 }
102
103}
virtual void buffered_block(const byte input[], size_t length)=0
Buffered_Filter(size_t block_size, size_t final_minimum)
Definition buf_filt.cpp:18
void write(const byte in[], size_t length)
Definition buf_filt.cpp:34
virtual void buffered_final(const byte input[], size_t length)=0
T round_down(T n, T align_to)
Definition rounding.h:36
void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:22