エンコード( = encode )とは日本語に直訳するとコード化することであるが
インターネットの TCP/IP 通信でのエンコードとは HEX コードを
%xx 形式で文字表現することを言う。
例えば 「 / 」という文字は ASCII では 0x2f であるのでこれを
%2F として表現する。
エンコードされた受け手はこれを元の 0x2f に戻す。
つまり文字「 / 」を再構築する。
エンコードとは何のためにするのかというと文字列の中にあって
ファイルの区切りなどの特殊な意味を持つコード( /、¥… )を
文字列として使用するときに特殊コードではない、ということを
処理するプログラムに知らせるためである。
URL に特殊文字が入力された場合はブラウザによって
エンコードされる。
しかし STRPCCMD に特殊文字が入力された場合は
エンコードされないので誤解されて誤動作の原因となる。
例えば CALL MY¥PGM という文字列は STRPCCMD で
確実にエラーとなってしまう。
このようなことを避けるためにエンコードが必要となる。
ついでに説明しておくと今は IBM i だけで完結する時代ではなく
ソースであっても PC にダウンロードしたりアップロードすることがある。
文字 ¥ は円という文字ではなく通貨記号であるので
PC にダウンロードすれば $ に変わることがある。
この逆もある。
IBM i の開発者は ¥、#、@ などの特殊記号を使いたがる傾向にあるが
特殊記号の使用は余計なトラブルを増やすだけに過ぎない。
特殊記号の使用は避けるほうが賢明である。
【 TOWATSON 】
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 プログラムで上位ビットや下位ビットを
調べたいときにその方法を示唆している。
