JSONPUTVALUE 関数

目的

JSON テキストに値を UTF-8 として追加します。

構文

JSONPUTVALUE(p,l[,v])

パラメーター

p
JSON テキスト バッファーのアドレスを指定するポインター。
l
JSON テキスト バッファーの長さをバイト単位で指定します。
v
PL/I 変数への参照。スカラー変数、配列変数、構造体変数、またはそれらの組み合わせを指定できます。構造体変数を指定する場合は、名前が * の要素、UNION 属性または GRAPHIC 属性を持つ要素、スケールを指定済みの FIXED BINARY である要素、あるいは FIXED DECIMAL (p, q) (q < 0 または q > p) である要素が含まれていてはなりません。

説明

JSONPUTVALUE は、値 (名前と値のペアの値) を UTF-8 にエンコードしてバッファーに書き込みます (十分なスペースがある場合)。成功すると、書き込まれたバイト数が返されます。値とは何かについては、JSONGETVALUE の説明を参照してください。

JSON テキスト バッファーに値を格納するための十分なスペースがない場合は、エラー状態が発生します。ONCODE 組み込み関数を使用すると、エラー状態が発生した理由を確認できます。ONSUBCODE 組み込み関数を使用すると、書き込まれたバイト数が示されます。実際に書き込まれるバイト数は、<= l (2 番目の引数) になります。

さまざまな JSON 組み込み関数を使用する完全なプログラムについては、JSONPUTVALUE の最後の例を参照してください。

例 1:

Dcl Array(5) fixed bin(31) init(1, 2, 3, 4, 5); である場合に bytes = jsonputvalue (bufp, bufl, Array);

を実行すると、次の UTF-8 テキストがバッファーの先頭に書き込まれます。[1,2,3,4,5] (空白文字は含まれない)

例 2:

Dcl Towns fixed bin(31) init(6); である場合に bytes = jsonputvalue(bufp, bufl, Towns); を実行すると、次の UTF-8 テキストがバッファーの先頭に書き込まれます。 6

例 3:

次の宣言があったとします。

dcl 1 S3,
       2 fd(2),
         3 d2 fixed bin(15) init(2, 4),
         3 d5 fixed dec(7) init(5, 9);

この場合、bytes = jsonputvalue (bufp, bufl, Array); を実行すると、次の UTF-8 テキストがバッファーの先頭に書き込まれます。{"FD":[{"D2":2,"D5":5},{"D2":4,"D5":9}]}

例 4:

以下にある例 5 の完全なプログラムを使用すると、次のことがわかります。

  • get_n_list プロシージャは、調整可能な構造体 (REFER オプションを含む) を読み取ります。Towns は任意の数にすることができ、同じコードでオブジェクト全体を読み取ることもできます。
  • put プロシージャは、さまざまな JSON 組み込み関数を使用して、オブジェクトを少しずつ読み取っては再作成します。新たに作成されたオブジェクトは、get_n_list を使用して再度読み取られます。新しい構造体が割り当てられます。
  • 新たに作成され、再度読み取られたオブジェクトは、元のオブジェクトと事実上同じです。このオブジェクトがさらに、bytes = jsonputvalue(bufp, buf_size, Unusual_Town_Names) という 1 つの JSON 組み込み関数呼び出しのみを使用して再作成されます。
  • この新たに作成されたオブジェクトが、次の 1 つの JSON 組み込み関数呼び出しのみを使用して再度読み取られます。 bytes = jsonputmember(bufp, buf_size, Unusual_Town_Names);

例 5:

以下のサンプルは説明のためのものです。実際のソース コードは、製品インストール ディレクトリの src フォルダーにあります。

