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 (second version) Date: Sun, 08 Sep 2019 21:32:25 +0000 Organization: Aioe.org NNTP Server Lines: 167 Message-ID: <1567977875.bystand@zzo38computer.org> References: <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.2 X-Notice: Filtered by postfilter v. 0.9.2 Xref: csiph.com comp.lang.postscript:3443 JSON.utf8 is now implemented (although it doesn't currently convert surrogate pairs into a single UTF-8 codepoint), and another change as suggested by some of the other follow-up messages to my first message have also been implemented. Also, the "dot stuffing" of this message is (hopefully) correct now; it was a bug in the NNTP software I was using, but I have now corrected that bug (hopefully). Also, I would like to know if you have any use for this, and especially if you have found any bugs in it. (This is not mandatory though; it is public domain, so you are allowed to do whatever you want with it.) 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 48 1 57 {.JSON.namech exch 1 put} for %0-9 97 1 122 {.JSON.namech exch 1 put} for %a-z (+-.E) {.JSON.namech exch 1 put} forall /.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 { .JSON.char 16#0800 lt { % Two byte UTF-8 .JSON.str 1 index .JSON.char -6 bitshift 16#C0 or put 1 add .JSON.str 1 index .JSON.char 16#3F and 16#80 or put } { % Three byte UTF-8 .JSON.str 1 index .JSON.char -12 bitshift 16#E0 or put 1 add .JSON.str 1 index .JSON.char -6 bitshift 16#3F and 16#80 or put 1 add .JSON.str 1 index .JSON.char 16#3F and 16#80 or put } ifelse } { .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.