home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
gened10.zip
/
SAMPLE2.C
< prev
next >
Wrap
Text File
|
1996-04-03
|
33KB
|
906 lines
/*
* Created 1993 IBM Corp. *
* *
* DISCLAIMER OF WARRANTIES. The following [enclosed] code is *
* sample code created by IBM Corporation. This sample code is not *
* part of any standard or IBM product and is provided to you solely *
* for the purpose of assisting you in the development of your *
* applications. The code is provided "AS IS", without *
* warranty of any kind. IBM shall not be liable for any damages *
* arising out of your use of the sample code, even if they have been *
* advised of the possibility of such damages. *
*/
/**************************************************************************
* encode/decode sample program for TEST2.ASN. It uses:
* - the encoding user exit
* - the GDS tree pointers-array
* - the BER type of encoding (with definite length form)
* - content user-exits for some fields
*
* ARGUMENTS:
* 1. the path and name of the .DAT file
* 2. the input buffer length
* 3. the output buffer length
*
* This program encodes and decodes a data stream on the basis of TEST2.ASN
* definitions. The data stream is written/read in/from the file: STREAM4.OUT.
* Two traces file are generated:
* 1.enctrace4.out, for the trace of the encoded GDS tree
* 2.dectrace4.out, for the trace of the decoded GDS tree
**************************************************************************
*/
/*
* The following are needed to compile this program. Note that the
* order of the header files is important.
*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "gdstypes.h"
#include "gdsrcods.h"
#include "gdsproto.h"
#include "sample2.h"
#include "test2ndx.h"
main(int argc, char **argv)
{
int rc;
char savmodname[50], *ModName, *out_buff, *in_buff, alldata;
unsigned long EncBytes; /* number of encoded bytes */
unsigned long DecBytes; /* number of decoded bytes */
unsigned long inbuflen; /* input buffer length (bytes) */
unsigned long outbuflen; /* output buffer length (bytes) */
unsigned short Typ; /* type index */
void *Mod; /* module pointer */
void *env; /* environment pointer */
struct gds *p1; /* GDS structure tree pointer */
struct usrpstruct usrp; /* user parms */
enum TypOfEnc enctype; /* encoding type */
FILE *trace_enc; /* file for encoded GDS tree trace */
FILE *trace_dec; /* file for decoded GDS tree trace */
FILE *EncStream; /* output file */
FILE *usrdecfile; /* user-exit decoding routine output
* file */
/*
* check if the number of arguments is correct
*/
if (argc < 4) {
exit(0);
}
/*
* set the type of encoding
*/
enctype = ber;
inbuflen = atol(argv[2]); /* set the length of the input buffer */
outbuflen = atol(argv[3]); /* set the length of output buffer */
/*
* open the trace file for the encoded gds tree
*/
trace_enc = fopen("enctrace4.out","w");
if (trace_enc == NULL) { /* open file failed */
printf("open enc trace file failed\n");
exit(-1);
} /* endif */
/*
* open the trace file for the decoded gds tree
*/
trace_dec = fopen("dectrace4.out","w");
if (trace_dec == NULL) { /* open file failed */
printf("open dec trace file failed\n");
exit(-1);
} /* endif */
/*
* open the input/output file that will contain the encoded data stream
*/
EncStream = fopen("stream4.out","wb");
if (EncStream == NULL) { /* open file failed */
printf("open input/output file failed\n");
exit(-1);
} /* endif */
/****************************
* INITIALIZE the environment
****************************
*/
/*
* Call the library routine, GDSinitEnvironment, to initialize the environment.
* Each application program has to do this before calling any routine to
* read .dat files, encode or decode GDSs.
*/
GDSinitEnvironment(&env); /* initialize environment for modules */
/*
* Call the library routine, GDSreaddatfile, to read a .dat file containing
* the metatables and symbol tables for one or more ASN.1 module. Note that
* references between ASN.1 modules (imported and exported symbols) are *not*
* resolved by GDSreaddatfile.
*/
rc = GDSreaddatfile(argv[1], env); /* first parm should be a readable data
* file */
if (rc != READ_DAT_OK) {
printf("GDSreaddatfile return code: %i\n", rc);
exit(rc);
}
/*
* Call the library routine, GDSsetUsrWrite, to set the user exit routine for
* writing buffer.
*/
GDSsetUsrWrite(mywrite, env);
/*
* Call the library routine, GDSsetUsrRead, to set the user exit routine for
* reading buffer.
*/
GDSsetUsrRead(myread, env);
/*
* Call the library routine, GDSsetUsrEnc, to set the user exit routine for
* encoding. In this program, it is set to encMIU the first time. However,
* it is called many times later, to change the encoding routine.
*/
GDSsetUsrEnc(encMIU, env);
/*
* Call the library routine, GDSfindmodule, to find the moddef structure
* corresponding to the "Miu" module.
*/
Mod = GDSfindmodule("Miu", env);
if (Mod == NULL) { /* if module not found */
printf("\nModule not found\n");
exit(-1);
}
printf("\nInitialization OK\n");
/****************************
* ENCODING
****************************
*/
printf("\nStart Encoding\n");
usrp.env = env; /* set the user parm */
Typ = Miu_MIU; /* the type to be encoded */
/*
* Call the library routine, GDSencode, to create one or more GDS structures
* that represent a value for Mod.Typ. The user encode exit is called
* during this process to provide the necessary values for the
* ASN.1 type. The last parm is the address of a structure with data
* to be passed to the user encode exit. Applications
* use this to pass local parameters to the user encode routine. This is
* useful when the the User Application Program (this routine) and the exit
* routine must share data.
*
* Note that the GDSencode function does *not* create the BER encoded
* data. The GDS structures contain the information needed to
* encode the data, but the actual encoding is a secondary step. This
* allows other encoding techniques besides BER to be used. The
* log component of the GDS structure is computed by GDSencode assuming
* BER rules (this is a slight optimization that prevents traversing
* the GDS structure tree another time); if GDSencber is not used to encode
* the data, the log component should not be used.
*/
rc = GDSencode(Mod, /* moddef module where type occurs */
&Typ, /* metatable index where type occurs */
NULL, /* pointer to Contents Array, not used */
&p1, /* returned GDS structure */
enctype, /* type of encoding */
env, /* environment */
&usrp /* parms to pass to the user encode
* routine */
);
if (rc != ENCODE_MATCH) { /* if the encoding failed */
printf("\nGDSencode return code: %i\n", rc);
printf("\nmetatable type index where error occurred: %i\n", Typ);
exit(rc);
} /* endif */
/*
* Call the library routine, GDSencber, to encode the GDS structure tree
* using BER rules.
*/
rc = GDSencber(&p1, /* the GDS structure tree to be encoded */
outbuflen, /* the length of the output buffer */
&out_buff, /* output buffer pointer */
&EncBytes, /* the number of encoded bytes */
0, /* definite length form */
env, /* environment */
(void *) EncStream /* pointer to the output file. It will
* be passed by GDSencber to the writing
* user-exit */
);
if (rc != ENCBER_OK) { /* if encoding was unsuccessful */
printf("\nGDSencber return code: %i\n", rc);
printf("module name: %s\n", p1->modname);
printf("type name: %s\n", p1->name);
GDSfreegds(p1, env); /* reclaim space for encoded GDS struct */
exit(rc);
} /* endif */
printf("\nnumber of encoded bytes: %lu\n", EncBytes);
/*
* Call the library routine, GDSprintgds, to print the encoded GDS
* structure and its contents.
*/
rc = GDSprintgds(p1, /* ptr to root GDS structure */
0, /* number of spaces to indent */
300, /* max content length */
80, /* number of characters for row */
trace_enc, /* gds tree trace file */
enctype /* type of encoding */
);
if (rc != PRINT_GDS_OK) { /* if the printing failed */
printf("\nGDSprintgds return code: %i\n", rc);
GDSfreegds(p1, env); /* reclaim space for encoded GDS struct */
exit(rc);
} /* endif */
fclose(trace_enc); /* close the trace file */
fclose(EncStream);
if (out_buff != NULL) free(out_buff);
EncStream = fopen("stream4.out","rb"); /* reopen the file for reading */
if (EncStream == NULL) { /* open file failed */
printf("\nopen input/output file failed\n");
exit(-1);
} /* endif */
/*
* Call the library routine, GDSfreegds, to reclaim the storage occupied by
* the GDS structures headed by p1 which are marked as allocated. Note
* that some GDSs may be marked as static, which prevents them from
* being freed.
*/
GDSfreegds(p1, env);
printf("\nEnd Encoding\n");
/****************************
* DECODING
****************************
*/
printf("\nStart Decoding\n");
/*
* Call the library routine, GDSdecber, to decode encoded data in the
* buffer we just built. The result should be a tree of GDS structures
* topped by p1 which matches the original structure created by the
* encode library routine.
*/
alldata = 0;
in_buff = &alldata;
rc = GDSdecber(&p1, /* pointer to the root of the GDS tree */
inbuflen, /* the length of the input buffer */
&DecBytes, /* number of decoded bytes */
&in_buff, /* data buffered indicator */
env, /* environment */
(void *) EncStream /* pointer to the input file. It will
* be passed by GDSdecber to the writing
* user-exit */
);
if (rc != DECBER_OK) { /* if decoding failed */
printf("\nGDSdecber return code: %i\n", rc);
printf("\nnumber of decoded bytes: %u\n", DecBytes);
GDSfreegds(p1, env); /* reclaim space for encoded GDS struct */
exit(rc);
}
printf("\nnumber of decoded bytes: %u\n", DecBytes);
/*
* Call the library routine, GDSprintgds, to print the structure and
* content of the decoded GDS. At this point, before GDSdecode call,
* the GDS structure tree is missing of some information (names,
* base types...) and it is not matched with the ASN.1 type.
*/
rc = GDSprintgds(p1, /* ptr to root GDS structure */
0, /* number of spaces to indent */
300, /* max content length */
80, /* number of characters for row */
trace_dec, /* gds tree trace file */
enctype /* type of encoding */
);
if (rc != PRINT_GDS_OK) { /* if the printing failed */
printf("\nGDSprintgds return code: %i\n", rc);
GDSfreegds(p1, env); /* reclaim space for encoded GDS struct */
exit(rc);
} /* endif */
/*
* Call the library routine, GDSdecode, to match the GDS structure tree
* created by GDSdecber with the ASN.1 type referenced by Mod and Typ.
* If successful, the GDS structures will have name information set.
*/
Typ = Miu_MIU; /* the type to be decoded */
rc = GDSdecode(Mod, /* module where type occurs */
&Typ, /* Metatable index where type occurs */
&p1, /* root of GDS structure tree */
NULL, /* pointer to the GDS tree pointers array */
env, /* environment */
NULL /* user parms, not used in this case */
);
if (rc != DECODE_MATCH) { /* if decoding didn't go ok */
printf("\nGDSdecode return code: %i\n", rc);
printf("Metatable type index where error occurred: %i\n", Typ);
printf("module name: %s\n", p1->modname);
printf("type name: %s\n", p1->name);
GDSfreegds(p1, env); /* reclaim space for encoded GDS struct */
exit(rc);
} /* endif */
/*
* Call the library routine, GDSprintgds, to print the structure and
* content of the decoded GDS tree.
*/
rc = GDSprintgds(p1, /* ptr to root GDS structure */
0, /* number of spaces to indent */
300, /* max content length */
80, /* number of characters for row */
trace_dec, /* gds tree trace file */
enctype /* type of encoding */
);
if (rc != PRINT_GDS_OK) { /* if the printing failed */
printf("\nGDSprintgds return code: %i\n", rc);
GDSfreegds(p1, env);
exit(rc);
} /* endif */
fclose(EncStream);
/*
* Call the library routine to free the GDS structures in the tree rooted
* by *p1.
*/
GDSfreegds(p1, env);
printf("\nEnd Decoding\n");
/****************************
* CLEAN UP the environment
****************************
*/
/*
* Clean up the environment by unloading all modules by calling
* GDSunloadmodule for each module in the environment. NOTE:
* the GDSunloadmodule function should only be called for modules which
* were loaded by the GDSreaddatfile function or which have allocated
* storage in the heap like the GDSreaddatfile function.
*/
for (GDSfirstmodule(&Mod, &ModName, env); Mod != NULL;
GDSfirstmodule(&Mod, &ModName, env)) {
GDSunloadmodule(Mod, env);
} /* endfor */
/*
* Call the library routine GDSfreeEnvironment to free the storage
* allocated for the current environment
*/
GDSfreeEnvironment(env);
return 0;
} /* end main */
/*
* writing user-exit
*/
unsigned long mywrite(char *buf, unsigned long buflen, void *usrparms)
{
FILE *EncStream;
EncStream = (FILE *) usrparms;
return (unsigned long) (fwrite(buf,sizeof(unsigned char),buflen,EncStream));
}
/*
* reading user-exit
*/
unsigned long myread(char *buf, unsigned long buflen, void *usrparms)
{
FILE *EncStream;
EncStream = (FILE *) usrparms;
return (unsigned long) (fread(buf,sizeof(unsigned char),buflen,EncStream));
}
/*
* encMIU encoding user exit, the first to be called
*/
int
encMIU(struct encinh ia, /* inherited attrs */
struct encinhsyn *sa, /* synthesized and inherited attrs */
enum tagclass cls, /* class of item to encode */
long id, /* id of class to encode */
enum frm form, /* form (prim or constr) of data to encode */
char *encsubs /* set to !0 to encode contained types */
)
{
int rc;
struct usrpstruct *usrparms;
rc = ENCODE_MATCH;
usrparms = (struct usrpstruct *) ia.usrparms;
*encsubs = 1; /* encode contained types */
switch (sa->ndx) {
case Miu_MIU_SEQUENCE:
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, NULL, 0L, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
break;
case Miu_ALH:
GDSsetUsrEnc(encALH, usrparms->env); /* set the encoding user-exit for ALH */
break;
case Miu_RSH:
GDSsetUsrEnc(encRSH, usrparms->env); /* set the encoding user-exit for RSH */
break;
case Miu_CSH:
rc = ENCODE_NO_MATCH; /* don't encode CSH */
break;
case Miu_AGD:
GDSsetUsrEnc(encAGD, usrparms->env); /* set the encoding user-exit for AGD */
break;
case Miu_APD:
rc = ENCODE_NO_MATCH; /* don't encode APD */
break;
} /* endswitch */
return rc;
} /* end encMIU */
/*
* encALH encoding user exit, for ALH type
*/
int
encALH(struct encinh ia, /* inherited attrs */
struct encinhsyn *sa, /* synthesized and inherited attrs */
enum tagclass cls, /* class of item to encode */
long id, /* id of class to encode */
enum frm form, /* form (prim or constr) of data to encode */
char *encsubs /* set to !0 to encode contained types */
)
{
int rc;
char *contents;
static int pass = 0;
struct usrpstruct *usrparms;
usrparms = (struct usrpstruct *) ia.usrparms;
*encsubs = 1; /* encode contained types */
rc = ENCODE_MATCH;
contents = NEW(char);
switch (sa->ndx) {
case Miu_ALH_SEQUENCE:
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, NULL, 0L, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
break;
case Miu_BYTES_OCTET_STRING:
if (pass) /* globalcsid: 'BB'H */
GDSstr2hex(contents, 1, "BB", 2);
else /* archlevel: 'AA'H */
GDSstr2hex(contents, 1, "AA", 2);
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, contents, 1L, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
pass++;
break;
default:
break;
} /* endswitch */
return rc;
} /* encALH */
/*
* encRSH encoding user exit, for RSH type
*/
int
encRSH(struct encinh ia, /* inherited attrs */
struct encinhsyn *sa, /* synthesized and inherited attrs */
enum tagclass cls, /* class of item to encode */
long id, /* id of class to encode */
enum frm form, /* form (prim or constr) of data to encode */
char *encsubs /* set to !0 to encode contained types */
)
{
int rc;
char *contents;
static int pass = 0;
struct usrpstruct *usrparms;
usrparms = (struct usrpstruct *) ia.usrparms;
*encsubs = 1; /* encode contained types */
rc = ENCODE_MATCH;
contents = NEW(char);
switch (sa->ndx) {
case Miu_RSH_SEQUENCE:
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, NULL, 0L, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
break;
case Miu_BYTES_OCTET_STRING:
switch(pass) {
case 0: /* msflags: '00'H */
GDSstr2hex(contents, 1, "00", 2);
break;
case 1: /* ssflags: '01'H */
GDSstr2hex(contents, 1, "01", 2);
break;
case 2: /* mshopcount: '02'H */
GDSstr2hex(contents, 1, "02", 2);
break;
case 3: /* swhopcount: */
rc = ENCODE_NO_MATCH; /* don't encode it */
break;
} /* endswitch */
if (rc == ENCODE_MATCH) {
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, contents, 1L, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
} /* endif */
pass++;
break;
case Miu_MSGCLASS:
GDSsetUsrEnc(encMSGCLASS, usrparms->env); /* set encoding user-exit for MSGCLASS */
break;
case Miu_NAPS:
GDSsetUsrEnc(encDESTNAPS, usrparms->env); /* set the encoding user-exit for DESTNAPS */
break;
case Miu_AGENT:
rc = ENCODE_NO_MATCH; /* don't encode MONITORAGENT */
break;
default:
break;
} /* endswitch */
return rc;
} /* encRSH */
/*
* encAGD encoding user exit, for AGD
*/
int
encAGD(struct encinh ia, /* inherited attrs */
struct encinhsyn *sa, /* synthesized and inherited attrs */
enum tagclass cls, /* class of item to encode */
long id, /* id of class to encode */
enum frm form, /* form (prim or constr) of data to encode */
char *encsubs /* set to !0 to encode contained types */
)
{
int rc;
char *contents;
static int pass = 0;
struct usrpstruct *usrparms;
usrparms = (struct usrpstruct *) ia.usrparms;
*encsubs = 1; /* encode contained types */
rc = ENCODE_MATCH;
contents = NEW2(8, char);
switch (sa->ndx) {
case Miu_AGD_SEQUENCE:
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, NULL, 0L, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
break;
case Miu_BYTES_OCTET_STRING:
if (!pass) { /* mapname: '0011223344'H */
GDSstr2hex(contents, 5, "0011223344", 10);
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, contents, 5L, allocd, NULL, usrparms->env);
} else { /* agentdata: 'AA'H */
/* use the agentdata_cont user-exit */
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, NULL, 5000L, allocd, agentdata_cont, usrparms->env);
} /* endif */
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
pass++;
break;
default:
break;
} /* endswitch */
return rc;
} /* encAGD */
/*
* encMSGCLASS encoding user exit, for MSGCLASS
*/
int
encMSGCLASS(struct encinh ia, /* inherited attrs */
struct encinhsyn *sa, /* synthesized and inherited attrs */
enum tagclass cls, /* class of item to encode */
long id, /* id of class to encode */
enum frm form, /* form (prim or constr) of data to encode */
char *encsubs /* set to !0 to encode contained types */
)
{
int rc;
char *contents;
static int pass = 0;
int contlen;
struct usrpstruct *usrparms;
usrparms = (struct usrpstruct *) ia.usrparms;
*encsubs = 1; /* encode contained types */
rc = ENCODE_MATCH;
contents = NEW2(8, char);
switch (sa->ndx) {
case Miu_NAME8_SEQUENCE:
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, NULL, 0L, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
break;
case Miu_BYTES_OCTET_STRING:
switch(pass) {
case 0: /* nametype: '001122'H */
GDSstr2hex(contents, 3, "001122", 6);
contlen = 3;
break;
case 1: /* namestring: '0011223344556677'H */
GDSstr2hex(contents, 8, "0011223344556677", 16);
contlen = 8;
break;
} /* endswitch */
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, contents, contlen, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
pass++;
break;
default:
break;
} /* endswitch */
return rc;
} /* encMSGCLASS */
/*
* encDESTNAPS encoding user exit, for DESTNAPS
*/
int
encDESTNAPS(struct encinh ia, /* inherited attrs */
struct encinhsyn *sa, /* synthesized and inherited attrs */
enum tagclass cls, /* class of item to encode */
long id, /* id of class to encode */
enum frm form, /* form (prim or constr) of data to encode */
char *encsubs /* set to !0 to encode contained types */
)
{
int rc;
struct usrpstruct *usrparms;
usrparms = (struct usrpstruct *) ia.usrparms;
*encsubs = 1; /* encode contained types */
rc = ENCODE_MATCH;
switch (sa->ndx) {
case Miu_NAPS_SEQUENCE:
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, NULL, 0L, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
break;
case Miu_NODE:
GDSsetUsrEnc(encNODENAME, usrparms->env); /* set encoding user-exit for NODENAME */
break;
case Miu_AGENT:
GDSsetUsrEnc(encAGENTNAME, usrparms->env); /* set the encoding user-exit for AGENTNAME */
break;
case Miu_NAPS:
rc = ENCODE_NO_MATCH; /* don't encode TRAILER */
break;
default:
break;
} /* endswitch */
return rc;
} /* encDESTNAPS */
/*
* encNODENAME encoding user exit, for NODENAME
*/
int
encNODENAME(struct encinh ia, /* inherited attrs */
struct encinhsyn *sa, /* synthesized and inherited attrs */
enum tagclass cls, /* class of item to encode */
long id, /* id of class to encode */
enum frm form, /* form (prim or constr) of data to encode */
char *encsubs /* set to !0 to encode contained types */
)
{
int rc;
char *contents;
static int pass = 0;
int contlen;
struct usrpstruct *usrparms;
usrparms = (struct usrpstruct *) ia.usrparms;
*encsubs = 1; /* encode contained types */
rc = ENCODE_MATCH;
contents = NEW2(20, char);
switch (sa->ndx) {
case Miu_NAME64_SEQUENCE:
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, NULL, 0L, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
break;
case Miu_BYTES_OCTET_STRING:
switch(pass) {
case 0: /* nametype: '001122'H */
GDSstr2hex(contents, 3, "001122", 6);
contlen = 3;
break;
case 1: /* namestring: '00112233445566778899...'H */
GDSstr2hex(contents, 20, "0011223344556677889900112233445566778899", 40);
contlen = 20;
break;
} /* endswitch */
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, contents, contlen, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
pass++;
break;
default:
break;
} /* endswitch */
return rc;
} /* encNODENAME */
/*
* encAGENTNAME encoding user exit, for AGENTNAME
*/
int
encAGENTNAME(struct encinh ia, /* inherited attrs */
struct encinhsyn *sa, /* synthesized and inherited attrs */
enum tagclass cls, /* class of item to encode */
long id, /* id of class to encode */
enum frm form, /* form (prim or constr) of data to encode */
char *encsubs /* set to !0 to encode contained types */
)
{
int rc;
struct usrpstruct *usrparms;
usrparms = (struct usrpstruct *) ia.usrparms;
*encsubs = 1; /* encode contained types */
rc = ENCODE_MATCH;
switch (sa->ndx) {
case Miu_AGENT_SEQUENCE:
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, NULL, 0L, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
break;
case Miu_NAME64: /* agentname */
GDSsetUsrEnc(encNAME64, usrparms->env); /* set the encoding user-exit for NAME64 */
break;
case Miu_BYTES_OCTET_STRING: /* agentparm */
rc = ENCODE_NO_MATCH; /* don't encode it */
break;
default:
break;
} /* endswitch */
return rc;
} /* encAGENTNAME */
/*
* encNAME64 encoding user exit, for NAME64
*/
int
encNAME64(struct encinh ia, /* inherited attrs */
struct encinhsyn *sa, /* synthesized and inherited attrs */
enum tagclass cls, /* class of item to encode */
long id, /* id of class to encode */
enum frm form, /* form (prim or constr) of data to encode */
char *encsubs /* set to !0 to encode contained types */
)
{
int rc;
char *contents;
static int pass = 0;
int contlen;
struct usrpstruct *usrparms;
usrparms = (struct usrpstruct *) ia.usrparms;
*encsubs = 1; /* encode contained types */
rc = ENCODE_MATCH;
contents = NEW2(20, char);
switch (sa->ndx) {
case Miu_NAME64_SEQUENCE:
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, NULL, 0L, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
break;
case Miu_BYTES_OCTET_STRING:
switch(pass) {
case 0: /* nametype: '334455'H */
GDSstr2hex(contents, 3, "334455", 6);
contlen = 3;
break;
case 1: /* namestring: '00112233445566778899'H */
GDSstr2hex(contents, 10, "00112233445566778899", 20);
contlen = 10;
break;
} /* endswitch */
rc = GDSnewgds(&(sa->p), ia.modname, ia.symname, ia.it, cls, id,
form, contents, contlen, allocd, NULL, usrparms->env);
rc = (rc != NEWGDS_OK) ? rc : ENCODE_MATCH;
pass++;
break;
default:
break;
} /* endswitch */
return rc;
} /* encNAME64 */
/*
* content user-exit, agentdata_cont
*/
int agentdata_cont (char **buff, unsigned long *buflen, enum lastflag *lastf)
{
unsigned char buffer[2000];
static unsigned char hexbuff[1000];
int rc = 0, i;
static int pass = 0;
/* pass the 5000 bytes of the content of AGD.agentdata in pieces of 1000
* bytes. This is only an example, a content user-exit could be get
* the data from any other places.
*/
*buflen = 1000;
*lastf = NO;
switch (pass) {
case 0: /* first piece */
for (i=0;i<2000;i++) {
buffer[i] = 'A';
} /* endfor */
break;
case 1: /* second piece */
for (i=0;i<2000;i++) {
buffer[i] = 'B';
} /* endfor */
break;
case 2: /* third piece */
for (i=0;i<2000;i++) {
buffer[i] = 'C';
} /* endfor */
break;
case 3: /* fourth piece */
for (i=0;i<2000;i++) {
buffer[i] = 'D';
} /* endfor */
break;
case 4: /* fifth piece */
for (i=0;i<2000;i++) {
buffer[i] = 'E';
} /* endfor */
*lastf = YES;
break;
default:
break;
} /* endswitch */
GDSstr2hex(hexbuff, 1000, buffer, 2000);
*buff = hexbuff;
pass++;
return rc;
}