(index<- )        ./libstd/to_bytes.rs

   1  // Copyright 2012 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.
   4  //
   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.
  10  
  11  /*!
  12  
  13  The `ToBytes` and `IterBytes` traits
  14  
  15  */
  16  
  17  use cast;
  18  use container::Container;
  19  use io;
  20  use io::Writer;
  21  use iter::Iterator;
  22  use option::{None, Option, Some};
  23  use str::{Str, StrSlice};
  24  use vec::{Vector, ImmutableVector};
  25  
  26  pub type Cb<'self> = &'self fn(buf: &[u8]) -> bool;
  27  
  28  ///
  29  /// A trait to implement in order to make a type hashable;
  30  /// This works in combination with the trait `std::hash::Hash`, and
  31  /// may in the future be merged with that trait or otherwise
  32  /// modified when default methods and trait inheritance are
  33  /// completed.
  34  ///
  35  /// IterBytes should be implemented so that the extent of the
  36  /// produced byte stream can be discovered, given the original
  37  /// type.
  38  /// For example, the IterBytes implementation for vectors emits
  39  /// its length first, and enums should emit their discriminant.
  40  ///
  41  pub trait IterBytes {
  42      /// Call the provided callback `f` one or more times with
  43      /// byte-slices that should be used when computing a hash
  44      /// value or otherwise "flattening" the structure into
  45      /// a sequence of bytes. The `lsb0` parameter conveys
  46      /// whether the caller is asking for little-endian bytes
  47      /// (`true`) or big-endian (`false`); this should only be
  48      /// relevant in implementations that represent a single
  49      /// multi-byte datum such as a 32 bit integer or 64 bit
  50      /// floating-point value. It can be safely ignored for
  51      /// larger structured types as they are usually processed
  52      /// left-to-right in declaration order, regardless of
  53      /// underlying memory endianness.
  54      ///
  55      fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool;
  56  }
  57  
  58  impl IterBytes for bool {
  59      #[inline]
  60      fn iter_bytes(&self, _lsb0bool, fCb) -> bool {
  61          f([
  62              *self as u8
  63          ])
  64      }
  65  }
  66  
  67  impl IterBytes for u8 {
  68      #[inline]
  69      fn iter_bytes(&self, _lsb0bool, fCb) -> bool {
  70          f([
  71              *self
  72          ])
  73      }
  74  }
  75  
  76  impl IterBytes for u16 {
  77      #[inline]
  78      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
  79          if lsb0 {
  80              f([
  81                  *self as u8,
  82                  (*self >> 8) as u8
  83              ])
  84          } else {
  85              f([
  86                  (*self >> 8) as u8,
  87                  *self as u8
  88              ])
  89          }
  90      }
  91  }
  92  
  93  impl IterBytes for u32 {
  94      #[inline]
  95      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
  96          if lsb0 {
  97              f([
  98                  *self as u8,
  99                  (*self >> 8) as u8,
 100                  (*self >> 16) as u8,
 101                  (*self >> 24) as u8,
 102              ])
 103          } else {
 104              f([
 105                  (*self >> 24) as u8,
 106                  (*self >> 16) as u8,
 107                  (*self >> 8) as u8,
 108                  *self as u8
 109              ])
 110          }
 111      }
 112  }
 113  
 114  impl IterBytes for u64 {
 115      #[inline]
 116      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 117          if lsb0 {
 118              f([
 119                  *self as u8,
 120                  (*self >> 8) as u8,
 121                  (*self >> 16) as u8,
 122                  (*self >> 24) as u8,
 123                  (*self >> 32) as u8,
 124                  (*self >> 40) as u8,
 125                  (*self >> 48) as u8,
 126                  (*self >> 56) as u8
 127              ])
 128          } else {
 129              f([
 130                  (*self >> 56) as u8,
 131                  (*self >> 48) as u8,
 132                  (*self >> 40) as u8,
 133                  (*self >> 32) as u8,
 134                  (*self >> 24) as u8,
 135                  (*self >> 16) as u8,
 136                  (*self >> 8) as u8,
 137                  *self as u8
 138              ])
 139          }
 140      }
 141  }
 142  
 143  impl IterBytes for i8 {
 144      #[inline]
 145      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 146          (*self as u8).iter_bytes(lsb0, f)
 147      }
 148  }
 149  
 150  impl IterBytes for i16 {
 151      #[inline]
 152      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 153          (*self as u16).iter_bytes(lsb0, f)
 154      }
 155  }
 156  
 157  impl IterBytes for i32 {
 158      #[inline]
 159      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 160          (*self as u32).iter_bytes(lsb0, f)
 161      }
 162  }
 163  
 164  impl IterBytes for i64 {
 165      #[inline]
 166      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 167          (*self as u64).iter_bytes(lsb0, f)
 168      }
 169  }
 170  
 171  impl IterBytes for char {
 172      #[inline]
 173      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 174          (*self as u32).iter_bytes(lsb0, f)
 175      }
 176  }
 177  
 178  #[cfg(target_word_size = "32")]
 179  impl IterBytes for uint {
 180      #[inline]
 181      fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
 182          (*self as u32).iter_bytes(lsb0, f)
 183      }
 184  }
 185  
 186  #[cfg(target_word_size = "64")]
 187  impl IterBytes for uint {
 188      #[inline]
 189      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 190          (*self as u64).iter_bytes(lsb0, f)
 191      }
 192  }
 193  
 194  impl IterBytes for int {
 195      #[inline]
 196      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 197          (*self as uint).iter_bytes(lsb0, f)
 198      }
 199  }
 200  
 201  impl IterBytes for f32 {
 202      #[inline]
 203      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 204          let iu32 = unsafe {
 205              // 0.0 == -0.0 so they should also have the same hashcode
 206              cast::transmute(if *self == -0.0 { 0.0 } else { *self })
 207          };
 208          i.iter_bytes(lsb0, f)
 209      }
 210  }
 211  
 212  impl IterBytes for f64 {
 213      #[inline]
 214      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 215          let iu64 = unsafe {
 216              // 0.0 == -0.0 so they should also have the same hashcode
 217              cast::transmute(if *self == -0.0 { 0.0 } else { *self })
 218          };
 219          i.iter_bytes(lsb0, f)
 220      }
 221  }
 222  
 223  impl<'self,A:IterBytes> IterBytes for &'self [A{
 224      #[inline]
 225      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 226          self.len().iter_bytes(lsb0, |b| f(b)) &&
 227          self.iter().advance(|elt| elt.iter_bytes(lsb0, |b| f(b)))
 228      }
 229  }
 230  
 231  impl<A: IterBytes> IterBytes for (A, ) {
 232      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 233          match *self {
 234              (ref a, ) => a.iter_bytes(lsb0, |b| f(b))
 235          }
 236      }
 237  }
 238  
 239  macro_rules! iter_bytes_tuple(
 240      ($($A:ident),+) => (
 241          impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
 242              fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 243                  match *self {
 244                      ($(ref $A),+) => {
 245                          $(
 246                              $A .iter_bytes(lsb0, |b| f(b))
 247                          )&&+
 248                      }
 249                  }
 250              }
 251          }
 252      )
 253  )
 254  
 255  iter_bytes_tuple!(A, B)
 256  iter_bytes_tuple!(A, B, C)
 257  iter_bytes_tuple!(A, B, C, D)
 258  iter_bytes_tuple!(A, B, C, D, E)
 259  iter_bytes_tuple!(A, B, C, D, E, F)
 260  iter_bytes_tuple!(A, B, C, D, E, F, G)
 261  iter_bytes_tuple!(A, B, C, D, E, F, G, H)
 262  
 263  impl<A:IterBytes> IterBytes for ~[A{
 264      #[inline]
 265      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 266          self.as_slice().iter_bytes(lsb0, f)
 267      }
 268  }
 269  
 270  impl<A:IterBytes> IterBytes for @[A{
 271      #[inline]
 272      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 273          self.as_slice().iter_bytes(lsb0, f)
 274      }
 275  }
 276  
 277  impl<'self> IterBytes for &'self str {
 278      #[inline]
 279      fn iter_bytes(&self, _lsb0bool, fCb) -> bool {
 280          // Terminate the string with a byte that does not appear in UTF-8
 281          f(self.as_bytes()) && f([0xFF])
 282      }
 283  }
 284  
 285  impl IterBytes for ~str {
 286      #[inline]
 287      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 288          self.as_slice().iter_bytes(lsb0, f)
 289      }
 290  }
 291  
 292  impl IterBytes for @str {
 293      #[inline]
 294      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 295          self.as_slice().iter_bytes(lsb0, f)
 296      }
 297  }
 298  
 299  impl<A:IterBytes> IterBytes for Option<A> {
 300      #[inline]
 301      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 302          match *self {
 303            Some(ref a) => 0u8.iter_bytes(lsb0, |b| f(b)) && a.iter_bytes(lsb0, |b| f(b)),
 304            None => 1u8.iter_bytes(lsb0, f)
 305          }
 306      }
 307  }
 308  
 309  impl<'self,A:IterBytes> IterBytes for &'self A {
 310      #[inline]
 311      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 312          (**self).iter_bytes(lsb0, f)
 313      }
 314  }
 315  
 316  impl<A:IterBytes> IterBytes for @A {
 317      #[inline]
 318      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 319          (**self).iter_bytes(lsb0, f)
 320      }
 321  }
 322  
 323  impl<A:IterBytes> IterBytes for @mut A {
 324      #[inline]
 325      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 326          (**self).iter_bytes(lsb0, f)
 327      }
 328  }
 329  
 330  impl<A:IterBytes> IterBytes for ~A {
 331      #[inline]
 332      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 333          (**self).iter_bytes(lsb0, f)
 334      }
 335  }
 336  
 337  // NB: raw-pointer IterBytes does _not_ dereference
 338  // to the target; it just gives you the pointer-bytes.
 339  impl<A> IterBytes for *A {
 340      #[inline]
 341      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 342          (*self as uint).iter_bytes(lsb0, f)
 343      }
 344  }
 345  
 346  impl<A> IterBytes for *mut A {
 347      #[inline]
 348      fn iter_bytes(&self, lsb0bool, fCb) -> bool {
 349          (*self as uint).iter_bytes(lsb0, f)
 350      }
 351  }
 352  
 353  /// A trait for converting a value to a list of bytes.
 354  pub trait ToBytes {
 355      /// Converts the current value to a list of bytes. This is equivalent to
 356      /// invoking iter_bytes on a type and collecting all yielded values in an
 357      /// array
 358      fn to_bytes(&self, lsb0: bool) -> ~[u8];
 359  }
 360  
 361  impl<A:IterBytes> ToBytes for A {
 362      fn to_bytes(&self, lsb0bool) -> ~[u8] {
 363          do io::with_bytes_writer |wr| {
 364              do self.iter_bytes(lsb0) |bytes| {
 365                  wr.write(bytes);
 366                  true
 367              };
 368          }
 369      }
 370  }
 371  
 372  #[cfg(test)]
 373  mod test {
 374      use super::*;
 375      // just test to see if it compiles:
 376      #[test] fn iterbytes_compiles () {
 377          takes_iterbytes((3,4,5,false));
 378      }
 379      fn takes_iterbytes<T : IterBytes>(_x : T) {}
 380  }

