OSS ASN.1 Tools for C#


Example: Building an Application

The following sample application illustrates the use of the OSS ASN.1/C# Compiler to compile a simple ASN.1 module, and the use of the OSS API to invoke the encoder/decoder. By following these steps you can produce and run an executable program that encodes and then decodes a message.

The C# application program in this example is tbcas.cs and the associated ASN.1 source file is bcas.asn .

 

Step 1: Invoking the OSS ASN.1 Compiler

The following describes how to compile the abstract syntax defined in bcas.asn:

INPUT


-- Baseball Card Abstract Syntax (BCAS)
BCAS DEFINITIONS ::= BEGIN
   BBCard ::= SEQUENCE {
        name IA5String (SIZE (1..60)),
        team IA5String (SIZE (1..60)),
        age INTEGER (1..100),
        position IA5String (SIZE (1..60)),
        handedness ENUMERATED
                {left-handed(0), right-handed(1), ambidextrous(2)},
        batting-average REAL
   }
   myCard BBCard ::= {
        name "Casey",
        team "Mudville Nine",
        age 32,
        position "left field",
        handedness ambidextrous,
        batting-average {mantissa 250, base 10, exponent -3}
   }
END

COMMAND

You enter the following command:

        asn1 bcas.asn


or equivalently:

        asn1 bcas

The above command informs the OSS ASN.1/C# Compiler that we want to convert the ASN.1 file bcas.asn to C#. This is implied by default when no command line option is specified.

The OSS ASN.1/C# Compiler will emit the following files and C# classes:

bcas\   // project class set directory
bcas\AssemblyInfo.cs   // administrative information for bcas assembly
bcas\bcas   // main namespace directory
bcas\bcas\BCAS   // BCAS module namespace directory
bcas\bcas\BCAS\BBCard.cs   // BBCard type class
bcas\bcas\BCAS\BCAS_values.cs   // BCAS module types values class
bcas\bcas\BCAS\NamespaceDoc.cs   // NamespaceDoc class
bcas\bcas\BcasFactory.cs   // Factory class
bcas\bcas\files   // generated cs files list
bcas\bcas\namespace-list   // generated namespaces list
bcas\bcas\overview.html   // overview

 

OUTPUT

The following class represents the BBCard PDU. Accessor and mutator methods are generated for each component of the PDU. Some internal information has been omitted.

BBCard.cs:


namespace bcas.BCAS
{
    using System;
    using BcasFactory = bcas.BcasFactory;

    using IBerAsn1Writer = OSS.Asn1rt.Writer.Ber.IBerAsn1Writer;
    using IBerAsn1Reader = OSS.Asn1rt.Reader.Ber.IBerAsn1Reader;
    using Asn1Factory = OSS.Asn1rt.Util.Asn1Factory;
    using Asn1RuntimeProperties = OSS.Asn1rt.Util.Asn1RuntimeProperties;
    using IEncoder = OSS.Asn1rt.IEncoder;
    using IDecoder = OSS.Asn1rt.IDecoder;
    using Asn1Exception = OSS.Asn1rt.Asn1Exception;
    using Asn1Type = OSS.Asn1rt.Type.Asn1Type;
    using OSS.Asn1rt.Util;

    ///  Runtime class for 'BBCard' type.
    /// 
    [Serializable()]
    public class BBCard : OSS.Asn1rt.Type.Asn1SequenceType
    {
        ///  Runtime class for 'name' member.
        /// 
        [Serializable()]
        public  class _name : OSS.Asn1rt.Type.Asn1IA5StringType
        {


            /// The default constructor for _name.
            /// 
            public _name() : base()
            {
            }

            /// The constructor for _name.
            /// 
            /// The value to initialize this instance.
            public _name(string val) : base(val)
            {
            }

            ///  Sets the value of this type using an already
            /// valued appropriate Asn1Type.
            /// 
            public void SetValue(
                OSS.Asn1rt.Type.Asn1IA5StringType typeInstance)
            {
                base.__setTypeValue(typeInstance);
            }

            ///  Returns the lower size for this type.
            /// 
            public override long GetLowerSize()
            {
                return 1L;
            }