package: package exports(*);
 zzyzx: proc options(main);
 %replace buf_size by 500;
 dcl txt                             char(120) var;
 dcl (Towns, bufl, bytes, ix)        fixed bin(31);
 dcl (bufp, Unusual_Town_Names_ptr)  ptr;
 dcl (buf, bufe)                     char(buf_size) var;
 dcl err                             char(20);
 dcl charvar_len                     fixed bin(15) based;
 dcl 1 * union static,
       3 *                           fixed bin(15) init(1),
       3 *,
         5 *                         char,
         5 big                       char;
 dcl 1 Unusual_Town_Names            based(Unusual_Town_Names_ptr),
       3 No_of_Towns                 fixed bin(31),
       3 Details(Towns refer(No_of_Towns)),
         5 No                        fixed bin(31),
         5 Name                      char(30) varying,
         5 Place                     char(30) varying,
         5 Really                    bit;

 on error
   begin;
     on error system;
     put skip list('Bytes read=' || bytes, ' oncode=' ||
           trim(oncode()) || ' onsubcode=' || trim(onsubcode()));
     if onsubcode() ^= 0 then
       do;
         put skip list('JSON object invalid at pos ' ||
                        trim(onsubcode));
         put skip list('<V---+----10---+----2>');
         err = substr(buf, onsubcode());
         if 'a' = 'a'e then
           call pliebcdic(addr(err), addr(err), length(err));
         put skip list('<' || err || '>');
       end;
     put skip list('bufl=', length(buf));
   end;

 if 'a'  = 'a'e  then put skip list('Running EBCDIC,');
                 else put skip list('Running ASCII,');
 if big ^= '00'x then    put list(' Bigendian.');
                 else    put list(' Littleendian.');
 bufe =
 '{ "Towns": 6,
    "Details" :
    [
     { "No": 1, "Name": "Accident","Place": "Maryland", "Really":true},
     { "No": 2, "Name": "Boring",  "Place": "Oregon",  "Really": true},
     { "No": 3, "Name": "Dull",    "Place": "Scotland","Really": true},
     { "No": 4, "Name": "Noplace", "Place": "England","Really": false},
     { "No": 5, "Name": "Why",     "Place": "Arizona", "Really": true},
     { "No": 6, "Name": "Zzyzx",   "Place":"California","Really":true}
    ]
   }';
 buf   = utf8(bufe);
 bufp  = addrdata(buf);
 bufl  = length(buf);
 bytes = jsonvalid(bufp, bufl);
 if bytes ^= 0 then
   do;
     put skip list("Original JSON invalid at pos " || trim(bytes));
     put skip list('<V---+----10---+----2>');
     err = substr(buf, bytes);
     put skip list('<' || err || '>');
   end;
 else
   put skip list("Original JSON object is valid.");

 /*===================================================================*/
 /* Let's read the JSON object and populate Unusual_Town_Names        */
 /* structure, then create the JSON object again. After "call put",   */
 /* newly created JSON object should have exectaly the same content   */
 /* as the original except that all blanks will have been removed     */
 /*===================================================================*/
 call get_n_list;

 put skip list((70)'*');
 put skip list('Using BUILTINs jsonput/get functions ...');
 call put;

 bytes = jsonvalid(bufp, bufl);
 if bytes ^= 0 then
   do;
     put skip list("Newly created JSON invalid at pos " || trim(bytes));
     put skip list('<V---+----10---+----2>');
     err = substr(buf, bytes);
     if 'a' = 'a'e then
       call pliebcdic(addr(err), addr(err), length(err));
     put skip list('<' || err || '>');
   end;
 else
   put skip list("Newly created JSON object is valid.");

 /*===================================================================*/
 /* If all goes well, we should be able ot read it again              */
 /*===================================================================*/
 call get_n_list;

 /*===================================================================*/
 /* We can re-create the entire object with just BUILTIN invocation   */
 /*===================================================================*/
 put skip list((70)'*');
 put skip list('Using BUILTINs jsonput/get VALUE ...');
 bytes = jsonputvalue(bufp, buf_size, Unusual_Town_Names);
 addr(buf)->charvar_len = bytes;
 bufl  = length(buf);
 put skip list('Bytes Written=' || trim(bytes));
 /*===================================================================*/
 /* ... read the entire object with just one BUILTIN invocation       */
 /*===================================================================*/
 bytes = jsongetvalue(bufp, bufl, Unusual_Town_Names);
 put skip;
 put skip list('Bytes Read=' || trim(bytes) ||
               ' Buffer Length=' || trim(bufl));

 /*===================================================================*/
 /* We can re-create the entire object with just BUILTIN invocation   */
 /* but with inclusion of the top lebel name                          */
 /*===================================================================*/
 put skip list((70)'*');
 put skip list('Using BUILTINs jsonput/get MEMBER ...');
 bytes = jsonputmember(bufp, buf_size, Unusual_Town_Names);
 addr(buf)->charvar_len = bytes;
 bufl  = length(buf);
 put skip list('Bytes Written=' || trim(bytes));
 /*===================================================================*/
 /* ... read the entire object with just one BUILTIN invocation       */
 /* but with inclusion of the top lebel name                          */
 /*===================================================================*/
 bytes = jsongetmember(bufp, bufl, Unusual_Town_Names);
 put skip;
 put skip list('Bytes Read=' || trim(bytes) ||
               ' Buffer Length=' || trim(bufl));

 put skip list((70)'*');
 put skip list('Done with the tests.');

 /*===================================================================*/
 get_n_list:proc;
   bytes  = jsongetobjectstart(bufp,       bufl        );
   bytes += jsongetmember(bufp + bytes,    bufl - bytes, Towns);
   allocate Unusual_Town_Names;
   bytes += jsongetcomma (bufp + bytes,    bufl - bytes);
   bytes += jsongetmember(bufp + bytes,    bufl - bytes, Details);
   bytes += jsongetobjectend(bufp + bytes, bufl - bytes);
   do ix = 1 to towns;
     txt = trim(no(ix)) || ' is ' || name(ix)  || ', ' ||
                                     place(ix) || '. ';
     if really(ix) then
       txt ||= "Yes it's true.";
     else
       txt ||= "It's false!.";
     put skip list(txt);
   end;
   put skip;
   put skip list('Bytes Read=' || trim(bytes) ||
                 ' Buffer Length=' || trim(bufl));
 end get_n_list;

 /*===================================================================*/
 put:proc;
   bytes  = jsonputobjectstart(bufp,    buf_size              );
   bytes += jsonputmember(bufp + bytes, buf_size - bytes, Towns);
   bytes += jsonputcomma(bufp + bytes, buf_size - bytes);
   bytes += jsonputmember(bufp + bytes, buf_size - bytes, Details);
   bytes += jsonputobjectend(bufp + bytes, buf_size - bytes);
   addr(buf)->charvar_len = bytes;
   bufl  = length(buf);
   put skip list('Bytes Written=' || trim(bytes));
   put skip;
 end put;

 end zzyzx;
 end package;

制約事項

多次元配列はサポートされていません。