Skip to content

Commit e86ac24

Browse files
committed
Implement unimplemented methods in ebml
1 parent f8cef24 commit e86ac24

File tree

3 files changed

+108
-73
lines changed

3 files changed

+108
-73
lines changed

src/libextra/ebml.rs

+79-71
Original file line numberDiff line numberDiff line change
@@ -51,32 +51,34 @@ pub enum EbmlEncoderTag {
5151
EsI16, // 8
5252
EsI8, // 9
5353
EsBool, // 10
54-
EsStr, // 11
55-
EsF64, // 12
56-
EsF32, // 13
57-
EsFloat, // 14
58-
EsEnum, // 15
59-
EsEnumVid, // 16
60-
EsEnumBody, // 17
61-
EsVec, // 18
62-
EsVecLen, // 19
63-
EsVecElt, // 20
54+
EsChar, // 11
55+
EsStr, // 12
56+
EsF64, // 13
57+
EsF32, // 14
58+
EsFloat, // 15
59+
EsEnum, // 16
60+
EsEnumVid, // 17
61+
EsEnumBody, // 18
62+
EsVec, // 19
63+
EsVecLen, // 20
64+
EsVecElt, // 21
65+
EsMap, // 22
66+
EsMapLen, // 23
67+
EsMapKey, // 24
68+
EsMapVal, // 25
6469

6570
EsOpaque,
6671

67-
EsLabel // Used only when debugging
72+
EsLabel, // Used only when debugging
6873
}
6974
// --------------------------------------
7075