            ///  Returns the upper size for this type.
            /// 
            public override long GetUpperSize()
            {
                return 60L;
            }

        }

        ///  Runtime class for 'team' member.
        /// 
        [Serializable()]
        public  class _team : OSS.Asn1rt.Type.Asn1IA5StringType
        {
            /// The default constructor for _team.
            /// 
            public _team() : base()
            {
            }

            /// The constructor for _team.
            /// 
            /// The value to initialize this instance.
            public _team(string val) : base(val)
            {
            }

            ///  Sets the value of this type using an already
            /// valued appropriate Asn1Type.
            /// 
            public void SetValue(
                OSS.Asn1rt.Type.Asn1IA5StringType typeInstance)
            {
                base.__setTypeValue(typeInstance);
            }

            ///  Returns the lower size for this type.
            /// 
            public override long GetLowerSize()
            {
                return 1L;
            }

            ///  Returns the upper size for this type.
            /// 
            public override long GetUpperSize()
            {
                return 60L;
            }

        }

        ///  Runtime class for 'age' member.
        /// 
        [Serializable()]
        public  class _age : OSS.Asn1rt.Type.Asn1IntegerType
        {
            /// The constructor for _age.
            /// 
            public _age() : base(0)
            {
            }

            /// The constructor for _age.
            /// 
            /// The value to initialize this instance.
            public _age(long val) : base(val)
            {
            }

            ///  Sets the value of this type using an already valued
            /// appropriate Asn1Type.
            /// 
            public void SetValue(
                OSS.Asn1rt.Type.Asn1IntegerType typeInstance)
            {
                base.__setTypeValue(typeInstance);
            }

            ///  Returns the lower bound for this type.
            /// 
            public override long GetLowerBound()
            {
                return 1L;
            }

            ///  Returns the upper bound for this type.
            /// 
            public override long GetUpperBound()
            {
                return 100L;
            }

        }

        ///  Runtime class for 'position' member.
        /// 
        [Serializable()]
        public  class _position : OSS.Asn1rt.Type.Asn1IA5StringType
        {
            /// The default constructor for _position.
            /// 
            public _position() : base()
            {
            }

            /// The constructor for _position.
            /// 
            /// The value to initialize this instance.
            public _position(string val) : base(val)
            {
            }

            ///  Sets the value of this type using an already
            /// valued appropriate Asn1Type.
            /// 
            public void SetValue(
                OSS.Asn1rt.Type.Asn1IA5StringType typeInstance)
            {
                base.__setTypeValue(typeInstance);
            }

            ///  Returns the lower size for this type.
            /// 
            public override long GetLowerSize()
            {
                return 1L;
            }

            ///  Returns the upper size for this type.
            /// 
            public override long GetUpperSize()
            {
                return 60L;
            }

        }

        ///  Runtime class for 'handedness' member.
        /// 
        [Serializable()]
        public  class _handedness : OSS.Asn1rt.Type.Asn1EnumeratedType
        {
            /// The constant for 'left-handed' state.
            /// 
            public const int left_handed = 0;
            /// The constant for 'right-handed' state.
            /// 
            public const int right_handed = 1;
            /// The constant for 'ambidextrous' state.
            /// 
            public const int ambidextrous = 2;

            /// The default constructor for _handedness.
            /// 
            public _handedness() : base(0)
            {
            }
            /// The constructor for _handedness.
            /// 
            /// The value to initialize this instance.
            public _handedness(long val) : base(val)
            {
            }

            ///  Sets the value of this type using an already
            /// valued appropriate Asn1Type.
            /// 
            public void SetValue(
                OSS.Asn1rt.Type.Asn1EnumeratedType typeInstance)
            {
                base.__setTypeValue(typeInstance);
            }

        }

        ///  Constructor for BBCard.
        /// 
        public BBCard() : base()
        {
        }

        ///  Sets the value of this type using an already valued
        /// appropriate Asn1Type.
        /// 
        public void SetValue(BBCard typeInstance)
        {
            base.__setTypeValue(typeInstance);
        }

        ///  The instance accessor for 'name' giving access to
        /// internal values.
        /// 
        ///  the instance of '_name'.
        /// 
        public _name name()
        {
            __setComponentIsDefined(0);
            return (_name)__instantiateTypeByIndex(0);
        }

