diff options
author | lloyd <[email protected]> | 2008-09-28 22:14:54 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2008-09-28 22:14:54 +0000 |
commit | 31204986023619c385d378e79a6511bb81ef7b78 (patch) | |
tree | ce272a6585dc070f750f6875b0450d53145b935d /src/codec/hex/hex.cpp | |
parent | 42c0fe76ab6d9625d0e51c68b8dd187322c991bd (diff) |
Move almost all of the ASN.1, BER, and DER codec related code into new
module asn1
Move hex and base64 codecs into new codecs directory. Also move zlib and
bzip2 to codecs from compress.
Diffstat (limited to 'src/codec/hex/hex.cpp')
-rw-r--r-- | src/codec/hex/hex.cpp | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/src/codec/hex/hex.cpp b/src/codec/hex/hex.cpp new file mode 100644 index 000000000..afb082f76 --- /dev/null +++ b/src/codec/hex/hex.cpp @@ -0,0 +1,188 @@ +/************************************************* +* Hex Encoder/Decoder Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include <botan/hex.h> +#include <botan/parsing.h> +#include <botan/charset.h> +#include <algorithm> + +namespace Botan { + +/************************************************* +* Hex_Encoder Constructor * +*************************************************/ +Hex_Encoder::Hex_Encoder(bool breaks, u32bit length, Case c) : + casing(c), line_length(breaks ? length : 0) + { + in.create(64); + out.create(2*in.size()); + counter = position = 0; + } + +/************************************************* +* Hex_Encoder Constructor * +*************************************************/ +Hex_Encoder::Hex_Encoder(Case c) : casing(c), line_length(0) + { + in.create(64); + out.create(2*in.size()); + counter = position = 0; + } + +/************************************************* +* Hex Encoding Operation * +*************************************************/ +void Hex_Encoder::encode(byte in, byte out[2], Hex_Encoder::Case casing) + { + const byte* BIN_TO_HEX = ((casing == Uppercase) ? BIN_TO_HEX_UPPER : + BIN_TO_HEX_LOWER); + + out[0] = BIN_TO_HEX[((in >> 4) & 0x0F)]; + out[1] = BIN_TO_HEX[((in ) & 0x0F)]; + } + +/************************************************* +* Encode and send a block * +*************************************************/ +void Hex_Encoder::encode_and_send(const byte block[], u32bit length) + { + for(u32bit j = 0; j != length; ++j) + encode(block[j], out + 2*j, casing); + + if(line_length == 0) + send(out, 2*length); + else + { + u32bit remaining = 2*length, offset = 0; + while(remaining) + { + u32bit sent = std::min(line_length - counter, remaining); + send(out + offset, sent); + counter += sent; + remaining -= sent; + offset += sent; + if(counter == line_length) + { + send('\n'); + counter = 0; + } + } + } + } + +/************************************************* +* Convert some data into hex format * +*************************************************/ +void Hex_Encoder::write(const byte input[], u32bit length) + { + in.copy(position, input, length); + if(position + length >= in.size()) + { + encode_and_send(in, in.size()); + input += (in.size() - position); + length -= (in.size() - position); + while(length >= in.size()) + { + encode_and_send(input, in.size()); + input += in.size(); + length -= in.size(); + } + in.copy(input, length); + position = 0; + } + position += length; + } + +/************************************************* +* Flush buffers * +*************************************************/ +void Hex_Encoder::end_msg() + { + encode_and_send(in, position); + if(counter && line_length) + send('\n'); + counter = position = 0; + } + +/************************************************* +* Hex_Decoder Constructor * +*************************************************/ +Hex_Decoder::Hex_Decoder(Decoder_Checking c) : checking(c) + { + in.create(64); + out.create(in.size() / 2); + position = 0; + } + +/************************************************* +* Check if a character is a valid hex char * +*************************************************/ +bool Hex_Decoder::is_valid(byte in) + { + return (HEX_TO_BIN[in] != 0x80); + } + +/************************************************* +* Handle processing an invalid character * +*************************************************/ +void Hex_Decoder::handle_bad_char(byte c) + { + if(checking == NONE) + return; + + if((checking == IGNORE_WS) && Charset::is_space(c)) + return; + + throw Decoding_Error("Hex_Decoder: Invalid hex character: " + + to_string(c)); + } + +/************************************************* +* Hex Decoding Operation * +*************************************************/ +byte Hex_Decoder::decode(const byte hex[2]) + { + return ((HEX_TO_BIN[hex[0]] << 4) | HEX_TO_BIN[hex[1]]); + } + +/************************************************* +* Decode and send a block * +*************************************************/ +void Hex_Decoder::decode_and_send(const byte block[], u32bit length) + { + for(u32bit j = 0; j != length / 2; ++j) + out[j] = decode(block + 2*j); + send(out, length / 2); + } + +/************************************************* +* Convert some data from hex format * +*************************************************/ +void Hex_Decoder::write(const byte input[], u32bit length) + { + for(u32bit j = 0; j != length; ++j) + { + if(is_valid(input[j])) + in[position++] = input[j]; + else + handle_bad_char(input[j]); + if(position == in.size()) + { + decode_and_send(in, in.size()); + position = 0; + } + } + } + +/************************************************* +* Flush buffers * +*************************************************/ +void Hex_Decoder::end_msg() + { + decode_and_send(in, position); + position = 0; + } + +} |