Chinaunix首页 | 论坛 | 博客
  • 博客访问: 303542
  • 博文数量: 40
  • 博客积分: 1
  • 博客等级: 民兵
  • 技术积分: 670
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-31 11:19
个人简介

从事银行核心系统设计开发的程序猿

文章存档

2019年(1)

2018年(4)

2017年(11)

2016年(6)

2015年(18)

分类: 信息化

2015-06-08 11:14:16

*用户空间USER SPACE的使用

用户空间USER SPACE,是AS400所提供进程间通讯的另一个机制,可以保存一块较大的持久化数据。常用的三大机制,DATA AREA在核心系统中用于控制参数的设置,例如批处理平台并发数控制,联机平台各种标志,以及全局内容在*LDA的跨PGM保存传递。DATA QUEUE可用于进程间传递消息数据,因核心系统设计上处理进程的隔离性而没有用到。USER SPACE则用于实现输出报文的灵活性,保存核心系统交易处理过程中,可能产生返回的凭证打印报文接口段。
USER SPACE最大长度可达16M,必须命名以持久化。由于在系统中用于暂存一笔联机交易需要返回的附加报文数据,因此对持久化其实没有要求,但性能要求很高,又不能互相影响。于是将USER SPACE建立在QTEMP中。这样不同JOB各自有一份使用,而且QTEMP数据系统应该是在内存中建立的,恰好符合要求。

那么程序中如何访问呢,可以看实际使用的例子。


创建USER SPACE,名称为QTEMP/JOBADDUS。

  1. PGM PARM(&SPCLEN)
  2. INCLUDE SRCMBR(CLHD) SRCFILE(DSCPPGM)
  3. DCL VAR(&PASSPCNM) TYPE(*CHAR) LEN(20)
  4. DCL VAR(&SPCATTR) TYPE(*CHAR) LEN(10)
  5. DCL VAR(&SPCLEN) TYPE(*UINT) LEN(4)
  6. DCL VAR(&SPCVALUE) TYPE(*CHAR) LEN(1)
  7. DCL VAR(&SPCAUTH) TYPE(*CHAR) LEN(10)
  8. DCL VAR(&SPCTEXT) TYPE(*CHAR) LEN(50)
  9. CHGVAR VAR(&PASSPCNM) VALUE('JOBADDUS QTEMP     ')
  10. CHGVAR VAR(&SPCAUTH) VALUE('*CHANGE')
  11. CHGVAR VAR(&SPCTEXT) VALUE('附加报文用户空间')
  12. CHGVAR VAR(&SPCVALUE) VALUE(X'00')
  13. CALL PGM(QUSCRTUS) PARM(&PASSPCNM &SPCATTR +
  14. &SPCLEN &SPCVALUE &SPCAUTH &SPCTEXT)
  15. MONMSG MSGID(CPF9870)
  16. ENDPGM


因为JOB结束时QTEMP自动释放,而JOB不结束的话USER SPACE可以重复使用,因此不需要人为去删除这个USER SPACE。


