Botan 3.8.1
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
10#include <botan/exceptn.h>
11#include <botan/hex.h>
12#include <botan/mem_ops.h>
13#include <algorithm>
14
15namespace Botan {
16
17/**
18* Size used for internal buffer in hex encoder/decoder
19*/
20const size_t HEX_CODEC_BUFFER_SIZE = 256;
21
22/*
23* Hex_Encoder Constructor
24*/
25Hex_Encoder::Hex_Encoder(bool breaks, size_t length, Case c) : m_casing(c), m_line_length(breaks ? length : 0) {
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*/
34Hex_Encoder::Hex_Encoder(Case c) : m_casing(c), m_line_length(0) {
35 m_in.resize(HEX_CODEC_BUFFER_SIZE);
36 m_out.resize(2 * m_in.size());
37 m_counter = m_position = 0;
38}
39
40/*
41* Encode and send a block
42*/
43void Hex_Encoder::encode_and_send(const uint8_t block[], size_t length) {
44 hex_encode(cast_uint8_ptr_to_char(m_out.data()), block, length, m_casing == Uppercase);
45
46 if(m_line_length == 0) {
47 send(m_out, 2 * length);
48 } else {
49 size_t remaining = 2 * length, offset = 0;
50 while(remaining) {
51 size_t sent = std::min(m_line_length - m_counter, remaining);
52 send(&m_out[offset], sent);
53 m_counter += sent;
54 remaining -= sent;
55 offset += sent;
56 if(m_counter == m_line_length) {
57 send('\n');
58 m_counter = 0;
59 }
60 }
61 }
62}
63
64/*
65* Convert some data into hex format
66*/
67void Hex_Encoder::write(const uint8_t input[], size_t length) {
68 const size_t initial_fill = std::min(m_in.size() - m_position, length);
69 copy_mem(&m_in[m_position], input, initial_fill);
70
71 if(m_position + length >= m_in.size()) {
72 encode_and_send(m_in.data(), m_in.size());
73 input += (m_in.size() - m_position);
74 length -= (m_in.size() - m_position);
75 while(length >= m_in.size()) {
76 encode_and_send(input, m_in.size());
77 input += m_in.size();
78 length -= m_in.size();
79 }
80 copy_mem(m_in.data(), input, length);
81 m_position = 0;
82 }
83 m_position += length;
84}
85
86/*
87* Flush buffers
88*/
90 encode_and_send(m_in.data(), m_position);
91 if(m_counter && m_line_length) {
92 send('\n');
93 }
94 m_counter = m_position = 0;
95}
96
97/*
98* Hex_Decoder Constructor
99*/
101 m_in.resize(HEX_CODEC_BUFFER_SIZE);
102 m_out.resize(m_in.size() / 2);
103 m_position = 0;
104}
105
106/*
107* Convert some data from hex format
108*/
109void Hex_Decoder::write(const uint8_t input[], size_t length) {
110 while(length) {
111 size_t to_copy = std::min<size_t>(length, m_in.size() - m_position);
112 copy_mem(&m_in[m_position], input, to_copy);
113 m_position += to_copy;
114
115 size_t consumed = 0;
116 size_t written =
117 hex_decode(m_out.data(), cast_uint8_ptr_to_char(m_in.data()), m_position, consumed, m_checking != FULL_CHECK);
118
119 send(m_out, written);
120
121 if(consumed != m_position) {
122 copy_mem(m_in.data(), m_in.data() + consumed, m_position - consumed);
123 m_position = m_position - consumed;
124 } else {
125 m_position = 0;
126 }
127
128 length -= to_copy;
129 input += to_copy;
130 }
131}
132
133/*
134* Flush buffers
135*/
137 size_t consumed = 0;
138 size_t written =
139 hex_decode(m_out.data(), cast_uint8_ptr_to_char(m_in.data()), m_position, consumed, m_checking != FULL_CHECK);
140
141 send(m_out, written);
142
143 const bool not_full_bytes = consumed != m_position;
144
145 m_position = 0;
146
147 if(not_full_bytes) {
148 throw Invalid_Argument("Hex_Decoder: Input not full bytes");
149 }
150}
151
152} // namespace Botan
virtual void send(const uint8_t in[], size_t length)
Definition filter.cpp:33
void end_msg() override
Definition hex_filt.cpp:136
Hex_Decoder(Decoder_Checking checking=NONE)
Definition hex_filt.cpp:100
void write(const uint8_t[], size_t) override
Definition hex_filt.cpp:109
void write(const uint8_t in[], size_t length) override
Definition hex_filt.cpp:67
void end_msg() override
Definition hex_filt.cpp:89
Hex_Encoder(Case the_case)
Definition hex_filt.cpp:34
const size_t HEX_CODEC_BUFFER_SIZE
Definition hex_filt.cpp:20
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
Definition hex.cpp:35
size_t hex_decode(uint8_t output[], const char input[], size_t input_length, size_t &input_consumed, bool ignore_ws)
Definition hex.cpp:73
const char * cast_uint8_ptr_to_char(const uint8_t *b)
Definition mem_ops.h:280
Decoder_Checking
Definition filter.h:164
@ FULL_CHECK
Definition filter.h:164
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:149