(index<- ) ./libserialize/ebml.rs
git branch: * master 5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
modified: Sat Apr 19 11:22:39 2014
1 // Copyright 2012-2014 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 #![allow(missing_doc)]
12
13 use std::io;
14 use std::str;
15
16 // Simple Extensible Binary Markup Language (ebml) reader and writer on a
17 // cursor model. See the specification here:
18 // http://www.matroska.org/technical/specs/rfc/index.html
19
20 // Common data structures
21 #[deriving(Clone)]
22 pub struct Doc<'a> {
23 pub data: &'a [u8],
24 pub start: uint,
25 pub end: uint,
26 }
27
28 impl<'doc> Doc<'doc> {
29 pub fn get<'a>(&'a self, tag: uint) -> Doc<'a> {
30 reader::get_doc(*self, tag)
31 }
32
33 pub fn as_str_slice<'a>(&'a self) -> &'a str {
34 str::from_utf8(self.data.slice(self.start, self.end)).unwrap()
35 }
36
37 pub fn as_str(&self) -> ~str {
38 self.as_str_slice().to_owned()
39 }
40 }
41
42 pub struct TaggedDoc<'a> {
43 tag: uint,
44 pub doc: Doc<'a>,
45 }
46
47 pub enum EbmlEncoderTag {
48 EsUint, // 0
49 EsU64, // 1
50 EsU32, // 2
51 EsU16, // 3
52 EsU8, // 4
53 EsInt, // 5
54 EsI64, // 6
55 EsI32, // 7
56 EsI16, // 8
57 EsI8, // 9
58 EsBool, // 10
59 EsChar, // 11
60 EsStr, // 12
61 EsF64, // 13
62 EsF32, // 14
63 EsFloat, // 15
64 EsEnum, // 16
65 EsEnumVid, // 17
66 EsEnumBody, // 18
67 EsVec, // 19
68 EsVecLen, // 20
69 EsVecElt, // 21
70 EsMap, // 22
71 EsMapLen, // 23
72 EsMapKey, // 24
73 EsMapVal, // 25
74
75 EsOpaque,
76
77 EsLabel, // Used only when debugging
78 }
79
80 #[deriving(Show)]
81 pub enum Error {
82 IntTooBig(uint),
83 Expected(~str),
84 IoError(io::IoError)
85 }
86 // --------------------------------------
87
88 pub mod reader {
89 use std::char;
90
91 use std::cast::transmute;
92 use std::int;
93 use std::option::{None, Option, Some};
94 use std::io::extensions::u64_from_be_bytes;
95
96 use serialize;
97
98 use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
99 EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
100 EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
101 EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc, Error, IntTooBig,
102 Expected };
103
104 pub type DecodeResult<T> = Result<T, Error>;
105 // ebml reading
106
107 macro_rules! try_or(
108 ($e:expr, $r:expr) => (
109 match $e {
110 Ok(e) => e,
111 Err(e) => {
112 debug!("ignored error: {}", e);
113 return $r
114 }
115 }
116 )
117 )
118
119 pub struct Res {
120 pub val: uint,
121 pub next: uint
122 }
123
124 #[inline(never)]
125 fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
126 let a = data[start];
127 if a & 0x80u8 != 0u8 {
128 return Ok(Res {val: (a & 0x7fu8) as uint, next: start + 1u});
129 }
130 if a & 0x40u8 != 0u8 {
131 return Ok(Res {val: ((a & 0x3fu8) as uint) << 8u |
132 (data[start + 1u] as uint),
133 next: start + 2u});
134 }
135 if a & 0x20u8 != 0u8 {
136 return Ok(Res {val: ((a & 0x1fu8) as uint) << 16u |
137 (data[start + 1u] as uint) << 8u |
138 (data[start + 2u] as uint),
139 next: start + 3u});
140 }
141 if a & 0x10u8 != 0u8 {
142 return Ok(Res {val: ((a & 0x0fu8) as uint) << 24u |
143 (data[start + 1u] as uint) << 16u |
144 (data[start + 2u] as uint) << 8u |
145 (data[start + 3u] as uint),
146 next: start + 4u});
147 }
148 Err(IntTooBig(a as uint))
149 }
150
151 pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
152 use std::mem::from_be32;
153
154 if data.len() - start < 4 {
155 return vuint_at_slow(data, start);
156 }
157
158 // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/
159 // The Element IDs are parsed by reading a big endian u32 positioned at data[start].
160 // Using the four most significant bits of the u32 we lookup in the table below how the
161 // element ID should be derived from it.
162 //
163 // The table stores tuples (shift, mask) where shift is the number the u32 should be right
164 // shifted with and mask is the value the right shifted value should be masked with.
165 // If for example the most significant bit is set this means it's a class A ID and the u32
166 // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at
167 // index 0x8 - 0xF (four bit numbers where the most significant bit is set).
168 //
169 // By storing the number of shifts and masks in a table instead of checking in order if
170 // the most significant bit is set, the second most significant bit is set etc. we can
171 // replace up to three "and+branch" with a single table lookup which gives us a measured
172 // speedup of around 2x on x86_64.
173 static SHIFT_MASK_TABLE: [(u32, u32), ..16] = [
174 (0, 0x0), (0, 0x0fffffff),
175 (8, 0x1fffff), (8, 0x1fffff),
176 (16, 0x3fff), (16, 0x3fff), (16, 0x3fff), (16, 0x3fff),
177 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f),
178 (24, 0x7f), (24, 0x7f), (24, 0x7f), (24, 0x7f)
179 ];
180
181 unsafe {
182 let ptr = data.as_ptr().offset(start as int) as *u32;
183 let val = from_be32(*ptr);
184
185 let i = (val >> 28u) as uint;
186 let (shift, mask) = SHIFT_MASK_TABLE[i];
187 Ok(Res {
188 val: ((val >> shift) & mask) as uint,
189 next: start + (((32 - shift) >> 3) as uint)
190 })
191 }
192 }
193
194 pub fn Doc<'a>(data: &'a [u8]) -> Doc<'a> {
195 Doc { data: data, start: 0u, end: data.len() }
196 }
197
198 pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
199 let elt_tag = try!(vuint_at(data, start));
200 let elt_size = try!(vuint_at(data, elt_tag.next));
201 let end = elt_size.next + elt_size.val;
202 Ok(TaggedDoc {
203 tag: elt_tag.val,
204 doc: Doc { data: data, start: elt_size.next, end: end }
205 })
206 }
207
208 pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
209 let mut pos = d.start;
210 while pos < d.end {
211 let elt_tag = try_or!(vuint_at(d.data, pos), None);
212 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), None);
213 pos = elt_size.next + elt_size.val;
214 if elt_tag.val == tg {
215 return Some(Doc { data: d.data, start: elt_size.next,
216 end: pos });
217 }
218 }
219 None
220 }
221
222 pub fn get_doc<'a>(d: Doc<'a>, tg: uint) -> Doc<'a> {
223 match maybe_get_doc(d, tg) {
224 Some(d) => d,
225 None => {
226 error!("failed to find block with tag {}", tg);
227 fail!();
228 }
229 }
230 }
231
232 pub fn docs<'a>(d: Doc<'a>, it: |uint, Doc<'a>| -> bool) -> bool {
233 let mut pos = d.start;
234 while pos < d.end {
235 let elt_tag = try_or!(vuint_at(d.data, pos), false);
236 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
237 pos = elt_size.next + elt_size.val;
238 let doc = Doc { data: d.data, start: elt_size.next, end: pos };
239 if !it(elt_tag.val, doc) {
240 return false;
241 }
242 }
243 return true;
244 }
245
246 pub fn tagged_docs<'a>(d: Doc<'a>, tg: uint, it: |Doc<'a>| -> bool) -> bool {
247 let mut pos = d.start;
248 while pos < d.end {
249 let elt_tag = try_or!(vuint_at(d.data, pos), false);
250 let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
251 pos = elt_size.next + elt_size.val;
252 if elt_tag.val == tg {
253 let doc = Doc { data: d.data, start: elt_size.next,
254 end: pos };
255 if !it(doc) {
256 return false;
257 }
258 }
259 }
260 return true;
261 }
262
263 pub fn with_doc_data<'a, T>(d: Doc<'a>, f: |x: &'a [u8]| -> T) -> T {
264 f(d.data.slice(d.start, d.end))
265 }
266
267
268 pub fn doc_as_u8(d: Doc) -> u8 {
269 assert_eq!(d.end, d.start + 1u);
270 d.data[d.start]
271 }
272
273 pub fn doc_as_u16(d: Doc) -> u16 {
274 assert_eq!(d.end, d.start + 2u);
275 u64_from_be_bytes(d.data, d.start, 2u) as u16
276 }
277
278 pub fn doc_as_u32(d: Doc) -> u32 {
279 assert_eq!(d.end, d.start + 4u);
280 u64_from_be_bytes(d.data, d.start, 4u) as u32
281 }
282
283 pub fn doc_as_u64(d: Doc) -> u64 {
284 assert_eq!(d.end, d.start + 8u);
285 u64_from_be_bytes(d.data, d.start, 8u)
286 }
287
288 pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
289 pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
290 pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
291 pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
292
293 pub struct Decoder<'a> {
294 parent: Doc<'a>,
295 pos: uint,
296 }
297
298 pub fn Decoder<'a>(d: Doc<'a>) -> Decoder<'a> {
299 Decoder {
300 parent: d,
301 pos: d.start
302 }
303 }
304
305 impl<'doc> Decoder<'doc> {
306 fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> {
307 if self.pos < self.parent.end {
308 let TaggedDoc { tag: r_tag, doc: r_doc } =
309 try!(doc_at(self.parent.data, self.pos));
310
311 if r_tag == (EsLabel as uint) {
312 self.pos = r_doc.end;
313 let str = r_doc.as_str_slice();
314 if lbl != str {
315 return Err(Expected(format!("Expected label {} but found {}", lbl, str)));
316 }
317 }
318 }
319 Ok(())
320 }
321
322 fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
323 debug!(". next_doc(exp_tag={:?})", exp_tag);
324 if self.pos >= self.parent.end {
325 return Err(Expected(format!("no more documents in current node!")));
326 }
327 let TaggedDoc { tag: r_tag, doc: r_doc } =
328 try!(doc_at(self.parent.data, self.pos));
329 debug!("self.parent={}-{} self.pos={} r_tag={} r_doc={}-{}",
330 self.parent.start,
331 self.parent.end,
332 self.pos,
333 r_tag,
334 r_doc.start,
335 r_doc.end);
336 if r_tag != (exp_tag as uint) {
337 return Err(Expected(format!("expected EBML doc with tag {:?} but found tag {:?}",
338 exp_tag, r_tag)));
339 }
340 if r_doc.end > self.parent.end {
341 return Err(Expected(format!("invalid EBML, child extends to {:#x}, parent to {:#x}",
342 r_doc.end, self.parent.end)));
343 }
344 self.pos = r_doc.end;
345 Ok(r_doc)
346 }
347
348 fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag,
349 f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
350 let d = try!(self.next_doc(exp_tag));
351 let old_parent = self.parent;
352 let old_pos = self.pos;
353 self.parent = d;
354 self.pos = d.start;
355 let r = try!(f(self));
356 self.parent = old_parent;
357 self.pos = old_pos;
358 Ok(r)
359 }
360
361 fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
362 let r = doc_as_u32(try!(self.next_doc(exp_tag)));
363 debug!("_next_uint exp_tag={:?} result={}", exp_tag, r);
364 Ok(r as uint)
365 }
366
367 pub fn read_opaque<R>(&mut self,
368 op: |&mut Decoder<'doc>, Doc| -> DecodeResult<R>) -> DecodeResult<R> {
369 let doc = try!(self.next_doc(EsOpaque));
370
371 let (old_parent, old_pos) = (self.parent, self.pos);
372 self.parent = doc;
373 self.pos = doc.start;
374
375 let result = try!(op(self, doc));
376
377 self.parent = old_parent;
378 self.pos = old_pos;
379 Ok(result)
380 }
381 }
382
383 impl<'doc> serialize::Decoder<Error> for Decoder<'doc> {
384 fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
385
386 fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
387 fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
388 fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
389 fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
390 fn read_uint(&mut self) -> DecodeResult<uint> {
391 let v = doc_as_u64(try!(self.next_doc(EsUint)));
392 if v > (::std::uint::MAX as u64) {
393 Err(IntTooBig(v as uint))
394 } else {
395 Ok(v as uint)
396 }
397 }
398
399 fn read_i64(&mut self) -> DecodeResult<i64> {
400 Ok(doc_as_u64(try!(self.next_doc(EsI64))) as i64)
401 }
402 fn read_i32(&mut self) -> DecodeResult<i32> {
403 Ok(doc_as_u32(try!(self.next_doc(EsI32))) as i32)
404 }
405 fn read_i16(&mut self) -> DecodeResult<i16> {
406 Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
407 }
408 fn read_i8 (&mut self) -> DecodeResult<i8> {
409 Ok(doc_as_u8(try!(self.next_doc(EsI8 ))) as i8)
410 }
411 fn read_int(&mut self) -> DecodeResult<int> {
412 let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
413 if v > (int::MAX as i64) || v < (int::MIN as i64) {
414 debug!("FIXME \\#6122: Removing this makes this function miscompile");
415 Err(IntTooBig(v as uint))
416 } else {
417 Ok(v as int)
418 }
419 }
420
421 fn read_bool(&mut self) -> DecodeResult<bool> {
422 Ok(doc_as_u8(try!(self.next_doc(EsBool))) != 0)
423 }
424
425 fn read_f64(&mut self) -> DecodeResult<f64> {
426 let bits = doc_as_u64(try!(self.next_doc(EsF64)));
427 Ok(unsafe { transmute(bits) })
428 }
429 fn read_f32(&mut self) -> DecodeResult<f32> {
430 let bits = doc_as_u32(try!(self.next_doc(EsF32)));
431 Ok(unsafe { transmute(bits) })
432 }
433 fn read_char(&mut self) -> DecodeResult<char> {
434 Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap())
435 }
436 fn read_str(&mut self) -> DecodeResult<~str> {
437 Ok(try!(self.next_doc(EsStr)).as_str())
438 }
439
440 // Compound types:
441 fn read_enum<T>(&mut self,
442 name: &str,
443 f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
444 debug!("read_enum({})", name);
445 try!(self._check_label(name));
446
447 let doc = try!(self.next_doc(EsEnum));
448
449 let (old_parent, old_pos) = (self.parent, self.pos);
450 self.parent = doc;
451 self.pos = self.parent.start;
452
453 let result = try!(f(self));
454
455 self.parent = old_parent;
456 self.pos = old_pos;
457 Ok(result)
458 }
459
460 fn read_enum_variant<T>(&mut self,
461 _: &[&str],
462 f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>)
463 -> DecodeResult<T> {
464 debug!("read_enum_variant()");
465 let idx = try!(self._next_uint(EsEnumVid));
466 debug!(" idx={}", idx);
467
468 let doc = try!(self.next_doc(EsEnumBody));
469
470 let (old_parent, old_pos) = (self.parent, self.pos);
471 self.parent = doc;
472 self.pos = self.parent.start;
473
474 let result = try!(f(self, idx));
475
476 self.parent = old_parent;
477 self.pos = old_pos;
478 Ok(result)
479 }
480
481 fn read_enum_variant_arg<T>(&mut self,
482 idx: uint,
483 f: |&mut Decoder<'doc>| -> DecodeResult<T>) -> DecodeResult<T> {
484 debug!("read_enum_variant_arg(idx={})", idx);
485 f(self)
486 }
487
488 fn read_enum_struct_variant<T>(&mut self,
489 _: &[&str],
490 f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>)
491 -> DecodeResult<T> {
492 debug!("read_enum_struct_variant()");
493 let idx = try!(self._next_uint(EsEnumVid));
494 debug!(" idx={}", idx);
495
496 let doc = try!(self.next_doc(EsEnumBody));
497
498 let (old_parent, old_pos) = (self.parent, self.pos);
499 self.parent = doc;
500 self.pos = self.parent.start;
501
502 let result = try!(f(self, idx));
503
504 self.parent = old_parent;
505 self.pos = old_pos;
506 Ok(result)
507 }
508
509 fn read_enum_struct_variant_field<T>(&mut self,
510 name: &str,
511 idx: uint,
512 f: |&mut Decoder<'doc>| -> DecodeResult<T>)
513 -> DecodeResult<T> {
514 debug!("read_enum_struct_variant_arg(name={}, idx={})", name, idx);
515 f(self)
516 }
517
518 fn read_struct<T>(&mut self,
519 name: &str,
520 _: uint,
521 f: |&mut Decoder<'doc>| -> DecodeResult<T>)
522 -> DecodeResult<T> {
523 debug!("read_struct(name={})", name);
524 f(self)
525 }
526
527 fn read_struct_field<T>(&mut self,
528 name: &str,
529 idx: uint,
530 f: |&mut Decoder<'doc>| -> DecodeResult<T>)
531 -> DecodeResult<T> {
532 debug!("read_struct_field(name={}, idx={})", name, idx);
533 try!(self._check_label(name));
534 f(self)
535 }
536
537 fn read_tuple<T>(&mut self,
538 f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
539 debug!("read_tuple()");
540 self.read_seq(f)
541 }
542
543 fn read_tuple_arg<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
544 -> DecodeResult<T> {
545 debug!("read_tuple_arg(idx={})", idx);
546 self.read_seq_elt(idx, f)
547 }
548
549 fn read_tuple_struct<T>(&mut self,
550 name: &str,
551 f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>)
552 -> DecodeResult<T> {
553 debug!("read_tuple_struct(name={})", name);
554 self.read_tuple(f)
555 }
556
557 fn read_tuple_struct_arg<T>(&mut self,
558 idx: uint,
559 f: |&mut Decoder<'doc>| -> DecodeResult<T>)
560 -> DecodeResult<T> {
561 debug!("read_tuple_struct_arg(idx={})", idx);
562 self.read_tuple_arg(idx, f)
563 }
564
565 fn read_option<T>(&mut self,
566 f: |&mut Decoder<'doc>, bool| -> DecodeResult<T>) -> DecodeResult<T> {
567 debug!("read_option()");
568 self.read_enum("Option", |this| {
569 this.read_enum_variant(["None", "Some"], |this, idx| {
570 match idx {
571 0 => f(this, false),
572 1 => f(this, true),
573 _ => Err(Expected(format!("Expected None or Some"))),
574 }
575 })
576 })
577 }
578
579 fn read_seq<T>(&mut self,
580 f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
581 debug!("read_seq()");
582 self.push_doc(EsVec, |d| {
583 let len = try!(d._next_uint(EsVecLen));
584 debug!(" len={}", len);
585 f(d, len)
586 })
587 }
588
589 fn read_seq_elt<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
590 -> DecodeResult<T> {
591 debug!("read_seq_elt(idx={})", idx);
592 self.push_doc(EsVecElt, f)
593 }
594
595 fn read_map<T>(&mut self,
596 f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
597 debug!("read_map()");
598 self.push_doc(EsMap, |d| {
599 let len = try!(d._next_uint(EsMapLen));
600 debug!(" len={}", len);
601 f(d, len)
602 })
603 }
604
605 fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
606 -> DecodeResult<T> {
607 debug!("read_map_elt_key(idx={})", idx);
608 self.push_doc(EsMapKey, f)
609 }
610
611 fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
612 -> DecodeResult<T> {
613 debug!("read_map_elt_val(idx={})", idx);
614 self.push_doc(EsMapVal, f)
615 }
616 }
617 }
618
619 pub mod writer {
620 use std::cast;
621 use std::clone::Clone;
622 use std::io;
623 use std::io::{Writer, Seek};
624 use std::io::extensions::u64_to_be_bytes;
625
626 use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
627 EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
628 EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
629 EsOpaque, EsLabel, EbmlEncoderTag };
630
631 use serialize;
632
633
634 pub type EncodeResult = io::IoResult<()>;
635
636 // ebml writing
637 pub struct Encoder<'a, W> {
638 pub writer: &'a mut W,
639 size_positions: Vec<uint>,
640 }
641
642 fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
643 match size {
644 1u => w.write(&[0x80u8 | (n as u8)]),
645 2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
646 3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
647 n as u8]),
648 4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
649 (n >> 8_u) as u8, n as u8]),
650 _ => Err(io::IoError {
651 kind: io::OtherIoError,
652 desc: "int too big",
653 detail: Some(format!("{}", n))
654 })
655 }
656 }
657
658 fn write_vuint<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
659 if n < 0x7f_u { return write_sized_vuint(w, n, 1u); }
660 if n < 0x4000_u { return write_sized_vuint(w, n, 2u); }
661 if n < 0x200000_u { return write_sized_vuint(w, n, 3u); }
662 if n < 0x10000000_u { return write_sized_vuint(w, n, 4u); }
663 Err(io::IoError {
664 kind: io::OtherIoError,
665 desc: "int too big",
666 detail: Some(format!("{}", n))
667 })
668 }
669
670 pub fn Encoder<'a, W: Writer + Seek>(w: &'a mut W) -> Encoder<'a, W> {
671 Encoder {
672 writer: w,
673 size_positions: vec!(),
674 }
675 }
676
677 // FIXME (#2741): Provide a function to write the standard ebml header.
678 impl<'a, W: Writer + Seek> Encoder<'a, W> {
679 /// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
680 pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
681 Encoder {
682 writer: cast::transmute_copy(&self.writer),
683 size_positions: self.size_positions.clone(),
684 }
685 }
686
687 pub fn start_tag(&mut self, tag_id: uint) -> EncodeResult {
688 debug!("Start tag {}", tag_id);
689
690 // Write the enum ID:
691 try!(write_vuint(self.writer, tag_id));
692
693 // Write a placeholder four-byte size.
694 self.size_positions.push(try!(self.writer.tell()) as uint);
695 let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
696 self.writer.write(zeroes)
697 }
698
699 pub fn end_tag(&mut self) -> EncodeResult {
700 let last_size_pos = self.size_positions.pop().unwrap();
701 let cur_pos = try!(self.writer.tell());
702 try!(self.writer.seek(last_size_pos as i64, io::SeekSet));
703 let size = cur_pos as uint - last_size_pos - 4;
704 try!(write_sized_vuint(self.writer, size, 4u));
705 let r = try!(self.writer.seek(cur_pos as i64, io::SeekSet));
706
707 debug!("End tag (size = {})", size);
708 Ok(r)
709 }
710
711 pub fn wr_tag(&mut self, tag_id: uint, blk: || -> EncodeResult) -> EncodeResult {
712 try!(self.start_tag(tag_id));
713 try!(blk());
714 self.end_tag()
715 }
716
717 pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
718 try!(write_vuint(self.writer, tag_id));
719 try!(write_vuint(self.writer, b.len()));
720 self.writer.write(b)
721 }
722
723 pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) -> EncodeResult {
724 u64_to_be_bytes(v, 8u, |v| {
725 self.wr_tagged_bytes(tag_id, v)
726 })
727 }
728
729 pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) -> EncodeResult{
730 u64_to_be_bytes(v as u64, 4u, |v| {
731 self.wr_tagged_bytes(tag_id, v)
732 })
733 }
734
735 pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) -> EncodeResult {
736 u64_to_be_bytes(v as u64, 2u, |v| {
737 self.wr_tagged_bytes(tag_id, v)
738 })
739 }
740
741 pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
742 self.wr_tagged_bytes(tag_id, &[v])
743 }
744
745 pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) -> EncodeResult {
746 u64_to_be_bytes(v as u64, 8u, |v| {
747 self.wr_tagged_bytes(tag_id, v)
748 })
749 }
750
751 pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) -> EncodeResult {
752 u64_to_be_bytes(v as u64, 4u, |v| {
753 self.wr_tagged_bytes(tag_id, v)
754 })
755 }
756
757 pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) -> EncodeResult {
758 u64_to_be_bytes(v as u64, 2u, |v| {
759 self.wr_tagged_bytes(tag_id, v)
760 })
761 }
762
763 pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) -> EncodeResult {
764 self.wr_tagged_bytes(tag_id, &[v as u8])
765 }
766
767 pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) -> EncodeResult {
768 self.wr_tagged_bytes(tag_id, v.as_bytes())
769 }
770
771 pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult {
772 debug!("Write {} bytes", b.len());
773 self.writer.write(b)
774 }
775
776 pub fn wr_str(&mut self, s: &str) -> EncodeResult {
777 debug!("Write str: {}", s);
778 self.writer.write(s.as_bytes())
779 }
780 }
781
782 // FIXME (#2743): optionally perform "relaxations" on end_tag to more
783 // efficiently encode sizes; this is a fixed point iteration
784
785 // Set to true to generate more debugging in EBML code.
786 // Totally lame approach.
787 static DEBUG: bool = true;
788
789 impl<'a, W: Writer + Seek> Encoder<'a, W> {
790 // used internally to emit things like the vector length and so on
791 fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) -> EncodeResult {
792 assert!(v <= 0xFFFF_FFFF_u);
793 self.wr_tagged_u32(t as uint, v as u32)
794 }
795
796 fn _emit_label(&mut self, label: &str) -> EncodeResult {
797 // There are various strings that we have access to, such as
798 // the name of a record field, which do not actually appear in
799 // the encoded EBML (normally). This is just for
800 // efficiency. When debugging, though, we can emit such
801 // labels and then they will be checked by decoder to
802 // try and check failures more quickly.
803 if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
804 else { Ok(()) }
805 }
806
807 pub fn emit_opaque(&mut self, f: |&mut Encoder<W>| -> EncodeResult) -> EncodeResult {
808 try!(self.start_tag(EsOpaque as uint));
809 try!(f(self));
810 self.end_tag()
811 }
812 }
813
814 impl<'a, W: Writer + Seek> serialize::Encoder<io::IoError> for Encoder<'a, W> {
815 fn emit_nil(&mut self) -> EncodeResult {
816 Ok(())
817 }
818
819 fn emit_uint(&mut self, v: uint) -> EncodeResult {
820 self.wr_tagged_u64(EsUint as uint, v as u64)
821 }
822 fn emit_u64(&mut self, v: u64) -> EncodeResult {
823 self.wr_tagged_u64(EsU64 as uint, v)
824 }
825 fn emit_u32(&mut self, v: u32) -> EncodeResult {
826 self.wr_tagged_u32(EsU32 as uint, v)
827 }
828 fn emit_u16(&mut self, v: u16) -> EncodeResult {
829 self.wr_tagged_u16(EsU16 as uint, v)
830 }
831 fn emit_u8(&mut self, v: u8) -> EncodeResult {
832 self.wr_tagged_u8(EsU8 as uint, v)
833 }
834
835 fn emit_int(&mut self, v: int) -> EncodeResult {
836 self.wr_tagged_i64(EsInt as uint, v as i64)
837 }
838 fn emit_i64(&mut self, v: i64) -> EncodeResult {
839 self.wr_tagged_i64(EsI64 as uint, v)
840 }
841 fn emit_i32(&mut self, v: i32) -> EncodeResult {
842 self.wr_tagged_i32(EsI32 as uint, v)
843 }
844 fn emit_i16(&mut self, v: i16) -> EncodeResult {
845 self.wr_tagged_i16(EsI16 as uint, v)
846 }
847 fn emit_i8(&mut self, v: i8) -> EncodeResult {
848 self.wr_tagged_i8(EsI8 as uint, v)
849 }
850
851 fn emit_bool(&mut self, v: bool) -> EncodeResult {
852 self.wr_tagged_u8(EsBool as uint, v as u8)
853 }
854
855 fn emit_f64(&mut self, v: f64) -> EncodeResult {
856 let bits = unsafe { cast::transmute(v) };
857 self.wr_tagged_u64(EsF64 as uint, bits)
858 }
859 fn emit_f32(&mut self, v: f32) -> EncodeResult {
860 let bits = unsafe { cast::transmute(v) };
861 self.wr_tagged_u32(EsF32 as uint, bits)
862 }
863 fn emit_char(&mut self, v: char) -> EncodeResult {
864 self.wr_tagged_u32(EsChar as uint, v as u32)
865 }
866
867 fn emit_str(&mut self, v: &str) -> EncodeResult {
868 self.wr_tagged_str(EsStr as uint, v)
869 }
870
871 fn emit_enum(&mut self,
872 name: &str,
873 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
874 try!(self._emit_label(name));
875 try!(self.start_tag(EsEnum as uint));
876 try!(f(self));
877 self.end_tag()
878 }
879
880 fn emit_enum_variant(&mut self,
881 _: &str,
882 v_id: uint,
883 _: uint,
884 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
885 try!(self._emit_tagged_uint(EsEnumVid, v_id));
886 try!(self.start_tag(EsEnumBody as uint));
887 try!(f(self));
888 self.end_tag()
889 }
890
891 fn emit_enum_variant_arg(&mut self,
892 _: uint,
893 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
894 f(self)
895 }
896
897 fn emit_enum_struct_variant(&mut self,
898 v_name: &str,
899 v_id: uint,
900 cnt: uint,
901 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
902 self.emit_enum_variant(v_name, v_id, cnt, f)
903 }
904
905 fn emit_enum_struct_variant_field(&mut self,
906 _: &str,
907 idx: uint,
908 f: |&mut Encoder<'a, W>| -> EncodeResult)
909 -> EncodeResult {
910 self.emit_enum_variant_arg(idx, f)
911 }
912
913 fn emit_struct(&mut self,
914 _: &str,
915 _len: uint,
916 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
917 f(self)
918 }
919
920 fn emit_struct_field(&mut self,
921 name: &str,
922 _: uint,
923 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
924 try!(self._emit_label(name));
925 f(self)
926 }
927
928 fn emit_tuple(&mut self,
929 len: uint,
930 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
931 self.emit_seq(len, f)
932 }
933 fn emit_tuple_arg(&mut self,
934 idx: uint,
935 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
936 self.emit_seq_elt(idx, f)
937 }
938
939 fn emit_tuple_struct(&mut self,
940 _: &str,
941 len: uint,
942 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
943 self.emit_seq(len, f)
944 }
945 fn emit_tuple_struct_arg(&mut self,
946 idx: uint,
947 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
948 self.emit_seq_elt(idx, f)
949 }
950
951 fn emit_option(&mut self,
952 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
953 self.emit_enum("Option", f)
954 }
955 fn emit_option_none(&mut self) -> EncodeResult {
956 self.emit_enum_variant("None", 0, 0, |_| Ok(()))
957 }
958 fn emit_option_some(&mut self,
959 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
960
961 self.emit_enum_variant("Some", 1, 1, f)
962 }
963
964 fn emit_seq(&mut self,
965 len: uint,
966 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
967
968 try!(self.start_tag(EsVec as uint));
969 try!(self._emit_tagged_uint(EsVecLen, len));
970 try!(f(self));
971 self.end_tag()
972 }
973
974 fn emit_seq_elt(&mut self,
975 _idx: uint,
976 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
977
978 try!(self.start_tag(EsVecElt as uint));
979 try!(f(self));
980 self.end_tag()
981 }
982
983 fn emit_map(&mut self,
984 len: uint,
985 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
986
987 try!(self.start_tag(EsMap as uint));
988 try!(self._emit_tagged_uint(EsMapLen, len));
989 try!(f(self));
990 self.end_tag()
991 }
992
993 fn emit_map_elt_key(&mut self,
994 _idx: uint,
995 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
996
997 try!(self.start_tag(EsMapKey as uint));
998 try!(f(self));
999 self.end_tag()
1000 }
1001
1002 fn emit_map_elt_val(&mut self,
1003 _idx: uint,
1004 f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
1005 try!(self.start_tag(EsMapVal as uint));
1006 try!(f(self));
1007 self.end_tag()
1008 }
1009 }
1010 }
1011
1012 // ___________________________________________________________________________
1013 // Testing
1014
1015 #[cfg(test)]
1016 mod tests {
1017 use ebml::reader;
1018 use ebml::writer;
1019 use {Encodable, Decodable};
1020
1021 use std::io::MemWriter;
1022 use std::option::{None, Option, Some};
1023
1024 #[test]
1025 fn test_vuint_at() {
1026 let data = [
1027 0x80,
1028 0xff,
1029 0x40, 0x00,
1030 0x7f, 0xff,
1031 0x20, 0x00, 0x00,
1032 0x3f, 0xff, 0xff,
1033 0x10, 0x00, 0x00, 0x00,
1034 0x1f, 0xff, 0xff, 0xff
1035 ];
1036
1037 let mut res: reader::Res;
1038
1039 // Class A
1040 res = reader::vuint_at(data, 0).unwrap();
1041 assert_eq!(res.val, 0);
1042 assert_eq!(res.next, 1);
1043 res = reader::vuint_at(data, res.next).unwrap();
1044 assert_eq!(res.val, (1 << 7) - 1);
1045 assert_eq!(res.next, 2);
1046
1047 // Class B
1048 res = reader::vuint_at(data, res.next).unwrap();
1049 assert_eq!(res.val, 0);
1050 assert_eq!(res.next, 4);
1051 res = reader::vuint_at(data, res.next).unwrap();
1052 assert_eq!(res.val, (1 << 14) - 1);
1053 assert_eq!(res.next, 6);
1054
1055 // Class C
1056 res = reader::vuint_at(data, res.next).unwrap();
1057 assert_eq!(res.val, 0);
1058 assert_eq!(res.next, 9);
1059 res = reader::vuint_at(data, res.next).unwrap();
1060 assert_eq!(res.val, (1 << 21) - 1);
1061 assert_eq!(res.next, 12);
1062
1063 // Class D
1064 res = reader::vuint_at(data, res.next).unwrap();
1065 assert_eq!(res.val, 0);
1066 assert_eq!(res.next, 16);
1067 res = reader::vuint_at(data, res.next).unwrap();
1068 assert_eq!(res.val, (1 << 28) - 1);
1069 assert_eq!(res.next, 20);
1070 }
1071
1072 #[test]
1073 fn test_option_int() {
1074 fn test_v(v: Option<int>) {
1075 debug!("v == {:?}", v);
1076 let mut wr = MemWriter::new();
1077 {
1078 let mut ebml_w = writer::Encoder(&mut wr);
1079 let _ = v.encode(&mut ebml_w);
1080 }
1081 let ebml_doc = reader::Doc(wr.get_ref());
1082 let mut deser = reader::Decoder(ebml_doc);
1083 let v1 = Decodable::decode(&mut deser).unwrap();
1084 debug!("v1 == {:?}", v1);
1085 assert_eq!(v, v1);
1086 }
1087
1088 test_v(Some(22));
1089 test_v(None);
1090 test_v(Some(3));
1091 }
1092 }
1093
1094 #[cfg(test)]
1095 mod bench {
1096 extern crate test;
1097 use self::test::Bencher;
1098 use ebml::reader;
1099
1100 #[bench]
1101 pub fn vuint_at_A_aligned(b: &mut Bencher) {
1102 let data = Vec::from_fn(4*100, |i| {
1103 match i % 2 {
1104 0 => 0x80u8,
1105 _ => i as u8,
1106 }
1107 });
1108 let mut sum = 0u;
1109 b.iter(|| {
1110 let mut i = 0;
1111 while i < data.len() {
1112 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1113 i += 4;
1114 }
1115 });
1116 }
1117
1118 #[bench]
1119 pub fn vuint_at_A_unaligned(b: &mut Bencher) {
1120 let data = Vec::from_fn(4*100+1, |i| {
1121 match i % 2 {
1122 1 => 0x80u8,
1123 _ => i as u8
1124 }
1125 });
1126 let mut sum = 0u;
1127 b.iter(|| {
1128 let mut i = 1;
1129 while i < data.len() {
1130 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1131 i += 4;
1132 }
1133 });
1134 }
1135
1136 #[bench]
1137 pub fn vuint_at_D_aligned(b: &mut Bencher) {
1138 let data = Vec::from_fn(4*100, |i| {
1139 match i % 4 {
1140 0 => 0x10u8,
1141 3 => i as u8,
1142 _ => 0u8
1143 }
1144 });
1145 let mut sum = 0u;
1146 b.iter(|| {
1147 let mut i = 0;
1148 while i < data.len() {
1149 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1150 i += 4;
1151 }
1152 });
1153 }
1154
1155 #[bench]
1156 pub fn vuint_at_D_unaligned(b: &mut Bencher) {
1157 let data = Vec::from_fn(4*100+1, |i| {
1158 match i % 4 {
1159 1 => 0x10u8,
1160 0 => i as u8,
1161 _ => 0u8
1162 }
1163 });
1164 let mut sum = 0u;
1165 b.iter(|| {
1166 let mut i = 1;
1167 while i < data.len() {
1168 sum += reader::vuint_at(data.as_slice(), i).unwrap().val;
1169 i += 4;
1170 }
1171 });
1172 }
1173 }
libserialize/ebml.rs:642:4-642:4 -fn- definition:
fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
match size {
1u => w.write(&[0x80u8 | (n as u8)]),
references:- 5659: if n < 0x7f_u { return write_sized_vuint(w, n, 1u); }
660: if n < 0x4000_u { return write_sized_vuint(w, n, 2u); }
661: if n < 0x200000_u { return write_sized_vuint(w, n, 3u); }
--
703: let size = cur_pos as uint - last_size_pos - 4;
704: try!(write_sized_vuint(self.writer, size, 4u));
705: let r = try!(self.writer.seek(cur_pos as i64, io::SeekSet));
libserialize/ebml.rs:21:19-21:19 -struct- definition:
pub struct Doc<'a> {
pub data: &'a [u8],
pub start: uint,
references:- 34libserialize/ebml.rs:104:4-104:4 -NK_AS_STR_TODO- definition:
pub type DecodeResult<T> = Result<T, Error>;
// ebml reading
macro_rules! try_or(
references:- 60libserialize/ebml.rs:283:4-283:4 -fn- definition:
pub fn doc_as_u64(d: Doc) -> u64 {
assert_eq!(d.end, d.start + 8u);
u64_from_be_bytes(d.data, d.start, 8u)
references:- 6386: fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
387: fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
--
411: fn read_int(&mut self) -> DecodeResult<int> {
412: let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
413: if v > (int::MAX as i64) || v < (int::MIN as i64) {
--
425: fn read_f64(&mut self) -> DecodeResult<f64> {
426: let bits = doc_as_u64(try!(self.next_doc(EsF64)));
427: Ok(unsafe { transmute(bits) })
libserialize/ebml.rs:637:4-637:4 -struct- definition:
pub struct Encoder<'a, W> {
pub writer: &'a mut W,
size_positions: Vec<uint>,
references:- 26670: pub fn Encoder<'a, W: Writer + Seek>(w: &'a mut W) -> Encoder<'a, W> {
671: Encoder {
672: writer: w,
--
680: pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
681: Encoder {
682: writer: cast::transmute_copy(&self.writer),
--
814: impl<'a, W: Writer + Seek> serialize::Encoder<io::IoError> for Encoder<'a, W> {
815: fn emit_nil(&mut self) -> EncodeResult {
--
934: idx: uint,
935: f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
936: self.emit_seq_elt(idx, f)
--
958: fn emit_option_some(&mut self,
959: f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
--
1003: _idx: uint,
1004: f: |&mut Encoder<'a, W>| -> EncodeResult) -> EncodeResult {
1005: try!(self.start_tag(EsMapVal as uint));
libserialize/ebml.rs:293:4-293:4 -struct- definition:
pub struct Decoder<'a> {
parent: Doc<'a>,
pos: uint,
references:- 23298: pub fn Decoder<'a>(d: Doc<'a>) -> Decoder<'a> {
299: Decoder {
300: parent: d,
--
595: fn read_map<T>(&mut self,
596: f: |&mut Decoder<'doc>, uint| -> DecodeResult<T>) -> DecodeResult<T> {
597: debug!("read_map()");
--
605: fn read_map_elt_key<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
606: -> DecodeResult<T> {
--
611: fn read_map_elt_val<T>(&mut self, idx: uint, f: |&mut Decoder<'doc>| -> DecodeResult<T>)
612: -> DecodeResult<T> {
libserialize/ebml.rs:634:4-634:4 -NK_AS_STR_TODO- definition:
pub type EncodeResult = io::IoResult<()>;
// ebml writing
pub struct Encoder<'a, W> {
references:- 75libserialize/ebml.rs:151:4-151:4 -fn- definition:
pub fn vuint_at(data: &[u8], start: uint) -> DecodeResult<Res> {
use std::mem::from_be32;
if data.len() - start < 4 {
references:- 8198: pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
199: let elt_tag = try!(vuint_at(data, start));
200: let elt_size = try!(vuint_at(data, elt_tag.next));
--
248: while pos < d.end {
249: let elt_tag = try_or!(vuint_at(d.data, pos), false);
250: let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
251: pos = elt_size.next + elt_size.val;
libserialize/ebml.rs:46:1-46:1 -enum- definition:
pub enum EbmlEncoderTag {
EsUint, // 0
EsU64, // 1
references:- 4361: fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
362: let r = doc_as_u32(try!(self.next_doc(exp_tag)));
--
790: // used internally to emit things like the vector length and so on
791: fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) -> EncodeResult {
792: assert!(v <= 0xFFFF_FFFF_u);
libserialize/ebml.rs:268:4-268:4 -fn- definition:
pub fn doc_as_u8(d: Doc) -> u8 {
assert_eq!(d.end, d.start + 1u);
d.data[d.start]
references:- 4421: fn read_bool(&mut self) -> DecodeResult<bool> {
422: Ok(doc_as_u8(try!(self.next_doc(EsBool))) != 0)
423: }
libserialize/ebml.rs:273:4-273:4 -fn- definition:
pub fn doc_as_u16(d: Doc) -> u16 {
assert_eq!(d.end, d.start + 2u);
u64_from_be_bytes(d.data, d.start, 2u) as u16
references:- 3387: fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
388: fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
389: fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
--
405: fn read_i16(&mut self) -> DecodeResult<i16> {
406: Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
407: }
libserialize/ebml.rs:41:1-41:1 -struct- definition:
pub struct TaggedDoc<'a> {
tag: uint,
pub doc: Doc<'a>,
references:- 4201: let end = elt_size.next + elt_size.val;
202: Ok(TaggedDoc {
203: tag: elt_tag.val,
--
326: }
327: let TaggedDoc { tag: r_tag, doc: r_doc } =
328: try!(doc_at(self.parent.data, self.pos));
libserialize/ebml.rs:80:18-80:18 -enum- definition:
pub enum Error {
IntTooBig(uint),
Expected(~str),
references:- 3104: pub type DecodeResult<T> = Result<T, Error>;
105: // ebml reading
--
383: impl<'doc> serialize::Decoder<Error> for Decoder<'doc> {
384: fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
libserialize/ebml.rs:658:4-658:4 -fn- definition:
fn write_vuint<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
if n < 0x7f_u { return write_sized_vuint(w, n, 1u); }
if n < 0x4000_u { return write_sized_vuint(w, n, 2u); }
references:- 3717: pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
718: try!(write_vuint(self.writer, tag_id));
719: try!(write_vuint(self.writer, b.len()));
720: self.writer.write(b)
libserialize/ebml.rs:119:4-119:4 -struct- definition:
pub struct Res {
pub val: uint,
pub next: uint
references:- 7135: if a & 0x20u8 != 0u8 {
136: return Ok(Res {val: ((a & 0x1fu8) as uint) << 16u |
137: (data[start + 1u] as uint) << 8u |
--
141: if a & 0x10u8 != 0u8 {
142: return Ok(Res {val: ((a & 0x0fu8) as uint) << 24u |
143: (data[start + 1u] as uint) << 16u |
--
186: let (shift, mask) = SHIFT_MASK_TABLE[i];
187: Ok(Res {
188: val: ((val >> shift) & mask) as uint,
libserialize/ebml.rs:198:4-198:4 -fn- definition:
pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
let elt_tag = try!(vuint_at(data, start));
let elt_size = try!(vuint_at(data, elt_tag.next));
references:- 2327: let TaggedDoc { tag: r_tag, doc: r_doc } =
328: try!(doc_at(self.parent.data, self.pos));
329: debug!("self.parent={}-{} self.pos={} r_tag={} r_doc={}-{}",
libserialize/ebml.rs:278:4-278:4 -fn- definition:
pub fn doc_as_u32(d: Doc) -> u32 {
assert_eq!(d.end, d.start + 4u);
u64_from_be_bytes(d.data, d.start, 4u) as u32
references:- 6361: fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
362: let r = doc_as_u32(try!(self.next_doc(exp_tag)));
363: debug!("_next_uint exp_tag={:?} result={}", exp_tag, r);
--
433: fn read_char(&mut self) -> DecodeResult<char> {
434: Ok(char::from_u32(doc_as_u32(try!(self.next_doc(EsChar)))).unwrap())
435: }