monotone

monotone Mtn Source Tree

Root/botan/hex.cpp

1/*************************************************
2* Hex Encoder/Decoder Source File *
3* (C) 1999-2006 The Botan Project *
4*************************************************/
5
6#include <botan/hex.h>
7#include <botan/bit_ops.h>
8#include <botan/parsing.h>
9#include <botan/charset.h>
10#include <algorithm>
11
12namespace Botan {
13
14/*************************************************
15* Hex_Encoder Constructor *
16*************************************************/
17Hex_Encoder::Hex_Encoder(bool breaks, u32bit length, Case c) :
18 casing(c), line_length(breaks ? length : 0)
19 {
20 in.create(64);
21 out.create(2*in.size());
22 counter = position = 0;
23 }
24
25/*************************************************
26* Hex_Encoder Constructor *
27*************************************************/
28Hex_Encoder::Hex_Encoder(Case c) : casing(c), line_length(0)
29 {
30 in.create(64);
31 out.create(2*in.size());
32 counter = position = 0;
33 }
34
35/*************************************************
36* Hex Encoding Operation *
37*************************************************/
38void Hex_Encoder::encode(byte in, byte out[2], Hex_Encoder::Case casing)
39 {
40 const byte* BIN_TO_HEX = ((casing == Uppercase) ? BIN_TO_HEX_UPPER :
41 BIN_TO_HEX_LOWER);
42
43 out[0] = BIN_TO_HEX[((in >> 4) & 0x0F)];
44 out[1] = BIN_TO_HEX[((in ) & 0x0F)];
45 }
46
47/*************************************************
48* Encode and send a block *
49*************************************************/
50void Hex_Encoder::encode_and_send(const byte block[], u32bit length)
51 {
52 for(u32bit j = 0; j != length; ++j)
53 encode(block[j], out + 2*j, casing);
54
55 if(line_length == 0)
56 send(out, 2*length);
57 else
58 {
59 u32bit remaining = 2*length, offset = 0;
60 while(remaining)
61 {
62 u32bit sent = std::min(line_length - counter, remaining);
63 send(out + offset, sent);
64 counter += sent;
65 remaining -= sent;
66 offset += sent;
67 if(counter == line_length)
68 {
69 send('\n');
70 counter = 0;
71 }
72 }
73 }
74 }
75
76/*************************************************
77* Convert some data into hex format *
78*************************************************/
79void Hex_Encoder::write(const byte input[], u32bit length)
80 {
81 in.copy(position, input, length);
82 if(position + length >= in.size())
83 {
84 encode_and_send(in, in.size());
85 input += (in.size() - position);
86 length -= (in.size() - position);
87 while(length >= in.size())
88 {
89 encode_and_send(input, in.size());
90 input += in.size();
91 length -= in.size();
92 }
93 in.copy(input, length);
94 position = 0;
95 }
96 position += length;
97 }
98
99/*************************************************
100* Flush buffers *
101*************************************************/
102void Hex_Encoder::end_msg()
103 {
104 encode_and_send(in, position);
105 if(counter && line_length)
106 send('\n');
107 counter = position = 0;
108 }
109
110/*************************************************
111* Hex_Decoder Constructor *
112*************************************************/
113Hex_Decoder::Hex_Decoder(Decoder_Checking c) : checking(c)
114 {
115 in.create(64);
116 out.create(in.size() / 2);
117 position = 0;
118 }
119
120/*************************************************
121* Check if a character is a valid hex char *
122*************************************************/
123bool Hex_Decoder::is_valid(byte in)
124 {
125 return (HEX_TO_BIN[in] != 0x80);
126 }
127
128/*************************************************
129* Handle processing an invalid character *
130*************************************************/
131void Hex_Decoder::handle_bad_char(byte c)
132 {
133 if(checking == NONE)
134 return;
135
136 if((checking == IGNORE_WS) && Charset::is_space(c))
137 return;
138
139 throw Decoding_Error("Hex_Decoder: Invalid hex character: " +
140 to_string(c));
141 }
142
143/*************************************************
144* Hex Decoding Operation *
145*************************************************/
146byte Hex_Decoder::decode(const byte hex[2])
147 {
148 return (byte)((HEX_TO_BIN[hex[0]] << 4) | HEX_TO_BIN[hex[1]]);
149 }
150
151/*************************************************
152* Decode and send a block *
153*************************************************/
154void Hex_Decoder::decode_and_send(const byte block[], u32bit length)
155 {
156 for(u32bit j = 0; j != length / 2; ++j)
157 out[j] = decode(block + 2*j);
158 send(out, length / 2);
159 }
160
161/*************************************************
162* Convert some data from hex format *
163*************************************************/
164void Hex_Decoder::write(const byte input[], u32bit length)
165 {
166 for(u32bit j = 0; j != length; ++j)
167 {
168 if(is_valid(input[j]))
169 in[position++] = input[j];
170 else
171 handle_bad_char(input[j]);
172 if(position == in.size())
173 {
174 decode_and_send(in, in.size());
175 position = 0;
176 }
177 }
178 }
179
180/*************************************************
181* Flush buffers *
182*************************************************/
183void Hex_Decoder::end_msg()
184 {
185 decode_and_send(in, position);
186 position = 0;
187 }
188
189}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status