@@ -59,10 +59,13 @@ pub mod reader {
59
59
use ebml:: { EsVec , EsVecElt , EsVecLen , TaggedDoc } ;
60
60
use serialize;
61
61
62
+ use core:: cast:: transmute;
62
63
use core:: int;
63
64
use core:: io;
64
65
use core:: prelude:: * ;
66
+ use core:: ptr:: offset;
65
67
use core:: str;
68
+ use core:: unstable:: intrinsics:: bswap32;
66
69
use core:: vec;
67
70
68
71
// ebml reading
@@ -78,7 +81,8 @@ pub mod reader {
78
81
next : uint
79
82
}
80
83
81
- fn vuint_at ( data : & [ u8 ] , start : uint ) -> Res {
84
+ #[ inline( never) ]
85
+ fn vuint_at_slow ( data : & [ u8 ] , start : uint ) -> Res {
82
86
let a = data[ start] ;
83
87
if a & 0x80u8 != 0u8 {
84
88
return Res { val : ( a & 0x7fu8 ) as uint , next : start + 1 u} ;
@@ -87,18 +91,63 @@ pub mod reader {
87
91
return Res { val : ( ( a & 0x3fu8 ) as uint ) << 8 u |
88
92
( data[ start + 1 u] as uint ) ,
89
93
next : start + 2 u} ;
90
- } else if a & 0x20u8 != 0u8 {
94
+ }
95
+ if a & 0x20u8 != 0u8 {
91
96
return Res { val : ( ( a & 0x1fu8 ) as uint ) << 16 u |
92
97
( data[ start + 1 u] as uint ) << 8 u |
93
98
( data[ start + 2 u] as uint ) ,
94
99
next : start + 3 u} ;
95
- } else if a & 0x10u8 != 0u8 {
100
+ }
101
+ if a & 0x10u8 != 0u8 {
96
102
return Res { val : ( ( a & 0x0fu8 ) as uint ) << 24 u |
97
103
( data[ start + 1 u] as uint ) << 16 u |
98
104
( data[ start + 2 u] as uint ) << 8 u |
99
105
( data[ start + 3 u] as uint ) ,
100
106
next : start + 4 u} ;
101
- } else { error ! ( "vint too big" ) ; fail ! ( ) ; }
107
+ }
108
+ fail ! ( ~"vint too big");
109
+ }
110
+
111
+ #[cfg(target_arch = " x86")]
112
+ #[cfg(target_arch = " x86_64")]
113
+ pub fn vuint_at(data: &[u8], start: uint) -> Res {
114
+ if data.len() - start < 4 {
115
+ return vuint_at_slow(data, start);
116
+ }
117
+
118
+ unsafe {
119
+ let (ptr, _): (*u8, uint) = transmute(data);
120
+ let ptr = offset(ptr, start);
121
+ let ptr: *i32 = transmute(ptr);
122
+ let val = bswap32(*ptr);
123
+ let val: u32 = transmute(val);
124
+ if (val & 0x80000000) != 0 {
125
+ Res {
126
+ val: ((val >> 24) & 0x7f) as uint,
127
+ next: start + 1
128
+ }
129
+ } else if (val & 0x40000000) != 0 {
130
+ Res {
131
+ val: ((val >> 16) & 0x3fff) as uint,
132
+ next: start + 2
133
+ }
134
+ } else if (val & 0x20000000) != 0 {
135
+ Res {
136
+ val: ((val >> 8) & 0x1fffff) as uint,
137
+ next: start + 3
138
+ }
139
+ } else {
140
+ Res {
141
+ val: (val & 0x0fffffff) as uint,
142
+ next: start + 4
143
+ }
144
+ }
145
+ }
146
+ }
147
+
148
+ #[cfg(target_arch = " arm")]
149
+ pub fn vuint_at(data: &[u8], start: uint) -> Res {
150
+ vuint_at_slow(data, start)
102
151
}
103
152
104
153
pub fn Doc(data: @~[u8]) -> Doc {
0 commit comments