
Example: Building an XER Application
The following sample application illustrates the use of the OSS ASN.1 Compiler to compile a simple ASN.1 module, and the use of the OSS runtime APIs to invoke the Basic-XER (here after called XER) encoder/decoder.
The C application program in this example is tperson.c and the associated ASN.1 source file is person.asn . The ASN.1 file contains two Personnel records, john and mary . The application program encodes these Personnel records using XER, and then decodes the encoded XER encoded data into structures.
The following outline shows how you can produce and run a sample executable program that encodes and then decodes a message using XER (XML Encoding Rules).
Step 1: Invoking the ASN.1 Compiler
1.1 Input ASN.1 Syntax (person.asn)
1.2 Command to compile person.asn
1.3 Output files generated by the ASN.1 Compiler
Step 2: Compiling and Linking the sample application
2.1 Input application program tperson.c
2.2 Commands to compile and link the sample program
Step 3: Running the sample program
3.1 Command to run the executable
3.2 Output of sample program
Step 1: Invoking the ASN.1 Compiler
The following describes how
to compile abstract syntax defined in the person.asn file.
1.1 Input
ASN.1 Syntax (person.asn)
Personnel
DEFINITIONS AUTOMATIC TAGS ::=
BEGIN
PersonnelRecord ::= SET {
name [0]
Name,
title [1] VisibleString,
number [2] EmployeeNumber,
dateOfHire [3] Date,
nameOfSpouse [4] Name,
children [5] SEQUENCE OF ChildInformation
}
ChildInformation ::= SET {
name [0] Name,
dateOfBirth [1] Date,
sex [2]
ENUMERATED {
male(1),
female(2),
unknown(3)
} OPTIONAL
}
Name ::= SEQUENCE {
givenName [0] NameString,
initial [1] NameString,
familyName [2] NameString
}
EmployeeNumber ::= INTEGER (0..9999)
Date ::= VisibleString (FROM ("0".."9") INTERSECTION SIZE
(8..20))
NameString ::= VisibleString (FROM ("a".."z" | "A".."Z"
|
"-.") INTERSECTION SIZE (1..64))
john ::=
<PersonnelRecord>
<name>
<givenName>John</givenName>
<initial>P</initial>
<familyName>Smith</familyName>
</name>
<title>Director</title>
<number>51</number>
<dateOfHire>19710917</dateOfHire>
<nameOfSpouse>
<givenName>Mary</givenName>
<initial>T</initial>
<familyName>Smith</familyName>
</nameOfSpouse>
<children>
<ChildInformation>
<name>
<givenName>Ralph</givenName>
<initial>J</initial>
<familyName>Smith</familyName>
</name>
<dateOfBirth>19791111</dateOfBirth>
</ChildInformation>
<ChildInformation>
<name>
<givenName>Susan</givenName>
<initial>J</initial>
<familyName>Smith</familyName>
</name>
<dateOfBirth>19820715</dateOfBirth>
<sex><female/></sex>
</ChildInformation>
</children>
</PersonnelRecord>
mary PersonnelRecord ::= {
name {
givenName "Mary",
initial "T",
familyName "Smith"
},
title "Housewife",
number 1281,
dateOfHire "19790422",
nameOfSpouse {
givenName "John",
initial "P",
familyName "Smith"
},
children {
{
name
{
givenName "Ralph",
initial
"J",
familyName "Smith"
},
dateOfBirth "19791111"
},
{
name
{
givenName "Susan",
initial
"J",
familyName "Smith"
},
dateOfBirth "19820715",
sex
female
}
}
}
END
Go back
to top
1.2 Command
to compile person.asn
The following command compiles person.asn,
and generates person.h and person.c files. The person.h
file contains the structures corresponding to the components of ASN.1 file.
The person.c file
contains information needed by the encoder and the decoder at runtime. The
file, person.c,
must be compiled and linked with the sample application.
asn1 -xer person.asn
or
asn1 -xer person
The -xer compiler
option notifies compiler that XER (XML Encoding Rules) will be used at runtime.
A detailed description of all the compiler options supported by the OSS ASN.1/C
Compiler can be found in the OSS ASN.1 Compiler
for C Reference Manual.
Go back
to top
1.3 Output files generated
by the ASN.1 Compiler
person.h
#ifndef OSS_person
#define OSS_person
#include "asn1hdr.h"
#include "asn1code.h"
#define PersonnelRecord_PDU 1
typedef char NameString[65];
typedef struct Name {
NameString givenName;
NameString initial;
NameString familyName;
} Name;
typedef unsigned short EmployeeNumber;
typedef char Date[21];
typedef struct ChildInformation {
unsigned char bit_mask;
# define sex_present 0x80
Name name;
Date dateOfBirth;
enum {
male = 1,
female = 2,
unknown = 3
} sex; /* optional; set in bit_mask sex_present if present */
} ChildInformation;
typedef struct PersonnelRecord {
Name name;
char *title;
EmployeeNumber number;
Date dateOfHire;
Name nameOfSpouse;
struct _seqof1 {
struct _seqof1 *next;
ChildInformation value;
} *children;
} PersonnelRecord;
extern PersonnelRecord john;
extern PersonnelRecord mary;
extern void * const person; /* encoder-decoder control table */
#endif /* OSS_person */
Go back
to top
person.c
The person.c file contains the information
needed by the runtime APIs to encode and decode PDUs. Since this file contains
internal information, it is not shown here. This file must be compiled and
linked with the sample application.
Step 2: Compiling and Linking
the sample application
The following C program, tperson.c,
encodes the PDU described by the person.asn abstract syntax using
XER (XML Encoding Rules), and then decodes it. Note that person.h (generated
by the compiler) has been #included in the application program.
This header file contains the generated declarations for the application.
(The function calls to the OSS Encoder/Decoder functions are in bold font.)
After
the application program is compiled, the OSS Encoder/Decoder runtime library
must be linked into the resulting executable file.
2.1 Input application program tperson.c
/* Application Program: tperson.c
*/
/* Encodes and decodes sample personnel records
using XER. */
#include "person.h" /* compiler-generated
header file */
static int encodeAndDecode(OssGlobal *world,
PersonnelRecord* ptrRecord)
{
OssBuf
encodedData; /* length and address of encoded
data */
PersonnelRecord
*myRecordPtr = NULL; /* address of decoded data */
int
pdu_num = 0; /* PDU number */
int
retcode = 0; /* return code */
/*
* Print the input
to the encoder
*/
ossPrint(world, "\nThe input
to the encoder ...\n\n");
ossPrintPDU(world, PersonnelRecord_PDU,
ptrRecord);
ossPrint(world, "\nEncoding
Personnel Record ...\n");
encodedData.length = 0;
encodedData.value = NULL;
/*
* Encode a record.
Return non-zero for failure.
*/
if (ossEncode(world, PersonnelRecord_PDU, ptrRecord, &encodedData))
{
ossPrint(world, "%s\n",
ossGetErrMsg(world)); /* an error occurred, print errmsg */
return 1;
}
else {
ossPrint(world, "Record
encoded successfully.\n");
/*
* Print XER encoded
data.
*/
ossPrint(world, "\nEncoded
Data: %.*s\n\n", encodedData.length, encodedData.value);
/*
* Decode a record.
Return non-zero for failure.
*/
ossPrint(world, "\nDecoding
XER encoded Personnel Record ...\n");
if (ossDecode(world, &pdu_num, &encodedData, (void
**)&myRecordPtr)) {
ossPrint(world,
"%s\n", ossGetErrMsg(world)); /* an error occurred, print errmsg */
retcode
= 1;
} else {
ossPrint(world,
"Record decoded successfully.\n");
/*
* Print the decoder's output
*/
ossPrint(world,
"\nOutput from the decoder ...\n\n");
ossPrintPDU(world,
pdu_num, myRecordPtr);
ossFreePDU(world,
pdu_num, myRecordPtr);
}
}
return retcode;
}
int main(void)
{
OssGlobal w, *world = &w;
/* structure ossGlobal */
int
retcode; /* return
code */
/*
* Call ossinit() first
to initialize OSS's global structure
*/
if (retcode = ossinit(world,
person)) {
ossPrint(NULL, "Ossinit()
returned %d\n", retcode);
return retcode;
}
/*
* Set OSS_XER encoding
rules.
*/
ossSier new;">
*/
if (retcode = encodeAndDecode(world,
&john))
return retcode;
if (retcode = encodeAndDecode(world,
&mary))
return retcode;
/*
* Call ossterm() to
free all resources
*/
ossterm(world);
return retcode;
}
2.2 Command to compile and link sample program
The sample program can be compiled
and linked using makefiles asn1cpl.mak and tperson.mak. The asn1cp.mak file compiles
the ASN.1 syntax and generates .h and .c files.
Another makefile, tperson.mak, compiles application code with
the generated .c file, and links the object file with the OSS
runtime libraries to generate a sample executable. These files are located
under the samples/xml directory.
For example, if you have installed OSS ASN.1/C tools under the /ossasn1/win32/6.1.0
directory, these makefiles can be found under the /ossasn1/win32/6.1.0/samples/xml
directory. An executable for the sample program can be created by using the
following commands on Windows and UNIX:
For Windows:
nmake
-f asn1cpl.mak
nmake -f tperson.mak
For
Unix:
make
-f asn1cpl.mak
make -f tperson.mak
Step
3: Running the sample program
3.1 Command to
run the executable
An executable tperson (tperson.exe for Windows) will be
generated after step 2.2. This executable can be run on the command line by
the following command:
tperson
3.2 Output of the sample program
Running tperson will generate the
following output:
The input to the encoder ...
value PersonnelRecord ::=
{
name
{
givenName "John",
initial "P",
familyName "Smith"
},
title "Director",
number 51,
dateOfHire "19710917",
nameOfSpouse
{
givenName "Mary",
initial "T",
familyName "Smith"
},
children
{
{
name
{
givenName "Ralph",
initial "J",
familyName "Smith"
},
dateOfBirth
"19791111"
},
{
name
{
givenName "Susan",
initial "J",
familyName "Smith"
},
dateOfBirth
"19820715",
sex female
}
}
}
Encoding Personnel Record ...
Record encoded successfully.
Encoded Data: <?xml version="1.0" encoding="UTF-8"?>
<PersonnelRecord>
<name>
<givenName>John</givenName>
<initial>P</initial>
<familyName>Smith</familyName>
</name>
<title>Director</title>
<number>51</number>
<dateOfHire>19710917</dateOfHire>
<nameOfSpouse>
<givenName>Mary</givenName>
<initial>T</initial>
<familyName>Smith</familyName>
</nameOfSpouse>
<children>
<ChildInformation>
<name>
<givenName>Ralph</givenName>
<initial>J</initial>
<familyName>Smith</familyName>
</name>
<dateOfBirth>19791111</dateOfBirth>
</ChildInformation>
<ChildInformation>
<name>
<givenName>Susan</givenName>
<initial>J</initial>
<familyName>Smith</familyName>
</name>
<dateOfBirth>19820715</dateOfBirth>
<sex><female/></sex>
</ChildInformation>
</children>
</PersonnelRecord>
Decoding XER encoded Personnel Record ...
Record decoded successfully.
Output from the decoder ...
value PersonnelRecord ::=
{
name
{
givenName "John",
initial "P",
familyName "Smith"
},
title "Director",
number 51,
dateOfHire "19710917",
nameOfSpouse
{
givenName "Mary",
initial "T",
familyName "Smith"
},
children
{
{
name
{
givenName "Ralph",
initial "J",
familyName "Smith"
},
dateOfBirth
"19791111"
},
{
name
{
givenName "Susan",
initial "J",
familyName "Smith"
},
dateOfBirth
"19820715",
sex female
}
}
}
The input to the encoder ...
value PersonnelRecord ::=
{
name
{
givenName "Mary",
initial "T",
familyName "Smith"
},
title "Housewife",
number 1281,
dateOfHire "19790422",
nameOfSpouse
{
givenName "John",
initial "Pr new;"> {
{
name
{
givenName "Ralph",
initial "J",
familyName "Smith"
},
dateOfBirth "19791111"
},
{
name
{
givenName "Susan",
initial "J",
familyName "Smith"
},
dateOfBirth "19820715",
sex female
}
}
}
Encoding Personnel Record ...
Record encoded successfully.
Encoded Data: <?xml version="1.0" encoding="UTF-8"?>
<PersonnelRecord>
<name>
<givenName>Mary</givenName>
<initial>T</initial>
<familyName>Smith</familyName>
</name>
<title>Housewife</title>
<number>1281</number>
<dateOfHire>19790422</dateOfHire>
<nameOfSpouse>
<givenName>John</givenName>
<initial>P</initial>
<familyName>Smith</familyName>
</nameOfSpouse>
<children>
<ChildInformation>
<name>
<givenName>Ralph</givenName>
<initial>J</initial>
<familyName>Smith</familyName>
</name>
<dateOfBirth>19791111</dateOfBirth>
</ChildInformation>
<ChildInformation>
<name>
<givenName>Susan</givenName>
<initial>J</initial>
<familyName>Smith</familyName>
</name>
<dateOfBirth>19820715</dateOfBirth>
<sex><female/></sex>
</ChildInformation>
</children>
</PersonnelRecord>
Decoding XER encoded Personnel Record ...
Record decoded successfully.
Output from the decoder ...
value PersonnelRecord ::=
{
name
{
givenName "Mary",
initial "T",
familyName "Smith"
},
title "Housewife",
number 1281,
dateOfHire "19790422",
nameOfSpouse
{
givenName "John",
initial "P",
familyName "Smith"
},
children
{
{
name
{
givenName "Ralph",
initial "J",
familyName "Smith"
},
dateOfBirth "19791111"
},
{
name
{
givenName "Susan",
initial "J",
familyName "Smith"
},
dateOfBirth "19820715",
sex female
}
}
}
Copyright © 2009 OSS Nokalva, Inc. All Rights Reserved.