        ///  Property to set and get value of 'name' member
        /// using a string.
        ///  WARNING : documentation may not link to the right item,
        /// trust the above comment!
        /// 
        /// 
        public string Name
        {
            get
            {
                return name().StringValue;
            }
            set
            {
                name().SetValue(value);
            }
        }

        ///  The instance accessor for 'team' giving access
        /// to internal values.
        /// 
        ///  the instance of '_team'.
        /// 
        public _team team()
        {
            __setComponentIsDefined(1);
            return (_team)__instantiateTypeByIndex(1);
        }

        ///  Property to set and get value of 'team' member using
        /// a string.
        ///  WARNING : documentation may not link to the right item,
        /// trust the above comment!
        /// 
        /// 
        public string Team
        {
            get
            {
                return team().StringValue;
            }
            set
            {
                team().SetValue(value);
            }
        }

        ///  The instance accessor for 'age' giving access to
        /// internal values.
        /// 
        ///  the instance of '_age'.
        /// 
        public _age age()
        {
            __setComponentIsDefined(2);
            return (_age)__instantiateTypeByIndex(2);
        }

        ///  Property to set and get value of 'age' member using a int.
        ///  WARNING : documentation may not link to the right item,
        /// trust the above comment!
        /// 
        /// 
        public int Age
        {
            get
            {
                return age().IntValue;
            }
            set
            {
                age().SetValue(value);
            }
        }

        ///  The instance accessor for 'position' giving access
        /// to internal values.
        /// 
        ///  the instance of '_position'.
        /// 
        public _position position()
        {
            __setComponentIsDefined(3);
            return (_position)__instantiateTypeByIndex(3);
        }

        ///  Property to set and get value of 'position' member
        /// using a string.
        ///  WARNING : documentation may not link to the right item,
        /// trust the above comment!
        /// 
        /// 
        public string Position
        {
            get
            {
                return position().StringValue;
            }
            set
            {
                position().SetValue(value);
            }
        }

        ///  The instance accessor for 'handedness' giving access
        /// to internal values.
        /// 
        ///  the instance of '_handedness'.
        /// 
        public _handedness handedness()
        {
            __setComponentIsDefined(4);
            return (_handedness)__instantiateTypeByIndex(4);
        }

        ///  Property to set and get value of 'handedness'
        /// member using a int.
        ///  WARNING : documentation may not link to the right item,
        /// trust the above comment!
        /// 
        /// 
        public int Handedness
        {
            get
            {
                return handedness().IntValue;
            }
            set
            {
                handedness().SetValue(value);
            }
        }

        /// Tests for equality this BBCard with the specified object.
        /// 
        ///  the object to test against.
        /// 
        ///  The result is true if the argument is not null and
        /// is an BBCard
        /// instance that holds an internal value that is equal to the one
        /// held by this instance.
        /// 
        public override bool Equals(object anObject)
        {
            if ( !(anObject is BBCard))
                return false;
            return base.Equals(anObject);
        }

        ///  Returns a hash code for this type instance.
        /// 
        /// a hash code for this type instance.
        /// 
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
}

The following class provides all initialized values of the BCAS module. Some internal information has been omitted.

BCAS_values.cs:

namespace bcas.BCAS
{
    using System;
    using Asn1Type = OSS.Asn1rt.Type.Asn1Type;

    /// Convenient class holding ASN.1 values defined in BCAS module.
    /// 
    /// 
    /// Each ASN.1 value is defined as a static variable, the type of which
    /// is the appropriate Asn1Type
    ///  and the value of which is set with the value from the ASN.1 module.
    /// 
    public class BCAS_values
    {
        /// Runtime variable for myCard.
        /// 
        public static bcas.BCAS.BBCard myCard = new bcas.BCAS.BBCard();

