URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [encoding/] [asn1/] [common.go] - Rev 747
Compare with Previous | Blame | View Log
// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package asn1import ("reflect""strconv""strings")// ASN.1 objects have metadata preceding them:// the tag: the type of the object// a flag denoting if this object is compound or not// the class type: the namespace of the tag// the length of the object, in bytes// Here are some standard tags and classesconst (tagBoolean = 1tagInteger = 2tagBitString = 3tagOctetString = 4tagOID = 6tagEnum = 10tagUTF8String = 12tagSequence = 16tagSet = 17tagPrintableString = 19tagT61String = 20tagIA5String = 22tagUTCTime = 23tagGeneralizedTime = 24tagGeneralString = 27)const (classUniversal = 0classApplication = 1classContextSpecific = 2classPrivate = 3)type tagAndLength struct {class, tag, length intisCompound bool}// ASN.1 has IMPLICIT and EXPLICIT tags, which can be translated as "instead// of" and "in addition to". When not specified, every primitive type has a// default tag in the UNIVERSAL class.//// For example: a BIT STRING is tagged [UNIVERSAL 3] by default (although ASN.1// doesn't actually have a UNIVERSAL keyword). However, by saying [IMPLICIT// CONTEXT-SPECIFIC 42], that means that the tag is replaced by another.//// On the other hand, if it said [EXPLICIT CONTEXT-SPECIFIC 10], then an// /additional/ tag would wrap the default tag. This explicit tag will have the// compound flag set.//// (This is used in order to remove ambiguity with optional elements.)//// You can layer EXPLICIT and IMPLICIT tags to an arbitrary depth, however we// don't support that here. We support a single layer of EXPLICIT or IMPLICIT// tagging with tag strings on the fields of a structure.// fieldParameters is the parsed representation of tag string from a structure field.type fieldParameters struct {optional bool // true iff the field is OPTIONALexplicit bool // true iff an EXPLICIT tag is in use.application bool // true iff an APPLICATION tag is in use.defaultValue *int64 // a default value for INTEGER typed fields (maybe nil).tag *int // the EXPLICIT or IMPLICIT tag (maybe nil).stringType int // the string tag to use when marshaling.set bool // true iff this should be encoded as a SET// Invariants:// if explicit is set, tag is non-nil.}// Given a tag string with the format specified in the package comment,// parseFieldParameters will parse it into a fieldParameters structure,// ignoring unknown parts of the string.func parseFieldParameters(str string) (ret fieldParameters) {for _, part := range strings.Split(str, ",") {switch {case part == "optional":ret.optional = truecase part == "explicit":ret.explicit = trueif ret.tag == nil {ret.tag = new(int)}case part == "ia5":ret.stringType = tagIA5Stringcase part == "printable":ret.stringType = tagPrintableStringcase strings.HasPrefix(part, "default:"):i, err := strconv.ParseInt(part[8:], 10, 64)if err == nil {ret.defaultValue = new(int64)*ret.defaultValue = i}case strings.HasPrefix(part, "tag:"):i, err := strconv.Atoi(part[4:])if err == nil {ret.tag = new(int)*ret.tag = i}case part == "set":ret.set = truecase part == "application":ret.application = trueif ret.tag == nil {ret.tag = new(int)}}}return}// Given a reflected Go type, getUniversalType returns the default tag number// and expected compound flag.func getUniversalType(t reflect.Type) (tagNumber int, isCompound, ok bool) {switch t {case objectIdentifierType:return tagOID, false, truecase bitStringType:return tagBitString, false, truecase timeType:return tagUTCTime, false, truecase enumeratedType:return tagEnum, false, truecase bigIntType:return tagInteger, false, true}switch t.Kind() {case reflect.Bool:return tagBoolean, false, truecase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:return tagInteger, false, truecase reflect.Struct:return tagSequence, true, truecase reflect.Slice:if t.Elem().Kind() == reflect.Uint8 {return tagOctetString, false, true}if strings.HasSuffix(t.Name(), "SET") {return tagSet, true, true}return tagSequence, true, truecase reflect.String:return tagPrintableString, false, true}return 0, false, false}
