package ssob import ( "encoding/binary" "fmt" "io" "reflect" "sync" ) type Decoder struct { mutex sync.Mutex r io.Reader } func NewDecoder(r io.Reader) *Decoder { dec := new(Decoder) dec.r = r return dec } func (dec *Decoder) Decode(e interface{}) (ret interface{}, err error) { st := make([]byte, ST_ID_SIZE) dec.mutex.Lock() defer dec.mutex.Unlock() if err = binary.Read(dec.r, binary.BigEndian, st); err != nil { return nil, err } l := binary.BigEndian.Uint32(st) b := make([]byte, l) if err = binary.Read(dec.r, binary.BigEndian, b); err != nil { return nil, fmt.Errorf("ssob: Cannot decode value: %w", err) } _, ret, err = unmarshalVal(b) if err != nil { return ret, err } ret = getVal(ret).Interface() if e != nil { var v reflect.Value if v, err = indirectValue(reflect.ValueOf(e)); err != nil { return ret, ErrValueInvalid } if valueIsNil(v) { return ret, ErrValueInvalid } if v.Type() != reflect.TypeOf(ret) { return ret, ErrTypeMismatch } v.Set(reflect.ValueOf(ret)) } return ret, err }