]> gitweb.factorcode.org Git - factor.git/commitdiff
JSON reader improvements (#2353)
authorAbtin Molavi <amolavi@hmc.edu>
Mon, 26 Oct 2020 16:08:26 +0000 (10:08 -0600)
committerGitHub <noreply@github.com>
Mon, 26 Oct 2020 16:08:26 +0000 (16:08 +0000)
* added counter

* removed old first-json-object word

* added tests

* cleaning up namespace

* spacing

* minor comment revision

* one more formatting change

basis/json/reader/reader-tests.factor
basis/json/reader/reader.factor

index c39a565e9fe59a9d1ec1bbebb331a269a4d00440..e86b689e1bd9b557f23d88f64618f419f5f434fb 100644 (file)
@@ -84,4 +84,11 @@ ${ { 0xabcd } >string } [ " \"\\uaBCd\" " json> ] unit-test
 [ "<!doctype html>\n<html>\n<head>\n   " json> ]
 [ not-a-json-number? ] must-fail-with
 
-{ H{ } } [ "" json> ] unit-test
+! unclosed objects and mismatched brackets are not allowed
+ [ "[\"a\",
+4
+,1," json> ] must-fail
+
+[ "[]]]" json> ]  must-fail
+
+[ "{[: \"x\"}" json> ] must-fail
index 7d223c062312957769bd225855292d4c13e1b1cb..8ba83882eef78a01bd74c0a3e81a4426d9fcbeb2 100644 (file)
@@ -10,6 +10,8 @@ IN: json.reader
 
 ERROR: not-a-json-number string ;
 
+SYMBOL: counter
+
 : json-number ( char stream -- num char )
     [ 1string ] [ "\s\t\r\n,:}]" swap stream-read-until ] bi*
     [
@@ -109,9 +111,9 @@ DEFER: (read-json-string)
     { object vector object } declare
     {
         { CHAR: \" [ over read-json-string suffix! ] }
-        { CHAR: [  [ json-open-array ] }
+        { CHAR: [  [ 1 counter +@ json-open-array ] }
         { CHAR: ,  [ v-over-push ] }
-        { CHAR: ]  [ json-close-array ] }
+        { CHAR: ]  [ -1 counter +@ json-close-array ] }
         { CHAR: {  [ json-open-hash ] }
         { CHAR: :  [ v-pick-push ] }
         { CHAR: }  [ json-close-hash ] }
@@ -128,10 +130,10 @@ DEFER: (read-json-string)
 : json-read-input ( stream -- objects )
     V{ } clone over '[ _ stream-read1 ] [ scan ] while* nip ;
 
-! If there are no json objects, return an empty hashtable
-! This happens for empty files.
-: first-json-object ( objects -- obj )
-    [ H{ } clone ] [ first ] if-empty ;
+
+! A properly formed JSON input should contain exactly one object with balanced brackets.
+: get-json-object ( objects  --  obj  )
+    dup length 1 = counter get 0 = and [ first ] [ json-error ] if ;
 
 PRIVATE>
 
@@ -141,7 +143,7 @@ PRIVATE>
 GENERIC: json> ( string -- object )
 
 M: string json>
-    [ read-json-objects first-json-object ] with-string-reader ;
+    [ 0 counter [ read-json-objects get-json-object ] with-variable ] with-string-reader ;
 
 : path>json ( path -- json )
-    utf8 [ read-json-objects first-json-object ] with-file-reader ;
+    utf8 [ 0 counter [ read-json-objects get-json-object ] with-variable ] with-file-reader ;