Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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