Botan  2.6.0
Crypto and TLS for C++11
hex_filt.cpp
Go to the documentation of this file.
1 /*
2 * Hex Encoder/Decoder
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/hex_filt.h>
9 #include <botan/hex.h>
10 #include <botan/exceptn.h>
11 #include <algorithm>
12 
13 namespace Botan {
14 
15 /**
16 * Size used for internal buffer in hex encoder/decoder
17 */
18 const size_t HEX_CODEC_BUFFER_SIZE = 256;
19 
20 /*
21 * Hex_Encoder Constructor
22 */
23 Hex_Encoder::Hex_Encoder(bool breaks, size_t length, Case c) :
24  m_casing(c), m_line_length(breaks ? length : 0)
25  {
26  m_in.resize(HEX_CODEC_BUFFER_SIZE);
27  m_out.resize(2*m_in.size());
28  m_counter = m_position = 0;
29  }
30 
31 /*
32 * Hex_Encoder Constructor
33 */
34 Hex_Encoder::Hex_Encoder(Case c) : m_casing(c), m_line_length(0)
35  {
36  m_in.resize(HEX_CODEC_BUFFER_SIZE);
37  m_out.resize(2*m_in.size());
38  m_counter = m_position = 0;
39  }
40 
41 /*
42 * Encode and send a block
43 */
44 void Hex_Encoder::encode_and_send(const uint8_t block[], size_t length)
45  {
46  hex_encode(cast_uint8_ptr_to_char(m_out.data()),
47  block, length,
48  m_casing == Uppercase);
49 
50  if(m_line_length == 0)
51  send(m_out, 2*length);
52  else
53  {
54  size_t remaining = 2*length, offset = 0;
55  while(remaining)
56  {
57  size_t sent = std::min(m_line_length - m_counter, remaining);
58  send(&m_out[offset], sent);
59  m_counter += sent;
60  remaining -= sent;
61  offset += sent;
62  if(m_counter == m_line_length)
63  {
64  send('\n');
65  m_counter = 0;
66  }
67  }
68  }
69  }
70 
71 /*
72 * Convert some data into hex format
73 */
74 void Hex_Encoder::write(const uint8_t input[], size_t length)
75  {
76  buffer_insert(m_in, m_position, input, length);
77  if(m_position + length >= m_in.size())
78  {
79  encode_and_send(m_in.data(), m_in.size());
80  input += (m_in.size() - m_position);
81  length -= (m_in.size() - m_position);
82  while(length >= m_in.size())
83  {
84  encode_and_send(input, m_in.size());
85  input += m_in.size();
86  length -= m_in.size();
87  }
88  copy_mem(m_in.data(), input, length);
89  m_position = 0;
90  }
91  m_position += length;
92  }
93 
94 /*
95 * Flush buffers
96 */
98  {
99  encode_and_send(m_in.data(), m_position);
100  if(m_counter && m_line_length)
101  send('\n');
102  m_counter = m_position = 0;
103  }
104 
105 /*
106 * Hex_Decoder Constructor
107 */
109  {
110  m_in.resize(HEX_CODEC_BUFFER_SIZE);
111  m_out.resize(m_in.size() / 2);
112  m_position = 0;
113  }
114 
115 /*
116 * Convert some data from hex format
117 */
118 void Hex_Decoder::write(const uint8_t input[], size_t length)
119  {
120  while(length)
121  {
122  size_t to_copy = std::min<size_t>(length, m_in.size() - m_position);
123  copy_mem(&m_in[m_position], input, to_copy);
124  m_position += to_copy;
125 
126  size_t consumed = 0;
127  size_t written = hex_decode(m_out.data(),
128  cast_uint8_ptr_to_char(m_in.data()),
129  m_position,
130  consumed,
131  m_checking != FULL_CHECK);
132 
133  send(m_out, written);
134 
135  if(consumed != m_position)
136  {
137  copy_mem(m_in.data(), m_in.data() + consumed, m_position - consumed);
138  m_position = m_position - consumed;
139  }
140  else
141  m_position = 0;
142 
143  length -= to_copy;
144  input += to_copy;
145  }
146  }
147 
148 /*
149 * Flush buffers
150 */
152  {
153  size_t consumed = 0;
154  size_t written = hex_decode(m_out.data(),
155  cast_uint8_ptr_to_char(m_in.data()),
156  m_position,
157  consumed,
158  m_checking != FULL_CHECK);
159 
160  send(m_out, written);
161 
162  const bool not_full_bytes = consumed != m_position;
163 
164  m_position = 0;
165 
166  if(not_full_bytes)
167  throw Invalid_Argument("Hex_Decoder: Input not full bytes");
168  }
169 
170 }
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
Definition: hex.cpp:14
virtual void send(const uint8_t in[], size_t length)
Definition: filter.cpp:27
void write(const uint8_t in[], size_t length) override
Definition: hex_filt.cpp:74
const size_t HEX_CODEC_BUFFER_SIZE
Definition: hex_filt.cpp:18
void write(const uint8_t[], size_t) override
Definition: hex_filt.cpp:118
Hex_Decoder(Decoder_Checking checking=NONE)
Definition: hex_filt.cpp:108
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:108
Definition: alg_id.cpp:13
size_t hex_decode(uint8_t output[], const char input[], size_t input_length, size_t &input_consumed, bool ignore_ws)
Definition: hex.cpp:49
void end_msg() override
Definition: hex_filt.cpp:151
Hex_Encoder(Case the_case)
Definition: hex_filt.cpp:34
const char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition: mem_ops.h:136
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: secmem.h:103
void end_msg() override
Definition: hex_filt.cpp:97
Decoder_Checking
Definition: filter.h:179