提交 f091a1e0 编写于 作者: G Gary Linscott

Convert json Reader to iterators

This is much faster for strings, and eventually when there is a
buffered reader of some sort.

Reading example.json 100 times before was around 1.18s.
After:
- reading from string 0.68s
- reading from file 1.08s (extra time is all in io::Reader)
上级 8fa09736
...@@ -16,11 +16,10 @@ ...@@ -16,11 +16,10 @@
//! json serialization //! json serialization
use std::iterator;
use std::char;
use std::float; use std::float;
use std::hashmap::HashMap; use std::hashmap::HashMap;
use std::io::{WriterUtil, ReaderUtil}; use std::io::WriterUtil;
use std::io; use std::io;
use std::str; use std::str;
use std::to_str; use std::to_str;
...@@ -481,24 +480,17 @@ pub fn to_pretty_str(json: &Json) -> ~str { ...@@ -481,24 +480,17 @@ pub fn to_pretty_str(json: &Json) -> ~str {
io::with_str_writer(|wr| to_pretty_writer(wr, json)) io::with_str_writer(|wr| to_pretty_writer(wr, json))
} }
static BUF_SIZE : uint = 64000; pub struct Parser<T> {
priv rdr: ~T,
#[allow(missing_doc)]
pub struct Parser {
priv rdr: @io::Reader,
priv buf: ~[char],
priv buf_idx: uint,
priv ch: char, priv ch: char,
priv line: uint, priv line: uint,
priv col: uint, priv col: uint,
} }
/// Decode a json value from an io::reader /// Decode a json value from an Iterator<char>
pub fn Parser(rdr: @io::Reader) -> Parser { pub fn Parser<T : iterator::Iterator<char>>(rdr: ~T) -> Parser<T> {
let mut p = Parser { let mut p = Parser {
rdr: rdr, rdr: rdr,
buf: rdr.read_chars(BUF_SIZE),
buf_idx: 0,
ch: 0 as char, ch: 0 as char,
line: 1, line: 1,
col: 0, col: 0,
...@@ -507,7 +499,7 @@ pub fn Parser(rdr: @io::Reader) -> Parser { ...@@ -507,7 +499,7 @@ pub fn Parser(rdr: @io::Reader) -> Parser {
p p
} }
impl Parser { impl<T: iterator::Iterator<char>> Parser<T> {
pub fn parse(&mut self) -> Result<Json, Error> { pub fn parse(&mut self) -> Result<Json, Error> {
match self.parse_value() { match self.parse_value() {
Ok(value) => { Ok(value) => {
...@@ -525,30 +517,20 @@ pub fn parse(&mut self) -> Result<Json, Error> { ...@@ -525,30 +517,20 @@ pub fn parse(&mut self) -> Result<Json, Error> {
} }
} }
impl Parser { impl<T : iterator::Iterator<char>> Parser<T> {
fn eof(&self) -> bool { self.ch == -1 as char } fn eof(&self) -> bool { self.ch == -1 as char }
fn bump(&mut self) { fn bump(&mut self) {
if self.eof() { match self.rdr.next() {
return; Some(ch) => self.ch = ch,
} None() => self.ch = -1 as char,
self.col += 1u;
if self.buf_idx >= self.buf.len() {
self.buf = self.rdr.read_chars(BUF_SIZE);
if self.buf.len() == 0 {
self.ch = -1 as char;
return;
}
self.buf_idx = 0;
} }
self.ch = self.buf[self.buf_idx];
self.buf_idx += 1;
if self.ch == '\n' { if self.ch == '\n' {
self.line += 1u; self.line += 1u;
self.col = 1u; self.col = 1u;
} else {
self.col += 1u;
} }
} }
...@@ -583,7 +565,10 @@ fn parse_value(&mut self) -> Result<Json, Error> { ...@@ -583,7 +565,10 @@ fn parse_value(&mut self) -> Result<Json, Error> {
} }
fn parse_whitespace(&mut self) { fn parse_whitespace(&mut self) {
while char::is_whitespace(self.ch) { self.bump(); } while self.ch == ' ' ||
self.ch == '\n' ||
self.ch == '\t' ||
self.ch == '\r' { self.bump(); }
} }
fn parse_ident(&mut self, ident: &str, value: Json) -> Result<Json, Error> { fn parse_ident(&mut self, ident: &str, value: Json) -> Result<Json, Error> {
...@@ -727,8 +712,11 @@ fn parse_str(&mut self) -> Result<~str, Error> { ...@@ -727,8 +712,11 @@ fn parse_str(&mut self) -> Result<~str, Error> {
let mut escape = false; let mut escape = false;
let mut res = ~""; let mut res = ~"";
while !self.eof() { loop {
self.bump(); self.bump();
if self.eof() {
return self.error(~"EOF while parsing string");
}
if (escape) { if (escape) {
match self.ch { match self.ch {
...@@ -783,8 +771,6 @@ fn parse_str(&mut self) -> Result<~str, Error> { ...@@ -783,8 +771,6 @@ fn parse_str(&mut self) -> Result<~str, Error> {
res.push_char(self.ch); res.push_char(self.ch);
} }
} }
self.error(~"EOF while parsing string")
} }
fn parse_list(&mut self) -> Result<Json, Error> { fn parse_list(&mut self) -> Result<Json, Error> {
...@@ -870,15 +856,15 @@ fn parse_object(&mut self) -> Result<Json, Error> { ...@@ -870,15 +856,15 @@ fn parse_object(&mut self) -> Result<Json, Error> {
/// Decodes a json value from an @io::Reader /// Decodes a json value from an @io::Reader
pub fn from_reader(rdr: @io::Reader) -> Result<Json, Error> { pub fn from_reader(rdr: @io::Reader) -> Result<Json, Error> {
let mut parser = Parser(rdr); let s = str::from_bytes(rdr.read_whole_stream());
let mut parser = Parser(~s.iter());
parser.parse() parser.parse()
} }
/// Decodes a json value from a string /// Decodes a json value from a string
pub fn from_str(s: &str) -> Result<Json, Error> { pub fn from_str(s: &str) -> Result<Json, Error> {
do io::with_str_reader(s) |rdr| { let mut parser = Parser(~s.iter());
from_reader(rdr) parser.parse()
}
} }
/// A structure to decode JSON to values in rust. /// A structure to decode JSON to values in rust.
...@@ -1744,7 +1730,7 @@ fn test_decode_numbers() { ...@@ -1744,7 +1730,7 @@ fn test_decode_numbers() {
assert_eq!(v, 0.4e-01f); assert_eq!(v, 0.4e-01f);
} }
// FIXME: #7611: xfailed for now #[test]
fn test_read_str() { fn test_read_str() {
assert_eq!(from_str("\""), assert_eq!(from_str("\""),
Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing string" Err(Error {line: 1u, col: 2u, msg: @~"EOF while parsing string"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册