monotone

monotone Mtn Source Tree

Root/botan/hex.cpp

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

Archive Download this file

Branches

Tags

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