]> git.lizzy.rs Git - rust.git/commitdiff
Implement unimplemented methods in ebml
authorAlex Crichton <alex@alexcrichton.com>
Fri, 31 May 2013 04:42:00 +0000 (23:42 -0500)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 31 May 2013 05:28:17 +0000 (00:28 -0500)
src/libextra/ebml.rs
src/libextra/serialize.rs
src/test/run-pass/auto-encode.rs

index 70beaa58d07b72da055860357caefb410aab08bc..641f01dfb0b6ede1b9c1da7c368d204812972d6a 100644 (file)
@@ -51,32 +51,34 @@ pub enum EbmlEncoderTag {
     EsI16,      // 8
     EsI8,       // 9
     EsBool,     // 10
-    EsStr,      // 11
-    EsF64,      // 12
-    EsF32,      // 13
-    EsFloat,    // 14
-    EsEnum,     // 15
-    EsEnumVid,  // 16
-    EsEnumBody, // 17
-    EsVec,      // 18
-    EsVecLen,   // 19
-    EsVecElt,   // 20
+    EsChar,     // 11
+    EsStr,      // 12
+    EsF64,      // 13
+    EsF32,      // 14
+    EsFloat,    // 15
+    EsEnum,     // 16
+    EsEnumVid,  // 17
+    EsEnumBody, // 18
+    EsVec,      // 19
+    EsVecLen,   // 20
+    EsVecElt,   // 21
+    EsMap,      // 22
+    EsMapLen,   // 23
+    EsMapKey,   // 24
+    EsMapVal,   // 25
 
     EsOpaque,
 
-    EsLabel // Used only when debugging
+    EsLabel, // Used only when debugging
 }
 // --------------------------------------
 
 pub mod reader {
-    use core::prelude::*;
+    use super::*;
 
-    use ebml::{Doc, EbmlEncoderTag, EsBool, EsEnum, EsEnumBody, EsEnumVid};
-    use ebml::{EsI16, EsI32, EsI64, EsI8, EsInt};
-    use ebml::{EsLabel, EsOpaque, EsStr, EsU16, EsU32, EsU64, EsU8, EsUint};
-    use ebml::{EsVec, EsVecElt, EsVecLen, TaggedDoc};
     use serialize;
 
+    use core::prelude::*;
     use core::cast::transmute;
     use core::int;
     use core::io;
@@ -321,12 +323,14 @@ fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> Doc {
             r_doc
         }
 
-        fn push_doc<T>(&mut self, d: Doc, f: &fn() -> T) -> T {
+        fn push_doc<T>(&mut self, exp_tag: EbmlEncoderTag,
+                       f: &fn(&mut Decoder) -> T) -> T {
+            let d = self.next_doc(exp_tag);
             let old_parent = self.parent;
             let old_pos = self.pos;
             self.parent = d;
             self.pos = d.start;
-            let r = f();
+            let r = f(self);
             self.parent = old_parent;
             self.pos = old_pos;
             r
@@ -395,10 +399,21 @@ fn read_bool(&mut self) -> bool {
             doc_as_u8(self.next_doc(EsBool)) as bool
         }
 
-        fn read_f64(&mut self) -> f64 { fail!("read_f64()"); }
-        fn read_f32(&mut self) -> f32 { fail!("read_f32()"); }
-        fn read_float(&mut self) -> float { fail!("read_float()"); }
-        fn read_char(&mut self) -> char { fail!("read_char()"); }
+        fn read_f64(&mut self) -> f64 {
+            let bits = doc_as_u64(self.next_doc(EsF64));
+            unsafe { transmute(bits) }
+        }
+        fn read_f32(&mut self) -> f32 {
+            let bits = doc_as_u32(self.next_doc(EsF32));
+            unsafe { transmute(bits) }
+        }
+        fn read_float(&mut self) -> float {
+            let bits = doc_as_u64(self.next_doc(EsFloat));
+            (unsafe { transmute::<u64, f64>(bits) }) as float
+        }
+        fn read_char(&mut self) -> char {
+            doc_as_u32(self.next_doc(EsChar)) as char
+        }
         fn read_str(&mut self) -> ~str { doc_as_str(self.next_doc(EsStr)) }
 
         // Compound types:
@@ -541,66 +556,50 @@ fn read_option<T>(&mut self, f: &fn(&mut Decoder, bool) -> T) -> T {
 
         fn read_seq<T>(&mut self, f: &fn(&mut Decoder, uint) -> T) -> T {
             debug!("read_seq()");
-            let doc = self.next_doc(EsVec);
-
-            let (old_parent, old_pos) = (self.parent, self.pos);
-            self.parent = doc;
-            self.pos = self.parent.start;
-
-            let len = self._next_uint(EsVecLen);
-            debug!("  len=%u", len);
-            let result = f(self, len);
-
-            self.parent = old_parent;
-            self.pos = old_pos;
-            result
+            do self.push_doc(EsVec) |d| {
+                let len = d._next_uint(EsVecLen);
+                debug!("  len=%u", len);
+                f(d, len)
+            }
         }
 
         fn read_seq_elt<T>(&mut self, idx: uint, f: &fn(&mut Decoder) -> T)
                            -> T {
             debug!("read_seq_elt(idx=%u)", idx);
-            let doc = self.next_doc(EsVecElt);
-
-            let (old_parent, old_pos) = (self.parent, self.pos);
-            self.parent = doc;
-            self.pos = self.parent.start;
-
-            let result = f(self);
-
-            self.parent = old_parent;
-            self.pos = old_pos;
-            result
+            self.push_doc(EsVecElt, f)
         }
 
-        fn read_map<T>(&mut self, _: &fn(&mut Decoder, uint) -> T) -> T {
+        fn read_map<T>(&mut self, f: &fn(&mut Decoder, uint) -> T) -> T {
             debug!("read_map()");
-            fail!("read_map is unimplemented");
+            do self.push_doc(EsMap) |d| {
+                let len = d._next_uint(EsMapLen);
+                debug!("  len=%u", len);
+                f(d, len)
+            }
         }
 
         fn read_map_elt_key<T>(&mut self,
                                idx: uint,
-                               _: &fn(&mut Decoder) -> T)
+                               f: &fn(&mut Decoder) -> T)
                                -> T {
             debug!("read_map_elt_key(idx=%u)", idx);
-            fail!("read_map_elt_val is unimplemented");
+            self.push_doc(EsMapKey, f)
         }
 
         fn read_map_elt_val<T>(&mut self,
                                idx: uint,
-                               _: &fn(&mut Decoder) -> T)
+                               f: &fn(&mut Decoder) -> T)
                                -> T {
             debug!("read_map_elt_val(idx=%u)", idx);
-            fail!("read_map_elt_val is unimplemented");
+            self.push_doc(EsMapVal, f)
         }
     }
 }
 
 pub mod writer {
-    use ebml::{EbmlEncoderTag, EsBool, EsEnum, EsEnumBody, EsEnumVid};
-    use ebml::{EsI16, EsI32, EsI64, EsI8, EsInt};
-    use ebml::{EsLabel, EsOpaque, EsStr, EsU16, EsU32, EsU64, EsU8, EsUint};
-    use ebml::{EsVec, EsVecElt, EsVecLen};
+    use super::*;
 
+    use core::cast;
     use core::io;
     use core::str;
 
@@ -806,19 +805,21 @@ fn emit_bool(&mut self, v: bool) {
             self.wr_tagged_u8(EsBool as uint, v as u8)
         }
 
-        // FIXME (#2742): implement these
-        fn emit_f64(&mut self, _v: f64) {
-            fail!("Unimplemented: serializing an f64");
+        fn emit_f64(&mut self, v: f64) {
+            let bits = unsafe { cast::transmute(v) };
+            self.wr_tagged_u64(EsF64 as uint, bits);
         }
-        fn emit_f32(&mut self, _v: f32) {
-            fail!("Unimplemented: serializing an f32");
+        fn emit_f32(&mut self, v: f32) {
+            let bits = unsafe { cast::transmute(v) };
+            self.wr_tagged_u32(EsF32 as uint, bits);
         }
-        fn emit_float(&mut self, _v: float) {
-            fail!("Unimplemented: serializing a float");
+        fn emit_float(&mut self, v: float) {
+            let bits = unsafe { cast::transmute(v as f64) };
+            self.wr_tagged_u64(EsFloat as uint, bits);
         }
 
-        fn emit_char(&mut self, _v: char) {
-            fail!("Unimplemented: serializing a char");
+        fn emit_char(&mut self, v: char) {
+            self.wr_tagged_u32(EsChar as uint, v as u32);
         }
 
         fn emit_str(&mut self, v: &str) {
@@ -914,16 +915,23 @@ fn emit_seq_elt(&mut self, _idx: uint, f: &fn(&mut Encoder)) {
             self.end_tag();
         }
 
-        fn emit_map(&mut self, _len: uint, _f: &fn(&mut Encoder)) {
-            fail!("emit_map is unimplemented");
+        fn emit_map(&mut self, len: uint, f: &fn(&mut Encoder)) {
+            self.start_tag(EsMap as uint);
+            self._emit_tagged_uint(EsMapLen, len);
+            f(self);
+            self.end_tag();
         }
 
-        fn emit_map_elt_key(&mut self, _idx: uint, _f: &fn(&mut Encoder)) {
-            fail!("emit_map_elt_key is unimplemented");
+        fn emit_map_elt_key(&mut self, _idx: uint, f: &fn(&mut Encoder)) {
+            self.start_tag(EsMapKey as uint);
+            f(self);
+            self.end_tag();
         }
 
-        fn emit_map_elt_val(&mut self, _idx: uint, _f: &fn(&mut Encoder)) {
-            fail!("emit_map_elt_val is unimplemented");
+        fn emit_map_elt_val(&mut self, _idx: uint, f: &fn(&mut Encoder)) {
+            self.start_tag(EsMapVal as uint);
+            f(self);
+            self.end_tag();
         }
     }
 }
index 4d2b8d0b50a282fff7bca88abc296e0bd466f9da..a54db07261a6aeaaeb078fc2fbda390982c8ff92 100644 (file)
@@ -375,6 +375,18 @@ fn decode(d: &mut D) -> bool {
     }
 }
 
+impl<S:Encoder> Encodable<S> for char {
+    fn encode(&self, s: &mut S) {
+        s.emit_char(*self)
+    }
+}
+
+impl<D:Decoder> Decodable<D> for char {
+    fn decode(d: &mut D) -> char {
+        d.read_char()
+    }
+}
+
 impl<S:Encoder> Encodable<S> for () {
     fn encode(&self, s: &mut S) {
         s.emit_nil()
index eebd4d51fb66ed6002f428519c790ff775778685..899c97b825ff8307f19d4de0b3090757e1176245 100644 (file)
 // These tests used to be separate files, but I wanted to refactor all
 // the common code.
 
+use std::hashmap::{HashMap, HashSet};
+
 use EBReader = extra::ebml::reader;
 use EBWriter = extra::ebml::writer;
 use std::cmp::Eq;
 use std::cmp;
-use std::io::Writer;
 use std::io;
-use extra::ebml;
 use extra::serialize::{Decodable, Encodable};
 use extra::time;
 
@@ -158,4 +158,19 @@ pub fn main() {
 
     let a = &time::now();
     test_ebml(a);
+
+    test_ebml(&1.0f32);
+    test_ebml(&1.0f64);
+    test_ebml(&1.0f);
+    test_ebml(&'a');
+
+    let mut a = HashMap::new();
+    test_ebml(&a);
+    a.insert(1, 2);
+    test_ebml(&a);
+
+    let mut a = HashSet::new();
+    test_ebml(&a);
+    a.insert(1);
+    test_ebml(&a);
 }