Botan 2.19.5 Crypto and TLS for C&

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/filters.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*/
97 void Hex_Encoder::end_msg()
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*/
108 Hex_Decoder::Hex_Decoder(Decoder_Checking c) : m_checking(c)
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*/
151 void Hex_Decoder::end_msg()
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}
Botan::Filter::send
virtual void send(const uint8_t in[], size_t length)
Definition: filter.cpp:27
Botan::Hex_Decoder::end_msg
void end_msg() override
Definition: hex_filt.cpp:151
Botan::Hex_Decoder::Hex_Decoder
Hex_Decoder(Decoder_Checking checking=NONE)
Definition: hex_filt.cpp:108
Botan::Hex_Decoder::write
void write(const uint8_t[], size_t) override
Definition: hex_filt.cpp:118
Botan::Hex_Encoder::write
void write(const uint8_t in[], size_t length) override
Definition: hex_filt.cpp:74
Botan::Hex_Encoder::end_msg
void end_msg() override
Definition: hex_filt.cpp:97
Botan::Hex_Encoder::Case
Case
Definition: filters.h:583
Botan::Hex_Encoder::Uppercase
@ Uppercase
Definition: filters.h:583
Botan::Hex_Encoder::Hex_Encoder
Hex_Encoder(Case the_case)
Definition: hex_filt.cpp:34
Botan::Invalid_Argument
Definition: exceptn.h:137
Botan
Definition: alg_id.cpp:13
Botan::buffer_insert
size_t buffer_insert(std::vector< T, Alloc > &buf, size_t buf_offset, const T input[], size_t input_length)
Definition: mem_ops.h:228
Botan::HEX_CODEC_BUFFER_SIZE
const size_t HEX_CODEC_BUFFER_SIZE
Definition: hex_filt.cpp:18
Botan::copy_mem
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:133
Botan::hex_encode
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
Definition: hex.cpp:31
Botan::hex_decode
size_t hex_decode(uint8_t output[], const char input[], size_t input_length, size_t &input_consumed, bool ignore_ws)
Definition: hex.cpp:89
Botan::cast_uint8_ptr_to_char
const char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition: mem_ops.h:195
Botan::Decoder_Checking
Decoder_Checking
Definition: filter.h:171
Botan::FULL_CHECK
@ FULL_CHECK
Definition: filter.h:171