使用这个USER SPACE,会有两种情况。
一是交易运行过程中,产生需要附加的打印接口数据,这时候调用下面的程序记录进USER SPACE,注意,同时将已附加长度写进*LDA记录。另一种情况是组返回报文时,读取数据打包进报文,这个用的是后续的USER SPACE指针操作。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <arpa/inet.h>

  4. #include "dscppgm/cpyrgt_h"
  5. #include "config_h"
  6. #include "msginfo_h"
  7. #include "opdtaac_h"

  8. extern void JOBUSPTR(char **usptr);
  9. extern void fill_str(char *buf, const char *str, int len);
  10. extern int get_output_arrays_count(oa_otct*);
  11. extern int set_otlen(int len);

  12. /* parm1 MESG
  13.    parm2 ITNAME 10A
  14.    parm3 ITCNT 2B hostorder
  15.    parm4 ITPLEN 2B hostorder
  16.    parm5 ITBUF ITCNT*ITPLEN
  17. */
  18. int main(int argc, char **argv)
  19. {
  20.   oa_otct oa;
  21.   rpg_msg_info *rpginfo;
  22.   int olen, tlen;
  23.   unsigned short pcnt, plen, tmp;
  24.   char *obuf, *itbuf;
  25.   char *itnm;
  26.   char linebuf[LINENO_LEN+1];

  27.   if (argc<2)
  28.     return -1;
  29.   rpginfo=(rpg_msg_info *)argv[1];
  30.   if (argc!=6)
  31.   {
  32.     fill_str(rpginfo->msgflnm, __FILE__, FILENM_LEN);
  33.     sprintf(linebuf, "%6d", __LINE__);
  34.     fill_str(rpginfo->msgline, linebuf, LINENO_LEN);
  35.     fill_str(rpginfo->msgid, "EPLMNOPCK ", MSG_ID_LEN);
  36.     fill_str(rpginfo->msgtext, "组附加报文接口不正确", MSG_TEXT_LEN);
  37.     fill_str(rpginfo->msgotds, "", MSG_TEXT_LEN);
  38.     return -1;
  39.   }
  40.   itnm=argv[2];
  41.   pcnt=*(unsigned short *)argv[3];
  42.   plen=*(unsigned short *)argv[4];
  43.   itbuf=argv[5];

  44.   JOBUSPTR(&obuf);
  45.   get_output_arrays_count(&oa);
  46.   olen=oa.ot_len;
  47.   obuf += olen;

  48.   tlen = olen + ITNAME_SIZE + ITCNT_SIZE + ITPLEN_SIZE
  49.          + (pcnt==0 ? plen : pcnt*plen);
  50.   if (tlen > DAT_MAX_LEN)
  51.   {
  52.     char errbuf[MSG_TEXT_LEN];

  53.     fill_str(rpginfo->msgflnm, __FILE__, FILENM_LEN);
  54.     sprintf(linebuf, "%6d", __LINE__);
  55.     fill_str(rpginfo->msgline, linebuf, LINENO_LEN);
  56.     fill_str(rpginfo->msgid, "EPLMNOLEN ", MSG_ID_LEN);
  57.     sprintf(errbuf, "组附加报文时长度%d + %d超过最大长度%d",
  58.             olen, tlen-olen, DAT_MAX_LEN);
  59.     fill_str(rpginfo->msgtext, errbuf, MSG_TEXT_LEN);
  60.     fill_str(rpginfo->msgotds, "", MSG_TEXT_LEN);
  61.     return -1;
  62.   }

  63.   fill_str(obuf, itnm, ITNAME_SIZE);
  64.   obuf += ITNAME_SIZE;
  65.   tmp = htons(pcnt);
  66.   memcpy(obuf, &tmp, ITCNT_SIZE);
  67.   obuf += ITCNT_SIZE;
  68.   tmp = htons(plen);
  69.   memcpy(obuf, &tmp, ITPLEN_SIZE);
  70.   obuf += ITPLEN_SIZE;
  71.   memcpy(obuf, itbuf, pcnt==0 ? plen : pcnt*plen);

  72.   set_otlen(olen);
  73.   return tlen;
  74. }


这个程序将一个报文接口,以ITNAME接口名,ITCNT接口数组条数,ITLEN接口单条长度,ITBUF接口数据的方式,打包记录进USER SPACE。其中,JOBUSPTR用于获取USER SPACE的指针,然后就像普通内存一样操作。下面就是JOBUSPTR的程序。


  1. PGM PARM(&USPTR)
  2. INCLUDE SRCMBR(CLHD) SRCFILE(DSCPPGM)
  3. DCL VAR(&PASSPCNM) TYPE(*CHAR) LEN(20)
  4. DCL VAR(&USPTR) TYPE(*PTR)
  5. CHGVAR VAR(&PASSPCNM) VALUE('JOBADDUS QTEMP     ')
  6. CALL PGM(QUSPTRUS) PARM(&PASSPCNM &USPTR)
  7. ENDPGM


核心系统中的用法到此为止。实际上,USER SPACE相关的命令和调用有不少,修改内容的方式除了获取指针,还可以用QUSRTVUS获取USER SPACE内容,QUSCHGUS修改USER SPACE内容。这两个调用以字符串的形式操作。遗憾的是,CL对USER SPACE的支持较少,需要用到的话自己写程序扩充吧。


阅读(2212) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~