package ssob import ( "encoding/binary" "fmt" "io" "reflect" "sync" ) type UnsafeEncoder struct { mutex sync.Mutex w io.Writer } func NewUnsafeEncoder(w io.Writer) *UnsafeEncoder { enc := new(UnsafeEncoder) enc.w = w return enc } func (enc *UnsafeEncoder) Encode(e interface{}) (err error) { return enc.EncodeValue(reflect.ValueOf(e)) } func (enc *UnsafeEncoder) EncodeValue(value reflect.Value) (err error) { if value.Kind() == reflect.Invalid { return fmt.Errorf("ssob: Cannot encode nil: %w", ErrValueInvalid) } if value.Kind() == reflect.Ptr && value.IsNil() { return fmt.Errorf("ssob: Cannot encode nil of type %s: %w", value.Type().String(), ErrValueInvalid) } bb, err := unsafeMarshal(value.Interface()) if err != nil { return err } bl := UnsafeMarshalInt32(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) }