Botan  1.10.9
b64_filt.cpp
Go to the documentation of this file.
1 /*
2 * Base64 Encoder/Decoder
3 * (C) 1999-2010 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
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  line_length(breaks ? length : 0),
21  trailing_newline(t_n && breaks),
22  in(48),
23  out(64),
24  position(0),
25  out_position(0)
26  {
27  }
28 
29 /*
30 * Encode and send a block
31 */
32 void Base64_Encoder::encode_and_send(const byte input[], size_t length,
33  bool final_inputs)
34  {
35  while(length)
36  {
37  const size_t proc = std::min(length, in.size());
38 
39  size_t consumed = 0;
40  size_t produced = base64_encode(reinterpret_cast<char*>(&out[0]), input,
41  proc, consumed, final_inputs);
42 
43  do_output(&out[0], 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 byte input[], size_t length)
55  {
56  if(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(line_length - out_position, remaining);
64  send(input + offset, sent);
65  out_position += sent;
66  remaining -= sent;
67  offset += sent;
68  if(out_position == line_length)
69  {
70  send('\n');
71  out_position = 0;
72  }
73  }
74  }
75  }
76 
77 /*
78 * Convert some data into Base64
79 */
80 void Base64_Encoder::write(const byte input[], size_t length)
81  {
82  in.copy(position, input, length);
83  if(position + length >= in.size())
84  {
85  encode_and_send(&in[0], in.size());
86  input += (in.size() - position);
87  length -= (in.size() - position);
88  while(length >= in.size())
89  {
90  encode_and_send(input, in.size());
91  input += in.size();
92  length -= in.size();
93  }
94  in.copy(input, length);
95  position = 0;
96  }
97  position += length;
98  }
99 
100 /*
101 * Flush buffers
102 */
104  {
105  encode_and_send(&in[0], position, true);
106 
107  if(trailing_newline || (out_position && line_length))
108  send('\n');
109 
110  out_position = position = 0;
111  }
112 
113 /*
114 * Base64_Decoder Constructor
115 */
117  checking(c), in(64), out(48), position(0)
118  {
119  }
120 
121 /*
122 * Convert some data from Base64
123 */
124 void Base64_Decoder::write(const byte input[], size_t length)
125  {
126  while(length)
127  {
128  size_t to_copy = std::min<size_t>(length, in.size() - position);
129  copy_mem(&in[position], input, to_copy);
130  position += to_copy;
131 
132  size_t consumed = 0;
133  size_t written = base64_decode(&out[0],
134  reinterpret_cast<const char*>(&in[0]),
135  position,
136  consumed,
137  false,
138  checking != FULL_CHECK);
139 
140  send(out, written);
141 
142  if(consumed != position)
143  {
144  copy_mem(&in[0], &in[consumed], position - consumed);
145  position = position - consumed;
146  }
147  else
148  position = 0;
149 
150  length -= to_copy;
151  input += to_copy;
152  }
153  }
154 
155 /*
156 * Flush buffers
157 */
159  {
160  size_t consumed = 0;
161  size_t written = base64_decode(&out[0],
162  reinterpret_cast<const char*>(&in[0]),
163  position,
164  consumed,
165  true,
166  checking != FULL_CHECK);
167 
168  send(out, written);
169 
170  const bool not_full_bytes = consumed != position;
171 
172  position = 0;
173 
174  if(not_full_bytes)
175  throw std::invalid_argument("Base64_Decoder: Input not full bytes");
176  }
177 
178 }
Base64_Encoder(bool breaks=false, size_t length=72, bool t_n=false)
Definition: b64_filt.cpp:19
size_t base64_decode(byte output[], const char input[], size_t input_length, size_t &input_consumed, bool final_inputs, bool ignore_ws)
Definition: base64.cpp:100
Base64_Decoder(Decoder_Checking checking=NONE)
Definition: b64_filt.cpp:116
void copy(const T in[], size_t n)
Definition: secmem.h:120
unsigned char byte
Definition: types.h:22
void send(const byte in[], size_t length)
Definition: filter.cpp:28
void write(const byte input[], size_t length)
Definition: b64_filt.cpp:124
size_t size() const
Definition: secmem.h:29
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:22
void write(const byte input[], size_t length)
Definition: b64_filt.cpp:80
size_t base64_encode(char out[], const byte in[], size_t input_length, size_t &input_consumed, bool final_inputs)
Definition: base64.cpp:36
Decoder_Checking
Definition: filter.h:155