monotone

monotone Mtn Source Tree

Root/botan/hex.cpp

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

Archive Download this file

Branches

Tags

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