From ca4f53655e82a0a0e1d613b16108720bb7a50fde Mon Sep 17 00:00:00 2001 From: Barosl Lee Date: Mon, 24 Nov 2014 02:22:30 +0900 Subject: [PATCH] libserialize: Remove float preprocessing in serialize::json::Encoder serialize::json::Encoder currently uses f64 to emit any integral type. This is possibly due to the behavior of JavaScript, which uses f64 to represent any numeric value. This leads to a problem that only the integers in the range of [-2^53+1, 2^53-1] can be encoded. Therefore, i64 and u64 cannot be used reliably in the current implementation. RFC 7159 suggests that good interoperability can be achieved if the range is respected by implementations. However, it also says that implementations are allowed to set the range of number accepted. And it seems that the JSON encoders outside of the JavaScript world usually make use of i64 values. This commit removes the float preprocessing done in the emit_* methods. It also increases performance, because transforming f64 into String costs more than that of an integral type. Fixes #18319 [breaking-change] --- src/libserialize/json.rs | 45 +++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 248d78236ad..371034746fc 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -419,17 +419,17 @@ pub fn buffer_encode, io::IoError>>(object: &T) -> Vec ::Encoder for Encoder<'a> { fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") } - fn emit_uint(&mut self, v: uint) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u64(&mut self, v: u64) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u32(&mut self, v: u32) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u16(&mut self, v: u16) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u8(&mut self, v: u8) -> EncodeResult { self.emit_f64(v as f64) } - - fn emit_int(&mut self, v: int) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i64(&mut self, v: i64) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i32(&mut self, v: i32) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i16(&mut self, v: i16) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i8(&mut self, v: i8) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u64(&mut self, v: u64) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u32(&mut self, v: u32) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u16(&mut self, v: u16) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u8(&mut self, v: u8) -> EncodeResult { write!(self.writer, "{}", v) } + + fn emit_int(&mut self, v: int) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i64(&mut self, v: i64) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i32(&mut self, v: i32) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i16(&mut self, v: i16) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i8(&mut self, v: i8) -> EncodeResult { write!(self.writer, "{}", v) } fn emit_bool(&mut self, v: bool) -> EncodeResult { if v { @@ -620,17 +620,17 @@ pub fn set_indent<'a>(&mut self, indent: uint) { impl<'a> ::Encoder for PrettyEncoder<'a> { fn emit_nil(&mut self) -> EncodeResult { write!(self.writer, "null") } - fn emit_uint(&mut self, v: uint) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u64(&mut self, v: u64) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u32(&mut self, v: u32) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u16(&mut self, v: u16) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_u8(&mut self, v: u8) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_uint(&mut self, v: uint) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u64(&mut self, v: u64) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u32(&mut self, v: u32) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u16(&mut self, v: u16) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_u8(&mut self, v: u8) -> EncodeResult { write!(self.writer, "{}", v) } - fn emit_int(&mut self, v: int) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i64(&mut self, v: i64) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i32(&mut self, v: i32) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i16(&mut self, v: i16) -> EncodeResult { self.emit_f64(v as f64) } - fn emit_i8(&mut self, v: i8) -> EncodeResult { self.emit_f64(v as f64) } + fn emit_int(&mut self, v: int) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i64(&mut self, v: i64) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i32(&mut self, v: i32) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i16(&mut self, v: i16) -> EncodeResult { write!(self.writer, "{}", v) } + fn emit_i8(&mut self, v: i8) -> EncodeResult { write!(self.writer, "{}", v) } fn emit_bool(&mut self, v: bool) -> EncodeResult { if v { @@ -2500,6 +2500,9 @@ fn test_write_i64() { assert_eq!(I64(-5678).to_string().into_string(), "-5678"); assert_eq!(I64(-5678).to_pretty_str().into_string(), "-5678"); + + assert_eq!(U64(7650007200025252000).to_string(), "7650007200025252000"); + assert_eq!(U64(7650007200025252000).to_pretty_str(), "7650007200025252000"); } #[test] -- 2.44.0