(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, _lsb0: bool, f: Cb) -> bool {
61 f([
62 *self as u8
63 ])
64 }
65 }
66
67 impl IterBytes for u8 {
68 #[inline]
69 fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
70 f([
71 *self
72 ])
73 }
74 }
75
76 impl IterBytes for u16 {
77 #[inline]
78 fn iter_bytes(&self, lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> bool {
146 (*self as u8).iter_bytes(lsb0, f)
147 }
148 }
149
150 impl IterBytes for i16 {
151 #[inline]
152 fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
153 (*self as u16).iter_bytes(lsb0, f)
154 }
155 }
156
157 impl IterBytes for i32 {
158 #[inline]
159 fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
160 (*self as u32).iter_bytes(lsb0, f)
161 }
162 }
163
164 impl IterBytes for i64 {
165 #[inline]
166 fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
167 (*self as u64).iter_bytes(lsb0, f)
168 }
169 }
170
171 impl IterBytes for char {
172 #[inline]
173 fn iter_bytes(&self, lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> bool {
190 (*self as u64).iter_bytes(lsb0, f)
191 }
192 }
193
194 impl IterBytes for int {
195 #[inline]
196 fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
197 (*self as uint).iter_bytes(lsb0, f)
198 }
199 }
200
201 impl IterBytes for f32 {
202 #[inline]
203 fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
204 let i: u32 = 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, lsb0: bool, f: Cb) -> bool {
215 let i: u64 = 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, lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> 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, _lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> bool {
288 self.as_slice().iter_bytes(lsb0, f)
289 }
290 }
291
292 impl IterBytes for @str {
293 #[inline]
294 fn iter_bytes(&self, lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> bool {
312 (**self).iter_bytes(lsb0, f)
313 }
314 }
315
316 impl<A:IterBytes> IterBytes for @A {
317 #[inline]
318 fn iter_bytes(&self, lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> bool {
326 (**self).iter_bytes(lsb0, f)
327 }
328 }
329
330 impl<A:IterBytes> IterBytes for ~A {
331 #[inline]
332 fn iter_bytes(&self, lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> 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, lsb0: bool, f: Cb) -> 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, lsb0: bool) -> ~[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)