How Unmarshal Works And Alternatives

The Unmarshal function is the most convenient way to decode, but taking a look at how it works also provides alternatives, should you want them.

First, we'll look at the other PER decode functions that are generated. There are two general forms:

          func PerDecode<type name>(pctxt *asn1rt.OSRTContext) (value <go type>, err error)
          
          func (pvalue *<type name>) PerDecode(pctxt *asn1rt.OSRTContext) (err error)
        

Here are two examples from the employee sample:

          func PerDecodeEmployeeNumber(pctxt *asn1rt.OSRTContext) (value int64, err error)
          
          func (pvalue *Name) PerDecode(pctxt *asn1rt.OSRTContext) (err error)
        

The first form is used when the Go type for the ASN.1 type is a built-in Go type - so basically it's used for the simple, nonconstructed ASN.1 types. The second form is used when the Go type is a generated type.

Now we can look at the Unmarshal function to see what it does and how these functions are used:

   // Create context object to manage encoding
   pctxt := new(asn1rt.OSRTContext)
   pctxt.InitDecodeBytes(b)   // Initialize for decoding; b holds the encoded data
   pctxt.NewBitFieldList()   // Optional: enable bit tracing
   ...     
   err = v.PerDecode(pctxt)   // Invoke the decode function; v is a generated type
   ...
   pctxt.AlignBuffer()        // Optional: prepare to decode a second message
   pctxt.PrintBitFieldList("pdu")   // Optional: print bit trace