libstd/to_bytes.rs:40:4-40:4 -trait- definition:
///
pub trait IterBytes {
references:-
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
223: impl<'self,A:IterBytes> IterBytes for &'self [A] {
171: impl IterBytes for char {
194: impl IterBytes for int {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
270: impl<A:IterBytes> IterBytes for @[A] {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
309: impl<'self,A:IterBytes> IterBytes for &'self A {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
201: impl IterBytes for f32 {
270: impl<A:IterBytes> IterBytes for @[A] {
277: impl<'self> IterBytes for &'self str {
223: impl<'self,A:IterBytes> IterBytes for &'self [A] {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
323: impl<A:IterBytes> IterBytes for @mut A {
263: impl<A:IterBytes> IterBytes for ~[A] {
299: impl<A:IterBytes> IterBytes for Option<A> {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
143: impl IterBytes for i8 {
241:         impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
76: impl IterBytes for u16 {
316: impl<A:IterBytes> IterBytes for @A {
(150)(285)(241)(323)(241)(263)(241)(339)(93)(212)(157)(299)(292)(241)(241)(241)(241)(241)(241)(241)(241)(241)(241)(241)(241)(241)(231)(241)(241)(241)(241)(241)(67)(346)(187)(316)(241)(241)(330)(361)(58)(241)(309)(330)(241)(241)(231)(164)(114)(241)
libstd/hash.rs:
(104)(123)(105)(124)(77)(103)(89)(155)(157)(90)
libstd/either.rs:
libstd/path/posix.rs:
libstd/path/windows.rs:
libstd/fmt/parse.rs:
libstd/rt/kill.rs:
libstd/str/ascii.rs:
libstd/send_str.rs:
..14more..


libstd/to_bytes.rs:353:55-353:55 -trait- definition:
/// A trait for converting a value to a list of bytes.
pub trait ToBytes {
references:-
361: impl<A:IterBytes> ToBytes for A {


libstd/to_bytes.rs:25:1-25:1 -ty- definition:

pub type Cb<'self> = &'self fn(buf: &[u8]) -> bool;
references:-
265:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
55:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool;
232:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
69:     fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
145:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
332:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
242:             fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
173:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
78:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
287:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
214:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
242:             fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
116:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
166:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
242:             fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
242:             fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
272:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
301:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
152:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
203:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
242:             fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
189:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
279:     fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
341:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
348:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
325:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
196:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
60:     fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
294:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
159:     fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
(242)(318)(242)(225)(311)(95)
libstd/either.rs:
(28)
libstd/fmt/parse.rs:
(139)
libstd/send_str.rs:
(169)