@@ -15,37 +15,43 @@ The `ToBytes` and `IterBytes` traits
1515*/
1616
1717use cast;
18+ use container:: Container ;
1819use io;
1920use io:: Writer ;
2021use iterator:: Iterator ;
2122use option:: { None , Option , Some } ;
22- use str:: StrSlice ;
23- use vec:: ImmutableVector ;
23+ use str:: { Str , StrSlice } ;
24+ use vec:: { Vector , ImmutableVector } ;
2425
2526pub type Cb < ' self > = & ' self fn ( buf : & [ u8 ] ) -> bool ;
2627
27- /**
28- * A trait to implement in order to make a type hashable;
29- * This works in combination with the trait `Hash::Hash`, and
30- * may in the future be merged with that trait or otherwise
31- * modified when default methods and trait inheritance are
32- * completed.
33- */
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+ ///
3441pub trait IterBytes {
35- /**
36- * Call the provided callback `f` one or more times with
37- * byte-slices that should be used when computing a hash
38- * value or otherwise "flattening" the structure into
39- * a sequence of bytes. The `lsb0` parameter conveys
40- * whether the caller is asking for little-endian bytes
41- * (`true`) or big-endian (`false`); this should only be
42- * relevant in implementations that represent a single
43- * multi-byte datum such as a 32 bit integer or 64 bit
44- * floating-point value. It can be safely ignored for
45- * larger structured types as they are usually processed
46- * left-to-right in declaration order, regardless of
47- * underlying memory endianness.
48- */
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+ ///
4955 fn iter_bytes ( & self , lsb0 : bool , f : Cb ) -> bool ;
5056}
5157
@@ -224,6 +230,7 @@ impl IterBytes for f64 {
224230impl < ' self , A : IterBytes > IterBytes for & ' self [ A ] {
225231 #[ inline]
226232 fn iter_bytes ( & self , lsb0 : bool , f : Cb ) -> bool {
233+ self . len ( ) . iter_bytes ( lsb0, |b| f ( b) ) &&
227234 self . iter ( ) . advance ( |elt| elt. iter_bytes ( lsb0, |b| f ( b) ) )
228235 }
229236}
@@ -251,47 +258,39 @@ impl<A:IterBytes,B:IterBytes,C:IterBytes> IterBytes for (A,B,C) {
251258 }
252259}
253260
254- // Move this to vec, probably.
255- fn borrow < ' x , A > ( a : & ' x [ A ] ) -> & ' x [ A ] {
256- a
257- }
258-
259261impl < A : IterBytes > IterBytes for ~[ A ] {
260262 #[ inline]
261263 fn iter_bytes ( & self , lsb0 : bool , f : Cb ) -> bool {
262- borrow ( * self ) . iter_bytes ( lsb0, f)
264+ self . as_slice ( ) . iter_bytes ( lsb0, f)
263265 }
264266}
265267
266268impl < A : IterBytes > IterBytes for @[ A ] {
267269 #[ inline]
268270 fn iter_bytes ( & self , lsb0 : bool , f : Cb ) -> bool {
269- borrow ( * self ) . iter_bytes ( lsb0, f)
271+ self . as_slice ( ) . iter_bytes ( lsb0, f)
270272 }
271273}
272274
273275impl < ' self > IterBytes for & ' self str {
274276 #[ inline]
275277 fn iter_bytes ( & self , _lsb0 : bool , f : Cb ) -> bool {
276- f ( self . as_bytes ( ) )
278+ // Terminate the string with a byte that does not appear in UTF-8
279+ f ( self . as_bytes ( ) ) && f ( [ 0xFF ] )
277280 }
278281}
279282
280283impl IterBytes for ~str {
281284 #[ inline]
282- fn iter_bytes ( & self , _lsb0 : bool , f : Cb ) -> bool {
283- // this should possibly include the null terminator, but that
284- // breaks .find_equiv on hashmaps.
285- f ( self . as_bytes ( ) )
285+ fn iter_bytes ( & self , lsb0 : bool , f : Cb ) -> bool {
286+ self . as_slice ( ) . iter_bytes ( lsb0, f)
286287 }
287288}
288289
289290impl IterBytes for @str {
290291 #[ inline]
291- fn iter_bytes ( & self , _lsb0 : bool , f : Cb ) -> bool {
292- // this should possibly include the null terminator, but that
293- // breaks .find_equiv on hashmaps.
294- f ( self . as_bytes ( ) )
292+ fn iter_bytes ( & self , lsb0 : bool , f : Cb ) -> bool {
293+ self . as_slice ( ) . iter_bytes ( lsb0, f)
295294 }
296295}
297296
0 commit comments