Skip to content

Commit 1a9a431

Browse files
committed
---
yaml --- r: 1807 b: refs/heads/master c: d56971d h: refs/heads/master i: 1805: c38c572 1803: 455ec2d 1799: 75167af 1791: 85b2f30 v: v3
1 parent 3d5a43e commit 1a9a431

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
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: e890383db1930d0628f487f0008f1a9c2837c7fa
2+
refs/heads/master: d56971d5b466dd2bcd2ed147fd1668f06c7dbca0

trunk/src/lib/ebml.rs

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,72 @@ impure fn peek(&reader r) -> ebml_tag {
103103

104104
// EBML writing
105105

106-
type writer = rec(io.writer writer, mutable vec[ebml_state] states);
106+
type writer = rec(io.buf_writer writer, mutable vec[uint] size_positions);
107+
108+
fn write_sized_vint(&io.buf_writer w, uint n, uint size) {
109+
let vec[u8] buf;
110+
alt (size) {
111+
case (1u) {
112+
buf = vec(0x80u8 | (n as u8));
113+
}
114+
case (2u) {
115+
buf = vec(0x40u8 | ((n >> 8u) as u8),
116+
(n & 0xffu) as u8);
117+
}
118+
case (3u) {
119+
buf = vec(0x20u8 | ((n >> 16u) as u8),
120+
((n >> 8u) & 0xffu) as u8,
121+
(n & 0xffu) as u8);
122+
}
123+
case (4u) {
124+
buf = vec(0x10u8 | ((n >> 24u) as u8),
125+
((n >> 16u) & 0xffu) as u8,
126+
((n >> 8u) & 0xffu) as u8,
127+
(n & 0xffu) as u8);
128+
}
129+
case (_) {
130+
log "vint to write too big";
131+
fail;
132+
}
133+
}
134+
135+
w.write(buf);
136+
}
137+
138+
fn write_vint(&io.buf_writer w, uint n) {
139+
if (n < 0x7fu) { write_sized_vint(w, n, 1u); ret; }
140+
if (n < 0x4000u) { write_sized_vint(w, n, 2u); ret; }
141+
if (n < 0x200000u) { write_sized_vint(w, n, 3u); ret; }
142+
if (n < 0x10000000u) { write_sized_vint(w, n, 4u); ret; }
143+
log "vint to write too big";
144+
fail;
145+
}
146+
147+
fn create_writer(&io.buf_writer w) -> writer {
148+
let vec[uint] size_positions = vec();
149+
ret rec(writer=w, mutable size_positions=size_positions);
150+
}
151+
152+
// TODO: Provide a function to write the standard EBML header.
153+
154+
fn start_tag(&writer w, uint tag_id) {
155+
// Write the tag ID.
156+
write_vint(w.writer, tag_id);
157+
158+
// Write a placeholder four-byte size.
159+
w.size_positions += vec(w.writer.tell());
160+
let vec[u8] zeroes = vec(0u8, 0u8, 0u8, 0u8);
161+
w.writer.write(zeroes);
162+
}
163+
164+
fn end_tag(&writer w) {
165+
auto last_size_pos = _vec.pop[uint](w.size_positions);
166+
auto cur_pos = w.writer.tell();
167+
w.writer.seek(last_size_pos as int, io.seek_set);
168+
write_sized_vint(w.writer, cur_pos - last_size_pos - 4u, 4u);
169+
w.writer.seek(cur_pos as int, io.seek_set);
170+
}
107171

108-
// TODO
172+
// TODO: optionally perform "relaxations" on end_tag to more efficiently
173+
// encode sizes; this is a fixed point iteration
109174

0 commit comments

Comments
 (0)