From 6b6c369b624b9ddccd9a23eed78e0340db99ad85 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sat, 27 Jun 2015 01:34:48 +0200 Subject: Add Marshal --- ber/marshal.go | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 ber/marshal.go (limited to 'ber/marshal.go') diff --git a/ber/marshal.go b/ber/marshal.go new file mode 100644 index 0000000..ca91271 --- /dev/null +++ b/ber/marshal.go @@ -0,0 +1,82 @@ +package ber + +import ( + "bytes" + "reflect" + "runtime" +) + +type encodeState struct { + bytes.Buffer +} + +type Marshaler interface { + MarschalBER() ([]byte, error) +} + +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) { + defer func() { + if r := recover(); r != nil { + if _, ok := r.(runtime.Error); ok { + panic(r) + } + if s, ok := r.(string); ok { + panic(s) + } + err = r.(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) +} -- cgit v1.2.3