        static BCAS_values()
        {
            /* myCard */ myCard.name().SetValue("Casey");
            /* myCard */ myCard.team().SetValue("Mudville Nine");
            /* myCard */ myCard.age().SetValue(32);
            /* myCard */ myCard.position().SetValue("left field");
            /* myCard */ myCard.handedness().SetValue(
                bcas.BCAS.BBCard._handedness.ambidextrous);
        }
    }
}

The following class provides a C# class holding information for decoder and encoder creation. Some internal information has been omitted.

BcasFactory.cs:
namespace bcas
{
    using System;
    using Asn1Factory = OSS.Asn1rt.Util.Asn1Factory;
    using Asn1RuntimeProperties = OSS.Asn1rt.Util.Asn1RuntimeProperties;
    using IEncoder = OSS.Asn1rt.IEncoder;
    using IDecoder = OSS.Asn1rt.IDecoder;
    using Asn1Exception = OSS.Asn1rt.Asn1Exception;

    ///  Specific class for runtime information for bcas Asn1CsAPI.
    /// This class holds information for decoder and encoder creation.
    /// 
    public class BcasFactory
    {
        // encoding rules
        private static string _encodingRules = "BER";

        // pre-encoding / post-decoding properties for direct access
        private static bool _isPreEncodingForConstructedOf = false;
        private static bool _isPostDecodingForConstructedOf = false;

        // properties static initialization
        static BcasFactory()
        {
            _encoderProperties["validating"] = "true";

            _decoderProperties["resolvingContent"] = "true";
            _decoderProperties["validating"] = "true";

        }

        ///  returns the encoding rules family to be used with
        /// this generated API.
        /// 
        ///   Trying to use encoding rules that are not part
        /// of this family may
        /// result in encoding/decoding problems. The encoding rules
        /// family : "Basic" (BER/DER),
        /// "Packed" (PER), "XML" (XER) or "*" (standing for all encoding
        /// rules family).
        /// 
        ///  This API is built for "Basic" encoding rules family.
        /// 
        /// 

        public static string GetGeneratedAPIEncodingRulesFamily()
        {
            return "Basic";
        }

        ///  sets the encoding rules. Default value is "BER".
        /// 
        /// Thrown if the given
        /// encodingRules are not part of the encoding
        /// rules family defined for this generated API or if they are not
        /// supported.
        /// 
        ///  "BER", "DER", "AlignedBasicPER",
        /// "UnalignedBasicPER", "AlignedCanonicalPER",
        /// "UnalignedCanonicalPER",
        ///  "BasicXER", "CanonicalXER" (ignoring case) 
        /// 
        public static void SetEncodingRules(string encodingRules)
        {
            Asn1RuntimeProperties.checkEncodingRulesFamily(
                "Basic", encodingRules);
            _encodingRules = encodingRules;
        }

        ///  sets an encoder property.
        /// 
        /// Thrown if the given
        /// property is not supported 
        /// The property name.
        /// The value for property.

        public static void SetEncoderProperty(string property, string val)
        {
            Asn1RuntimeProperties.checkEncoderProperty(property,
                _encodingRules);
            _encoderProperties[property] = val;
        }

        ///  gets an encoder property as a string.
        /// 
        /// Thrown if the given
        /// property is not supported 
        /// The property name.
        ///  The encoder property value as a string.
        /// 
        public static string GetEncoderProperty(string property)
        {
            Asn1RuntimeProperties.checkEncoderProperty(property,
                _encodingRules);
            return (string)_encoderProperties[property];
        }

        ///  sets a decoder property as a string.
        /// 
        /// Thrown if the given
        /// property is not supported 
        /// The property name.
        /// The value for property.
        public static void SetDecoderProperty(string property, string val)
        {
            Asn1RuntimeProperties.checkDecoderProperty(property,
                _encodingRules);
            _decoderProperties[property] = val;
        }

        ///  gets a decoder property as a string.
        /// 
        /// Thrown if the
        /// given property is not supported 
        /// The property name.
        ///  the decoder property value as a string.
        /// 
        public static string GetDecoderProperty(string property)
        {
            Asn1RuntimeProperties.checkDecoderProperty(property,
                _encodingRules);
            return (string)_decoderProperties[property];
        }

