Skip to content

Commit 6d6ab1d

Browse files
committed
---
yaml --- r: 1795 b: refs/heads/master c: 6623597 h: refs/heads/master i: 1793: c11a1ca 1791: 85b2f30 v: v3
1 parent d0d7266 commit 6d6ab1d

File tree

3 files changed

+111
-1
lines changed

3 files changed

+111
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: bb75a53cbd0e326fd4f16ca284ba7080698d0d81
2+
refs/heads/master: 6623597c187c025095842598f7d9db816cb1858b

trunk/src/lib/ebml.rs

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Simple Extensible Binary Markup Language (EBML) reader and writer on a
2+
// cursor model. See the specification here:
3+
// http://www.matroska.org/technical/specs/rfc/index.html
4+
5+
import option.none;
6+
import option.some;
7+
8+
type ebml_tag = rec(uint id, uint size);
9+
type ebml_state = rec(ebml_tag ebml_tag, uint pos);
10+
11+
// TODO: When we have module renaming, make "reader" and "writer" separate
12+
// modules within this file.
13+
14+
// EBML reading
15+
16+
type reader = rec(
17+
io.reader reader,
18+
mutable vec[ebml_state] states,
19+
uint size
20+
);
21+
22+
// TODO: eventually use u64 or big here
23+
impure fn read_vint(&io.reader reader) -> uint {
24+
auto a = reader.read_byte();
25+
if (a & 0x80u8 != 0u8) { ret (a & 0x7fu8) as uint; }
26+
auto b = reader.read_byte();
27+
if (a & 0x40u8 != 0u8) {
28+
ret (((a & 0x3fu8) as uint) << 8u) | (b as uint);
29+
}
30+
auto c = reader.read_byte();
31+
if (a & 0x20u8 != 0u8) {
32+
ret (((a & 0x1fu8) as uint) << 16u) | ((b as uint) << 8u) |
33+
(c as uint);
34+
}
35+
auto d = reader.read_byte();
36+
if (a & 0x10u8 != 0u8) {
37+
ret (((a & 0x0fu8) as uint) << 24u) | ((b as uint) << 16u) |
38+
((c as uint) << 8u) | (d as uint);
39+
}
40+
41+
log "vint too big"; fail;
42+
}
43+
44+
impure fn create_reader(&io.reader r) -> reader {
45+
let vec[ebml_state] states = vec();
46+
47+
// Calculate the size of the stream.
48+
auto pos = r.tell();
49+
r.seek(0, io.seek_end);
50+
auto size = r.tell() - pos;
51+
r.seek(pos as int, io.seek_set);
52+
53+
ret rec(reader=r, mutable states=states, size=size);
54+
}
55+
56+
impure fn bytes_left(&reader r) -> uint {
57+
auto pos = r.reader.tell();
58+
alt (_vec.last[ebml_state](r.states)) {
59+
case (none[ebml_state]) { ret r.size - pos; }
60+
case (some[ebml_state](?st)) { ret st.pos + st.ebml_tag.size - pos; }
61+
}
62+
}
63+
64+
impure fn read_tag(&reader r) -> ebml_tag {
65+
auto id = read_vint(r.reader);
66+
auto size = read_vint(r.reader);
67+
ret rec(id=id, size=size);
68+
}
69+
70+
// Reads a tag and moves the cursor to its first child or data segment.
71+
impure fn move_to_first_child(&reader r) {
72+
auto pos = r.reader.tell();
73+
auto t = read_tag(r);
74+
r.states += vec(rec(ebml_tag=t, pos=pos));
75+
}
76+
77+
// Reads a tag and skips over its contents, moving to its next sibling.
78+
impure fn move_to_next_sibling(&reader r) {
79+
auto t = read_tag(r);
80+
r.reader.seek(t.size as int, io.seek_cur);
81+
}
82+
83+
// Moves to the parent of this tag.
84+
impure fn move_to_parent(&reader r) {
85+
check (_vec.len[ebml_state](r.states) > 0u);
86+
auto st = _vec.pop[ebml_state](r.states);
87+
r.reader.seek(st.pos as int, io.seek_set);
88+
}
89+
90+
// Reads the data segment of a tag.
91+
impure fn read_data(&reader r) -> vec[u8] {
92+
ret r.reader.read_bytes(bytes_left(r));
93+
}
94+
95+
impure fn peek(&reader r) -> ebml_tag {
96+
check (bytes_left(r) > 0u);
97+
auto pos = r.reader.tell();
98+
auto t = read_tag(r);
99+
r.reader.seek(pos as int, io.seek_set);
100+
ret t;
101+
}
102+
103+
104+
// EBML writing
105+
106+
type writer = rec(io.writer writer, mutable vec[ebml_state] states);
107+
108+
// TODO
109+

trunk/src/lib/std.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ mod dbg;
7777
mod bitv;
7878
mod sort;
7979
mod sha1;
80+
mod ebml;
8081

8182
// Local Variables:
8283
// mode: rust;

0 commit comments

Comments
 (0)