Xiao Qing
作者Xiao Qing·2022-11-16 15:54
系统工程师·浪潮商用机器有限公司

通过QDCSLATE API函数实现AS/400代码页转换

字数 4191阅读 6308评论 0赞 6

大家知道, AS/400 采用 EBCDIC(Extended Binary Coded Decimal Interchange Code) 字符集,而其他大多数异构平台使用 ASCII 字符集,如果 AS/400 要与其他异构平台进行网络通信,就需要进行字符集之间的转换,也就是人们常说的转码。

下图是 AS/400 EBCDIC code page 的例子。

AS/400 有很多种方法可以实现 EBCDIC 和 ASCII 之间的代码转换,其中 QDCSLATE API 是常用的方法,大家可以从下面 IBM 的官方网站找到其基本说明。

https://www.ibm.com/docs/en/i/7.4?topic=ssw_ibm_i_74/apis/QDCXLATE.html

QDCXLATE API 通过使用表对象来进行数据转换,如果你需要转换数据的大小写,可以使用 QLGCNVCS API 转换大小写 , 也可以使用同等的 QTBXLATE API 来实现同样的功能, QTBXLATE 的调用接口与转换数据( QDCXLATE )相同。

用户可以用 CRTTBL 命令为 QDCXLATE API 函数创建用于转换的转换表,也可以使用 IBM 提供的表。 IBM 提供的表可以在 QUSRSYS 库中找到。

当以参数 1 、 2 、 3 和 4 调用 QDCXLATE API 时,它将转换单字节数据。当所有参数都被指定时,进行 DBCS 转换。 QDCXLATE API 可以实现从 EBCDIC 到 ASCII 以及从 ASCII 到 EBCDIC 双字节和单字节字符的转换。

当只对单字节数据被转换时,输入(未转换的)数据会被转换后的数据取代。当双字节数据被转换时,转换后的数据被放在输出数据参数中。

QDCXLATE API 仅在转换单字节数据或 T.61 数据时是线程安全的, T.61 是 ITU-T( 国际电信联盟电信标准分局 ) 建议的 Teletex 字符集, 关于IBM i 上的 T.61 可以参考 https://www.ibm.com/docs/en/i/7.4?topic=sets-t61-graphic-character-conversions 网页所提供的内容。

QDCXLATE API 函数参数介绍:
必须参数

1Length of data being convertedInputPacked(5,0)
2Conversion dataI/OChar(*)
3SBCS conversion table name 注意: This parameter is ignored when the DBCS language parameter is set to BG5, KSC, SCGS J90X5026, J90X5035, or SCGBKInputChar(10)

可选参数

4SBCS conversion table library name 注意: This parameter is ignored when the DBCS language parameter is set to BG5, KSC, SCGS, J90X5026, J90X5035 or SCGBK.InputChar(10)
5Output dataOutputChar(*)
6Length of output bufferInputPacked(5,0)
7Length of converted dataOutputPacked(5,0)
8DBCS languageInputChar(10)
9Shift-out and shift-in characters 注意: Whether shift-out and shift-in characters should be inserted during the conversion. This parameter is ignored when the DBCS language parameter is set to BG5, KSC, SCGS, J90X5026, J90X5035 or SCGBK.InputChar(1)
10Type of conversion 注意: You are responsible for specifying the correct SBCS table name for the type of conversion being done by this DBCS request except when the DBCS language parameter is set to BG5, KSC, SCGS, J90X5026, J90X5035 or SCGBK.InputChar(10)

第八个参数 DBCS language 有 10 个可选项:

*JPNIBM Japanese graphic character set
*KORIBM Korean graphic character set
*CHSIBM Simplified Chinese graphic character set
*CHTIBM Traditional Chinese graphic character set
*BG5Taiwan industry standard graphic character set (BIG-5)
*KSCKorean industry standard graphic character set (KS)
*SCGSThe People's Republic of China National standard graphic character set (GB)
*J90X5026The Japanese JIS X 0208 1990 standard mapped using CCSID 5026.
*J90X5035The Japanese JIS X 0208 1990 standard mapped using CCSID 5035.
*SCGBKThe People's Republic of China National standard graphic character set extended (GBK)

下面通过一个例子来说明如何用函数实现 EBCDIC 和 ASCII 之间的代码转换。

/**********************************************/
/*  EBCDEC and ASCII converation        */
/*  QTBXLATE API                                  */
/*                                                              */
/*  Edited by Xiao Qing       2022/11        */
/**********************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <QDCXLATE.h>
#include <ctype.h>
 
#define TRUE         0
#define FALSE       -1
 
void main(void){
 
   int len, i;
 
   unsigned char ebcdic[1024];
 
   unsigned char ascii[1024];
 
   _Decimal(5,0)  cvted_len, out_len;
 
   _Decimal(5,0)  maxotl = 36;
 
   printf("** NLS convert testing **\\n");
 
   getchar();
 
   strcpy(ebcdic,"IPS");
 
   printf("EBCDIC characters and hex value of string are : \\n");
 
   len = strlen(ebcdic);
 
   for (i=0;i<len;i++){
     printf("ebcdic[%d] = 0x%02x %c\\n",i,ebcdic[i],ebcdic[i]);
   } 
 
   cvted_len = (_Decimal(5,0))len;
 
   QDCXLATE(&cvted_len, ebcdic, "QASCII    ", "QSYS      " ,ascii,
            &maxotl, &out_len, "*SCGBK    ", "Y", "*EA       ");
 
   printf("EBCDIC characters were converted to ASCII. \\n",ebcdic);
 
   len = (int)out_len;
 
   for(i = 0; i<len; i++){
     printf("ascii[%d] = 0x%02x\\n", i, ascii[i]);
   }
 
   getchar();
}

在 AS/400 命令行编译这个程序,然后执行。

执行结果

大家可以看到“ IPS ”这三个字符所对应的 EBCDIC 码是 0xc9 、 0xd7 、 0xe2 ,经过转码之后,“ IPS ”被换为 0x49 , 0x50 , 0x53 ,所对应的 ASCII 字符为“ I ”、“ P ”、“ S ”。
下图是ASCII编码一览表,大家可以进行参考对照 。

仅供参考

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

6

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

X社区推广