@@ -19,35 +19,42 @@ type doc = {data: @[u8], start: uint, end: uint};
19
19
20
20
type tagged_doc = { tag : uint , doc : doc } ;
21
21
22
- fn vint_at ( data : [ u8 ] , start : uint ) -> { val : uint , next : uint } {
22
+ fn vu64_at ( data : [ u8 ] , start : uint ) -> { val : u64 , next : uint } {
23
23
let a = data[ start] ;
24
24
if a & 0x80u8 != 0u8 {
25
- ret { val : ( a & 0x7fu8 ) as uint , next : start + 1 u} ;
25
+ ret { val : ( a & 0x7fu8 ) as u64 , next : start + 1 u} ;
26
26
}
27
27
if a & 0x40u8 != 0u8 {
28
- ret { val : ( ( a & 0x3fu8 ) as uint ) << 8 u | ( data[ start + 1 u] as uint ) ,
28
+ ret { val : ( ( a & 0x3fu8 ) as u64 ) << 8u64 |
29
+ ( data[ start + 1 u] as u64 ) ,
29
30
next : start + 2 u} ;
30
31
} else if a & 0x20u8 != 0u8 {
31
- ret { val : ( ( a & 0x1fu8 ) as uint ) << 16 u |
32
- ( data[ start + 1 u] as uint ) << 8 u |
33
- ( data[ start + 2 u] as uint ) ,
32
+ ret { val : ( ( a & 0x1fu8 ) as u64 ) << 16u64 |
33
+ ( data[ start + 1 u] as u64 ) << 8u64 |
34
+ ( data[ start + 2 u] as u64 ) ,
34
35
next : start + 3 u} ;
35
36
} else if a & 0x10u8 != 0u8 {
36
- ret { val : ( ( a & 0x0fu8 ) as uint ) << 24 u |
37
- ( data[ start + 1 u] as uint ) << 16 u |
38
- ( data[ start + 2 u] as uint ) << 8 u |
39
- ( data[ start + 3 u] as uint ) ,
37
+ ret { val : ( ( a & 0x0fu8 ) as u64 ) << 24u64 |
38
+ ( data[ start + 1 u] as u64 ) << 16u64 |
39
+ ( data[ start + 2 u] as u64 ) << 8u64 |
40
+ ( data[ start + 3 u] as u64 ) ,
40
41
next : start + 4 u} ;
41
42
} else { #error ( "vint too big" ) ; fail; }
42
43
}
43
44
45
+ fn vuint_at ( data : [ u8 ] , start : uint ) -> { val : uint , next : uint } {
46
+ let { val, next} = vu64_at ( data, start) ;
47
+ ret { val : val as uint , next : next} ;
48
+ }
49
+
50
+
44
51
fn new_doc ( data : @[ u8 ] ) -> doc {
45
52
ret { data : data, start : 0 u, end : vec:: len :: < u8 > ( * data) } ;
46
53
}
47
54
48
55
fn doc_at ( data : @[ u8 ] , start : uint ) -> tagged_doc {
49
- let elt_tag = vint_at ( * data, start) ;
50
- let elt_size = vint_at ( * data, elt_tag. next ) ;
56
+ let elt_tag = vuint_at ( * data, start) ;
57
+ let elt_size = vuint_at ( * data, elt_tag. next ) ;
51
58
let end = elt_size. next + elt_size. val ;
52
59
ret { tag : elt_tag. val ,
53
60
doc : { data: data, start : elt_size. next , end : end} } ;
@@ -56,8 +63,8 @@ fn doc_at(data: @[u8], start: uint) -> tagged_doc {
56
63
fn maybe_get_doc ( d : doc , tg : uint ) -> option < doc > {
57
64
let pos = d. start ;
58
65
while pos < d. end {
59
- let elt_tag = vint_at ( * d. data , pos) ;
60
- let elt_size = vint_at ( * d. data , elt_tag. next ) ;
66
+ let elt_tag = vuint_at ( * d. data , pos) ;
67
+ let elt_size = vuint_at ( * d. data , elt_tag. next ) ;
61
68
pos = elt_size. next + elt_size. val ;
62
69
if elt_tag. val == tg {
63
70
ret some :: < doc > ( { data: d. data , start: elt_size. next , end: pos} ) ;
@@ -79,8 +86,8 @@ fn get_doc(d: doc, tg: uint) -> doc {
79
86
fn docs ( d : doc , it : fn ( uint , doc ) ) {
80
87
let pos = d. start ;
81
88
while pos < d. end {
82
- let elt_tag = vint_at ( * d. data , pos) ;
83
- let elt_size = vint_at ( * d. data , elt_tag. next ) ;
89
+ let elt_tag = vuint_at ( * d. data , pos) ;
90
+ let elt_size = vuint_at ( * d. data , elt_tag. next ) ;
84
91
pos = elt_size. next + elt_size. val ;
85
92
it ( elt_tag. val , { data: d. data , start: elt_size. next , end: pos} ) ;
86
93
}
@@ -89,8 +96,8 @@ fn docs(d: doc, it: fn(uint, doc)) {
89
96
fn tagged_docs ( d : doc , tg : uint , it : fn ( doc ) ) {
90
97
let pos = d. start ;
91
98
while pos < d. end {
92
- let elt_tag = vint_at ( * d. data , pos) ;
93
- let elt_size = vint_at ( * d. data , elt_tag. next ) ;
99
+ let elt_tag = vuint_at ( * d. data , pos) ;
100
+ let elt_size = vuint_at ( * d. data , elt_tag. next ) ;
94
101
pos = elt_size. next + elt_size. val ;
95
102
if elt_tag. val == tg {
96
103
it ( { data: d. data , start: elt_size. next , end: pos} ) ;
@@ -102,28 +109,36 @@ fn doc_data(d: doc) -> [u8] { ret vec::slice::<u8>(*d.data, d.start, d.end); }
102
109
103
110
fn doc_str ( d : doc ) -> str { ret str:: from_bytes ( doc_data ( d) ) ; }
104
111
105
- fn be_uint_from_bytes ( data : @[ u8 ] , start : uint , size : uint ) -> uint {
112
+ fn be_u64_from_bytes ( data : @[ u8 ] , start : uint , size : uint ) -> u64 {
106
113
let sz = size;
107
114
assert ( sz <= 4 u) ;
108
- let val = 0 u ;
115
+ let val = 0_u64 ;
109
116
let pos = start;
110
117
while sz > 0 u {
111
118
sz -= 1 u;
112
- val += ( data[ pos] as uint ) << sz * 8 u;
119
+ val += ( data[ pos] as u64 ) << ( ( sz * 8 u) as u64 ) ;
113
120
pos += 1 u;
114
121
}
115
122
ret val;
116
123
}
117
124
118
- fn doc_as_uint ( d : doc ) -> uint {
119
- ret be_uint_from_bytes ( d. data , d. start , d. end - d. start ) ;
125
+ fn doc_as_u8 ( d : doc ) -> u8 {
126
+ assert d. end == d. start + 1 u;
127
+ ret ( * d. data ) [ d. start ] ;
128
+ }
129
+
130
+ fn doc_as_vu64 ( d : doc ) -> u64 {
131
+ ret vu64_at ( * d. data , d. start ) . val ;
120
132
}
121
133
134
+ fn doc_as_vuint ( d : doc ) -> uint {
135
+ ret vuint_at ( * d. data , d. start ) . val ;
136
+ }
122
137
123
138
// ebml writing
124
139
type writer = { writer : io:: writer , mutable size_positions : [ uint ] } ;
125
140
126
- fn write_sized_vint ( w : io:: writer , n : u64 , size : uint ) {
141
+ fn write_sized_vu64 ( w : io:: writer , n : u64 , size : uint ) {
127
142
let buf: [ u8 ] ;
128
143
alt size {
129
144
1 u { buf = [ 0x80u8 | ( n as u8 ) ] ; }
@@ -141,11 +156,11 @@ fn write_sized_vint(w: io::writer, n: u64, size: uint) {
141
156
w. write ( buf) ;
142
157
}
143
158
144
- fn write_vint ( w : io:: writer , n : u64 ) {
145
- if n < 0x7f_u64 { write_sized_vint ( w, n, 1 u) ; ret; }
146
- if n < 0x4000_u64 { write_sized_vint ( w, n, 2 u) ; ret; }
147
- if n < 0x200000_u64 { write_sized_vint ( w, n, 3 u) ; ret; }
148
- if n < 0x10000000_u64 { write_sized_vint ( w, n, 4 u) ; ret; }
159
+ fn write_vu64 ( w : io:: writer , n : u64 ) {
160
+ if n < 0x7f_u64 { write_sized_vu64 ( w, n, 1 u) ; ret; }
161
+ if n < 0x4000_u64 { write_sized_vu64 ( w, n, 2 u) ; ret; }
162
+ if n < 0x200000_u64 { write_sized_vu64 ( w, n, 3 u) ; ret; }
163
+ if n < 0x10000000_u64 { write_sized_vu64 ( w, n, 4 u) ; ret; }
149
164
#error ( "vint to write too big" ) ;
150
165
fail;
151
166
}
@@ -158,8 +173,10 @@ fn create_writer(w: io::writer) -> writer {
158
173
159
174
// TODO: Provide a function to write the standard ebml header.
160
175
fn start_tag ( w : writer , tag_id : uint ) {
176
+ #debug[ "Start tag %u" , tag_id] ;
177
+
161
178
// Write the enum ID:
162
- write_vint ( w. writer , tag_id as u64 ) ;
179
+ write_vu64 ( w. writer , tag_id as u64 ) ;
163
180
164
181
// Write a placeholder four-byte size.
165
182
w. size_positions += [ w. writer . tell ( ) ] ;
@@ -171,8 +188,11 @@ fn end_tag(w: writer) {
171
188
let last_size_pos = vec:: pop :: < uint > ( w. size_positions ) ;
172
189
let cur_pos = w. writer . tell ( ) ;
173
190
w. writer . seek ( last_size_pos as int , io:: seek_set) ;
174
- write_sized_vint ( w. writer , ( cur_pos - last_size_pos - 4 u) as u64 , 4 u) ;
191
+ let size = ( cur_pos - last_size_pos - 4 u) ;
192
+ write_sized_vu64 ( w. writer , size as u64 , 4 u) ;
175
193
w. writer . seek ( cur_pos as int , io:: seek_set) ;
194
+
195
+ #debug[ "End tag (size = %u)" , size] ;
176
196
}
177
197
178
198
impl writer_util for writer {
@@ -182,20 +202,26 @@ impl writer_util for writer {
182
202
end_tag ( self ) ;
183
203
}
184
204
185
- fn wr_u64 ( id : u64 ) {
186
- write_vint ( self . writer , id) ;
205
+ fn wr_vu64 ( id : u64 ) {
206
+ #debug[ "Write u64 0x%02x%02x" ,
207
+ ( id >> 32u64 ) as uint ,
208
+ ( id & 0xFFFFFFFFu64 ) as uint ] ;
209
+ write_vu64 ( self . writer , id) ;
187
210
}
188
211
189
- fn wr_uint ( id : uint ) {
190
- self . wr_u64 ( id as u64 ) ;
212
+ fn wr_vuint ( id : uint ) {
213
+ #debug[ "Write uint: %u" , id] ;
214
+ write_vu64 ( self . writer , id as u64 ) ;
191
215
}
192
216
193
217
fn wr_bytes ( b : [ u8 ] ) {
218
+ #debug[ "Write %u bytes" , vec:: len ( b) ] ;
194
219
self . writer . write ( b) ;
195
220
}
196
221
197
222
fn wr_str ( s : str ) {
198
- self . wr_bytes ( str:: bytes ( s) ) ;
223
+ #debug[ "Write str: %?" , s] ;
224
+ self . writer . write ( str:: bytes ( s) ) ;
199
225
}
200
226
}
201
227
0 commit comments