Pl1 And JSON Peter Elderon
-
Upload
nrb -
Category
Technology
-
view
124 -
download
6
Transcript of Pl1 And JSON Peter Elderon
®
IBM Software Group
© 2013 IBM Corporation
PL/I and JSON
Spring 2015
Peter Elderon
®
IBM Software Group
© 2013 IBM Corporation
A short introduction to JSON
IBM Software Group | Rational software
3
JSON
Is an alternative to XML
It is simpler and less rich than XML
for example, all JSON text is human readable
This is both a strength and a weakness
IBM Software Group | Rational software
4
JSON
JSON text consists of an array or an object
An array is a comma-delimited list of values enclosed in [ … ]
An object is a comma-delimited list of name-value pairs enclosed in { … }
An array or object may be empty
So [ ] and { } form valid JSON text
Arrays and objects are also values and hence the definition is recursive
IBM Software Group | Rational software
5
JSON
A name (in a name-value pair) is a string
A value is one of
a string
a number
an object
an array
one of the keywords: true, false, null
All JSON text is in UTF-8
IBM Software Group | Rational software
6
JSON
A string is a "-delimited series of UTF-8 characters with \ used to escape
these characters
\
"
/
b, f, n, r, or t (backfeed, formfeed, newline, return, or tab)
u followed by 4 hex digits
So, the value PL/I is held as "PL\/I"
IBM Software Group | Rational software
7
JSON
A number is - essentially – one of the following with possibly a leading
minus sign
an integer (i.e. a series of digits)
a decimal number (i.e. a series of digits with a decimal point)
a floating-point number (i.e. one of the above followed by E (or e) and a possibly
signed series of digits)
Leading zeros are not allowed except when the number consists of exactly
one zero before an optional decimal point or exponent
IBM Software Group | Rational software
9
JSON
Since arrays and object are themselves values, recursion is possible, e.g.
{ "passes“ : 3,
"data“ :
[
{ "name“ : "Mather", "elevation“ : 12100 }
, { "name“ : "Pinchot", "elevation“ : 12130 }
, { "name“ : "Glenn", "elevation“ : 11940 }
]
}
Whitespace is insignificant except inside strings (and is invalid in numbers)
®
IBM Software Group
© 2013 IBM Corporation
PL/I support for JSON
IBM Software Group | Rational software
11
Functions like those provided for XML
We provide a series of built-in functions that support
Validating JSON text
Generating JSON text
Parsing JSON text
IBM Software Group | Rational software
12
Validating JSON text
The jsonValid built-in function validates the json text of a specified size at a
given address
If valid, zero is returned
Otherwise the index of the first invalid byte is returned
®
IBM Software Group
© 2013 IBM Corporation
Generating JSON from PL/I
IBM Software Group | Rational software
14
Generating JSON text
all JSON written out will be in UTF-8 with the compiler and library handling
any necessary conversions from EBCDIC
a series of “put” functions is provided and all have a buffer address and
buffer length as their first 2 arguments, and all return the number of bytes
written
attempts to write variables containing data types incompatible with JSON
are flagged at compile time
escaped characters are created as needed
IBM Software Group | Rational software
15
Generating JSON text
The functions allow you to write a variable as complete, valid JSON
Where the variable could be a scalar, an array, or a structure
But the functions also allow you to build some JSON text piecewise
IBM Software Group | Rational software
16
Put value
The jsonPutValue writes a JSON value to a buffer
It is probably be the simplest function to use to generate JSON
But a value is not a name-pair – this function writes just the value
IBM Software Group | Rational software
17
jsonPutValue - example
Given
dcl b(3) fixed bin init(2,3,5)
jsonPutValue( p, n, b ) writes this complete, valid JSON text
[2,3,5]
To the buffer of size n at address p
It returns the value 7 (the number of bytes written to p)
IBM Software Group | Rational software
18
jsonPutValue - example
Given
dcl 1 c, 2 d fixed bin init(2), 2 e fixed bin init(3);
jsonPutValue( p, n, c ) writes this complete, valid JSON text
{ "d" : 2, "e" : 3 }
To the buffer of size n at address p
It returns the value 13 (the number of bytes written to p)
IBM Software Group | Rational software
19
Put value
You could also use jsonPutValue to write a string or number to a buffer
So jsonPutValue( p, n, ‘some text’ ) writes “some text” as UTF8 to the buffer
p of length n and returns the number of bytes written
The return value is greater than the length of the source string if the source
contained characters requiring 2 or more bytes in UTF8
The conversion from EBCDIC to UTF8 is based on the compiler code page
option
IBM Software Group | Rational software
20
Put member
Name-value pairs are also known as members
And Member is shorter than NameValue and hence easier to type and use
jsonPutMember writes a JSON member to a buffer
It is probably be the next simplest function to use to generate JSON
But a member is not by itself valid JSON text
IBM Software Group | Rational software
21
jsonPutMember - example
Given
dcl a fixed bin init(2);
jsonPutMember( p, n, a ) writes this incomplete JSON text
"a" : 2
To the buffer of size n at address p
It returns the value 5 (the number of bytes written to p)
IBM Software Group | Rational software
22
jsonPutMember - example
Given
dcl b(3) fixed bin init(2,3,5);
jsonPutMember( p, n, b ) writes this incomplete JSON text
"b" : [2,3,5]
To the buffer of size n at address p
It returns the value 11 (the number of bytes written to p)
IBM Software Group | Rational software
23
jsonPutMember - example
Given
dcl 1 c, 2 d fixed bin init(2), 2 e fixed bin init(3);
jsonPutMember( p, n, c ) writes this incomplete JSON text
"c" : { "d" : 2, "e" : 3 }
To the buffer of size n at address p
It returns the value 17 (the number of bytes written to p)
IBM Software Group | Rational software
24
jsonPutMember - example
Given
dcl 1 c(2), 2 d fixed bin init(2,3), 2 d fixed bin init(5,7);
jsonPutMember( p, n, c ) writes this incomplete JSON text
"c" : [ { "d" : 2, "e" : 5 }, { "d": 3, "e" : 7 } ]
To the buffer of size n at address p and returns the number of bytes written
Note that is C is an array of structures, and the JSON text also says this
IBM Software Group | Rational software
25
Building JSON text piecewise
To help build JSON piecewise, a series of functions allows you to write any
of the SJON delimiters to a buffer:
jsonPutObjectStart writes {
jsonPutArrayStart writes [
jsonPutComma writes ,
jsonPutColon writes :
jsonPutArrayEnd writes ]
jsonPutObjectStart writes }
This can make your code less cluttered and help you avoid code page
problems since your source never needs to contain these characters
IBM Software Group | Rational software
26
Building JSON text piecewise
So, to write complete, valid JSON text containing the names and values of
the variables x and y, you could write this code
jsize = 0;
jsize += jsonPutObjectStart( addr(buffer)+jsize, length(buffer)-jsize );
jsize += jsonPutMember( addr(buffer)+jsize, length(buffer)-jsize, x );
jsize += jsonPutComma( addr(buffer)+jsize, length(buffer)-jsize );
jsize += jsonPutMember( addr(buffer)+jsize, length(buffer)-jsize, y );
jsize += jsonPutObjectEnd( addr(buffer)+jsize, length(buffer)-jsize );
IBM Software Group | Rational software
27
Building JSON text piecewise
Or if you wanted to write complete, valid JSON text containing only the
values of the variables x and y, you could write this code
jsize = 0;
jsize += jsonPutObjectStart( addr(buffer)+jsize, length(buffer)-jsize );
jsize += jsonPutValue( addr(buffer)+jsize, length(buffer)-jsize, x );
jsize += jsonPutComma( addr(buffer)+jsize, length(buffer)-jsize );
jsize += jsonPutValue( addr(buffer)+jsize, length(buffer)-jsize, y );
jsize += jsonPutObjectEnd( addr(buffer)+jsize, length(buffer)-jsize );
IBM Software Group | Rational software
28
Building JSON text piecewise
Or if you wanted to write complete, valid JSON text containing consisting of the name-value pair "positives" and all the positive values in an array a, you could write this code
jsonPutOjbectStart
jsonPutValue( "positivies" )
jsonPutColon
jsonPutArrayStart
count = 0
do jx = lbound(a) to hbound(a)
if a(jx) > 0 then
do
if count > 0 then
jsonPutComma
jsonPutValue( a(jx) )
count += 1
end
end
jsonPutArrayEnd
jsonPutOjbectEnd
®
IBM Software Group
© 2013 IBM Corporation
Parsing JSON into PL/I
IBM Software Group | Rational software
30
Parsing JSON text
all JSON to be parsed must be in UTF-8 with the compiler and library
handling any necessary conversions to EBCDIC
a series of “get” functions are provided and all have a buffer address and
buffer length as their first 2 arguments, and all return the number of bytes
read
attempts to read variables containing data types incompatible with JSON are
flagged at compile time
whitespace characters are skipped over when found
IBM Software Group | Rational software
31
Parsing JSON text
The functions let you to assign a variable from corresponding JSON
Where the variable could be a scalar, an array, or a structure
But the functions also allow you to parse JSON text piecewise
All these functions are counterparts to the jsonPut functions
IBM Software Group | Rational software
32
Get value and member
jsonGetValue is the counterpart to jsonPutValue
jsonGetMember is the counterpart to jsonPutMember
Usually, both have 3 arguments
But they also accept only 2 arguments in which case the next value (or
member) in the buffer is read over
This for is useful in piecewise parsing
IBM Software Group | Rational software
33
jsonGetValue - example
Given
dcl b(3) fixed bin;
jsonGetValue( p, n, b ) reads this JSON text
[ 2, 3, 5 ]
from the buffer of size n at address p and assign those values to b
It returns a value >= 7 (the number of bytes read including whitespace)
IBM Software Group | Rational software
34
jsonGetValue - example
And given
dcl b(3) fixed bin;
jsonGetValue( p, n, b ) reads this JSON text
[ 2, 5 ]
And assign values only to b(1) and b(2)
IBM Software Group | Rational software
35
jsonGetValue - example
Given
dcl 1 c, 2 d fixed bin, 2 e fixed bin;
jsonGetValue( p, n, c ) reads this JSON text
{ "d" : 2, "e" : 3 }
And assign values to the elements of c
It returns a value >= 13
IBM Software Group | Rational software
36
Get value
You could also use jsonPutValue to read a string or number from a buffer
and assign it to a scalar
So if the next element of some JSON text is the string “elements” and C is a
CHAR(20) VARYING variable, then jsonGetValue( p, n, C ) would
read the UTF8 string “elements”
convert it to EBCDIC
assign the converted value to C and
return the number of bytes read
The conversion to EBCDIC from UTF8 is based on the compiler code page
option
IBM Software Group | Rational software
37
Get member
jsonGetMember reads a JSON member from a buffer
This is the counterpart to jsonPutMember
But as was true in the jsonGetValue examples, the source can omit elements
of the target array or structure
Since a member is incomplete JSON, this function is probably more useful in
parsing JSON piecewise
IBM Software Group | Rational software
38
Parsing JSON text piecewise
To help parse JSON piecewise, a series of functions allows you to read over
whitespace to a specified SJON delimiter in a buffer:
jsonGetObjectStart reads to {
jsonGetArrayStart reads to [
jsonGetComma reads to ,
jsonGetColon reads to :
jsonGetArrayEnd reads to ]
jsonGetObjectStart reads to }
They can also be used to test if the next non-blank is a specified delimiter
(since if it is not, zero will be returned)
IBM Software Group | Rational software
39
Parsing JSON text piecewise
The corresponding jsonPut-delimiter functions (jsonPutObjectStart, etc) are
all inlined with very simple code
These jsonGet delimiter functions are also inlined
But the code is a little less simple - essentially it is
use verify to find the first non-whitespace character
if none, return zero
else if the character matches the delimiter, return bytes scanned
else return zero
IBM Software Group | Rational software
40
Parsing JSON text piecewise
If you wanted to read a JSON object containing name-value pairs for a, b,
and c but assign values only to a and c, you could write this code
jsize = 0;
jsize += jsonGetObjectStart( addr(buffer)+jsize, length(buffer)-jsize );
jsize += jsonGetMember( addr(buffer)+jsize, length(buffer)-jsize, a );
jsize += jsonGetComma( addr(buffer)+jsize, length(buffer)-jsize );
jsize += jsonGetMember( addr(buffer)+jsize, length(buffer)-jsize ); /* only 2 args! */
jsize += jsonGetComma( addr(buffer)+jsize, length(buffer)-jsize );
jsize += jsonGetMember( addr(buffer)+jsize, length(buffer)-jsize, c );
jsize += jsonGetObjectEnd( addr(buffer)+jsize, length(buffer)-jsize );
IBM Software Group | Rational software
41
JSON
Recall this sample JSON text
{ "passes“ : 3,
"data“ :
[
{ "name“ : "Mather", "elevation“ : 12100 }
, { "name“ : "Pinchot", "elevation“ : 12130 }
, { "name“ : "Glenn", "elevation“ : 11940 }
]
}
Suppose it is in a buffer at address p and of length n
IBM Software Group | Rational software
42
JSON
Suppose we had a corresponding PL/I structure
dcl
1 info
2 passes fixed bin(31),
2 data(3),
3 name char(20) varying,
3 elevation fixed bin(31);
Then jsonGetValue( p, n, info ) will by itself fill in the whole structure
And this would work as long as hbound(data) >= 3
IBM Software Group | Rational software
43
JSON
But if the PL/I structure was
dcl
1 info based(q)
2 passes fixed bin(31),
2 data( count refer(passes) ),
3 name char(20) varying,
3 elevation fixed bin(31);
Then the structure could be dynamically assigned as follows
IBM Software Group | Rational software
44
JSON
With the first 2 arguments in every call omitted:
jsonGetObjectStart read over {
jsonGetValue read over “passes”
jsonGetColon read over :
jsonGetValue( count ) read 3 and assign to count
allocate info
jsonGetComma read over ,
jsonGetValue( info.data ) read “data” … and assign it
And it is even simpler if the names in the structure were flipped
IBM Software Group | Rational software
45
JSON
So if the PL/I structure was instead
dcl
1 info based(q)
2 count fixed bin(31),
2 data( passes refer(count) ),
3 name char(20) varying,
3 elevation fixed bin(31);
( now passes sets the REFER object )
IBM Software Group | Rational software
46
JSON
Two fewer built-in references are needed:
jsonGetObjectStart read over {
jsonGetMember( passes ) read “passes” : 3 and assign
allocate info
jsonGetComma read over ,
jsonGetValue( info.data ) read “data” … and assign it
And either way would work no matter how much whitespace was present
IBM Software Group | Rational software
47
Options for JSON
All the examples above used lower-case names in the JSON text
By PL/I default, these should all be upper-case
But the JSON( CASE( ASIS ) ) compiler option allows the names in
the JSON text to be mixed-case – as long as they match the names
as they were declared in the source code
IBM Software Group | Rational software
48
© Copyright IBM Corporation 2008. All rights reserved. The information contained in these materials is provided for informational purposes only, and is provided AS IS without warranty of any kind, express or implied. IBM shall not be responsible for any damages arising out of the use of, or otherwise related to, these materials. Nothing contained in these materials is intended to, nor shall have the effect of, creating any warranties or representations from IBM or its suppliers or licensors, or altering the terms and conditions of the applicable license agreement governing the use of IBM software. References in these materials to IBM products, programs, or services do not imply that they will be available in all countries in which IBM operates. Product release dates and/or capabilities referenced in these materials may change at any time at IBM’s sole discretion based on market opportunities or other factors, and are not intended to be a commitment to future product or feature availability in any way. IBM, the IBM logo, the on-demand business logo, Rational, the Rational logo, and other IBM products and services are trademarks of the International Business Machines Corporation, in the United States, other countries or both. Other company, product, or service names may be trademarks or service marks of others.
Learn more at:
IBM Rational software
IBM Rational Software Delivery Platform
Process and portfolio management
Change and release management
Quality management
Architecture management
Rational trial downloads
developerWorks Rational
IBM Rational TV
IBM Rational Business Partners