7176
pub mod reader {
72-
use core::prelude::*;
77+
use super::*;
7378

74-
use ebml::{Doc, EbmlEncoderTag, EsBool, EsEnum, EsEnumBody, EsEnumVid};
75-
use ebml::{EsI16, EsI32, EsI64, EsI8, EsInt};
76-
use ebml::{EsLabel, EsOpaque, EsStr, EsU16, EsU32, EsU64, EsU8, EsUint};
77-
use ebml::{EsVec, EsVecElt, EsVecLen, TaggedDoc};
7879
use serialize;
7980

81+
use core::prelude::*;
8082
use core::cast::transmute;
8183
use core::int;
8284
use core::io;
@@ -321,12 +323,14 @@ pub mod reader {
321323
r_doc
322324
}
323325

324-
fn push_doc<T>(&mut self, d: Doc, f: &fn() -> T) -> T {
326+
fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag,
327+
f: &fn(&mut Decoder) -> T) -> T {
328+
let d = self.next_doc(exp_tag);
325329
let old_parent = self.parent;
326330
let old_pos = self.pos;
327331
self.parent = d;
328332
self.pos = d.start;
329-
let r = f();
333+
let r = f(self);
330334
self.parent = old_parent;
331335
self.pos = old_pos;
332336
r
@@ -395,10 +399,21 @@ pub mod reader {
395399
doc_as_u8(self.next_doc(EsBool)) as bool
396400
}
397401

398-
fn read_f64(&mut self) -> f64 { fail!("read_f64()"); }
399-
fn read_f32(&mut self) -> f32 { fail!("read_f32()"); }
400-
fn read_float(&mut self) -> float { fail!("read_float()"); }
401-
fn read_char(&mut self) -> char { fail!("read_char()"); }
402+
fn read_f64(&mut self) -> f64 {
403+
let bits = doc_as_u64(self.next_doc(EsF64));
404+
unsafe { transmute(bits) }
405+
}
406+
fn read_f32(&mut self) -> f32 {
407+
let bits = doc_as_u32(self.next_doc(EsF32));
408+
unsafe { transmute(bits) }
409+
}
410+
fn read_float(&mut self) -> float {
411+
let bits = doc_as_u64(self.next_doc(EsFloat));
412+
(unsafe { transmute::<u64, f64>(bits) }) as float
413+
}
414+
fn read_char(&mut self) -> char {
415+
doc_as_u32(self.next_doc(EsChar)) as char
416+
}
402417
fn read_str(&mut self) -> ~str { doc_as_str(self.next_doc(EsStr)) }
403418

404419
// Compound types:
@@ -541,66 +556,50 @@ pub mod reader {
541556

542557
fn read_seq<T>(&mut self, f: &fn(&mut Decoder, uint) -> T) -> T {
543558
debug!("read_seq()");
544-
let doc = self.next_doc(EsVec);
545-
546-
let (old_parent, old_pos) = (self.parent, self.pos);
547-
self.parent = doc;
548-
self.pos = self.parent.start;
549-
550-
let len = self._next_uint(EsVecLen);
551-
debug!(" len=%u", len);
552-
let result = f(self, len);
553-
554-
self.parent = old_parent;
555-
self.pos = old_pos;
556-
result
559+
do self.push_doc(EsVec) |d| {
560+
let len = d._next_uint(EsVecLen);
561+
debug!(" len=%u", len);
562+
f(d, len)
563+
}
557564
}
558565

559566
fn read_seq_elt<T>(&mut self, idx: uint, f: &fn(&mut Decoder) -> T)
560567
-> T {
561568
debug!("read_seq_elt(idx=%u)", idx);
562-
let doc = self.next_doc(EsVecElt);
563-
564-
let (old_parent, old_pos) = (self.parent, self.pos);
565-
self.parent = doc;
566-
self.pos = self.parent.start;
567-
568-
let result = f(self);
569-
570-
self.parent = old_parent;
571-
self.pos = old_pos;
572-
result
569+
self.push_doc(EsVecElt, f)
573570
}
574571

575-
fn read_map<T>(&mut self, _: &fn(&mut Decoder, uint) -> T) -> T {
572+
fn read_map<T>(&mut self, f: &fn(&mut Decoder, uint) -> T) -> T {
576573
debug!("read_map()");
577-
fail!("read_map is unimplemented");
574+
do self.push_doc(EsMap) |d| {
575+
let len = d._next_uint(EsMapLen);
576+
debug!(" len=%u", len);
577+
f(d, len)
578+
}
578579
}
579580

580581
fn read_map_elt_key<T>(&mut self,
581582
idx: uint,
582-
_: &fn(&mut Decoder) -> T)
583+
f: &fn(&mut Decoder) -> T)
583584
-> T {
584585
debug!("read_map_elt_key(idx=%u)", idx);
585-
fail!("read_map_elt_val is unimplemented");
586+
self.push_doc(EsMapKey, f)
586587
}
587588

588589
fn read_map_elt_val<T>(&mut self,
589590
idx: uint,
590-
_: &fn(&mut Decoder) -> T)
591+
f: &fn(&mut Decoder) -> T)
591592
-> T {
592593
debug!("read_map_elt_val(idx=%u)", idx);
593-
fail!("read_map_elt_val is unimplemented");
594+
self.push_doc(EsMapVal, f)
594595
}
595596
}
596597
}
597598

