エンコード( = encode )とは日本語に直訳するとコード化することであるが
インターネットの TCP/IP 通信でのエンコードとは HEX コードを
%xx 形式で文字表現することを言う。
例えば 「 / 」という文字は ASCII では 0x2f であるのでこれを
%2F として表現する。
エンコードされた受け手はこれを元の 0x2f に戻す。
つまり文字「 / 」を再構築する。
エンコードとは何のためにするのかというと文字列の中にあって
ファイルの区切りなどの特殊な意味を持つコード( /、¥... )を
文字列として使用するときに特殊コードではない、ということを
処理するプログラムに知らせるためである。
URL に特殊文字が入力された場合はブラウザによって
エンコードされる。
しかし STRPCCMD に特殊文字が入力された場合は
エンコードされないので誤解されて誤動作の原因となる。
例えば CALL MY¥PGM という文字列は STRPCCMD で
確実にエラーとなってしまう。
このようなことを避けるためにエンコードが必要となる。
ついでに説明しておくと今は IBM i だけで完結する時代ではなく
ソースであっても PC にダウンロードしたりアップロードすることがある。
文字 ¥ は円という文字ではなく通貨記号であるので
PC にダウンロードすれば $ に変わることがある。
この逆もある。
IBM i の開発者は ¥、#、@ などの特殊記号を使いたがる傾向にあるが
特殊記号の使用は余計なトラブルを増やすだけに過ぎない。
特殊記号の使用は避けるほうが賢明である。
0001.00 H DFTNAME(TOWATSON) DATEDIT(*YMD/) BNDDIR('QC2LE') 0002.00 F********** 初めてのワトソン ****************************************** 0003.00 FTOWATSONFMCF E WORKSTN 0004.00 F********************************************************************** 0005.00 0006.00 * CRTRPGMOD OBJ(QTEMP/TOWATSON) SRCFILE(R610SRC/QRPGLESRC) 0007.00 * DBGVIEW(*SOURCE) AUT(*ALL) 0008.00 * CRTPGM PGM(QUATTRO/TOWATSON) MODULE(QTEMP/TOWATSON) 0009.00 * BNDSRVPGM(ASNET.COM/HTTPSRV) ACTGRP(*NEW) AUT(*ALL) 0010.00 0011.00 *-------------------------------------------------------------------* 0012.00 * 2017/05/01 : 作成 0013.00 *-------------------------------------------------------------------* 0014.00 *( 作業変数 ) 0015.00 D DCR S 1A DIM(15) CTDATA PERRCD(15) 0016.00 D AR S 1A DIM(256) 0017.00 D N S 4S 0 0018.00 D M S 4S 0 0019.00 D TRUE# S 4B 0 INZ(0) 0020.00 D FALSE# S 4B 0 INZ(-1) 0021.00 D NULL C CONST(X'00') 0022.00 0023.00 D DS 0024.00 D 1 10A INZ('enesfritja') 0025.00 D LANG 1 10A DIM(5) 0026.00 0027.00 D*( TRANSLATE のプロトタイプ宣言 ) 0028.00 D TRANSLATE PR 0029.00 D FROMLANG 2A VALUE 0030.00 D TOLANG 2A VALUE 0031.00 D FROMTXT 120A VALUE 0032.00 D TOTXT * VALUE 0033.00 0034.00 D*( ENCODE のプロトタイプ宣言 ) 0035.00 D ENCODE PR 1000A 0036.00 D FROMSTR 120A VALUE 0037.00 0038.00 D*( HTTP_REQUEST のプロトタイプ宣言 ) 0039.00 D HTTP_REQUEST PR 10I 0 0040.00 D URLPATH * VALUE 0041.00 D RTNVALUE * VALUE 0042.00 D RTNLEN * VALUE 0043.00 D MODE 10I 0 VALUE 0044.00 0045.00 C*( 明細画面 ) 0046.00 C*----------------------------------------------------+ 0047.00 C DSPLY TAG 0048.00 C EXFMT DSPDTA01 0049.00 C*----------------------------------------------------+ 0050.00 C SETOFF 99 0051.00 C*( CF03 )- 終了 0052.00 C *IN03 IFEQ *ON 0053.00 C SETON LR 0054.00 C LR RETURN 0055.00 C GOTO DSPLY 0056.00 C END 0057.00 C*( 実行キー ) 0058.00 C SETON 80 0059.00 C WRITE DSPDTA01 0060.00 C SETOFF 80 0061.00 /FREE 0062.00 TRANSLATE(LANG(FROMLG):LANG(TOLANG):FROMTXT:%ADDR(TOTXT)); 0063.00 /END-FREE 0064.00 C GOTO DSPLY 0065.00 C SETON LR 0066.00 C RETURN 0067.00 C****************************************************** 0068.00 C *INZSR BEGSR 0069.00 C****************************************************** 0070.00 C Z-ADD 1 FROMLG 0071.00 C Z-ADD 5 TOLANG 0072.00 C MOVEL(P) 'I アテ ア イナモ' FROMTXT 0073.00 C ENDSR 0074.00 C****************************************************** 0075.00 P TRANSLATE B EXPORT 0076.00 C****************************************************** 0077.00 D PI 0078.00 D FROMLANG 2A VALUE 0079.00 D TOLANG 2A VALUE 0080.00 D FROMTXT 120A VALUE 0081.00 D TOTEXT_P * VALUE 0082.00 0083.00 D STR1 S 1000A 0084.00 D STR2 S 1000A 0085.00 D RC S 10I 0 0086.00 D TOTEXT S 120A BASED(TOTEXT_P) 0087.00 0088.00 D TEXTBACK DS QUALIFIED 0089.00 D LEN 1 4S 0 0090.00 D DATA 5 260A 0091.00 0092.00 /FREE 0093.00 STR2 = ENCODE(%TRIMR(FROMTXT)); 0094.00 STR1 = *BLANKS; 0095.00 STR1 = 'https://watson-api-explorer.ng.bluemix.net/' + 0096.00 'language-translator/api/v2/translate?model_id=' + 0097.00 FROMLANG + '-' + TOLANG + '&text=' + STR2 + NULL; 0098.00 STR1 = %TRIMR(STR1); 0099.00 RC = HTTP_REQUEST(%ADDR(STR1): %ADDR(TEXTBACK.DATA): 0100.00 %ADDR(TEXTBACK.LEN): 1); 0101.00 IF (TEXTBACK.LEN > 0); 0102.00 TOTEXT = TEXTBACK.DATA; 0103.00 ELSE; 0104.00 TOTEXT = *BLANKS; 0105.00 ENDIF; 0106.00 RETURN; 0107.00 /END-FREE 0108.00 P E 0109.00 C****************************************************** 0110.00 P ENCODE B EXPORT 0111.00 C****************************************************** 0112.00 D PI 1000A 0113.00 D FROMSTR 120A VALUE 0114.00 0115.00 D TOSTR S 1000A 0116.00 D BUFLEN S 5P 0 0117.00 D STRING S 256A 0118.00 D N S 4S 0 0119.00 D POS S 4S 0 INZ(1) 0120.00 D AR S 1A DIM(256) 0121.00 D BR S 1A DIM(3) 0122.00 D FLD3 S 3A 0123.00 D UPPER S 1A 0124.00 D LOWER S 1A 0125.00 0126.00 D DS 0127.00 D CH01 1 1 INZ(X'00') 0128.00 D CH02 2 2 0129.00 D BIN4 1 2B 0 0130.00 0131.00 C FROMSTR CAT(P) NULL:0 STRING 0132.00 C EVAL BUFLEN = %LEN(%TRIMR(FROMSTR)) 0133.00 C*----------------------------------------------------+ 0134.00 C CALL 'QDCXLATE' 99 0135.00 C PARM BUFLEN 0136.00 C PARM STRING 0137.00 C PARM 'QASCII ' TBL 10 0138.00 C PARM 'QSYS ' TBLLIB 10 0139.00 C*----------------------------------------------------+ 0140.00 C MOVEA *BLANKS AR 0141.00 C MOVEA *BLANKS BR 0142.00 C EVAL BR(1) = '%' 0143.00 C 1 DO BUFLEN N 0144.00 C EVAL CH02 = %SUBST(STRING:N:1) 0145.00 C BIN4 DIV 16 BIN4 0146.00 C MVR AMARI 2 0 0147.00 *( 上位ビット ) 0148.00 C EVAL M = BIN4 0149.00 C MOVE DCR(M) UPPER 0150.00 *( 下位ビット ) 0151.00 C AMARI IFGT 0 0152.00 C Z-ADD AMARI BIN4 0153.00 C Z-ADD AMARI M 0154.00 C MOVE DCR(M) LOWER 0155.00 C ELSE 0156.00 C MOVE '0' LOWER 0157.00 C ENDIF 0158.00 * 0159.00 /FREE 0160.00 FLD3 = '%' + UPPER + LOWER; 0161.00 /END-FREE 0162.00 C MOVEA FLD3 AR(POS) 0163.00 C ADD 3 POS 0164.00 C ENDDO 0165.00 C MOVEA(P) AR TOSTR 0166.00 C TOSTR CAT NULL:0 TOSTR 0167.00 C EVAL TOSTR = %TRIMR(TOSTR) 0168.00 C RETURN TOSTR 0169.00 P E 0170.00 ** DCR - 以下は配列 0171.00 123456789ABCDEF
上記のソースのうちでエンコードは
0093.00 STR2 = ENCODE(%TRIMR(FROMTXT)); : 0109.00 C****************************************************** 0110.00 P ENCODE B EXPORT 0111.00 C****************************************************** 0112.00 D PI 1000A 0113.00 D FROMSTR 120A VALUE 0114.00 0115.00 D TOSTR S 1000A 0116.00 D BUFLEN S 5P 0 0117.00 D STRING S 256A 0118.00 D N S 4S 0 0119.00 D POS S 4S 0 INZ(1) 0120.00 D AR S 1A DIM(256) 0121.00 D BR S 1A DIM(3) 0122.00 D FLD3 S 3A 0123.00 D UPPER S 1A 0124.00 D LOWER S 1A 0125.00 0126.00 D DS 0127.00 D CH01 1 1 INZ(X'00') 0128.00 D CH02 2 2 0129.00 D BIN4 1 2B 0 0130.00 0131.00 C FROMSTR CAT(P) NULL:0 STRING 0132.00 C EVAL BUFLEN = %LEN(%TRIMR(FROMSTR)) 0133.00 C*----------------------------------------------------+ 0134.00 C CALL 'QDCXLATE' 99 0135.00 C PARM BUFLEN 0136.00 C PARM STRING 0137.00 C PARM 'QASCII ' TBL 10 0138.00 C PARM 'QSYS ' TBLLIB 10 0139.00 C*----------------------------------------------------+ 0140.00 C MOVEA *BLANKS AR 0141.00 C MOVEA *BLANKS BR 0142.00 C EVAL BR(1) = '%' 0143.00 C 1 DO BUFLEN N 0144.00 C EVAL CH02 = %SUBST(STRING:N:1) 0145.00 C BIN4 DIV 16 BIN4 0146.00 C MVR AMARI 2 0 0147.00 *( 上位ビット ) 0148.00 C EVAL M = BIN4 0149.00 C MOVE DCR(M) UPPER 0150.00 *( 下位ビット ) 0151.00 C AMARI IFGT 0 0152.00 C Z-ADD AMARI BIN4 0153.00 C Z-ADD AMARI M 0154.00 C MOVE DCR(M) LOWER 0155.00 C ELSE 0156.00 C MOVE '0' LOWER 0157.00 C ENDIF 0158.00 * 0159.00 /FREE 0160.00 FLD3 = '%' + UPPER + LOWER; 0161.00 /END-FREE 0162.00 C MOVEA FLD3 AR(POS) 0163.00 C ADD 3 POS 0164.00 C ENDDO 0165.00 C MOVEA(P) AR TOSTR 0166.00 C TOSTR CAT NULL:0 TOSTR 0167.00 C EVAL TOSTR = %TRIMR(TOSTR) 0168.00 C RETURN TOSTR 0169.00 P E 0170.00 ** DCR - 以下は配列 0171.00 123456789ABCDEF
の部分である。
まず入力された FROMSTR に NULL を追加して
API : QDCXLATE によって ASCII コードに STRING という変数に変換する。
戻された長さ BUFLEN の長さの分だけ LOOP して STRING より 1 バイトずつ
CH02 として取り出す。
CH02 は次のように BIN4 の一部として定義されている。
0126.00 D DS 0127.00 D CH01 1 1 INZ(X'00') 0128.00 D CH02 2 2 0129.00 D BIN4 1 2B 0
つまり CH02 がもし X'2F' であれば BIN4 は X'002F' となる。
そこで
0145.00 C BIN4 DIV 16 BIN4 0146.00 C MVR AMARI 2 0
として BIN4 を 16 ( =X'10' )で割り算すると
BIN4 = 2 で余りは AMARI = X'0F'( 15 ) となる。
配列 DCR は
0015.00 D DCR S 1A DIM(15) CTDATA PERRCD(15) : 0170.00 ** DCR - 以下は配列 0171.00 123456789ABCDEF
として定義されているので DCR( M ) が 求める値となる。
( M は BIN4 または AMARI )
ENCODE はプロシージャーとして定義されているので
いろいろな上位プログラムから呼び出して使うことができる。
この ENCODE プロシージャーは RPG プログラムで上位ビットや下位ビットを
調べたいときにその方法を示唆している。