1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Hex binary-to-text encoding
15 /// A trait for converting a value to hexadecimal encoding
17 /// Converts the value of `self` to a hex value, returning the owned
19 fn to_hex(&self) -> ~str;
22 static CHARS: [char, ..16] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
23 'a', 'b', 'c', 'd', 'e', 'f'];
25 impl<'self> ToHex for &'self [u8] {
27 * Turn a vector of `u8` bytes into a hexadecimal string.
33 * use extra::hex::ToHex;
36 * let str = [52,32].to_hex();
37 * printfln!("%s", str);
41 fn to_hex(&self) -> ~str {
42 let mut s = str::with_capacity(self.len() * 2);
43 for &byte in self.iter() {
44 s.push_char(CHARS[byte >> 4]);
45 s.push_char(CHARS[byte & 0xf]);
52 impl<'self> ToHex for &'self str {
54 * Convert any string (literal, `@`, `&`, or `~`) to hexadecimal encoding.
64 * let str = "Hello, World".to_hex();
65 * printfln!("%s", str);
70 fn to_hex(&self) -> ~str {
71 self.as_bytes().to_hex()
75 /// A trait for converting hexadecimal encoded values
77 /// Converts the value of `self`, interpreted as hexadecimal encoded data,
78 /// into an owned vector of bytes, returning the vector.
79 fn from_hex(&self) -> Result<~[u8], ~str>;
82 impl<'self> FromHex for &'self [u8] {
84 * Convert hexadecimal `u8` vector into u8 byte values.
85 * Every 2 encoded characters is converted into 1 octet.
86 * Whitespace is ignored.
92 * use extra::hex::{ToHex, FromHex};
95 * let str = [52,32].to_hex();
96 * printfln!("%s", str);
97 * let bytes = str.from_hex().get();
98 * printfln!("%?", bytes);
102 fn from_hex(&self) -> Result<~[u8], ~str> {
103 // This may be an overestimate if there is any whitespace
104 let mut b = vec::with_capacity(self.len() / 2);
108 for (idx, &byte) in self.iter().enumerate() {
112 'A'..'F' => buf |= byte - ('A' as u8) + 10,
113 'a'..'f' => buf |= byte - ('a' as u8) + 10,
114 '0'..'9' => buf |= byte - ('0' as u8),
115 ' '|'\r'|'\n'|'\t' => {
119 _ => return Err(fmt!("Invalid byte '%c' found at position %u",
132 _ => Err(~"Invalid input length")
137 impl<'self> FromHex for &'self str {
139 * Convert any hexadecimal encoded string (literal, `@`, `&`, or `~`)
140 * to the byte values it encodes.
142 * You can use the `from_bytes` function in `std::str`
143 * to turn a `[u8]` into a string with characters corresponding to those
148 * This converts a string literal to hexadecimal and back.
152 * use extra::hex::{FromHex, ToHex};
156 * let hello_str = "Hello, World".to_hex();
157 * printfln!("%s", hello_str);
158 * let bytes = hello_str.from_hex().get();
159 * printfln!("%?", bytes);
160 * let result_str = str::from_bytes(bytes);
161 * printfln!("%s", result_str);
165 fn from_hex(&self) -> Result<~[u8], ~str> {
166 self.as_bytes().from_hex()
172 use test::BenchHarness;
176 pub fn test_to_hex() {
177 assert_eq!("foobar".to_hex(), ~"666f6f626172");
181 pub fn test_from_hex_okay() {
182 assert_eq!("666f6f626172".from_hex().get(),
183 "foobar".as_bytes().to_owned());
184 assert_eq!("666F6F626172".from_hex().get(),
185 "foobar".as_bytes().to_owned());
189 pub fn test_from_hex_odd_len() {
190 assert!("666".from_hex().is_err());
191 assert!("66 6".from_hex().is_err());
195 pub fn test_from_hex_invalid_char() {
196 assert!("66y6".from_hex().is_err());
200 pub fn test_from_hex_ignores_whitespace() {
201 assert_eq!("666f 6f6\r\n26172 ".from_hex().get(),
202 "foobar".as_bytes().to_owned());
206 pub fn test_to_hex_all_bytes() {
207 for i in range(0, 256) {
208 assert_eq!([i as u8].to_hex(), fmt!("%02x", i as uint));
213 pub fn test_from_hex_all_bytes() {
214 for i in range(0, 256) {
215 assert_eq!(fmt!("%02x", i as uint).from_hex().get(), ~[i as u8]);
216 assert_eq!(fmt!("%02X", i as uint).from_hex().get(), ~[i as u8]);
221 pub fn bench_to_hex(bh: & mut BenchHarness) {
222 let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \
223 ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
227 bh.bytes = s.len() as u64;
231 pub fn bench_from_hex(bh: & mut BenchHarness) {
232 let s = "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム \
233 ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
238 bh.bytes = b.len() as u64;