        ///  sets a generic type property.
        /// 
        /// Thrown if the given
        /// property is not supported 
        /// The property name.
        /// The value for property.
        public static void SetTypeProperty(string property, string val)
        {
            Asn1RuntimeProperties.checkTypeProperty(property,
                _encodingRules);
            _typeProperties[property] = val;
            // for direct access
            if ("postDecodingForConstructedOf".Equals(property))
                _isPostDecodingForConstructedOf = true;
            if ("preEncodingForConstructedOf".Equals(property))
                _isPreEncodingForConstructedOf = true;
        }

        ///  gets a generic type property.
        /// 
        /// Thrown if the given
        /// property is not supported 
        /// The property name.
        ///  the type property value as a string.
        /// 
        public static string GetTypeProperty(string property)
        {
            Asn1RuntimeProperties.checkTypeProperty(property,
                _encodingRules);
            return (string)_typeProperties[property];
        }

        /// Creates an instance of an appropriate decoder.
        /// Initial specified decoder is a BER decoder.
        /// 
        /// The inital specified properties are  :
        /// 
        ///     - "resolvingContent" with value "true"
        /// 
        /// 
        ///     - "validating" with value "true"
        /// 
        /// 
        ///  a IDecoder interface.
        /// 
        public static IDecoder CreateDecoder()
        {
            IDecoder decoder = Asn1Factory.createDecoder(_encodingRules);
            decoder.SetProperties(_decoderProperties);
            return decoder;
        }

        /// Creates an instance of an appropriate encoder.
        /// Initial specified encoder is a BER encoder.
        /// 
        /// The inital specified properties are  :
        /// 
        ///     - "validating" with value "true"
        /// 
        /// 
        ///  a IEncoder interface.
        /// 
        public static IEncoder CreateEncoder()
        {
            IEncoder encoder = Asn1Factory.createEncoder(_encodingRules);
            encoder.SetProperties(_encoderProperties);
            return encoder;
        }


        /// Says whether pre-encoding is to be used for SEQUENCE OF /
        /// SET OF types.
        /// 
        /// True if pre-encoding is used.
        public static bool IsPreEncodingForConstructedOf()
        {
            return _isPreEncodingForConstructedOf;
        }

