package ssob import ( "encoding/binary" "errors" "io" "reflect" "sync" ) type Encoder struct { mutex sync.Mutex w io.Writer } func NewEncoder(w io.Writer) *Encoder { enc := new(Encoder) enc.w = w return enc } func (enc *Encoder) Encode(e interface{}) (err error) { return enc.EncodeValue(reflect.ValueOf(e)) } func (enc *Encoder) EncodeValue(value reflect.Value) (err error) { if value.Kind() == reflect.Invalid { return errors.New("ssob: Cannot encode nil value") } if value.Kind() == reflect.Ptr && value.IsNil() { return errors.New("ssob: Cannot encode nil of type " + value.Type().String()) } bb, err := marshal(value.Interface()) if err != nil { return err } bl := MarshalInt32(int32(len(bb))) w := make([]byte, 4+len(bb)) copy(w, bl) copy(w[4:], bb) enc.mutex.Lock() defer enc.mutex.Unlock() return binary.Write(enc.w, binary.BigEndian, w) }