@@ -103,7 +103,72 @@ impure fn peek(&reader r) -> ebml_tag {
103
103
104
104
// EBML writing
105
105
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 ( 1 u) {
112
+ buf = vec ( 0x80u8 | ( n as u8 ) ) ;
113
+ }
114
+ case ( 2 u) {
115
+ buf = vec ( 0x40u8 | ( ( n >> 8 u) as u8 ) ,
116
+ ( n & 0xff u) as u8 ) ;
117
+ }
118
+ case ( 3 u) {
119
+ buf = vec ( 0x20u8 | ( ( n >> 16 u) as u8 ) ,
120
+ ( ( n >> 8 u) & 0xff u) as u8 ,
121
+ ( n & 0xff u) as u8 ) ;
122
+ }
123
+ case ( 4 u) {
124
+ buf = vec ( 0x10u8 | ( ( n >> 24 u) as u8 ) ,
125
+ ( ( n >> 16 u) & 0xff u) as u8 ,
126
+ ( ( n >> 8 u) & 0xff u) as u8 ,
127
+ ( n & 0xff u) 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 < 0x7f u) { write_sized_vint ( w, n, 1 u) ; ret; }
140
+ if ( n < 0x4000 u) { write_sized_vint ( w, n, 2 u) ; ret; }
141
+ if ( n < 0x200000 u) { write_sized_vint ( w, n, 3 u) ; ret; }
142
+ if ( n < 0x10000000 u) { write_sized_vint ( w, n, 4 u) ; 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 - 4 u, 4 u) ;
169
+ w. writer . seek ( cur_pos as int , io. seek_set ) ;
170
+ }
107
171
108
- // TODO
172
+ // TODO: optionally perform "relaxations" on end_tag to more efficiently
173
+ // encode sizes; this is a fixed point iteration
109
174
0 commit comments