        /// Says whether post-decoding is to be used for SEQUENCE OF /
        /// SET OF types.
        /// 
        /// True if post-decoding is used.
        public static bool IsPostDecodingForConstructedOf()
        {
            return _isPostDecodingForConstructedOf;
        }

    }
}

        

Step 2: Compiling and linking the sample application

The following is a copy of the C# program in tbcas.cs. This program validates the myCard value of the BBCard PDU described by the bcas.asn abstract syntax, encodes the PDU (using BER), decodes it, and compares the unencoded and decoded PDUs. Note that the bcas C# classes (generated by the compiler) have been used by the application program. (The function calls to the Encoder/Decoder methods are in bold font.)

INPUT

C#File, tbcas.cs:


using bcas;
using bcas.BCAS;

/* Universal classes from the OSS runtime library */
using OSS.Asn1rt;
using OSS.Asn1rt.Util;

/* C# system classes */
using System;
using System.IO;

public class Tbcas {
    public static int Main(string[] args)
    {
        IEncoder encoder      = null;
        IDecoder decoder      = null;
        string   encodingRule = null;
        BBCard   decoded      = new BBCard();

        /*
         * Get encoding rules which were specified on the ASN.1 compiler
         * command line.
         */
        if (BcasFactory.GetGeneratedAPIEncodingRulesFamily() == "Basic")
            encodingRule = "BER";
        else if (BcasFactory.GetGeneratedAPIEncodingRulesFamily() == "XML")
            encodingRule = "XER";
        else
            encodingRule = "PER";

        /*
         * Create instance of the encoder
         */
        try {
            encoder = BcasFactory.CreateEncoder();
        }
        catch (Asn1Exception ex) {
            Console.WriteLine(encodingRule +
                "-encoder object failed to create: " + ex.Message);
            return 1;
        }

        /*
         * Print the input to the encoder.
         */
        Console.WriteLine("Printing the unencoded PDU...\n");
        Console.WriteLine(BCAS_values.myCard);

        /*
         * Validate the input PDU value.
         */
        Console.WriteLine("\nValidating the unencoded PDU...");
        try {
            BCAS_values.myCard.Validate();
            Console.WriteLine("Validated successfully.");
        }
        catch (Asn1Exception ex) {
            /*
             * An error occurred, print the error message.
             */
            Console.WriteLine("Failed to validate: " + ex.Message);
            return 1;
        }

        /*
         * Encode the PDU.  Return non-zero for failure.
         */
        try {
            Console.WriteLine("\n{0}-encoding the PDU...", encodingRule);
            encoder.Encode(BCAS_values.myCard);
            Console.WriteLine("PDU encoded successfully.");
        }
        catch (Asn1Exception ex) {
           /*
            * An error occurred, print the error message.
            */
            Console.WriteLine("Failed to encode: " + ex.Message);
            return 1;
        }

        /*
         * Print the encoder's output.
         */
        Console.WriteLine("\nPrinting the {0}-encoded PDU...\n",
            encodingRule);
        Console.WriteLine(ByteArray.ByteArrayToHexString(encoder.Data,
            " ", 20));

        /*
         * Create instance of the decoder
         */
        try {
           decoder = BcasFactory.CreateDecoder();
        }
        catch (Asn1Exception ex) {
            Console.WriteLine(encodingRule +
                "-decoder object failed to create: " + ex.Message);
            return 1;
        }

        /*
         * Decode the encoded PDU whose encoding is in "encodedData".
         */
        try {
            Console.WriteLine("\n{0}-decoding the PDU...", encodingRule);
            decoder.Decode(encoder.Data, decoded);
            Console.WriteLine("Decoded successfully.");
        }
        catch (Asn1Exception ex) {
        /*
         * An error occurred, print the error message.
         */
            Console.WriteLine("Failed to decode: " + ex.Message);
            return 1;
        }

        /*
         * Print the decoder's output.
         */
        Console.WriteLine("\nPrinting the decoded PDU...\n\n" + decoded);

            /*
             * Compare the decoded PDU and unencoded one
             */
        try {
            Console.WriteLine
                ("\nComparing the unencoded and decoded PDUs...");
            if (BCAS_values.myCard.Equals(decoded))
                Console.WriteLine("Compared successfully.");
        }
        catch (Asn1Exception ex) {
            /*
             * An error occurred, print the error message.
             */
            Console.WriteLine("Failed to compare: " + ex.Message);
            return 1;
        }

        return 0;
    }
}

        

COMMAND

Next, generate a public-private key pair for signing the generated files as follows:

E> sn -q -k bcas.snk

OUTPUT

The above command generates bcas.snk key file.

COMMAND

Next, build the sample application program as follows:

csc -out:tbcas.exe tbcas.cs -recurse:bcas\*.cs -r:"%OSS_CSHARP_HOME%"\bin\asn1rt.dll

>OUTPUT

The above command C#-compiles the compiler generated and tbcas.cs . C# files and builds the resulting application tbcas.exe using the OSS runtime asn1rt.dll.

Step 3: Invoking the encoder/decoder

INPUT

(None: For this example, the encoder input is generated by the ASN.1 compiler as a C# class instance initialized from the ASN.1 value notation.)

COMMAND


tbcas

This command simply runs tbcas.

OUTPUT

Printing the unencoded PDU...


BBCard SEQUENCE
{
  name IA5String = Casey
  team IA5String = Mudville Nine
  age INTEGER = 32
  position IA5String = left field
  handedness ENUMERATED = ambidextrous(2)
}

Validating the unencoded PDU...
Validated successfully.

BER-encoding the PDU...
PDU encoded successfully.

Printing the BER-encoded PDU...

30 28 16 05 43 61 73 65 79 16 0d 4d 75 64 76 69 6c 6c 65 20
4e 69 6e 65 02 01 20 16 0a 6c 65 66 74 20 66 69 65 6c 64 0a
01 02

BER-decoding the PDU...
Decoded successfully.

Printing the decoded PDU...

BBCard SEQUENCE
{
  name IA5String = Casey
  team IA5String = Mudville Nine
  age INTEGER = 32
  position IA5String = left field
  handedness ENUMERATED = ambidextrous(2)
}

Comparing the unencoded and decoded PDUs...
Compared successfully.
        

.:. Top

 

 

 

Copyright © 2008 OSS Nokalva, Inc.   All Rights Reserved.