Skip to content

Commit 3a2f1e1

Browse files
committed
add serialization library; convert ebml lib to use u64 internally
1 parent 4eb52f6 commit 3a2f1e1

File tree

6 files changed

+188
-138
lines changed

6 files changed

+188
-138
lines changed

src/comp/metadata/decoder.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ fn lookup_hash(d: ebml::doc, eq_fn: fn@([u8]) -> bool, hash: uint) ->
4242
let index = ebml::get_doc(d, tag_index);
4343
let table = ebml::get_doc(index, tag_index_table);
4444
let hash_pos = table.start + hash % 256u * 4u;
45-
let pos = ebml::be_uint_from_bytes(d.data, hash_pos, 4u);
45+
let pos = ebml::be_u64_from_bytes(d.data, hash_pos, 4u) as uint;
4646
let {tag:_, doc:bucket} = ebml::doc_at(d.data, pos);
4747
// Awkward logic because we can't ret from foreach yet
4848

4949
let result: [ebml::doc] = [];
5050
let belt = tag_index_buckets_bucket_elt;
5151
ebml::tagged_docs(bucket, belt) {|elt|
52-
let pos = ebml::be_uint_from_bytes(elt.data, elt.start, 4u);
52+
let pos = ebml::be_u64_from_bytes(elt.data, elt.start, 4u) as uint;
5353
if eq_fn(vec::slice::<u8>(*elt.data, elt.start + 4u, elt.end)) {
5454
result += [ebml::doc_at(d.data, pos).doc];
5555
}
@@ -59,7 +59,7 @@ fn lookup_hash(d: ebml::doc, eq_fn: fn@([u8]) -> bool, hash: uint) ->
5959

6060
fn maybe_find_item(item_id: int, items: ebml::doc) -> option<ebml::doc> {
6161
fn eq_item(bytes: [u8], item_id: int) -> bool {
62-
ret ebml::be_uint_from_bytes(@bytes, 0u, 4u) as int == item_id;
62+
ret ebml::be_u64_from_bytes(@bytes, 0u, 4u) as int == item_id;
6363
}
6464
let eqer = bind eq_item(_, item_id);
6565
let found = lookup_hash(items, eqer, hash_node_id(item_id));
@@ -81,7 +81,7 @@ fn lookup_item(item_id: int, data: @[u8]) -> ebml::doc {
8181

8282
fn item_family(item: ebml::doc) -> u8 {
8383
let fam = ebml::get_doc(item, tag_items_data_item_family);
84-
ret ebml::doc_as_uint(fam) as u8;
84+
ret ebml::doc_as_u8(fam);
8585
}
8686

8787
fn item_symbol(item: ebml::doc) -> str {
@@ -183,7 +183,7 @@ fn item_path(item_doc: ebml::doc) -> ast_map::path {
183183
let path_doc = ebml::get_doc(item_doc, tag_path);
184184

185185
let len_doc = ebml::get_doc(path_doc, tag_path_len);
186-
let len = ebml::doc_as_uint(len_doc);
186+
let len = ebml::doc_as_vuint(len_doc);
187187

188188
let result = [];
189189
vec::reserve(result, len);
@@ -355,7 +355,7 @@ fn family_names_type(fam_ch: u8) -> bool {
355355

356356
fn read_path(d: ebml::doc) -> {path: str, pos: uint} {
357357
let desc = ebml::doc_data(d);
358-
let pos = ebml::be_uint_from_bytes(@desc, 0u, 4u);
358+
let pos = ebml::be_u64_from_bytes(@desc, 0u, 4u) as uint;
359359
let pathbytes = vec::slice::<u8>(desc, 4u, vec::len::<u8>(desc));
360360
let path = str::from_bytes(pathbytes);
361361
ret {path: path, pos: pos};

src/comp/metadata/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ fn encode_path(ebml_w: ebml::writer,
281281

282282
ebml_w.wr_tag(tag_path) {||
283283
ebml_w.wr_tag(tag_path_len) {||
284-
ebml_w.wr_uint(vec::len(path) + 1u);
284+
ebml_w.wr_vuint(vec::len(path) + 1u);
285285
}
286286
vec::iter(path) {|pe| encode_path_elt(ebml_w, pe); }
287287
encode_path_elt(ebml_w, name);

src/libstd/ebml.rs

Lines changed: 62 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,35 +19,42 @@ type doc = {data: @[u8], start: uint, end: uint};
1919

2020
type tagged_doc = {tag: uint, doc: doc};
2121

22-
fn vint_at(data: [u8], start: uint) -> {val: uint, next: uint} {
22+
fn vu64_at(data: [u8], start: uint) -> {val: u64, next: uint} {
2323
let a = data[start];
2424
if a & 0x80u8 != 0u8 {
25-
ret {val: (a & 0x7fu8) as uint, next: start + 1u};
25+
ret {val: (a & 0x7fu8) as u64, next: start + 1u};
2626
}
2727
if a & 0x40u8 != 0u8 {
28-
ret {val: ((a & 0x3fu8) as uint) << 8u | (data[start + 1u] as uint),
28+
ret {val: ((a & 0x3fu8) as u64) << 8u64 |
29+
(data[start + 1u] as u64),
2930
next: start + 2u};
3031
} else if a & 0x20u8 != 0u8 {
31-
ret {val: ((a & 0x1fu8) as uint) << 16u |
32-
(data[start + 1u] as uint) << 8u |
33-
(data[start + 2u] as uint),
32+
ret {val: ((a & 0x1fu8) as u64) << 16u64 |
33+
(data[start + 1u] as u64) << 8u64 |
34+
(data[start + 2u] as u64),
3435
next: start + 3u};
3536
} else if a & 0x10u8 != 0u8 {
36-
ret {val: ((a & 0x0fu8) as uint) << 24u |
37-
(data[start + 1u] as uint) << 16u |
38-
(data[start + 2u] as uint) << 8u |
39-
(data[start + 3u] as uint),
37+
ret {val: ((a & 0x0fu8) as u64) << 24u64 |
38+
(data[start + 1u] as u64) << 16u64 |
39+
(data[start + 2u] as u64) << 8u64 |
40+
(data[start + 3u] as u64),
4041
next: start + 4u};
4142
} else { #error("vint too big"); fail; }
4243
}
4344

45+
fn vuint_at(data: [u8], start: uint) -> {val: uint, next: uint} {
46+
let {val, next} = vu64_at(data, start);
47+
ret {val: val as uint, next: next};
48+
}
49+
50+
4451
fn new_doc(data: @[u8]) -> doc {
4552
ret {data: data, start: 0u, end: vec::len::<u8>(*data)};
4653
}
4754

4855
fn doc_at(data: @[u8], start: uint) -> tagged_doc {
49-
let elt_tag = vint_at(*data, start);
50-
let elt_size = vint_at(*data, elt_tag.next);
56+
let elt_tag = vuint_at(*data, start);
57+
let elt_size = vuint_at(*data, elt_tag.next);
5158
let end = elt_size.next + elt_size.val;
5259
ret {tag: elt_tag.val,
5360
doc: {data: data, start: elt_size.next, end: end}};
@@ -56,8 +63,8 @@ fn doc_at(data: @[u8], start: uint) -> tagged_doc {
5663
fn maybe_get_doc(d: doc, tg: uint) -> option<doc> {
5764
let pos = d.start;
5865
while pos < d.end {
59-
let elt_tag = vint_at(*d.data, pos);
60-
let elt_size = vint_at(*d.data, elt_tag.next);
66+
let elt_tag = vuint_at(*d.data, pos);
67+
let elt_size = vuint_at(*d.data, elt_tag.next);
6168
pos = elt_size.next + elt_size.val;
6269
if elt_tag.val == tg {
6370
ret some::<doc>({data: d.data, start: elt_size.next, end: pos});
@@ -79,8 +86,8 @@ fn get_doc(d: doc, tg: uint) -> doc {
7986
fn docs(d: doc, it: fn(uint, doc)) {
8087
let pos = d.start;
8188
while pos < d.end {
82-
let elt_tag = vint_at(*d.data, pos);
83-
let elt_size = vint_at(*d.data, elt_tag.next);
89+
let elt_tag = vuint_at(*d.data, pos);
90+
let elt_size = vuint_at(*d.data, elt_tag.next);
8491
pos = elt_size.next + elt_size.val;
8592
it(elt_tag.val, {data: d.data, start: elt_size.next, end: pos});
8693
}
@@ -89,8 +96,8 @@ fn docs(d: doc, it: fn(uint, doc)) {
8996
fn tagged_docs(d: doc, tg: uint, it: fn(doc)) {
9097
let pos = d.start;
9198
while pos < d.end {
92-
let elt_tag = vint_at(*d.data, pos);
93-
let elt_size = vint_at(*d.data, elt_tag.next);
99+
let elt_tag = vuint_at(*d.data, pos);
100+
let elt_size = vuint_at(*d.data, elt_tag.next);
94101
pos = elt_size.next + elt_size.val;
95102
if elt_tag.val == tg {
96103
it({data: d.data, start: elt_size.next, end: pos});
@@ -102,28 +109,36 @@ fn doc_data(d: doc) -> [u8] { ret vec::slice::<u8>(*d.data, d.start, d.end); }
102109

103110
fn doc_str(d: doc) -> str { ret str::from_bytes(doc_data(d)); }
104111

105-
fn be_uint_from_bytes(data: @[u8], start: uint, size: uint) -> uint {
112+
fn be_u64_from_bytes(data: @[u8], start: uint, size: uint) -> u64 {
106113
let sz = size;
107114
assert (sz <= 4u);
108-
let val = 0u;
115+
let val = 0_u64;
109116
let pos = start;
110117
while sz > 0u {
111118
sz -= 1u;
112-
val += (data[pos] as uint) << sz * 8u;
119+
val += (data[pos] as u64) << ((sz * 8u) as u64);
113120
pos += 1u;
114121
}
115122
ret val;
116123
}
117124

118-
fn doc_as_uint(d: doc) -> uint {
119-
ret be_uint_from_bytes(d.data, d.start, d.end - d.start);
125+
fn doc_as_u8(d: doc) -> u8 {
126+
assert d.end == d.start + 1u;
127+
ret (*d.data)[d.start];
128+
}
129+
130+
fn doc_as_vu64(d: doc) -> u64 {
131+
ret vu64_at(*d.data, d.start).val;
120132
}
121133

134+
fn doc_as_vuint(d: doc) -> uint {
135+
ret vuint_at(*d.data, d.start).val;
136+
}
122137

123138
// ebml writing
124139
type writer = {writer: io::writer, mutable size_positions: [uint]};
125140

126-
fn write_sized_vint(w: io::writer, n: u64, size: uint) {
141+
fn write_sized_vu64(w: io::writer, n: u64, size: uint) {
127142
let buf: [u8];
128143
alt size {
129144
1u { buf = [0x80u8 | (n as u8)]; }
@@ -141,11 +156,11 @@ fn write_sized_vint(w: io::writer, n: u64, size: uint) {
141156
w.write(buf);
142157
}
143158

144-
fn write_vint(w: io::writer, n: u64) {
145-
if n < 0x7f_u64 { write_sized_vint(w, n, 1u); ret; }
146-
if n < 0x4000_u64 { write_sized_vint(w, n, 2u); ret; }
147-
if n < 0x200000_u64 { write_sized_vint(w, n, 3u); ret; }
148-
if n < 0x10000000_u64 { write_sized_vint(w, n, 4u); ret; }
159+
fn write_vu64(w: io::writer, n: u64) {
160+
if n < 0x7f_u64 { write_sized_vu64(w, n, 1u); ret; }
161+
if n < 0x4000_u64 { write_sized_vu64(w, n, 2u); ret; }
162+
if n < 0x200000_u64 { write_sized_vu64(w, n, 3u); ret; }
163+
if n < 0x10000000_u64 { write_sized_vu64(w, n, 4u); ret; }
149164
#error("vint to write too big");
150165
fail;
151166
}
@@ -158,8 +173,10 @@ fn create_writer(w: io::writer) -> writer {
158173

159174
// TODO: Provide a function to write the standard ebml header.
160175
fn start_tag(w: writer, tag_id: uint) {
176+
#debug["Start tag %u", tag_id];
177+
161178
// Write the enum ID:
162-
write_vint(w.writer, tag_id as u64);
179+
write_vu64(w.writer, tag_id as u64);
163180

164181
// Write a placeholder four-byte size.
165182
w.size_positions += [w.writer.tell()];
@@ -171,8 +188,11 @@ fn end_tag(w: writer) {
171188
let last_size_pos = vec::pop::<uint>(w.size_positions);
172189
let cur_pos = w.writer.tell();
173190
w.writer.seek(last_size_pos as int, io::seek_set);
174-
write_sized_vint(w.writer, (cur_pos - last_size_pos - 4u) as u64, 4u);
191+
let size = (cur_pos - last_size_pos - 4u);
192+
write_sized_vu64(w.writer, size as u64, 4u);
175193
w.writer.seek(cur_pos as int, io::seek_set);
194+
195+
#debug["End tag (size = %u)", size];
176196
}
177197

178198
impl writer_util for writer {
@@ -182,20 +202,26 @@ impl writer_util for writer {
182202
end_tag(self);
183203
}
184204

185-
fn wr_u64(id: u64) {
186-
write_vint(self.writer, id);
205+
fn wr_vu64(id: u64) {
206+
#debug["Write u64 0x%02x%02x",
207+
(id >> 32u64) as uint,
208+
(id & 0xFFFFFFFFu64) as uint];
209+
write_vu64(self.writer, id);
187210
}
188211

189-
fn wr_uint(id: uint) {
190-
self.wr_u64(id as u64);
212+
fn wr_vuint(id: uint) {
213+
#debug["Write uint: %u", id];
214+
write_vu64(self.writer, id as u64);
191215
}
192216

193217
fn wr_bytes(b: [u8]) {
218+
#debug["Write %u bytes", vec::len(b)];
194219
self.writer.write(b);
195220
}
196221

197222
fn wr_str(s: str) {
198-
self.wr_bytes(str::bytes(s));
223+
#debug["Write str: %?", s];
224+
self.writer.write(str::bytes(s));
199225
}
200226
}
201227

0 commit comments

Comments
 (0)