Path: csiph.com!aioe.org!.POSTED.U158MBNsLt97drbZ2zludw.user.gioia.aioe.org!not-for-mail From: news@zzo38computer.org.invalid Newsgroups: comp.lang.postscript Subject: JSON reader/writer in PostScript Date: Wed, 04 Sep 2019 01:19:41 +0000 Organization: Aioe.org NNTP Server Lines: 173 Message-ID: <1567559086.bystand@zzo38computer.org> NNTP-Posting-Host: U158MBNsLt97drbZ2zludw.user.gioia.aioe.org Mime-Version: 1.0 X-Complaints-To: abuse@aioe.org User-Agent: bystand/0.6.1 X-Notice: Filtered by postfilter v. 0.9.2 Xref: csiph.com comp.lang.postscript:3440 I wrote a program in PostScript for reading/writing JSON data. You can use the following functions: * JSON.read ( file -- object ) Read JSON data from the file. An object will become a dictionary, with names (rather than strings) as keys. See also JSON.utf8 below. * JSON.write ( file object -- ) Write JSON data to the file. The object must be a null, boolean, string, name, integer, real, array, or dictionary. The JSON.utf8 option is unused; characters outside of the ASCII range are always written exactly as in the string. (ASCII control characters, and any character not allowed unescaped, will be escaped, though.) * JSON.utf8 - You can redefine this (like "/JSON.utf8 true def"); it is set to false by default. If false, only the low 8-bits of any character code specified by \u escapes are used. If true, then \u escapes will be converted into UTF-8. Bytes that are not escaped will just be passed through as is, regardless of this setting. Currently, the JSON.utf8 option is not implemented, so it must always be false, and it will not work if true. If I fix that later, then I will post a follow-up with the corrected program. You can also write a follow-up message if you have a comment of it, please. The below (between "===BEGIN CODE===" and "===END CODE===") is the PostScript program. ===BEGIN CODE=== % JSON implementation in PostScript % (public domain) currentpacking true setpacking /JSON.utf8 false def /.JSON.file null def /.JSON.str 65535 string def /.JSON.hex (16#????) def /.JSON.backchar 0 def /.JSON.char 0 def /.JSON.namech 256 string def .JSON.namech 43 1 put %+ JSON.namech 45 1 put %- .JSON.namech 46 1 put %. 8 1 57 {.JSON.namech exch 1 put} for %0-9 .JSON.namech 69 1 put %E 7 1 122 {.JSON.namech exch 1 put} for %a-z /.JSON.escape 256 string def 0 1 255 {.JSON.escape exch dup put} for .JSON.escape 98 8 put JSON.escape 102 12 put .JSON.escape 110 10 put JSON.escape 114 13 put .JSON.escape 116 9 put JSON.escape 117 0 put /.JSON.readnum { .JSON.str 0 .JSON.char put 1 {.JSON.file read { .JSON.namech 1 index get 0 eq { /.JSON.backchar exch store .JSON.str exch 0 exch getinterval cvr exit } { .JSON.str exch 2 index exch put 1 add } ifelse } {JSON.badinput} ifelse} loop } bind def /.JSON.readword { {.JSON.file read { .JSON.namech 1 index get 0 eq { /.JSON.backchar exch store exit } {pop} ifelse } {JSON.badinput} ifelse} loop } bind def /.JSON.readstring { 0 { .JSON.file read pop dup 34 eq { % End of string pop dup string dup 2 index .JSON.str exch 0 exch getinterval 0 exch putinterval exch pop exit } { % Character .JSON.str 2 index 2 index put 92 eq { .JSON.str 1 index .JSON.escape .JSON.file read pop get put .JSON.str 1 index get 0 eq { .JSON.file .JSON.hex 3 4 getinterval readstring pop pop /.JSON.char .JSON.hex cvi store .JSON.char 127 gt JSON.utf8 and { % Not yet implemented } { .JSON.str 1 index .JSON.char 255 and put } ifelse } if } if 1 add } ifelse } loop } bind def /.JSON.parsech 256 array def 33 1 255 {.JSON.parsech exch /JSON.badinput cvx put} for 0 1 32 {.JSON.parsech exch null cvx put} for %spaces .JSON.parsech 34 /.JSON.readstring load put %" JSON.parsech 43 /.JSON.readnum load put %+ .JSON.parsech 44 null cvx put %, JSON.parsech 45 /.JSON.readnum load put %- 48 1 57 {.JSON.parsech exch /.JSON.readnum load put} for %numbers .JSON.parsech 58 /cvn load put %: JSON.parsech 91 mark put %[ .JSON.parsech 93 (]) cvn load put %] JSON.parsech 102 {false .JSON.readword} put %f .JSON.parsech 110 {null .JSON.readword} put %n JSON.parsech 116 {true .JSON.readword} put %t .JSON.parsech 123 mark put %{ JSON.parsech 125 (>>) cvn load put %} /.JSON.parse { % ( -- object ) .JSON.backchar 0 eq { .JSON.file read } { .JSON.backchar /.JSON.backchar 0 store true } ifelse { /.JSON.char exch store .JSON.parsech .JSON.char get exec .JSON.parse } if } bind def /.JSON.charx [32 {true} repeat 224 {false} repeat] def .JSON.charx 34 true put JSON.charx 92 true put /.JSON.writechar { .JSON.charx 1 index get { .JSON.file (\\u00) writestring dup 16 lt {.JSON.file 48 write} if 16 .JSON.str cvrs .JSON.file exch writestring } { .JSON.file exch write } ifelse } def /.JSON.writedict << /arraytype {.JSON.file 91 write false exch {exch {.JSON.file 44 write} if .JSON.write true} forall pop .JSON.file 93 write} /booleantype {.JSON.str cvs .JSON.file exch writestring} /dicttype {.JSON.file 123 write false exch {3 -1 roll {.JSON.file 44 write} if exch .JSON.write .JSON.file 58 write .JSON.write true} forall pop .JSON.file 125 write} /integertype {.JSON.str cvs .JSON.file exch writestring} /nametype {.JSON.str cvs .JSON.write} /nulltype {.JSON.file (null) writestring} /realtype {.JSON.str cvs .JSON.file exch writestring} /stringtype {.JSON.file 34 write {.JSON.writechar} forall .JSON.file 34 write} >> def /JSON.read {/.JSON.file exch store .JSON.parse} bind def /.JSON.write {dup type .JSON.writedict exch get exec} bind def /JSON.write {exch /.JSON.file exch store .JSON.write .JSON.file 10 write} bind def setpacking ===END CODE=== -- Note: I am not always able to read/post messages during Monday-Friday.