"json.cls" as distributed with ooRexx 5.0.0 has one (actually two) limitation which can be regarded to be a bug:

 * It cannot handle JSON booleans properly: when reading a JSON file with 
boolean values and
   creating a JSON file from ooRexx the boolean values will not show up, rather 
their ooRexx
   numeric representations of "0" and "1".

In the past I came up with a solution for this problem which was not "liked" and was 30% slower than json.cls (sounds dramatic, but in today's world with such power horses in the hands of end-users may be negligeable, but still, one being made aware of this made it less attractive).

As the above limitation is really a problem if one wants to use ooRexx json.cls and exchange proper JSON with other systems, e.g. via curl, I came up with a version (starting out with the current json.cls) that does the following in addition:

 * It adds support for JSON true and false: just send .json~true or 
.json~false. The resulting
   JsonBoolean objects behave like ooRexx .true and .false (both strings with 
the numeric values
   "0" and "1") and can be used interchangeably

     o when reading a JSON file, JSON booleans will be represented with the 
appropriate .json~true
       or .json~false values

     o when writing a JSON file, any JSON boolean value will be properly encoded with 
"false" and
       "true"

 * It adds generic support for MapCollection and OrderedCollection instead of 
restricting support
   to Directory and Array,

 * It uses StringTable instead of Directory for reading in JSON data,

 * Although JSON is a string encoding, which could be read by humans, there are 
two observable
   properties that do not make it human-friendly:

     o by default the encoding is "minimized" such that no ignorable whitespace 
(usually used for
       making JSON better legible e.g. cf. Wikipedia's JSON [1] sample) is 
contained,

     o there is no sorted order of name/value pairs (per specification no order 
is implied, yet for
       humans having a sorted order in the JSON encoded data makes it possible 
to quickly check
       whether certain name/values pairs exist or not without affecting any 
JSON importer)

   the replacement version will create by default minimized JSON encodings, 
however it will sort
   name/value pairs by name to ease reading by humans

 * as this is Rexx/ooRexx it is made possible to create a "legible", a 
"human-oriented" JSON
   encoding in two ways: when creating a JSON instance or when sending the 
toJson message one can
   supply .true which causes the produced JSON encoding to be formatted with 
ignorable whitespace
   such that it will be easy to see the structure and spot name/value pairs 
therein; yet, the
   produced JSON is still JSON and can be processed without problems,

 * two new convenience class methods for reading from and writing to files are 
defined:
   fromJsonFile(fileName) and toJsonFile(fileName, ooRexxObject [, 
legible=.true])

Here the JSON sample given at [1]:

   {
   "firstName":"John",
   "lastName":"Smith",
   "isAlive":true,
   "age":27,
   "address":{
   "streetAddress":"21 2nd Street",
   "city":"New York",
   "state":"NY",
   "postalCode":"10021-3100"
   },
   "phoneNumbers":[
   {
   "type":"home",
   "number":"212 555-1234"
   },
   {
   "type":"office",
   "number":"646 555-4567"
   }
   ],
   "children":[
   "Catherine",
   "Thomas",
   "Trevor"
   ],
   "spouse":null
   }

Here the minimized rendering with the replacement version of json.cls:

   {"address":{"city":"New York","postalCode":"10021-3100","state":"NY","streetAddress":"21 2nd 
Street"},"age":27,"children":["Catherine","Thomas","Trevor"],"firstName":"John","isAlive":true,"lastName":"Smith","phoneNumbers":[{"number":"212 555-1234","type":"home"},{"number":"646 
555-4567","type":"office"}],"spouse":null}

Here the legible rendering with the replacement version of json.cls:

   {
       "address": {
          "city": "New York",
          "postalCode": "10021-3100",
          "state": "NY",
          "streetAddress": "21 2nd Street"
       },
       "age": 27,
       "children": [
          "Catherine",
          "Thomas",
          "Trevor"
       ],
       "firstName": "John",
       "isAlive": true,
       "lastName": "Smith",
       "phoneNumbers": [
          {
             "number": "212 555-1234",
             "type": "home"
          },
          {
             "number": "646 555-4567",
             "type": "office"
          }
       ],
       "spouse": null
   }

---

Here an ooRexx program that creates a structure which will get encoded as 
minimized and legible JSON:

   -- create a Rexx structure
   d=.directory~new
   d["firstName"] = "Mary"
   d["lastName" ]  = "Doe"
   d["children" ]  = .list~of("Maribel", "John", "Annabel")
   d["married"  ]  = .json~false
   d["born"     ]  = "2001-02-02"
   d["yearBorn" ]  = 2001
   d["bestMan"  ]  = .nil

   j = .json~new
   say j~toJson(d)         -- write minimized JSON
   say "---"
   say j~toJson(d,.true)   -- write legible JSON

   ::requires "json.cls"   -- get access to the JSON class

Here the output of the above program:

   
{"bestMan":null,"born":"2001-02-02","children":["Maribel","John","Annabel"],"firstName":"Mary","lastName":"Doe","married":false,"yearBorn":2001}
   ---
   {
       "bestMan": null,
       "born": "2001-02-02",
       "children": [
          "Maribel",
          "John",
          "Annabel"
       ],
       "firstName": "Mary",
       "lastName": "Doe",
       "married": false,
       "yearBorn": 2001
   }

---

The replacement json.cls and the adjusted official json.tesgroup can be found in my sandbox at <https://sourceforge.net/p/oorexx/code-0/HEAD/tree/sandbox/rony/json/>.

Performance when reading and writing is comparable to 5.0's json.cls.

---rony

[1] Wikipedia JSON: <https://en.wikipedia.org/wiki/JSON>

_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to