1717// This makes for some ugly code, but it is faster. Hopefully in the future
1818// with MIR support the compiler will get smarter about this.
1919
20- use std:: { ptr , mem , str, slice, char } ;
20+ use std:: { str, slice, char } ;
2121use object:: Object ;
2222use number:: Number ;
2323use { JsonValue , Error , Result } ;
@@ -27,6 +27,10 @@ use { JsonValue, Error, Result };
2727const MAX_PRECISION : u64 = 576460752303423500 ;
2828
2929
30+ // How many nested Objects/Arrays are allowed to be parsed
31+ const DEPTH_LIMIT : usize = 512 ;
32+
33+
3034// Position is only used when we stumble upon an unexpected character. We don't
3135// track lines during parsing, as that would mean doing unnecessary work.
3236// Instead, if an error occurs, we figure out the line and column from the
@@ -121,6 +125,20 @@ macro_rules! expect_byte_ignore_whitespace {
121125 } )
122126}
123127
128+ // Expect to find EOF or just whitespaces leading to EOF after a JSON value
129+ macro_rules! expect_eof {
130+ ( $parser: ident) => ( {
131+ while !$parser. is_eof( ) {
132+ match $parser. read_byte( ) {
133+ 9 ... 13 | 32 => $parser. bump( ) ,
134+ ch => {
135+ $parser. bump( ) ;
136+ return $parser. unexpected_character( ch) ;
137+ }
138+ }
139+ }
140+ } )
141+ }
124142
125143// Expect a particular byte to be next. Also available with a variant
126144// creates a `match` expression just to ease some pain.
@@ -350,52 +368,6 @@ macro_rules! expect_fraction {
350368 } )
351369}
352370
353-
354- // This is where the magic happens. This macro will read from the source
355- // and try to create an instance of `JsonValue`. Note that it only reads
356- // bytes that _begin_ a JSON value, however it can also accept an optional
357- // pattern with custom logic. This is used in arrays, which expect either
358- // a value or a closing bracket `b"]"`.
359- macro_rules! expect_value {
360- { $parser: ident $( , $byte: pat => $then: expr ) * } => ( {
361- let ch = expect_byte_ignore_whitespace!( $parser) ;
362-
363- match ch {
364- $(
365- $byte => $then,
366- ) *
367- b'[' => JsonValue :: Array ( try!( $parser. read_array( ) ) ) ,
368- b'{' => JsonValue :: Object ( try!( $parser. read_object( ) ) ) ,
369- b'"' => expect_string!( $parser) . into( ) ,
370- b'0' => JsonValue :: Number ( allow_number_extensions!( $parser) ) ,
371- b'1' ... b'9' => {
372- JsonValue :: Number ( expect_number!( $parser, ch) )
373- } ,
374- b'-' => {
375- let ch = expect_byte!( $parser) ;
376- JsonValue :: Number ( - match ch {
377- b'0' => allow_number_extensions!( $parser) ,
378- b'1' ... b'9' => expect_number!( $parser, ch) ,
379- _ => return $parser. unexpected_character( ch)
380- } )
381- }
382- b't' => {
383- expect_sequence!( $parser, b'r' , b'u' , b'e' ) ;
384- JsonValue :: Boolean ( true )
385- } ,
386- b'f' => {
387- expect_sequence!( $parser, b'a' , b'l' , b's' , b'e' ) ;
388- JsonValue :: Boolean ( false )
389- } ,
390- b'n' => {
391- expect_sequence!( $parser, b'u' , b'l' , b'l' ) ;
392- JsonValue :: Null
393- } ,
394- _ => return $parser. unexpected_character( ch)
395- }
396- } )
397- }
398-
399371impl < ' a > Parser < ' a > {
400372 pub fn new ( source : & ' a str ) -> Self {
401373 Parser {
@@ -704,102 +676,146 @@ impl<'a> Parser<'a> {
704676 Ok ( Number :: from_parts ( true , num, ( big_e. saturating_add ( e * sign) ) ) )
705677 }
706678
707- // Given how compilcated reading numbers and strings is, reading objects
708- // is actually pretty simple.
709- fn read_object ( & mut self ) -> Result < Object > {
710- let key = expect ! { self ,
711- b'}' => return Ok ( Object :: new( ) ) ,
712- b'\"' => expect_string!( self )
713- } ;
679+ // Parse away!
680+ fn parse ( & mut self ) -> Result < JsonValue > {
681+ let mut stack = Vec :: with_capacity ( 3 ) ;
682+ let mut ch = expect_byte_ignore_whitespace ! ( self ) ;
714683
715- let mut object = Object :: with_capacity ( 3 ) ;
684+ ' parsing: loop {
685+ let mut value = match ch {
686+ b'[' => {
687+ ch = expect_byte_ignore_whitespace ! ( self ) ;
716688
717- expect ! ( self , b':' ) ;
689+ if ch != b']' {
690+ if stack. len ( ) == DEPTH_LIMIT {
691+ return Err ( Error :: ExceededDepthLimit ) ;
692+ }
718693
719- object. insert ( key, expect_value ! ( self ) ) ;
694+ stack. push ( StackBlock :: Array ( Vec :: with_capacity ( 2 ) ) ) ;
695+ continue ' parsing;
696+ }
720697
721- loop {
722- let key = expect ! { self ,
723- b'}' => break ,
724- b',' => {
725- expect!( self , b'"' ) ;
726- expect_string!( self )
698+ JsonValue :: Array ( Vec :: new ( ) )
699+ } ,
700+ b'{' => {
701+ ch = expect_byte_ignore_whitespace ! ( self ) ;
702+
703+ if ch != b'}' {
704+ if stack. len ( ) == DEPTH_LIMIT {
705+ return Err ( Error :: ExceededDepthLimit ) ;
706+ }
707+
708+ let mut object = Object :: with_capacity ( 3 ) ;
709+
710+ if ch != b'"' {
711+ return self . unexpected_character ( ch)
712+ }
713+
714+ object. insert ( expect_string ! ( self ) , JsonValue :: Null ) ;
715+ expect ! ( self , b':' ) ;
716+
717+ stack. push ( StackBlock :: Object ( object) ) ;
718+
719+ ch = expect_byte_ignore_whitespace ! ( self ) ;
720+
721+ continue ' parsing;
722+ }
723+
724+ JsonValue :: Object ( Object :: new ( ) )
725+ } ,
726+ b'"' => expect_string ! ( self ) . into ( ) ,
727+ b'0' => JsonValue :: Number ( allow_number_extensions ! ( self ) ) ,
728+ b'1' ... b'9' => {
729+ JsonValue :: Number ( expect_number ! ( self , ch) )
730+ } ,
731+ b'-' => {
732+ let ch = expect_byte ! ( self ) ;
733+ JsonValue :: Number ( - match ch {
734+ b'0' => allow_number_extensions ! ( self ) ,
735+ b'1' ... b'9' => expect_number ! ( self , ch) ,
736+ _ => return self . unexpected_character ( ch)
737+ } )
727738 }
739+ b't' => {
740+ expect_sequence ! ( self , b'r' , b'u' , b'e' ) ;
741+ JsonValue :: Boolean ( true )
742+ } ,
743+ b'f' => {
744+ expect_sequence ! ( self , b'a' , b'l' , b's' , b'e' ) ;
745+ JsonValue :: Boolean ( false )
746+ } ,
747+ b'n' => {
748+ expect_sequence ! ( self , b'u' , b'l' , b'l' ) ;
749+ JsonValue :: Null
750+ } ,
751+ _ => return self . unexpected_character ( ch)
728752 } ;
729753
730- expect ! ( self , b':' ) ;
754+ ' popping: loop {
755+ match stack. pop ( ) {
756+ None => {
757+ expect_eof ! ( self ) ;
731758
732- object . insert ( key , expect_value ! ( self ) ) ;
733- }
759+ return Ok ( value ) ;
760+ } ,
734761
735- Ok ( object )
736- }
762+ Some ( StackBlock :: Array ( mut array ) ) => {
763+ array . push ( value ) ;
737764
738- // And reading arrays is simpler still!
739- fn read_array ( & mut self ) -> Result < Vec < JsonValue > > {
740- let first = expect_value ! { self , b']' => return Ok ( Vec :: new( ) ) } ;
765+ ch = expect_byte_ignore_whitespace ! ( self ) ;
741766
742- let mut array = Vec :: with_capacity ( 2 ) ;
767+ match ch {
768+ b',' => {
769+ stack. push ( StackBlock :: Array ( array) ) ;
743770
744- unsafe {
745- // First member can be written to the array without any checks!
746- ptr:: copy_nonoverlapping (
747- & first as * const JsonValue ,
748- array. as_mut_ptr ( ) ,
749- 1
750- ) ;
751- mem:: forget ( first) ;
752- array. set_len ( 1 ) ;
753- }
771+ ch = expect_byte_ignore_whitespace ! ( self ) ;
754772
755- expect ! {
756- self ,
757- b']' => return Ok ( array) ,
758- b',' => {
759- // Same for the second one!
760- let value = expect_value!( self ) ;
761- unsafe {
762- ptr:: copy_nonoverlapping(
763- & value as * const JsonValue ,
764- array. as_mut_ptr( ) . offset( 1 ) ,
765- 1
766- ) ;
767- mem:: forget( value) ;
768- array. set_len( 2 ) ;
769- }
770- }
771- }
773+ continue ' parsing;
774+ } ,
775+ b']' => {
776+ value = JsonValue :: Array ( array) ;
777+ continue ' popping;
778+ } ,
779+ _ => return self . unexpected_character ( ch)
780+ }
781+ } ,
772782
773- loop {
774- expect ! { self ,
775- b']' => break ,
776- b',' => array. push( expect_value!( self ) )
777- } ;
778- }
783+ Some ( StackBlock :: Object ( mut object) ) => {
784+ object. override_last ( value) ;
779785
780- Ok ( array)
781- }
786+ ch = expect_byte_ignore_whitespace ! ( self ) ;
782787
783- // Parse away!
784- fn parse ( & mut self ) -> Result < JsonValue > {
785- let value = expect_value ! ( self ) ;
788+ match ch {
789+ b',' => {
790+ expect ! ( self , b'"' ) ;
791+ object. insert ( expect_string ! ( self ) , JsonValue :: Null ) ;
792+ expect ! ( self , b':' ) ;
786793
787- // We have read whatever value was there, but we need to make sure
788- // there is nothing left to read - if there is, that's an error.
789- while !self . is_eof ( ) {
790- match self . read_byte ( ) {
791- 9 ... 13 | 32 => self . bump ( ) ,
792- ch => {
793- self . bump ( ) ;
794- return self . unexpected_character ( ch) ;
794+ stack. push ( StackBlock :: Object ( object) ) ;
795+
796+ ch = expect_byte_ignore_whitespace ! ( self ) ;
797+
798+ continue ' parsing;
799+ } ,
800+ b'}' => {
801+ value = JsonValue :: Object ( object) ;
802+
803+ continue ' popping;
804+ } ,
805+ _ => return self . unexpected_character ( ch)
806+ }
807+ } ,
795808 }
796809 }
797810 }
798-
799- Ok ( value)
800811 }
801812}
802813
814+ enum StackBlock {
815+ Array ( Vec < JsonValue > ) ,
816+ Object ( Object ) ,
817+ }
818+
803819// All that hard work, and in the end it's just a single function in the API.
804820#[ inline]
805821pub fn parse ( source : & str ) -> Result < JsonValue > {
0 commit comments