aboutsummaryrefslogtreecommitdiff
path: root/ber/marshal.go
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2015-06-27 01:34:48 +0200
committerDimitri Sokolyuk <demon@dim13.org>2015-06-27 01:34:48 +0200
commit6b6c369b624b9ddccd9a23eed78e0340db99ad85 (patch)
treee29a0467e2321f6cbfb1994a6339d709839b3212 /ber/marshal.go
parent69bf3fb4d2017639d5b0b01c1a5ba6e2dd31274f (diff)
Add Marshal
Diffstat (limited to 'ber/marshal.go')
-rw-r--r--ber/marshal.go82
1 files changed, 82 insertions, 0 deletions
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)
+}