ssob/decoder.go

61 lines
1.0 KiB
Go
Raw Permalink Normal View History

2019-10-04 12:28:45 +02:00
package ssob
import (
"encoding/binary"
"fmt"
2019-10-04 12:28:45 +02:00
"io"
"reflect"
2019-10-04 12:28:45 +02:00
"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) {
2021-09-02 00:08:59 +02:00
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
}
2021-09-06 23:33:50 +02:00
l := binary.BigEndian.Uint32(st)
b := make([]byte, l)
2021-09-07 16:05:04 +02:00
if err = binary.Read(dec.r, binary.BigEndian, b); err != nil {
2021-09-06 23:33:50 +02:00
return nil, fmt.Errorf("ssob: Cannot decode value: %w", err)
}
_, ret, err = unmarshalVal(b)
if err != nil {
return ret, err
2021-09-02 00:08:59 +02:00
}
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
2021-09-02 00:08:59 +02:00
}