func (ctx *Context) getRawValuesFromBytes(data []byte, max int) ([]*rawValue, error) {
	rawValues := []*rawValue{}
	reader := bytes.NewBuffer(data)
	for i := 0; i < max; i++ {
		raw, err := decodeRawValue(reader)
		if err != nil {
			return nil, err
		}
		rawValues = append(rawValues, raw)
		if reader.Len() == 0 {
			return rawValues, nil
		}
	}
	return nil, parseError("too many items for Sequence")
}
getRawValuesFromBytes reads up to max values from the byte sequence.
package asn1
import (
	"bytes"
	"io"
	"reflect"
	"sort"
)
type expectedElement struct {
	class   uint
	tag     uint
	decoder decoderFunction
}
type expectedFieldElement struct {
	expectedElement
	value reflect.Value
	opts  *fieldOptions
}
func (ctx *Context) Decode(data []byte, obj interface{}) (rest []byte, err error) {
	return ctx.DecodeWithOptions(data, obj, "")
}
func (ctx *Context) DecodeWithOptions(data []byte, obj interface{}, options string) (rest []byte, err error) {
	opts, err := parseOptions(options)
	if err != nil {
		return nil, err
	}
	value := reflect.ValueOf(obj)
	switch value.Kind() {
	case reflect.Ptr, reflect.Interface:
		value = value.Elem()
	}
	if !value.CanSet() {
		return nil, syntaxError("go type '%s' is read-only", value.Type())
	}
	reader := bytes.NewBuffer(data)
	err = ctx.decode(reader, value, opts)
	if err != nil {
		return nil, err
	}
	return reader.Bytes(), nil
}
func (ctx *Context) decode(reader io.Reader, value reflect.Value, opts *fieldOptions) error {
	raw, err := decodeRawValue(reader)
	if err != nil {
		return err
	}
	if ctx.der.decoding && raw.Indefinite {
		return parseError("indefinite length form is not supported by DER mode")
	}
	elem, err := ctx.getExpectedElement(raw, value.Type(), opts)
	if err != nil {
		return err
	}
	if raw.Class != elem.class || raw.Tag != elem.tag {
		ctx.log.Printf("%#v\n", opts)
		return parseError("expected tag (%d,%d) but found (%d,%d)",
			elem.class, elem.tag, raw.Class, raw.Tag)
	}
	return elem.decoder(raw.Content, value)
}
func (ctx *Context) getExpectedElement(raw *rawValue, elemType reflect.Type, opts *fieldOptions) (elem expectedElement, err error) {
	elem, err = ctx.getUniversalTag(elemType, opts)
	if err != nil {
		return
	}
	if opts.tag != nil {
		elem.class = classContextSpecific
		elem.tag = uint(*opts.tag)
	}
	if opts.universal {
		elem.class = classUniversal
	}
	if opts.application {
		elem.class = classApplication
	}
	if opts.explicit {
		elem.decoder = func(data []byte, value reflect.Value) error {
			opts.explicit = false
			opts.tag = nil
			opts.application = false
			reader := bytes.NewBuffer(data)
			return ctx.decode(reader, value, opts)
		}
		return
	}
	if opts.choice != nil {
		var entry choiceEntry
		entry, err = ctx.getChoiceByTag(*opts.choice, raw.Class, raw.Tag)
		if err != nil {
			return
		}
		elem.class, elem.tag = raw.Class, raw.Tag
		elem.decoder = func(data []byte, value reflect.Value) error {
			nestedValue := reflect.New(entry.typ).Elem()
			err = entry.decoder(data, nestedValue)
			if err != nil {
				return err
			}
			value.Set(nestedValue)
			return nil
		}
	}
	if elem.decoder == nil {
		err = parseError("go type not supported '%s'", elemType)
	}
	return
}
func (ctx *Context) getUniversalTag(objType reflect.Type, opts *fieldOptions) (elem expectedElement, err error) {
	elem.class = classUniversal
	switch objType {
	case bigIntType:
		elem.tag = tagInteger
		elem.decoder = ctx.decodeBigInt
	case oidType:
		elem.tag = tagOid
		elem.decoder = ctx.decodeOid
	case nullType:
		elem.tag = tagNull
		elem.decoder = ctx.decodeNull
	default:
		elem = ctx.getUniversalTagByKind(objType, opts)
	}
	if opts.set {
		if elem.tag != tagSequence {
			err = syntaxError(
				"'set' cannot be used with Go type '%s'", objType)
		}
		elem.tag = tagSet
	}
	return
}
func (ctx *Context) getUniversalTagByKind(objType reflect.Type, opts *fieldOptions) (elem expectedElement) {
	switch objType.Kind() {
	case reflect.Bool:
		elem.tag = tagBoolean
		elem.decoder = ctx.decodeBool
	case reflect.String:
		elem.tag = tagOctetString
		elem.decoder = ctx.decodeString
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		elem.tag = tagInteger
		elem.decoder = ctx.decodeInt
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		elem.tag = tagInteger
		elem.decoder = ctx.decodeUint
	case reflect.Struct:
		elem.tag = tagSequence
		elem.decoder = ctx.decodeStruct
		if opts.set {
			elem.decoder = ctx.decodeStructAsSet
		}
	case reflect.Array:
		if objType.Elem().Kind() == reflect.Uint8 {
			elem.tag = tagOctetString
			elem.decoder = ctx.decodeOctetString
		} else {
			elem.tag = tagSequence
			elem.decoder = ctx.decodeArray
		}
	case reflect.Slice:
		if objType.Elem().Kind() == reflect.Uint8 {
			elem.tag = tagOctetString
			elem.decoder = ctx.decodeOctetString
		} else {
			elem.tag = tagSequence
			elem.decoder = ctx.decodeSlice
		}
	}
	return
}
func (ctx *Context) getExpectedFieldElements(value reflect.Value) ([]expectedFieldElement, error) {
	expectedValues := []expectedFieldElement{}
	for i := 0; i < value.NumField(); i++ {
		if value.CanSet() {
			field := value.Field(i)
			opts, err := parseOptions(value.Type().Field(i).Tag.Get(tagKey))
			if err != nil {
				return nil, err
			}
			raw := &rawValue{}
			if opts.choice == nil {
				elem, err := ctx.getExpectedElement(raw, field.Type(), opts)
				if err != nil {
					return nil, err
				}
				expectedValues = append(expectedValues,
					expectedFieldElement{elem, field, opts})
			} else {
				entries, err := ctx.getChoices(*opts.choice)
				if err != nil {
					return nil, err
				}
				for _, entry := range entries {
					raw.Class = entry.class
					raw.Tag = entry.tag
					elem, err := ctx.getExpectedElement(raw, field.Type(), opts)
					if err != nil {
						return nil, err
					}
					expectedValues = append(expectedValues,
						expectedFieldElement{elem, field, opts})
				}
			}
		}
	}
	return expectedValues, nil
}