Sha256dHash: add string encoder/decoder
This commit is contained in:
parent
a2ce000b2b
commit
c80ec9bda8
|
@ -134,6 +134,17 @@ impl Sha256dHash {
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Human-readable hex output
|
||||||
|
pub fn be_hex_string(&self) -> String {
|
||||||
|
let &Sha256dHash(data) = self;
|
||||||
|
let mut ret = String::with_capacity(64);
|
||||||
|
for i in range(0u, 32) {
|
||||||
|
ret.push_char(from_digit((data[i] / 0x10) as uint, 16).unwrap());
|
||||||
|
ret.push_char(from_digit((data[i] & 0x0f) as uint, 16).unwrap());
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for Sha256dHash {
|
impl Clone for Sha256dHash {
|
||||||
|
@ -171,10 +182,38 @@ impl Index<uint, u8> for Sha256dHash {
|
||||||
// interface.
|
// interface.
|
||||||
impl ToJson for Sha256dHash {
|
impl ToJson for Sha256dHash {
|
||||||
fn to_json(&self) -> json::Json {
|
fn to_json(&self) -> json::Json {
|
||||||
json::String(self.le_hex_string())
|
json::String(self.be_hex_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Non-consensus encoding (big-endian hex string)
|
||||||
|
impl<S: ::serialize::Encoder<E>, E> ::serialize::Encodable<S, E> for Sha256dHash {
|
||||||
|
#[inline]
|
||||||
|
fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||||
|
s.emit_str(self.be_hex_string().as_slice())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: ::serialize::Decoder<E>, E> ::serialize::Decodable<D, E> for Sha256dHash {
|
||||||
|
#[inline]
|
||||||
|
fn decode(d: &mut D) -> Result<Sha256dHash, E> {
|
||||||
|
use serialize::hex::FromHex;
|
||||||
|
|
||||||
|
let hex_str = try!(d.read_str());
|
||||||
|
if hex_str.len() != 64 {
|
||||||
|
d.error("incorrect hash length");
|
||||||
|
}
|
||||||
|
let raw_str = try!(hex_str.as_slice().from_hex()
|
||||||
|
.map_err(|_| d.error("non-hexadecimal hash string")));
|
||||||
|
let mut ret = [0u8, ..32];
|
||||||
|
for i in range(0, 32) {
|
||||||
|
ret[i] = raw_str[i];
|
||||||
|
}
|
||||||
|
Ok(Sha256dHash(ret))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consensus encoding (little-endian)
|
||||||
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Sha256dHash {
|
impl<S:SimpleEncoder<E>, E> ConsensusEncodable<S, E> for Sha256dHash {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
fn consensus_encode(&self, s: &mut S) -> Result<(), E> {
|
||||||
|
@ -252,7 +291,11 @@ impl <T: BitcoinHash> MerkleRoot for Vec<T> {
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::prelude::*;
|
use std::prelude::*;
|
||||||
use collections::bitv::from_bytes;
|
use collections::bitv::from_bytes;
|
||||||
|
use std::io::{MemWriter, MemReader, Reader, Writer};
|
||||||
|
use std::str::from_utf8;
|
||||||
|
|
||||||
|
use serialize::Encodable;
|
||||||
|
use serialize::json;
|
||||||
use util::hash::Sha256dHash;
|
use util::hash::Sha256dHash;
|
||||||
use util::misc::hex_bytes;
|
use util::misc::hex_bytes;
|
||||||
|
|
||||||
|
@ -271,5 +314,19 @@ mod tests {
|
||||||
assert_eq!(Sha256dHash::from_data(&[]).as_bitv(),
|
assert_eq!(Sha256dHash::from_data(&[]).as_bitv(),
|
||||||
from_bytes(hex_bytes("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456").unwrap().as_slice()));
|
from_bytes(hex_bytes("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456").unwrap().as_slice()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_hash_encode_decode() {
|
||||||
|
let hash = Sha256dHash::from_data(&[]);
|
||||||
|
let mut writer = MemWriter::new();
|
||||||
|
{
|
||||||
|
let mut encoder = json::Encoder::new(&mut writer);
|
||||||
|
assert!(hash.encode(&mut encoder).is_ok());
|
||||||
|
}
|
||||||
|
let res = writer.unwrap();
|
||||||
|
assert_eq!(res.as_slice(),
|
||||||
|
"\"5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456\"".as_bytes());
|
||||||
|
assert_eq!(json::decode(from_utf8(res.as_slice()).unwrap()), Ok(hash));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue