package ber import ( "bytes" "reflect" ) type Marshaler interface { Marshal() ([]byte, error) } type Unmarshaler interface { Unmarshal([]byte) error } type ASN1 interface { Marshaler Unmarshaler } type encodeState struct { bytes.Buffer } func Marshal(v interface{}) ([]byte, error) { e := &encodeState{} err := e.marshal(v) if err != nil { return nil, err } return e.Bytes(), nil } func (e *encodeState) marshal(v interface{}) (err error) { e.reflectValue(reflect.ValueOf(v)) return nil } func (e *encodeState) reflectValue(v reflect.Value) { valueEncoder(v)(e, v) } type encoderFunc func(e *encodeState, v reflect.Value) func valueEncoder(v reflect.Value) encoderFunc { if !v.IsValid() { return invalidValueEncoder } return newTypeEncoder(v.Type()) } func invalidValueEncoder(e *encodeState, v reflect.Value) { e.WriteByte(0) } func newTypeEncoder(t reflect.Type) encoderFunc { switch t.Kind() { case reflect.Int: return intEncoder default: return unsupportedTypeEncoder } } type UnsupportedTypeError struct { Type reflect.Type } func (e *UnsupportedTypeError) Error() string { return "BER: unsupported type: " + e.Type.String() } func unsupportedTypeEncoder(e *encodeState, v reflect.Value) { e.error(&UnsupportedTypeError{v.Type()}) } func (e *encodeState) error(err error) { panic(err) } func intEncoder(e *encodeState, v reflect.Value) { b := marshalInt(v.Int()) e.Write(b) } func objEncoder(e *encodeState, v reflect.Value) { b := marshalOID(v.Interface().(OID)) e.Write(b) }