(index<- ) ./libextra/ebml.rs
1 // Copyright 2012-2013 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::str;
14
15 // Simple Extensible Binary Markup Language (ebml) reader and writer on a
16 // cursor model. See the specification here:
17 // http://www.matroska.org/technical/specs/rfc/index.html
18
19 // Common data structures
20 struct EbmlTag {
21 id: uint,
22 size: uint,
23 }
24
25 struct EbmlState {
26 ebml_tag: EbmlTag,
27 tag_pos: uint,
28 data_pos: uint,
29 }
30
31 #[deriving(Clone)]
32 pub struct Doc {
33 data: @~[u8],
34 start: uint,
35 end: uint,
36 }
37
38 impl Doc {
39 pub fn get(&self, tag: uint) -> Doc {
40 reader::get_doc(*self, tag)
41 }
42
43 pub fn as_str_slice<'a>(&'a self) -> &'a str {
44 str::from_utf8_slice(self.data.slice(self.start, self.end))
45 }
46
47 pub fn as_str(&self) -> ~str {
48 self.as_str_slice().to_owned()
49 }
50 }
51
52 pub struct TaggedDoc {
53 tag: uint,
54 doc: Doc,
55 }
56
57 pub enum EbmlEncoderTag {
58 EsUint, // 0
59 EsU64, // 1
60 EsU32, // 2
61 EsU16, // 3
62 EsU8, // 4
63 EsInt, // 5
64 EsI64, // 6
65 EsI32, // 7
66 EsI16, // 8
67 EsI8, // 9
68 EsBool, // 10
69 EsChar, // 11
70 EsStr, // 12
71 EsF64, // 13
72 EsF32, // 14
73 EsFloat, // 15
74 EsEnum, // 16
75 EsEnumVid, // 17
76 EsEnumBody, // 18
77 EsVec, // 19
78 EsVecLen, // 20
79 EsVecElt, // 21
80 EsMap, // 22
81 EsMapLen, // 23
82 EsMapKey, // 24
83 EsMapVal, // 25
84
85 EsOpaque,
86
87 EsLabel, // Used only when debugging
88 }
89 // --------------------------------------
90
91 pub mod reader {
92 use std::char;
93 use super::*;
94
95 use serialize;
96
97 use std::cast::transmute;
98 use std::int;
99 use std::io;
100 use std::option::{None, Option, Some};
101
102 #[cfg(target_arch = "x86")]
103 #[cfg(target_arch = "x86_64")]
104 use std::ptr::offset;
105
106 #[cfg(target_arch = "x86")]
107 #[cfg(target_arch = "x86_64")]
108 use std::unstable::intrinsics::bswap32;
109
110 // ebml reading
111
112 struct Res {
113 val: uint,
114 next: uint
115 }
116
117 #[inline(never)]
118 fn vuint_at_slow(data: &[u8], start: uint) -> Res {
119 let a = data[start];
120 if a & 0x80u8 != 0u8 {
121 return Res {val: (a & 0x7fu8) as uint, next: start + 1u};
122 }
123 if a & 0x40u8 != 0u8 {
124 return Res {val: ((a & 0x3fu8) as uint) << 8u |
125 (data[start + 1u] as uint),
126 next: start + 2u};
127 }
128 if a & 0x20u8 != 0u8 {
129 return Res {val: ((a & 0x1fu8) as uint) << 16u |
130 (data[start + 1u] as uint) << 8u |
131 (data[start + 2u] as uint),
132 next: start + 3u};
133 }
134 if a & 0x10u8 != 0u8 {
135 return Res {val: ((a & 0x0fu8) as uint) << 24u |
136 (data[start + 1u] as uint) << 16u |
137 (data[start + 2u] as uint) << 8u |
138 (data[start + 3u] as uint),
139 next: start + 4u};
140 }
141 fail!("vint too big");
142 }
143
144 #[cfg(target_arch = "x86")]
145 #[cfg(target_arch = "x86_64")]
146 pub fn vuint_at(data: &[u8], start: uint) -> Res {
147 if data.len() - start < 4 {
148 return vuint_at_slow(data, start);
149 }
150
151 unsafe {
152 let (ptr, _): (*u8, uint) = transmute(data);
153 let ptr = offset(ptr, start as int);
154 let ptr: *i32 = transmute(ptr);
155 let val = bswap32(*ptr);
156 let val: u32 = transmute(val);
157 if (val & 0x80000000) != 0 {
158 Res {
159 val: ((val >> 24) & 0x7f) as uint,
160 next: start + 1
161 }
162 } else if (val & 0x40000000) != 0 {
163 Res {
164 val: ((val >> 16) & 0x3fff) as uint,
165 next: start + 2
166 }
167 } else if (val & 0x20000000) != 0 {
168 Res {
169 val: ((val >> 8) & 0x1fffff) as uint,
170 next: start + 3
171 }
172 } else {
173 Res {
174 val: (val & 0x0fffffff) as uint,
175 next: start + 4
176 }
177 }
178 }
179 }
180
181 #[cfg(target_arch = "arm")]
182 #[cfg(target_arch = "mips")]
183 pub fn vuint_at(data: &[u8], start: uint) -> Res {
184 vuint_at_slow(data, start)
185 }
186
187 pub fn Doc(data: @~[u8]) -> Doc {
188 Doc { data: data, start: 0u, end: data.len() }
189 }
190
191 pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc {
192 let elt_tag = vuint_at(*data, start);
193 let elt_size = vuint_at(*data, elt_tag.next);
194 let end = elt_size.next + elt_size.val;
195 TaggedDoc {
196 tag: elt_tag.val,
197 doc: Doc { data: data, start: elt_size.next, end: end }
198 }
199 }
200
201 pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
202 let mut pos = d.start;
203 while pos < d.end {
204 let elt_tag = vuint_at(*d.data, pos);
205 let elt_size = vuint_at(*d.data, elt_tag.next);
206 pos = elt_size.next + elt_size.val;
207 if elt_tag.val == tg {
208 return Some(Doc { data: d.data, start: elt_size.next,
209 end: pos });
210 }
211 }
212 None
213 }
214
215 pub fn get_doc(d: Doc, tg: uint) -> Doc {
216 match maybe_get_doc(d, tg) {
217 Some(d) => d,
218 None => {
219 error!("failed to find block with tag %u", tg);
220 fail!();
221 }
222 }
223 }
224
225 pub fn docs(d: Doc, it: &fn(uint, Doc) -> bool) -> bool {
226 let mut pos = d.start;
227 while pos < d.end {
228 let elt_tag = vuint_at(*d.data, pos);
229 let elt_size = vuint_at(*d.data, elt_tag.next);
230 pos = elt_size.next + elt_size.val;
231 let doc = Doc { data: d.data, start: elt_size.next, end: pos };
232 if !it(elt_tag.val, doc) {
233 return false;
234 }
235 }
236 return true;
237 }
238
239 pub fn tagged_docs(d: Doc, tg: uint, it: &fn(Doc) -> bool) -> bool {
240 let mut pos = d.start;
241 while pos < d.end {
242 let elt_tag = vuint_at(*d.data, pos);
243 let elt_size = vuint_at(*d.data, elt_tag.next);
244 pos = elt_size.next + elt_size.val;
245 if elt_tag.val == tg {
246 let doc = Doc { data: d.data, start: elt_size.next,
247 end: pos };
248 if !it(doc) {
249 return false;
250 }
251 }
252 }
253 return true;
254 }
255
256 pub fn with_doc_data<T>(d: Doc, f: &fn(x: &[u8]) -> T) -> T {
257 f(d.data.slice(d.start, d.end))
258 }
259
260
261 pub fn doc_as_u8(d: Doc) -> u8 {
262 assert_eq!(d.end, d.start + 1u);
263 (*d.data)[d.start]
264 }
265
266 pub fn doc_as_u16(d: Doc) -> u16 {
267 assert_eq!(d.end, d.start + 2u);
268 io::u64_from_be_bytes(*d.data, d.start, 2u) as u16
269 }
270
271 pub fn doc_as_u32(d: Doc) -> u32 {
272 assert_eq!(d.end, d.start + 4u);
273 io::u64_from_be_bytes(*d.data, d.start, 4u) as u32
274 }
275
276 pub fn doc_as_u64(d: Doc) -> u64 {
277 assert_eq!(d.end, d.start + 8u);
278 io::u64_from_be_bytes(*d.data, d.start, 8u)
279 }
280
281 pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
282 pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
283 pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
284 pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
285
286 pub struct Decoder {
287 priv parent: Doc,
288 priv pos: uint,
289 }
290
291 pub fn Decoder(d: Doc) -> Decoder {
292 Decoder {
293 parent: d,
294 pos: d.start
295 }
296 }
297
298 impl Decoder {
299 fn _check_label(&mut self, lbl: &str) {
300 if self.pos < self.parent.end {
301 let TaggedDoc { tag: r_tag, doc: r_doc } =
302 doc_at(self.parent.data, self.pos);
303
304 if r_tag == (EsLabel as uint) {
305 self.pos = r_doc.end;
306 let str = r_doc.as_str_slice();
307 if lbl != str {
308 fail!("Expected label %s but found %s", lbl, str);
309 }
310 }
311 }
312 }
313
314 fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> Doc {
315 debug!(". next_doc(exp_tag=%?)", exp_tag);
316 if self.pos >= self.parent.end {
317 fail!("no more documents in current node!");
318 }
319 let TaggedDoc { tag: r_tag, doc: r_doc } =
320 doc_at(self.parent.data, self.pos);
321 debug!("self.parent=%?-%? self.pos=%? r_tag=%? r_doc=%?-%?",
322 self.parent.start,
323 self.parent.end,
324 self.pos,
325 r_tag,
326 r_doc.start,
327 r_doc.end);
328 if r_tag != (exp_tag as uint) {
329 fail!("expected EBML doc with tag %? but found tag %?", exp_tag, r_tag);
330 }
331 if r_doc.end > self.parent.end {
332 fail!("invalid EBML, child extends to 0x%x, parent to 0x%x",
333 r_doc.end, self.parent.end);
334 }
335 self.pos = r_doc.end;
336 r_doc
337 }
338
339 fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag,
340 f: &fn(&mut Decoder) -> T) -> T {
341 let d = self.next_doc(exp_tag);
342 let old_parent = self.parent;
343 let old_pos = self.pos;
344 self.parent = d;
345 self.pos = d.start;
346 let r = f(self);
347 self.parent = old_parent;
348 self.pos = old_pos;
349 r
350 }
351
352 fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> uint {
353 let r = doc_as_u32(self.next_doc(exp_tag));
354 debug!("_next_uint exp_tag=%? result=%?", exp_tag, r);
355 r as uint
356 }
357 }
358
359 impl Decoder {
360 pub fn read_opaque<R>(&mut self, op: &fn(&mut Decoder, Doc) -> R)
361 -> R {
362 let doc = self.next_doc(EsOpaque);
363
364 let (old_parent, old_pos) = (self.parent, self.pos);
365 self.parent = doc;
366 self.pos = doc.start;
367
368 let result = op(self, doc);
369
370 self.parent = old_parent;
371 self.pos = old_pos;
372 result
373 }
374 }
375
376 impl serialize::Decoder for Decoder {
377 fn read_nil(&mut self) -> () { () }
378
379 fn read_u64(&mut self) -> u64 { doc_as_u64(self.next_doc(EsU64)) }
380 fn read_u32(&mut self) -> u32 { doc_as_u32(self.next_doc(EsU32)) }
381 fn read_u16(&mut self) -> u16 { doc_as_u16(self.next_doc(EsU16)) }
382 fn read_u8 (&mut self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) }
383 fn read_uint(&mut self) -> uint {
384 let v = doc_as_u64(self.next_doc(EsUint));
385 if v > (::std::uint::max_value as u64) {
386 fail!("uint %? too large for this architecture", v);
387 }
388 v as uint
389 }
390
391 fn read_i64(&mut self) -> i64 {
392 doc_as_u64(self.next_doc(EsI64)) as i64
393 }
394 fn read_i32(&mut self) -> i32 {
395 doc_as_u32(self.next_doc(EsI32)) as i32
396 }
397 fn read_i16(&mut self) -> i16 {
398 doc_as_u16(self.next_doc(EsI16)) as i16
399 }
400 fn read_i8 (&mut self) -> i8 {
401 doc_as_u8(self.next_doc(EsI8 )) as i8
402 }
403 fn read_int(&mut self) -> int {
404 let v = doc_as_u64(self.next_doc(EsInt)) as i64;
405 if v > (int::max_value as i64) || v < (int::min_value as i64) {
406 debug!("FIXME #6122: Removing this makes this function miscompile");
407 fail!("int %? out of range for this architecture", v);
408 }
409 v as int
410 }
411
412 fn read_bool(&mut self) -> bool {
413 doc_as_u8(self.next_doc(EsBool)) != 0
414 }
415
416 fn read_f64(&mut self) -> f64 {
417 let bits = doc_as_u64(self.next_doc(EsF64));
418 unsafe { transmute(bits) }
419 }
420 fn read_f32(&mut self) -> f32 {
421 let bits = doc_as_u32(self.next_doc(EsF32));
422 unsafe { transmute(bits) }
423 }
424 fn read_float(&mut self) -> float {
425 let bits = doc_as_u64(self.next_doc(EsFloat));
426 (unsafe { transmute::<u64, f64>(bits) }) as float
427 }
428 fn read_char(&mut self) -> char {
429 char::from_u32(doc_as_u32(self.next_doc(EsChar))).unwrap()
430 }
431 fn read_str(&mut self) -> ~str {
432 self.next_doc(EsStr).as_str()
433 }
434
435 // Compound types:
436 fn read_enum<T>(&mut self,
437 name: &str,
438 f: &fn(&mut Decoder) -> T)
439 -> T {
440 debug!("read_enum(%s)", name);
441 self._check_label(name);
442
443 let doc = self.next_doc(EsEnum);
444
445 let (old_parent, old_pos) = (self.parent, self.pos);
446 self.parent = doc;
447 self.pos = self.parent.start;
448
449 let result = f(self);
450
451 self.parent = old_parent;
452 self.pos = old_pos;
453 result
454 }
455
456 fn read_enum_variant<T>(&mut self,
457 _: &[&str],
458 f: &fn(&mut Decoder, uint) -> T)
459 -> T {
460 debug!("read_enum_variant()");
461 let idx = self._next_uint(EsEnumVid);
462 debug!(" idx=%u", idx);
463
464 let doc = self.next_doc(EsEnumBody);
465
466 let (old_parent, old_pos) = (self.parent, self.pos);
467 self.parent = doc;
468 self.pos = self.parent.start;
469
470 let result = f(self, idx);
471
472 self.parent = old_parent;
473 self.pos = old_pos;
474 result
475 }
476
477 fn read_enum_variant_arg<T>(&mut self,
478 idx: uint,
479 f: &fn(&mut Decoder) -> T) -> T {
480 debug!("read_enum_variant_arg(idx=%u)", idx);
481 f(self)
482 }
483
484 fn read_enum_struct_variant<T>(&mut self,
485 _: &[&str],
486 f: &fn(&mut Decoder, uint) -> T)
487 -> T {
488 debug!("read_enum_struct_variant()");
489 let idx = self._next_uint(EsEnumVid);
490 debug!(" idx=%u", idx);
491
492 let doc = self.next_doc(EsEnumBody);
493
494 let (old_parent, old_pos) = (self.parent, self.pos);
495 self.parent = doc;
496 self.pos = self.parent.start;
497
498 let result = f(self, idx);
499
500 self.parent = old_parent;
501 self.pos = old_pos;
502 result
503 }
504
505 fn read_enum_struct_variant_field<T>(&mut self,
506 name: &str,
507 idx: uint,
508 f: &fn(&mut Decoder) -> T)
509 -> T {
510 debug!("read_enum_struct_variant_arg(name=%?, idx=%u)", name, idx);
511 f(self)
512 }
513
514 fn read_struct<T>(&mut self,
515 name: &str,
516 _: uint,
517 f: &fn(&mut Decoder) -> T)
518 -> T {
519 debug!("read_struct(name=%s)", name);
520 f(self)
521 }
522
523 fn read_struct_field<T>(&mut self,
524 name: &str,
525 idx: uint,
526 f: &fn(&mut Decoder) -> T)
527 -> T {
528 debug!("read_struct_field(name=%?, idx=%u)", name, idx);
529 self._check_label(name);
530 f(self)
531 }
532
533 fn read_tuple<T>(&mut self, f: &fn(&mut Decoder, uint) -> T) -> T {
534 debug!("read_tuple()");
535 self.read_seq(f)
536 }
537
538 fn read_tuple_arg<T>(&mut self, idx: uint, f: &fn(&mut Decoder) -> T)
539 -> T {
540 debug!("read_tuple_arg(idx=%u)", idx);
541 self.read_seq_elt(idx, f)
542 }
543
544 fn read_tuple_struct<T>(&mut self,
545 name: &str,
546 f: &fn(&mut Decoder, uint) -> T)
547 -> T {
548 debug!("read_tuple_struct(name=%?)", name);
549 self.read_tuple(f)
550 }
551
552 fn read_tuple_struct_arg<T>(&mut self,
553 idx: uint,
554 f: &fn(&mut Decoder) -> T)
555 -> T {
556 debug!("read_tuple_struct_arg(idx=%u)", idx);
557 self.read_tuple_arg(idx, f)
558 }
559
560 fn read_option<T>(&mut self, f: &fn(&mut Decoder, bool) -> T) -> T {
561 debug!("read_option()");
562 do self.read_enum("Option") |this| {
563 do this.read_enum_variant(["None", "Some"]) |this, idx| {
564 match idx {
565 0 => f(this, false),
566 1 => f(this, true),
567 _ => fail!(),
568 }
569 }
570 }
571 }
572
573 fn read_seq<T>(&mut self, f: &fn(&mut Decoder, uint) -> T) -> T {
574 debug!("read_seq()");
575 do self.push_doc(EsVec) |d| {
576 let len = d._next_uint(EsVecLen);
577 debug!(" len=%u", len);
578 f(d, len)
579 }
580 }
581
582 fn read_seq_elt<T>(&mut self, idx: uint, f: &fn(&mut Decoder) -> T)
583 -> T {
584 debug!("read_seq_elt(idx=%u)", idx);
585 self.push_doc(EsVecElt, f)
586 }
587
588 fn read_map<T>(&mut self, f: &fn(&mut Decoder, uint) -> T) -> T {
589 debug!("read_map()");
590 do self.push_doc(EsMap) |d| {
591 let len = d._next_uint(EsMapLen);
592 debug!(" len=%u", len);
593 f(d, len)
594 }
595 }
596
597 fn read_map_elt_key<T>(&mut self,
598 idx: uint,
599 f: &fn(&mut Decoder) -> T)
600 -> T {
601 debug!("read_map_elt_key(idx=%u)", idx);
602 self.push_doc(EsMapKey, f)
603 }
604
605 fn read_map_elt_val<T>(&mut self,
606 idx: uint,
607 f: &fn(&mut Decoder) -> T)
608 -> T {
609 debug!("read_map_elt_val(idx=%u)", idx);
610 self.push_doc(EsMapVal, f)
611 }
612 }
613 }
614
615 pub mod writer {
616 use super::*;
617
618 use std::cast;
619 use std::clone::Clone;
620 use std::io;
621
622 // ebml writing
623 pub struct Encoder {
624 writer: @io::Writer,
625 priv size_positions: ~[uint],
626 }
627
628 impl Clone for Encoder {
629 fn clone(&self) -> Encoder {
630 Encoder {
631 writer: self.writer,
632 size_positions: self.size_positions.clone(),
633 }
634 }
635 }
636
637 fn write_sized_vuint(w: @io::Writer, n: uint, size: uint) {
638 match size {
639 1u => w.write(&[0x80u8 | (n as u8)]),
640 2u => w.write(&[0x40u8 | ((n >> 8_u) as u8), n as u8]),
641 3u => w.write(&[0x20u8 | ((n >> 16_u) as u8), (n >> 8_u) as u8,
642 n as u8]),
643 4u => w.write(&[0x10u8 | ((n >> 24_u) as u8), (n >> 16_u) as u8,
644 (n >> 8_u) as u8, n as u8]),
645 _ => fail!("vint to write too big: %?", n)
646 };
647 }
648
649 fn write_vuint(w: @io::Writer, n: uint) {
650 if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; }
651 if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; }
652 if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; }
653 if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; }
654 fail!("vint to write too big: %?", n);
655 }
656
657 pub fn Encoder(w: @io::Writer) -> Encoder {
658 let size_positions: ~[uint] = ~[];
659 Encoder {
660 writer: w,
661 size_positions: size_positions
662 }
663 }
664
665 // FIXME (#2741): Provide a function to write the standard ebml header.
666 impl Encoder {
667 pub fn start_tag(&mut self, tag_id: uint) {
668 debug!("Start tag %u", tag_id);
669
670 // Write the enum ID:
671 write_vuint(self.writer, tag_id);
672
673 // Write a placeholder four-byte size.
674 self.size_positions.push(self.writer.tell());
675 let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
676 self.writer.write(zeroes);
677 }
678
679 pub fn end_tag(&mut self) {
680 let last_size_pos = self.size_positions.pop();
681 let cur_pos = self.writer.tell();
682 self.writer.seek(last_size_pos as int, io::SeekSet);
683 let size = (cur_pos - last_size_pos - 4u);
684 write_sized_vuint(self.writer, size, 4u);
685 self.writer.seek(cur_pos as int, io::SeekSet);
686
687 debug!("End tag (size = %u)", size);
688 }
689
690 pub fn wr_tag(&mut self, tag_id: uint, blk: &fn()) {
691 self.start_tag(tag_id);
692 blk();
693 self.end_tag();
694 }
695
696 pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) {
697 write_vuint(self.writer, tag_id);
698 write_vuint(self.writer, b.len());
699 self.writer.write(b);
700 }
701
702 pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) {
703 do io::u64_to_be_bytes(v, 8u) |v| {
704 self.wr_tagged_bytes(tag_id, v);
705 }
706 }
707
708 pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) {
709 do io::u64_to_be_bytes(v as u64, 4u) |v| {
710 self.wr_tagged_bytes(tag_id, v);
711 }
712 }
713
714 pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) {
715 do io::u64_to_be_bytes(v as u64, 2u) |v| {
716 self.wr_tagged_bytes(tag_id, v);
717 }
718 }
719
720 pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) {
721 self.wr_tagged_bytes(tag_id, &[v]);
722 }
723
724 pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) {
725 do io::u64_to_be_bytes(v as u64, 8u) |v| {
726 self.wr_tagged_bytes(tag_id, v);
727 }
728 }
729
730 pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) {
731 do io::u64_to_be_bytes(v as u64, 4u) |v| {
732 self.wr_tagged_bytes(tag_id, v);
733 }
734 }
735
736 pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) {
737 do io::u64_to_be_bytes(v as u64, 2u) |v| {
738 self.wr_tagged_bytes(tag_id, v);
739 }
740 }
741
742 pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) {
743 self.wr_tagged_bytes(tag_id, &[v as u8]);
744 }
745
746 pub fn wr_tagged_str(&mut self, tag_id: uint, v: &str) {
747 self.wr_tagged_bytes(tag_id, v.as_bytes());
748 }
749
750 pub fn wr_bytes(&mut self, b: &[u8]) {
751 debug!("Write %u bytes", b.len());
752 self.writer.write(b);
753 }
754
755 pub fn wr_str(&mut self, s: &str) {
756 debug!("Write str: %?", s);
757 self.writer.write(s.as_bytes());
758 }
759 }
760
761 // FIXME (#2743): optionally perform "relaxations" on end_tag to more
762 // efficiently encode sizes; this is a fixed point iteration
763
764 // Set to true to generate more debugging in EBML code.
765 // Totally lame approach.
766 static DEBUG: bool = true;
767
768 impl Encoder {
769 // used internally to emit things like the vector length and so on
770 fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) {
771 assert!(v <= 0xFFFF_FFFF_u);
772 self.wr_tagged_u32(t as uint, v as u32);
773 }
774
775 fn _emit_label(&mut self, label: &str) {
776 // There are various strings that we have access to, such as
777 // the name of a record field, which do not actually appear in
778 // the encoded EBML (normally). This is just for
779 // efficiency. When debugging, though, we can emit such
780 // labels and then they will be checked by decoder to
781 // try and check failures more quickly.
782 if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
783 }
784 }
785
786 impl Encoder {
787 pub fn emit_opaque(&mut self, f: &fn(&mut Encoder)) {
788 self.start_tag(EsOpaque as uint);
789 f(self);
790 self.end_tag();
791 }
792 }
793
794 impl ::serialize::Encoder for Encoder {
795 fn emit_nil(&mut self) {}
796
797 fn emit_uint(&mut self, v: uint) {
798 self.wr_tagged_u64(EsUint as uint, v as u64);
799 }
800 fn emit_u64(&mut self, v: u64) {
801 self.wr_tagged_u64(EsU64 as uint, v);
802 }
803 fn emit_u32(&mut self, v: u32) {
804 self.wr_tagged_u32(EsU32 as uint, v);
805 }
806 fn emit_u16(&mut self, v: u16) {
807 self.wr_tagged_u16(EsU16 as uint, v);
808 }
809 fn emit_u8(&mut self, v: u8) {
810 self.wr_tagged_u8(EsU8 as uint, v);
811 }
812
813 fn emit_int(&mut self, v: int) {
814 self.wr_tagged_i64(EsInt as uint, v as i64);
815 }
816 fn emit_i64(&mut self, v: i64) {
817 self.wr_tagged_i64(EsI64 as uint, v);
818 }
819 fn emit_i32(&mut self, v: i32) {
820 self.wr_tagged_i32(EsI32 as uint, v);
821 }
822 fn emit_i16(&mut self, v: i16) {
823 self.wr_tagged_i16(EsI16 as uint, v);
824 }
825 fn emit_i8(&mut self, v: i8) {
826 self.wr_tagged_i8(EsI8 as uint, v);
827 }
828
829 fn emit_bool(&mut self, v: bool) {
830 self.wr_tagged_u8(EsBool as uint, v as u8)
831 }
832
833 fn emit_f64(&mut self, v: f64) {
834 let bits = unsafe { cast::transmute(v) };
835 self.wr_tagged_u64(EsF64 as uint, bits);
836 }
837 fn emit_f32(&mut self, v: f32) {
838 let bits = unsafe { cast::transmute(v) };
839 self.wr_tagged_u32(EsF32 as uint, bits);
840 }
841 fn emit_float(&mut self, v: float) {
842 let bits = unsafe { cast::transmute(v as f64) };
843 self.wr_tagged_u64(EsFloat as uint, bits);
844 }
845
846 fn emit_char(&mut self, v: char) {
847 self.wr_tagged_u32(EsChar as uint, v as u32);
848 }
849
850 fn emit_str(&mut self, v: &str) {
851 self.wr_tagged_str(EsStr as uint, v)
852 }
853
854 fn emit_enum(&mut self, name: &str, f: &fn(&mut Encoder)) {
855 self._emit_label(name);
856 self.start_tag(EsEnum as uint);
857 f(self);
858 self.end_tag();
859 }
860
861 fn emit_enum_variant(&mut self,
862 _: &str,
863 v_id: uint,
864 _: uint,
865 f: &fn(&mut Encoder)) {
866 self._emit_tagged_uint(EsEnumVid, v_id);
867 self.start_tag(EsEnumBody as uint);
868 f(self);
869 self.end_tag();
870 }
871
872 fn emit_enum_variant_arg(&mut self, _: uint, f: &fn(&mut Encoder)) {
873 f(self)
874 }
875
876 fn emit_enum_struct_variant(&mut self,
877 v_name: &str,
878 v_id: uint,
879 cnt: uint,
880 f: &fn(&mut Encoder)) {
881 self.emit_enum_variant(v_name, v_id, cnt, f)
882 }
883
884 fn emit_enum_struct_variant_field(&mut self,
885 _: &str,
886 idx: uint,
887 f: &fn(&mut Encoder)) {
888 self.emit_enum_variant_arg(idx, f)
889 }
890
891 fn emit_struct(&mut self, _: &str, _len: uint, f: &fn(&mut Encoder)) {
892 f(self)
893 }
894
895 fn emit_struct_field(&mut self,
896 name: &str,
897 _: uint,
898 f: &fn(&mut Encoder)) {
899 self._emit_label(name);
900 f(self)
901 }
902
903 fn emit_tuple(&mut self, len: uint, f: &fn(&mut Encoder)) {
904 self.emit_seq(len, f)
905 }
906 fn emit_tuple_arg(&mut self, idx: uint, f: &fn(&mut Encoder)) {
907 self.emit_seq_elt(idx, f)
908 }
909
910 fn emit_tuple_struct(&mut self,
911 _: &str,
912 len: uint,
913 f: &fn(&mut Encoder)) {
914 self.emit_seq(len, f)
915 }
916 fn emit_tuple_struct_arg(&mut self, idx: uint, f: &fn(&mut Encoder)) {
917 self.emit_seq_elt(idx, f)
918 }
919
920 fn emit_option(&mut self, f: &fn(&mut Encoder)) {
921 self.emit_enum("Option", f);
922 }
923 fn emit_option_none(&mut self) {
924 self.emit_enum_variant("None", 0, 0, |_| ())
925 }
926 fn emit_option_some(&mut self, f: &fn(&mut Encoder)) {
927 self.emit_enum_variant("Some", 1, 1, f)
928 }
929
930 fn emit_seq(&mut self, len: uint, f: &fn(&mut Encoder)) {
931 self.start_tag(EsVec as uint);
932 self._emit_tagged_uint(EsVecLen, len);
933 f(self);
934 self.end_tag();
935 }
936
937 fn emit_seq_elt(&mut self, _idx: uint, f: &fn(&mut Encoder)) {
938 self.start_tag(EsVecElt as uint);
939 f(self);
940 self.end_tag();
941 }
942
943 fn emit_map(&mut self, len: uint, f: &fn(&mut Encoder)) {
944 self.start_tag(EsMap as uint);
945 self._emit_tagged_uint(EsMapLen, len);
946 f(self);
947 self.end_tag();
948 }
949
950 fn emit_map_elt_key(&mut self, _idx: uint, f: &fn(&mut Encoder)) {
951 self.start_tag(EsMapKey as uint);
952 f(self);
953 self.end_tag();
954 }
955
956 fn emit_map_elt_val(&mut self, _idx: uint, f: &fn(&mut Encoder)) {
957 self.start_tag(EsMapVal as uint);
958 f(self);
959 self.end_tag();
960 }
961 }
962 }
963
964 // ___________________________________________________________________________
965 // Testing
966
967 #[cfg(test)]
968 mod tests {
969 use ebml::reader;
970 use ebml::writer;
971 use serialize::Encodable;
972 use serialize;
973
974 use std::io;
975 use std::option::{None, Option, Some};
976
977 #[test]
978 fn test_option_int() {
979 fn test_v(v: Option<int>) {
980 debug!("v == %?", v);
981 let bytes = do io::with_bytes_writer |wr| {
982 let mut ebml_w = writer::Encoder(wr);
983 v.encode(&mut ebml_w)
984 };
985 let ebml_doc = reader::Doc(@bytes);
986 let mut deser = reader::Decoder(ebml_doc);
987 let v1 = serialize::Decodable::decode(&mut deser);
988 debug!("v1 == %?", v1);
989 assert_eq!(v, v1);
990 }
991
992 test_v(Some(22));
993 test_v(None);
994 test_v(Some(3));
995 }
996 }
libextra/ebml.rs:261:4-261:4 -fn- definition:
pub fn doc_as_u8(d: Doc) -> u8 {
assert_eq!(d.end, d.start + 1u);
references:-382: fn read_u8 (&mut self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) }
401: doc_as_u8(self.next_doc(EsI8 )) as i8
413: doc_as_u8(self.next_doc(EsBool)) != 0
281: pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
libextra/ebml.rs:146:4-146:4 -fn- definition:
pub fn vuint_at(data: &[u8], start: uint) -> Res {
if data.len() - start < 4 {
references:-205: let elt_size = vuint_at(*d.data, elt_tag.next);
243: let elt_size = vuint_at(*d.data, elt_tag.next);
193: let elt_size = vuint_at(*data, elt_tag.next);
204: let elt_tag = vuint_at(*d.data, pos);
229: let elt_size = vuint_at(*d.data, elt_tag.next);
228: let elt_tag = vuint_at(*d.data, pos);
242: let elt_tag = vuint_at(*d.data, pos);
192: let elt_tag = vuint_at(*data, start);
libextra/ebml.rs:31:19-31:19 -struct- definition:
#[deriving(Clone)]
pub struct Doc {
references:-261: pub fn doc_as_u8(d: Doc) -> u8 {
215: pub fn get_doc(d: Doc, tg: uint) -> Doc {
187: pub fn Doc(data: @~[u8]) -> Doc {
197: doc: Doc { data: data, start: elt_size.next, end: end }
31: #[deriving(Clone)]
246: let doc = Doc { data: d.data, start: elt_size.next,
54: doc: Doc,
231: let doc = Doc { data: d.data, start: elt_size.next, end: pos };
291: pub fn Decoder(d: Doc) -> Decoder {
215: pub fn get_doc(d: Doc, tg: uint) -> Doc {
39: pub fn get(&self, tag: uint) -> Doc {
201: pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
266: pub fn doc_as_u16(d: Doc) -> u16 {
287: priv parent: Doc,
225: pub fn docs(d: Doc, it: &fn(uint, Doc) -> bool) -> bool {
208: return Some(Doc { data: d.data, start: elt_size.next,
281: pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
314: fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> Doc {
239: pub fn tagged_docs(d: Doc, tg: uint, it: &fn(Doc) -> bool) -> bool {
284: pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
276: pub fn doc_as_u64(d: Doc) -> u64 {
225: pub fn docs(d: Doc, it: &fn(uint, Doc) -> bool) -> bool {
239: pub fn tagged_docs(d: Doc, tg: uint, it: &fn(Doc) -> bool) -> bool {
360: pub fn read_opaque<R>(&mut self, op: &fn(&mut Decoder, Doc) -> R)
31: #[deriving(Clone)]
38: impl Doc {
283: pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
31: #[deriving(Clone)]
31: #[deriving(Clone)]
188: Doc { data: data, start: 0u, end: data.len() }
(256)(201)(271)(282)libextra/ebml.rs:271:4-271:4 -fn- definition:
pub fn doc_as_u32(d: Doc) -> u32 {
assert_eq!(d.end, d.start + 4u);
references:-429: char::from_u32(doc_as_u32(self.next_doc(EsChar))).unwrap()
283: pub fn doc_as_i32(d: Doc) -> i32 { doc_as_u32(d) as i32 }
380: fn read_u32(&mut self) -> u32 { doc_as_u32(self.next_doc(EsU32)) }
421: let bits = doc_as_u32(self.next_doc(EsF32));
395: doc_as_u32(self.next_doc(EsI32)) as i32
353: let r = doc_as_u32(self.next_doc(exp_tag));
libextra/ebml.rs:649:4-649:4 -fn- definition:
fn write_vuint(w: @io::Writer, n: uint) {
if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; }
references:-697: write_vuint(self.writer, tag_id);
671: write_vuint(self.writer, tag_id);
698: write_vuint(self.writer, b.len());
libextra/ebml.rs:191:4-191:4 -fn- definition:
pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc {
let elt_tag = vuint_at(*data, start);
references:-320: doc_at(self.parent.data, self.pos);
302: doc_at(self.parent.data, self.pos);
libextra/ebml.rs:276:4-276:4 -fn- definition:
pub fn doc_as_u64(d: Doc) -> u64 {
assert_eq!(d.end, d.start + 8u);
references:-392: doc_as_u64(self.next_doc(EsI64)) as i64
417: let bits = doc_as_u64(self.next_doc(EsF64));
384: let v = doc_as_u64(self.next_doc(EsUint));
284: pub fn doc_as_i64(d: Doc) -> i64 { doc_as_u64(d) as i64 }
404: let v = doc_as_u64(self.next_doc(EsInt)) as i64;
425: let bits = doc_as_u64(self.next_doc(EsFloat));
379: fn read_u64(&mut self) -> u64 { doc_as_u64(self.next_doc(EsU64)) }
libextra/ebml.rs:19:26-19:26 -struct- definition:
// Common data structures
struct EbmlTag {
references:-26: ebml_tag: EbmlTag,
libextra/ebml.rs:187:4-187:4 -fn- definition:
pub fn Doc(data: @~[u8]) -> Doc {
Doc { data: data, start: 0u, end: data.len() }
references:-libextra/flatpipes.rs:
494: let doc = ebml::reader::Doc(buf);
libextra/ebml.rs:112:4-112:4 -struct- definition:
struct Res {
val: uint,
references:-168: Res {
118: fn vuint_at_slow(data: &[u8], start: uint) -> Res {
163: Res {
121: return Res {val: (a & 0x7fu8) as uint, next: start + 1u};
129: return Res {val: ((a & 0x1fu8) as uint) << 16u |
173: Res {
135: return Res {val: ((a & 0x0fu8) as uint) << 24u |
124: return Res {val: ((a & 0x3fu8) as uint) << 8u |
146: pub fn vuint_at(data: &[u8], start: uint) -> Res {
158: Res {
libextra/ebml.rs:286:4-286:4 -struct- definition:
pub struct Decoder {
priv parent: Doc,
references:-508: f: &fn(&mut Decoder) -> T)
607: f: &fn(&mut Decoder) -> T)
486: f: &fn(&mut Decoder, uint) -> T)
458: f: &fn(&mut Decoder, uint) -> T)
517: f: &fn(&mut Decoder) -> T)
599: f: &fn(&mut Decoder) -> T)
298: impl Decoder {
359: impl Decoder {
538: fn read_tuple_arg<T>(&mut self, idx: uint, f: &fn(&mut Decoder) -> T)
588: fn read_map<T>(&mut self, f: &fn(&mut Decoder, uint) -> T) -> T {
573: fn read_seq<T>(&mut self, f: &fn(&mut Decoder, uint) -> T) -> T {
291: pub fn Decoder(d: Doc) -> Decoder {
560: fn read_option<T>(&mut self, f: &fn(&mut Decoder, bool) -> T) -> T {
292: Decoder {
438: f: &fn(&mut Decoder) -> T)
582: fn read_seq_elt<T>(&mut self, idx: uint, f: &fn(&mut Decoder) -> T)
376: impl serialize::Decoder for Decoder {
546: f: &fn(&mut Decoder, uint) -> T)
479: f: &fn(&mut Decoder) -> T) -> T {
360: pub fn read_opaque<R>(&mut self, op: &fn(&mut Decoder, Doc) -> R)
554: f: &fn(&mut Decoder) -> T)
526: f: &fn(&mut Decoder) -> T)
533: fn read_tuple<T>(&mut self, f: &fn(&mut Decoder, uint) -> T) -> T {
340: f: &fn(&mut Decoder) -> T) -> T {
libextra/flatpipes.rs:
106: T, DeserializingUnflattener<DefaultDecoder, T>, PipeBytePort>;
491: impl FromReader for ebml::reader::Decoder {
136: deserialize_buffer::<DefaultDecoder, T>);
101: T, DeserializingUnflattener<DefaultDecoder, T>,
131: pub fn pipe_port<T:Decodable<DefaultDecoder>>(
111: pub fn reader_port<T: Decodable<DefaultDecoder>,
(154)(115)(134)(113)(492)libextra/ebml.rs:623:4-623:4 -struct- definition:
pub struct Encoder {
writer: @io::Writer,
references:-920: fn emit_option(&mut self, f: &fn(&mut Encoder)) {
880: f: &fn(&mut Encoder)) {
887: f: &fn(&mut Encoder)) {
787: pub fn emit_opaque(&mut self, f: &fn(&mut Encoder)) {
794: impl ::serialize::Encoder for Encoder {
950: fn emit_map_elt_key(&mut self, _idx: uint, f: &fn(&mut Encoder)) {
786: impl Encoder {
913: f: &fn(&mut Encoder)) {
659: Encoder {
630: Encoder {
865: f: &fn(&mut Encoder)) {
854: fn emit_enum(&mut self, name: &str, f: &fn(&mut Encoder)) {
898: f: &fn(&mut Encoder)) {
916: fn emit_tuple_struct_arg(&mut self, idx: uint, f: &fn(&mut Encoder)) {
926: fn emit_option_some(&mut self, f: &fn(&mut Encoder)) {
937: fn emit_seq_elt(&mut self, _idx: uint, f: &fn(&mut Encoder)) {
956: fn emit_map_elt_val(&mut self, _idx: uint, f: &fn(&mut Encoder)) {
906: fn emit_tuple_arg(&mut self, idx: uint, f: &fn(&mut Encoder)) {
930: fn emit_seq(&mut self, len: uint, f: &fn(&mut Encoder)) {
891: fn emit_struct(&mut self, _: &str, _len: uint, f: &fn(&mut Encoder)) {
872: fn emit_enum_variant_arg(&mut self, _: uint, f: &fn(&mut Encoder)) {
629: fn clone(&self) -> Encoder {
943: fn emit_map(&mut self, len: uint, f: &fn(&mut Encoder)) {
657: pub fn Encoder(w: @io::Writer) -> Encoder {
903: fn emit_tuple(&mut self, len: uint, f: &fn(&mut Encoder)) {
768: impl Encoder {
628: impl Clone for Encoder {
666: impl Encoder {
libextra/flatpipes.rs:
121: pub fn writer_chan<T: Encodable<DefaultEncoder>,
125: serialize_value::<DefaultEncoder, T>);
(123)(153)(499)(147)(500)(108)(104)(145)(142)libextra/ebml.rs:637:4-637:4 -fn- definition:
fn write_sized_vuint(w: @io::Writer, n: uint, size: uint) {
match size {
references:-650: if n < 0x7f_u { write_sized_vuint(w, n, 1u); return; }
684: write_sized_vuint(self.writer, size, 4u);
653: if n < 0x10000000_u { write_sized_vuint(w, n, 4u); return; }
652: if n < 0x200000_u { write_sized_vuint(w, n, 3u); return; }
651: if n < 0x4000_u { write_sized_vuint(w, n, 2u); return; }
libextra/ebml.rs:657:4-657:4 -fn- definition:
pub fn Encoder(w: @io::Writer) -> Encoder {
let size_positions: ~[uint] = ~[];
references:-libextra/flatpipes.rs:
501: ebml::writer::Encoder(w)
libextra/ebml.rs:56:1-56:1 -enum- definition:
pub enum EbmlEncoderTag {
references:-352: fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> uint {
314: fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> Doc {
770: fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) {
339: fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag,
libextra/ebml.rs:266:4-266:4 -fn- definition:
pub fn doc_as_u16(d: Doc) -> u16 {
assert_eq!(d.end, d.start + 2u);
references:-398: doc_as_u16(self.next_doc(EsI16)) as i16
381: fn read_u16(&mut self) -> u16 { doc_as_u16(self.next_doc(EsU16)) }
282: pub fn doc_as_i16(d: Doc) -> i16 { doc_as_u16(d) as i16 }
libextra/ebml.rs:291:4-291:4 -fn- definition:
pub fn Decoder(d: Doc) -> Decoder {
Decoder {
references:-libextra/flatpipes.rs:
495: ebml::reader::Decoder(doc)
libextra/ebml.rs:118:4-118:4 -fn- definition:
fn vuint_at_slow(data: &[u8], start: uint) -> Res {
let a = data[start];
references:-148: return vuint_at_slow(data, start);
libextra/ebml.rs:201:4-201:4 -fn- definition:
pub fn maybe_get_doc(d: Doc, tg: uint) -> Option<Doc> {
let mut pos = d.start;
references:-216: match maybe_get_doc(d, tg) {
libextra/ebml.rs:215:4-215:4 -fn- definition:
pub fn get_doc(d: Doc, tg: uint) -> Doc {
match maybe_get_doc(d, tg) {
references:-40: reader::get_doc(*self, tag)
libextra/ebml.rs:51:1-51:1 -struct- definition:
pub struct TaggedDoc {
references:-319: let TaggedDoc { tag: r_tag, doc: r_doc } =
195: TaggedDoc {
301: let TaggedDoc { tag: r_tag, doc: r_doc } =
191: pub fn doc_at(data: @~[u8], start: uint) -> TaggedDoc {