598599
pub mod writer {
599-
use ebml::{EbmlEncoderTag, EsBool, EsEnum, EsEnumBody, EsEnumVid};
600-
use ebml::{EsI16, EsI32, EsI64, EsI8, EsInt};
601-
use ebml::{EsLabel, EsOpaque, EsStr, EsU16, EsU32, EsU64, EsU8, EsUint};
602-
use ebml::{EsVec, EsVecElt, EsVecLen};
600+
use super::*;
603601

602+
use core::cast;
604603
use core::io;
605604
use core::str;
606605

@@ -806,19 +805,21 @@ pub mod writer {
806805
self.wr_tagged_u8(EsBool as uint, v as u8)
807806
}
808807

809-
// FIXME (#2742): implement these
810-
fn emit_f64(&mut self, _v: f64) {
811-
fail!("Unimplemented: serializing an f64");
808+
fn emit_f64(&mut self, v: f64) {
809+
let bits = unsafe { cast::transmute(v) };
810+
self.wr_tagged_u64(EsF64 as uint, bits);
812811
}
813-
fn emit_f32(&mut self, _v: f32) {
814-
fail!("Unimplemented: serializing an f32");
812+
fn emit_f32(&mut self, v: f32) {
813+
let bits = unsafe { cast::transmute(v) };
814+
self.wr_tagged_u32(EsF32 as uint, bits);
815815
}
816-
fn emit_float(&mut self, _v: float) {
817-
fail!("Unimplemented: serializing a float");
816+
fn emit_float(&mut self, v: float) {
817+
let bits = unsafe { cast::transmute(v as f64) };
818+
self.wr_tagged_u64(EsFloat as uint, bits);
818819
}
819820

820-
fn emit_char(&mut self, _v: char) {
821-
fail!("Unimplemented: serializing a char");
821+
fn emit_char(&mut self, v: char) {
822+
self.wr_tagged_u32(EsChar as uint, v as u32);
822823
}
823824

824825
fn emit_str(&mut self, v: &str) {
@@ -914,16 +915,23 @@ pub mod writer {
914915
self.end_tag();
915916
}
916917

917-
fn emit_map(&mut self, _len: uint, _f: &fn(&mut Encoder)) {
918-
fail!("emit_map is unimplemented");
918+
fn emit_map(&mut self, len: uint, f: &fn(&mut Encoder)) {
919+
self.start_tag(EsMap as uint);
920+
self._emit_tagged_uint(EsMapLen, len);
921+
f(self);
922+
self.end_tag();
919923
}
920924

921-
fn emit_map_elt_key(&mut self, _idx: uint, _f: &fn(&mut Encoder)) {
922-
fail!("emit_map_elt_key is unimplemented");
925+
fn emit_map_elt_key(&mut self, _idx: uint, f: &fn(&mut Encoder)) {
926+
self.start_tag(EsMapKey as uint);
927+
f(self);
928+
self.end_tag();
923929
}
924930

925-
fn emit_map_elt_val(&mut self, _idx: uint, _f: &fn(&mut Encoder)) {
926-
fail!("emit_map_elt_val is unimplemented");
931+
fn emit_map_elt_val(&mut self, _idx: uint, f: &fn(&mut Encoder)) {
932+
self.start_tag(EsMapVal as uint);
933+
f(self);
934+
self.end_tag();
927935
}
928936
}
929937
}

src/libextra/serialize.rs

+12
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,18 @@ impl<D:Decoder> Decodable<D> for bool {
375375
}
376376
}
377377

378+
impl<S:Encoder> Encodable<S> for char {
379+
fn encode(&self, s: &mut S) {
380+
s.emit_char(*self)
381+
}
382+
}
383+
384+
impl<D:Decoder> Decodable<D> for char {
385+
fn decode(d: &mut D) -> char {
386+
d.read_char()
387+
}
388+
}
389+
378390
impl<S:Encoder> Encodable<S> for () {
379391
fn encode(&self, s: &mut S) {
380392
s.emit_nil()

src/test/run-pass/auto-encode.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ extern mod extra;
1717
// These tests used to be separate files, but I wanted to refactor all
1818
// the common code.
1919

20+
use std::hashmap::{HashMap, HashSet};
21+
2022
use EBReader = extra::ebml::reader;
2123
use EBWriter = extra::ebml::writer;
2224
use std::cmp::Eq;
2325
use std::cmp;
24-
use std::io::Writer;
2526
use std::io;
26-
use extra::ebml;
2727
use extra::serialize::{Decodable, Encodable};
2828
use extra::time;
2929

@@ -158,4 +158,19 @@ pub fn main() {
158158

159159
let a = &time::now();
160160
test_ebml(a);
161+
162+
test_ebml(&1.0f32);
163+
test_ebml(&1.0f64);
164+
test_ebml(&1.0f);
165+
test_ebml(&'a');
166+
167+
let mut a = HashMap::new();
168+
test_ebml(&a);
169+
a.insert(1, 2);
170+
test_ebml(&a);
171+
172+
let mut a = HashSet::new();
173+
test_ebml(&a);
174+
a.insert(1);
175+
test_ebml(&a);
161176
}

0 commit comments

Comments
 (0)