Botan 3.0.0-alpha0
Crypto and TLS for C&
b64_filt.cpp
Go to the documentation of this file.
1/*
2* Base64 Encoder/Decoder
3* (C) 1999-2010 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/base64.h>
10#include <botan/exceptn.h>
11#include <algorithm>
12
13namespace Botan {
14
15/*
16* Base64_Encoder Constructor
17*/
19 size_t line_length,
20 bool trailing_newline) :
21 m_line_length(line_breaks ? line_length : 0),
22 m_trailing_newline(trailing_newline && line_breaks),
23 m_in(48),
24 m_out(64),
25 m_position(0),
26 m_out_position(0)
27 {
28 }
29
30/*
31* Encode and send a block
32*/
33void Base64_Encoder::encode_and_send(const uint8_t input[], size_t length,
34 bool final_inputs)
35 {
36 while(length)
37 {
38 const size_t proc = std::min(length, m_in.size());
39
40 size_t consumed = 0;
41 size_t produced = base64_encode(cast_uint8_ptr_to_char(m_out.data()),
42 input, proc, consumed, final_inputs);
43
44 do_output(m_out.data(), produced);
45
46 // FIXME: s/proc/consumed/?
47 input += proc;
48 length -= proc;
49 }
50 }
51
52/*
53* Handle the output
54*/
55void Base64_Encoder::do_output(const uint8_t input[], size_t length)
56 {
57 if(m_line_length == 0)
58 send(input, length);
59 else
60 {
61 size_t remaining = length, offset = 0;
62 while(remaining)
63 {
64 size_t sent = std::min(m_line_length - m_out_position, remaining);
65 send(input + offset, sent);
66 m_out_position += sent;
67 remaining -= sent;
68 offset += sent;
69 if(m_out_position == m_line_length)
70 {
71 send('\n');
72 m_out_position = 0;
73 }
74 }
75 }
76 }
77
78/*
79* Convert some data into Base64
80*/
81void Base64_Encoder::write(const uint8_t input[], size_t length)
82 {
83 buffer_insert(m_in, m_position, input, length);
84 if(m_position + length >= m_in.size())
85 {
86 encode_and_send(m_in.data(), m_in.size());
87 input += (m_in.size() - m_position);
88 length -= (m_in.size() - m_position);
89 while(length >= m_in.size())
90 {
91 encode_and_send(input, m_in.size());
92 input += m_in.size();
93 length -= m_in.size();
94 }
95 copy_mem(m_in.data(), input, length);
96 m_position = 0;
97 }
98 m_position += length;
99 }
100
101/*
102* Flush buffers
103*/
105 {
106 encode_and_send(m_in.data(), m_position, true);
107
108 if(m_trailing_newline || (m_out_position && m_line_length))
109 send('\n');
110
111 m_out_position = m_position = 0;
112 }
113
114/*
115* Base64_Decoder Constructor
116*/
118 m_checking(c), m_in(64), m_out(48), m_position(0)
119 {
120 }
121
122/*
123* Convert some data from Base64
124*/
125void Base64_Decoder::write(const uint8_t input[], size_t length)
126 {
127 while(length)
128 {
129 size_t to_copy = std::min<size_t>(length, m_in.size() - m_position);
130 if(to_copy == 0)
131 {
132 m_in.resize(m_in.size()*2);
133 m_out.resize(m_out.size()*2);
134 }
135 copy_mem(&m_in[m_position], input, to_copy);
136 m_position += to_copy;
137
138 size_t consumed = 0;
139 size_t written = base64_decode(m_out.data(),
140 cast_uint8_ptr_to_char(m_in.data()),
141 m_position,
142 consumed,
143 false,
144 m_checking != FULL_CHECK);
145
146 send(m_out, written);
147
148 if(consumed != m_position)
149 {
150 copy_mem(m_in.data(), m_in.data() + consumed, m_position - consumed);
151 m_position = m_position - consumed;
152 }
153 else
154 m_position = 0;
155
156 length -= to_copy;
157 input += to_copy;
158 }
159 }
160
161/*
162* Flush buffers
163*/
165 {
166 size_t consumed = 0;
167 size_t written = base64_decode(m_out.data(),
168 cast_uint8_ptr_to_char(m_in.data()),
169 m_position,
170 consumed,
171 true,
172 m_checking != FULL_CHECK);
173
174 send(m_out, written);
175
176 const bool not_full_bytes = consumed != m_position;
177
178 m_position = 0;
179
180 if(not_full_bytes)
181 throw Invalid_Argument("Base64_Decoder: Input not full bytes");
182 }
183
184}
Base64_Decoder(Decoder_Checking checking=NONE)
Definition: b64_filt.cpp:117
void end_msg() override
Definition: b64_filt.cpp:164
void write(const uint8_t input[], size_t length) override
Definition: b64_filt.cpp:125
void write(const uint8_t input[], size_t length) override
Definition: b64_filt.cpp:81
Base64_Encoder(bool line_breaks=false, size_t line_length=72, bool trailing_newline=false)
Definition: b64_filt.cpp:18
void end_msg() override
Definition: b64_filt.cpp:104
virtual void send(const uint8_t in[], size_t length)
Definition: filter.cpp:27
Definition: alg_id.cpp:13
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: mem_ops.h:221
size_t base64_encode(char out[], const uint8_t in[], size_t input_length, size_t &input_consumed, bool final_inputs)
Definition: base64.cpp:185
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:126
size_t base64_decode(uint8_t out[], const char in[], size_t input_length, size_t &input_consumed, bool final_inputs, bool ignore_ws)
Definition: base64.cpp:200
const char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition: mem_ops.h:188
Decoder_Checking
Definition: filter.h:166
@ FULL_CHECK
Definition: filter.h:166