Start moving core::hash to support a Hash trait. Add to_bytes::IterBytes trait.
This commit is contained in:
parent
ab53819a2c
commit
a9619306a5
3 changed files with 413 additions and 39 deletions
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
import io::Writer;
|
import io::Writer;
|
||||||
import io::WriterUtil;
|
import io::WriterUtil;
|
||||||
|
import to_bytes::IterBytes;
|
||||||
|
|
||||||
export Streaming, State;
|
export Streaming, State;
|
||||||
export default_state;
|
export default_state;
|
||||||
|
@ -33,6 +34,21 @@ export hash_u16;
|
||||||
export hash_u8;
|
export hash_u8;
|
||||||
export hash_uint;
|
export hash_uint;
|
||||||
|
|
||||||
|
/// Types that can meaningfully be hashed should implement this.
|
||||||
|
trait Hash {
|
||||||
|
pure fn hash_keyed(k0: u64, k1: u64) -> u64;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When we have default methods, won't need this.
|
||||||
|
trait HashUtil {
|
||||||
|
pure fn hash() -> u64;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <A: Hash> A: HashUtil {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn hash() -> u64 { self.hash_keyed(0,0) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Streaming hash-functions should implement this.
|
/// Streaming hash-functions should implement this.
|
||||||
trait Streaming {
|
trait Streaming {
|
||||||
fn input((&[const u8]));
|
fn input((&[const u8]));
|
||||||
|
@ -43,38 +59,97 @@ trait Streaming {
|
||||||
fn reset();
|
fn reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn keyed(k0: u64, k1: u64, f: fn(s: &State)) -> u64 {
|
impl <A: IterBytes> A: Hash {
|
||||||
|
#[inline(always)]
|
||||||
|
pure fn hash_keyed(k0: u64, k1: u64) -> u64 {
|
||||||
|
unchecked {
|
||||||
let s = &State(k0, k1);
|
let s = &State(k0, k1);
|
||||||
f(s);
|
for self.iter_le_bytes |bytes| {
|
||||||
|
s.input(bytes);
|
||||||
|
}
|
||||||
s.result_u64()
|
s.result_u64()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pure fn hash_bytes_keyed(buf: &[const u8], k0: u64, k1: u64) -> u64 {
|
// implementations
|
||||||
unchecked { keyed(k0, k1, |s| s.input(buf)) }
|
|
||||||
|
pure fn hash_keyed_2<A: IterBytes,
|
||||||
|
B: IterBytes>(a: &A, b: &B,
|
||||||
|
k0: u64, k1: u64) -> u64 {
|
||||||
|
unchecked {
|
||||||
|
let s = &State(k0, k1);
|
||||||
|
for a.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
for b.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
s.result_u64()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pure fn hash_str_keyed(s: &str, k0: u64, k1: u64) -> u64 {
|
|
||||||
unsafe {
|
pure fn hash_keyed_3<A: IterBytes,
|
||||||
do str::as_buf(s) |buf, len| {
|
B: IterBytes,
|
||||||
do vec::unsafe::form_slice(buf, len) |slice| {
|
C: IterBytes>(a: &A, b: &B, c: &C,
|
||||||
hash_bytes_keyed(slice, k0, k1)
|
k0: u64, k1: u64) -> u64 {
|
||||||
|
unchecked {
|
||||||
|
let s = &State(k0, k1);
|
||||||
|
for a.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
for b.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
for c.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
s.result_u64()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pure fn hash_keyed_4<A: IterBytes,
|
||||||
|
B: IterBytes,
|
||||||
|
C: IterBytes,
|
||||||
|
D: IterBytes>(a: &A, b: &B, c: &C, d: &D,
|
||||||
|
k0: u64, k1: u64) -> u64 {
|
||||||
|
unchecked {
|
||||||
|
let s = &State(k0, k1);
|
||||||
|
for a.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
for b.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
for c.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
for d.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
s.result_u64()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pure fn hash_keyed_5<A: IterBytes,
|
||||||
|
B: IterBytes,
|
||||||
|
C: IterBytes,
|
||||||
|
D: IterBytes,
|
||||||
|
E: IterBytes>(a: &A, b: &B, c: &C, d: &D, e: &E,
|
||||||
|
k0: u64, k1: u64) -> u64 {
|
||||||
|
unchecked {
|
||||||
|
let s = &State(k0, k1);
|
||||||
|
for a.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
for b.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
for c.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
for d.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
for e.iter_le_bytes |bytes| { s.input(bytes); }
|
||||||
|
s.result_u64()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pure fn hash_bytes_keyed(val: &[const u8], k0: u64, k1: u64) -> u64 {
|
||||||
|
val.hash_keyed(k0, k1)
|
||||||
|
}
|
||||||
|
pure fn hash_str_keyed(val: &str, k0: u64, k1: u64) -> u64 {
|
||||||
|
val.hash_keyed(k0, k1)
|
||||||
|
}
|
||||||
pure fn hash_u64_keyed(val: u64, k0: u64, k1: u64) -> u64 {
|
pure fn hash_u64_keyed(val: u64, k0: u64, k1: u64) -> u64 {
|
||||||
unchecked { keyed(k0, k1, |s| s.write_le_u64(val)) }
|
val.hash_keyed(k0, k1)
|
||||||
}
|
}
|
||||||
pure fn hash_u32_keyed(val: u32, k0: u64, k1: u64) -> u64 {
|
pure fn hash_u32_keyed(val: u32, k0: u64, k1: u64) -> u64 {
|
||||||
unchecked { keyed(k0, k1, |s| s.write_le_u32(val)) }
|
val.hash_keyed(k0, k1)
|
||||||
}
|
}
|
||||||
pure fn hash_u16_keyed(val: u16, k0: u64, k1: u64) -> u64 {
|
pure fn hash_u16_keyed(val: u16, k0: u64, k1: u64) -> u64 {
|
||||||
unchecked { keyed(k0, k1, |s| s.write_le_u16(val)) }
|
val.hash_keyed(k0, k1)
|
||||||
}
|
}
|
||||||
pure fn hash_u8_keyed(val: u8, k0: u64, k1: u64) -> u64 {
|
pure fn hash_u8_keyed(val: u8, k0: u64, k1: u64) -> u64 {
|
||||||
unchecked { keyed(k0, k1, |s| s.write_u8(val)) }
|
val.hash_keyed(k0, k1)
|
||||||
}
|
}
|
||||||
pure fn hash_uint_keyed(val: uint, k0: u64, k1: u64) -> u64 {
|
pure fn hash_uint_keyed(val: uint, k0: u64, k1: u64) -> u64 {
|
||||||
unchecked { keyed(k0, k1, |s| s.write_le_uint(val)) }
|
val.hash_keyed(k0, k1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pure fn hash_bytes(val: &[const u8]) -> u64 { hash_bytes_keyed(val, 0, 0) }
|
pure fn hash_bytes(val: &[const u8]) -> u64 { hash_bytes_keyed(val, 0, 0) }
|
||||||
|
@ -89,10 +164,13 @@ pure fn hash_uint(val: uint) -> u64 { hash_uint_keyed(val, 0, 0) }
|
||||||
// Implement State as SipState
|
// Implement State as SipState
|
||||||
|
|
||||||
type State = SipState;
|
type State = SipState;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn State(k0: u64, k1: u64) -> State {
|
fn State(k0: u64, k1: u64) -> State {
|
||||||
SipState(k0, k1)
|
SipState(k0, k1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn default_state() -> State {
|
fn default_state() -> State {
|
||||||
State(0,0)
|
State(0,0)
|
||||||
}
|
}
|
||||||
|
@ -109,6 +187,7 @@ struct SipState {
|
||||||
mut ntail: uint; // how many bytes in tail are valid
|
mut ntail: uint; // how many bytes in tail are valid
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn SipState(key0: u64, key1: u64) -> SipState {
|
fn SipState(key0: u64, key1: u64) -> SipState {
|
||||||
let state = SipState {
|
let state = SipState {
|
||||||
k0 : key0,
|
k0 : key0,
|
||||||
|
@ -129,6 +208,7 @@ fn SipState(key0: u64, key1: u64) -> SipState {
|
||||||
impl &SipState : io::Writer {
|
impl &SipState : io::Writer {
|
||||||
|
|
||||||
// Methods for io::writer
|
// Methods for io::writer
|
||||||
|
#[inline(always)]
|
||||||
fn write(msg: &[const u8]) {
|
fn write(msg: &[const u8]) {
|
||||||
|
|
||||||
macro_rules! u8to64_le (
|
macro_rules! u8to64_le (
|
||||||
|
@ -235,10 +315,12 @@ impl &SipState : io::Writer {
|
||||||
|
|
||||||
impl &SipState : Streaming {
|
impl &SipState : Streaming {
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn input(buf: &[const u8]) {
|
fn input(buf: &[const u8]) {
|
||||||
self.write(buf);
|
self.write(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn result_u64() -> u64 {
|
fn result_u64() -> u64 {
|
||||||
let mut v0 = self.v0;
|
let mut v0 = self.v0;
|
||||||
let mut v1 = self.v1;
|
let mut v1 = self.v1;
|
||||||
|
@ -269,7 +351,6 @@ impl &SipState : Streaming {
|
||||||
return (v0 ^ v1 ^ v2 ^ v3);
|
return (v0 ^ v1 ^ v2 ^ v3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn result_bytes() -> ~[u8] {
|
fn result_bytes() -> ~[u8] {
|
||||||
let h = self.result_u64();
|
let h = self.result_u64();
|
||||||
~[(h >> 0) as u8,
|
~[(h >> 0) as u8,
|
||||||
|
@ -290,6 +371,7 @@ impl &SipState : Streaming {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn reset() {
|
fn reset() {
|
||||||
self.length = 0;
|
self.length = 0;
|
||||||
self.v0 = self.k0 ^ 0x736f6d6570736575;
|
self.v0 = self.k0 ^ 0x736f6d6570736575;
|
||||||
|
@ -385,7 +467,7 @@ fn test_siphash() {
|
||||||
while t < 64 {
|
while t < 64 {
|
||||||
debug!("siphash test %?", t);
|
debug!("siphash test %?", t);
|
||||||
let vec = u8to64_le!(vecs[t], 0);
|
let vec = u8to64_le!(vecs[t], 0);
|
||||||
let out = hash_bytes_keyed(buf, k0, k1);
|
let out = buf.hash_keyed(k0, k1);
|
||||||
debug!("got %?, expected %?", out, vec);
|
debug!("got %?, expected %?", out, vec);
|
||||||
assert vec == out;
|
assert vec == out;
|
||||||
|
|
||||||
|
|
|
@ -2,22 +2,314 @@
|
||||||
#[forbid(deprecated_mode)];
|
#[forbid(deprecated_mode)];
|
||||||
#[forbid(deprecated_pattern)];
|
#[forbid(deprecated_pattern)];
|
||||||
|
|
||||||
|
import io::Writer;
|
||||||
|
|
||||||
|
type Cb = fn(buf: &[const u8]) -> bool;
|
||||||
|
|
||||||
|
trait IterBytes {
|
||||||
|
fn iter_le_bytes(f: Cb);
|
||||||
|
fn iter_be_bytes(f: Cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl u8: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) {
|
||||||
|
f([
|
||||||
|
self,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) {
|
||||||
|
f([
|
||||||
|
self as u8
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl u16: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) {
|
||||||
|
f([
|
||||||
|
self as u8,
|
||||||
|
(self >> 8) as u8
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) {
|
||||||
|
f([
|
||||||
|
(self >> 8) as u8,
|
||||||
|
self as u8
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl u32: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) {
|
||||||
|
f([
|
||||||
|
self as u8,
|
||||||
|
(self >> 8) as u8,
|
||||||
|
(self >> 16) as u8,
|
||||||
|
(self >> 24) as u8,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) {
|
||||||
|
f([
|
||||||
|
(self >> 24) as u8,
|
||||||
|
(self >> 16) as u8,
|
||||||
|
(self >> 8) as u8,
|
||||||
|
self as u8
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl u64: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) {
|
||||||
|
f([
|
||||||
|
self as u8,
|
||||||
|
(self >> 8) as u8,
|
||||||
|
(self >> 16) as u8,
|
||||||
|
(self >> 24) as u8,
|
||||||
|
(self >> 32) as u8,
|
||||||
|
(self >> 40) as u8,
|
||||||
|
(self >> 48) as u8,
|
||||||
|
(self >> 56) as u8
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) {
|
||||||
|
f([
|
||||||
|
(self >> 56) as u8,
|
||||||
|
(self >> 48) as u8,
|
||||||
|
(self >> 40) as u8,
|
||||||
|
(self >> 32) as u8,
|
||||||
|
(self >> 24) as u8,
|
||||||
|
(self >> 16) as u8,
|
||||||
|
(self >> 8) as u8,
|
||||||
|
self as u8
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl i8: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) { (self as u8).iter_le_bytes(f) }
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) { (self as u8).iter_be_bytes(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl i16: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) { (self as u16).iter_le_bytes(f) }
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) { (self as u16).iter_be_bytes(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl i32: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) { (self as u32).iter_le_bytes(f) }
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) { (self as u32).iter_be_bytes(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl i64: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) { (self as u64).iter_le_bytes(f) }
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) { (self as u64).iter_be_bytes(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_word_size = "32")]
|
||||||
|
impl uint: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) { (self as u32).iter_le_bytes(f) }
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) { (self as u32).iter_be_bytes(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_word_size = "64")]
|
||||||
|
impl uint: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) { (self as u64).iter_le_bytes(f) }
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) { (self as u64).iter_be_bytes(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl int: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) { (self as uint).iter_le_bytes(f) }
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) { (self as uint).iter_be_bytes(f) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ~[const u8]: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) { f(self); }
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) { f(self); }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl @[const u8]: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) { f(self); }
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) { f(self); }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: IterBytes> &[const A]: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) {
|
||||||
|
for self.each |elt| {
|
||||||
|
do elt.iter_le_bytes |bytes| {
|
||||||
|
f(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) {
|
||||||
|
for self.each |elt| {
|
||||||
|
do elt.iter_be_bytes |bytes| {
|
||||||
|
f(bytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iter_le_bytes_2<A: IterBytes, B: IterBytes>(a: &A, b: &B, f: Cb) {
|
||||||
|
let mut flag = true;
|
||||||
|
a.iter_le_bytes(|bytes| {flag = f(bytes); flag});
|
||||||
|
if !flag { return; }
|
||||||
|
b.iter_le_bytes(|bytes| {flag = f(bytes); flag});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iter_be_bytes_2<A: IterBytes, B: IterBytes>(a: &A, b: &B, f: Cb) {
|
||||||
|
let mut flag = true;
|
||||||
|
a.iter_be_bytes(|bytes| {flag = f(bytes); flag});
|
||||||
|
if !flag { return; }
|
||||||
|
b.iter_be_bytes(|bytes| {flag = f(bytes); flag});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iter_le_bytes_3<A: IterBytes,
|
||||||
|
B: IterBytes,
|
||||||
|
C: IterBytes>(a: &A, b: &B, c: &C, f: Cb) {
|
||||||
|
let mut flag = true;
|
||||||
|
a.iter_le_bytes(|bytes| {flag = f(bytes); flag});
|
||||||
|
if !flag { return; }
|
||||||
|
b.iter_le_bytes(|bytes| { flag = f(bytes); flag});
|
||||||
|
if !flag { return; }
|
||||||
|
c.iter_le_bytes(|bytes| {flag = f(bytes); flag});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn iter_be_bytes_3<A: IterBytes,
|
||||||
|
B: IterBytes,
|
||||||
|
C: IterBytes>(a: &A, b: &B, c: &C, f: Cb) {
|
||||||
|
let mut flag = true;
|
||||||
|
a.iter_be_bytes(|bytes| {flag = f(bytes); flag});
|
||||||
|
if !flag { return; }
|
||||||
|
b.iter_be_bytes(|bytes| {flag = f(bytes); flag});
|
||||||
|
if !flag { return; }
|
||||||
|
c.iter_be_bytes(|bytes| {flag = f(bytes); flag});
|
||||||
|
}
|
||||||
|
|
||||||
|
impl &str: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) {
|
||||||
|
do str::byte_slice(self) |bytes| {
|
||||||
|
f(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) {
|
||||||
|
do str::byte_slice(self) |bytes| {
|
||||||
|
f(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ~str: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) {
|
||||||
|
do str::byte_slice(self) |bytes| {
|
||||||
|
f(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) {
|
||||||
|
do str::byte_slice(self) |bytes| {
|
||||||
|
f(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl @str: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) {
|
||||||
|
do str::byte_slice(self) |bytes| {
|
||||||
|
f(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) {
|
||||||
|
do str::byte_slice(self) |bytes| {
|
||||||
|
f(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<A: IterBytes> &A: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) {
|
||||||
|
(*self).iter_le_bytes(f);
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) {
|
||||||
|
(*self).iter_be_bytes(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: IterBytes> @A: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) {
|
||||||
|
(*self).iter_le_bytes(f);
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) {
|
||||||
|
(*self).iter_be_bytes(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: IterBytes> ~A: IterBytes {
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_le_bytes(f: Cb) {
|
||||||
|
(*self).iter_le_bytes(f);
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn iter_be_bytes(f: Cb) {
|
||||||
|
(*self).iter_be_bytes(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
trait ToBytes {
|
trait ToBytes {
|
||||||
fn to_bytes() -> ~[u8];
|
fn to_le_bytes() -> ~[u8];
|
||||||
|
fn to_be_bytes() -> ~[u8];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ~[u8]: ToBytes {
|
impl<A: IterBytes> A: ToBytes {
|
||||||
fn to_bytes() -> ~[u8] { copy self }
|
fn to_le_bytes() -> ~[u8] {
|
||||||
}
|
let buf = io::mem_buffer();
|
||||||
|
for self.iter_le_bytes |bytes| {
|
||||||
|
buf.write(bytes)
|
||||||
|
}
|
||||||
|
io::mem_buffer_buf(buf)
|
||||||
|
}
|
||||||
|
fn to_be_bytes() -> ~[u8] {
|
||||||
|
let buf = io::mem_buffer();
|
||||||
|
for self.iter_be_bytes |bytes| {
|
||||||
|
buf.write(bytes)
|
||||||
|
}
|
||||||
|
io::mem_buffer_buf(buf)
|
||||||
|
}
|
||||||
|
|
||||||
impl @~[u8]: ToBytes {
|
|
||||||
fn to_bytes() -> ~[u8] { copy *self }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ~str: ToBytes {
|
|
||||||
fn to_bytes() -> ~[u8] { str::to_bytes(self) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl @(~str): ToBytes {
|
|
||||||
fn to_bytes() -> ~[u8] { str::to_bytes(*self) }
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1168,7 +1168,7 @@ pure fn iter_between<T>(v: &[T], start: uint, end: uint, f: fn(T)) {
|
||||||
* Return true to continue, false to break.
|
* Return true to continue, false to break.
|
||||||
*/
|
*/
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pure fn each<T>(v: &[T], f: fn(T) -> bool) {
|
pure fn each<T>(v: &[const T], f: fn(T) -> bool) {
|
||||||
do vec::as_buf(v) |p, n| {
|
do vec::as_buf(v) |p, n| {
|
||||||
let mut n = n;
|
let mut n = n;
|
||||||
let mut p = p;
|
let mut p = p;
|
||||||
|
@ -1206,7 +1206,7 @@ pure fn each_mut<T>(v: &[mut T], f: fn(elem: &mut T) -> bool) {
|
||||||
* Return true to continue, false to break.
|
* Return true to continue, false to break.
|
||||||
*/
|
*/
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pure fn eachi<T>(v: &[T], f: fn(uint, T) -> bool) {
|
pure fn eachi<T>(v: &[const T], f: fn(uint, T) -> bool) {
|
||||||
do vec::as_buf(v) |p, n| {
|
do vec::as_buf(v) |p, n| {
|
||||||
let mut i = 0u;
|
let mut i = 0u;
|
||||||
let mut p = p;
|
let mut p = p;
|
||||||
|
@ -1916,12 +1916,12 @@ mod u8 {
|
||||||
// This cannot be used with iter-trait.rs because of the region pointer
|
// This cannot be used with iter-trait.rs because of the region pointer
|
||||||
// required in the slice.
|
// required in the slice.
|
||||||
|
|
||||||
impl<A> &[A]: iter::BaseIter<A> {
|
impl<A> &[const A]: iter::BaseIter<A> {
|
||||||
pure fn each(blk: fn(A) -> bool) { each(self, blk) }
|
pure fn each(blk: fn(A) -> bool) { each(self, blk) }
|
||||||
pure fn size_hint() -> Option<uint> { Some(len(self)) }
|
pure fn size_hint() -> Option<uint> { Some(len(self)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A> &[A]: iter::ExtendedIter<A> {
|
impl<A> &[const A]: iter::ExtendedIter<A> {
|
||||||
pure fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) }
|
pure fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) }
|
||||||
pure fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
|
pure fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
|
||||||
pure fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }
|
pure fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue