New subroutine JSON performs some JSON-related utility functions.
xcall JSON, opcode, {, parameters...}
Parameters
opcode (num) [in]
specifies operation to be performed; described in detail below.
Opcode 1: Load a JSON string into an ordered map:
xcall JSON, 1, handle, status, jsontext$, $ordmap()
Parameters
handle (B4+ or F) [out]
returns a handle to the JSON structure in memory (for future expansion)
status (signed num) [out]
returns the status of the operation:
Code |
Status |
---|---|
>= 0 |
indicates success (# nodes parsed) |
< 0 |
indicates an error: |
-1 |
out of memory |
-3 |
out of JSON library handles |
-5 |
invalid map reference |
-6 |
ordered maps not supported in this A-Shell version |
The resulting map uses an XPATH-like syntax, consisting of a key representing the path to the value and the value representing the value. For example, the following JSON excerpt describing a program menu bar ...
{ "menu": {
"header": "SVG Viewer",
"items": [
{"id": "Open"},
{"id": "OpenNew", "label": "Open New"},
null,
{"id": "ZoomIn", "label": "Zoom In"},
...
... would be converted to an ordered map something like this:
/menu/header -> SVG Viewer
/menu/items[1]/id -> Open
/menu/items[2]/id -> OpenNew
/menu/items[2]/label -> Open New
/menu/items[4]/id -> ZoomIn
/menu/items[4]/label -> Zoom In
...
Note that you can use the function Fn'FileToStr$(fspec$) from fnfilestr.bsi in SOSLIB[907,10] to load a JSON file into the string needed by the JSON.SBR function.
Opcode2: Free the JSON memory associated with the HANDLE
xcall JSON, 2, handle, status
Parameters
handle (B4+ or F) [in]
handle returned from opcode 1
status (signed num) [out] -
0 for success
Opcode3: Escape the JSON text
xcall JSON, 3, status, jsontext$
Parameters
status (signed num) [out]
returns the number of special characters escaped
jsontext$ (string) [in/out]
JSON text, both source and destination
This function applies JSON escaping rules to special characters in the specified JSONTEXT$, returning the resulting string in the same variable. Note that since escaping increases the size of the text, the JSONTEXT$ parameter should be sufficiently large to handle the worst case, which could be up to six times the original, or be a dynamic string. The algorithm assumes that the JSONTEXT$ is encoded using the Latin1 character set, and supports the following:
Character |
Esc Seq |
|
Character |
Esc Seq |
---|---|---|---|---|
" (quote) |
\" |
|
chr(13) (CR) |
\r |
\ (backslash) |
\\ |
|
chr(9) (tab) |
\t |
/ (slash) |
\/ |
|
chr(1) - chr(31) |
\u0001 - \u001F |
chr(8) (backspace) |
\b |
|
chr(160) - chr(255) |
\u00A0 - \U00FF |
chr(12) (formfeed) |
\f |
|
|
|
Note that aside from eliminating the need to reinvent the wheel in a BASIC function, the subroutine operates much faster than you could possibly do in BASIC.
Opcode4: Unescape the JSON text
xcall JSON, 4, status, jsontext$
Parameters
status (signed num) [out]
returns the number of escaped characters unescaped
jsontext$ (string) [in/out]
JSON text, both source and destination
This is the reverse of opcode 3, converting the escaped sequences into their original raw form. Note that here the output will never be longer than the input.
Opcode5: Form a "name":"value" pair
xcall JSON, 5, status, name$, value$, jsonpair$ {,flags}
Parameters
status
not used
name$ (string) [in]
the name part of the name:value pair
value$ (string) [in]
the value part of the name:value pair
jsontext$ (string) [out]
the "name":"value" result is returned here
flags (num) [in]
optional flags from the table below
Symbol |
Value |
Description |
---|---|---|
XJSONF_NUMBER |
&h0001 |
treat VALUE$ as a number (don't quote it) |
XJSONF_LCS |
&h0002 |
fold NAME$ lower case |
XJSONF_UCS |
&h0004 |
fold NAME$ upper case |
XJSONF_NOTRIM |
&h0010 |
don't trim leading/trailing spaces from value (else do) |
XJSONF_NONULLVAL |
&h0020 |
if VALUE$="", output will be "" instead of "name":"" |
XJSONF_NOCOMMA |
&h0040 |
no trailing comma (else output pair ends with a comma) |
Definition file: ashinc:json.def |
Although this may seem like a minimal operation that can easily be accomplished in a simple BASIC function, as with opcode 3 and 4, the big advantage is speed, which might matter when dealing with large datasets involving hundreds of thousands or millions of such pairs.
Note that unless the XJSONF_NOCOMMA flag is specified, the output will contain a trailing comma so that you can call the function in a loop without having to explicitly output a comma between each pair.