varbin: Unique pointer value format for array or map value

This commit is contained in:
世界 2024-06-24 19:51:17 +08:00
parent 4745c34b4c
commit 0b4c0a1283
No known key found for this signature in database
GPG key ID: CD109927C34A63C4

View file

@ -42,7 +42,7 @@ func Read(r io.Reader, order binary.ByteOrder, rawData any) error {
return binary.Read(reader, order, rawData) return binary.Read(reader, order, rawData)
} }
} }
return read(reader, order, reflect.Indirect(reflect.ValueOf(rawData))) return read(reader, order, reflect.Indirect(reflect.ValueOf(rawData)), false)
} }
func ReadValue[T any](r io.Reader, order binary.ByteOrder) (T, error) { func ReadValue[T any](r io.Reader, order binary.ByteOrder) (T, error) {
@ -72,21 +72,23 @@ func readBase[T any](r Reader, order binary.ByteOrder, data *[]T) error {
return nil return nil
} }
func read(r Reader, order binary.ByteOrder, data reflect.Value) error { func read(r Reader, order binary.ByteOrder, data reflect.Value, isArrayMapValue bool) error {
switch data.Kind() { switch data.Kind() {
case reflect.Pointer: case reflect.Pointer:
pointerValue, err := r.ReadByte() if !isArrayMapValue {
if err != nil { pointerValue, err := r.ReadByte()
return err if err != nil {
} return err
if pointerValue == 0 { }
data.SetZero() if pointerValue == 0 {
return nil data.SetZero()
return nil
}
} }
if data.IsNil() { if data.IsNil() {
data.Set(reflect.New(data.Type().Elem())) data.Set(reflect.New(data.Type().Elem()))
} }
return read(r, order, data.Elem()) return read(r, order, data.Elem(), false)
case reflect.String: case reflect.String:
stringLength, err := binary.ReadUvarint(r) stringLength, err := binary.ReadUvarint(r)
if err != nil { if err != nil {
@ -114,7 +116,7 @@ func read(r Reader, order binary.ByteOrder, data reflect.Value) error {
binary.DecodeValue(order, buf, data) binary.DecodeValue(order, buf, data)
} else { } else {
for i := 0; i < arrayLen; i++ { for i := 0; i < arrayLen; i++ {
err := read(r, order, data.Index(i)) err := read(r, order, data.Index(i), true)
if err != nil { if err != nil {
return E.Cause(err, "[", i, "]") return E.Cause(err, "[", i, "]")
} }
@ -147,7 +149,7 @@ func read(r Reader, order binary.ByteOrder, data reflect.Value) error {
data.Set(reflect.MakeSlice(data.Type(), itemLength, itemLength)) data.Set(reflect.MakeSlice(data.Type(), itemLength, itemLength))
} }
for i := 0; i < itemLength; i++ { for i := 0; i < itemLength; i++ {
err := read(r, order, data.Index(i)) err := read(r, order, data.Index(i), true)
if err != nil { if err != nil {
return E.Cause(err, "[", i, "]") return E.Cause(err, "[", i, "]")
} }
@ -162,12 +164,12 @@ func read(r Reader, order binary.ByteOrder, data reflect.Value) error {
data.Set(reflect.MakeMap(data.Type())) data.Set(reflect.MakeMap(data.Type()))
for index := 0; index < int(mapLength); index++ { for index := 0; index < int(mapLength); index++ {
key := reflect.New(data.Type().Key()).Elem() key := reflect.New(data.Type().Key()).Elem()
err = read(r, order, key) err = read(r, order, key, false)
if err != nil { if err != nil {
return E.Cause(err, "[", index, "].key") return E.Cause(err, "[", index, "].key")
} }
value := reflect.New(data.Type().Elem()).Elem() value := reflect.New(data.Type().Elem()).Elem()
err = read(r, order, value) err = read(r, order, value, true)
if err != nil { if err != nil {
return E.Cause(err, "[", index, "].value") return E.Cause(err, "[", index, "].value")
} }
@ -180,7 +182,7 @@ func read(r Reader, order binary.ByteOrder, data reflect.Value) error {
field := data.Field(i) field := data.Field(i)
fieldName := fieldType.Field(i).Name fieldName := fieldType.Field(i).Name
if field.CanSet() || fieldName != "_" { if field.CanSet() || fieldName != "_" {
err := read(r, order, field) err := read(r, order, field, false)
if err != nil { if err != nil {
return E.Cause(err, fieldName) return E.Cause(err, fieldName)
} }
@ -239,7 +241,7 @@ func Write(w io.Writer, order binary.ByteOrder, rawData any) error {
case []float64: case []float64:
return writeBase(writer, order, data) return writeBase(writer, order, data)
} }
err := write(writer, order, reflect.Indirect(reflect.ValueOf(rawData))) err := write(writer, order, reflect.Indirect(reflect.ValueOf(rawData)), false)
if err != nil { if err != nil {
return err return err
} }
@ -263,20 +265,26 @@ func writeBase[T any](writer Writer, order binary.ByteOrder, data []T) error {
return nil return nil
} }
func write(writer Writer, order binary.ByteOrder, data reflect.Value) error { func write(writer Writer, order binary.ByteOrder, data reflect.Value, isArrayOrMapValue bool) error {
switch data.Kind() { switch data.Kind() {
case reflect.Pointer: case reflect.Pointer:
if data.IsNil() { if data.IsNil() {
err := writer.WriteByte(0) if isArrayOrMapValue {
if err != nil { return E.New("nil array or map value")
return err } else {
err := writer.WriteByte(0)
if err != nil {
return err
}
} }
} else { } else {
err := writer.WriteByte(1) if !isArrayOrMapValue {
if err != nil { err := writer.WriteByte(1)
return err if err != nil {
return err
}
} }
return write(writer, order, data.Elem()) return write(writer, order, data.Elem(), false)
} }
case reflect.String: case reflect.String:
stringValue := data.String() stringValue := data.String()
@ -303,7 +311,7 @@ func write(writer Writer, order binary.ByteOrder, data reflect.Value) error {
} }
} else { } else {
for i := 0; i < dataLen; i++ { for i := 0; i < dataLen; i++ {
err := write(writer, order, data.Index(i)) err := write(writer, order, data.Index(i), true)
if err != nil { if err != nil {
return E.Cause(err, "[", i, "]") return E.Cause(err, "[", i, "]")
} }
@ -325,7 +333,7 @@ func write(writer Writer, order binary.ByteOrder, data reflect.Value) error {
} }
} else { } else {
for i := 0; i < dataLen; i++ { for i := 0; i < dataLen; i++ {
err = write(writer, order, data.Index(i)) err = write(writer, order, data.Index(i), true)
if err != nil { if err != nil {
return E.Cause(err, "[", i, "]") return E.Cause(err, "[", i, "]")
} }
@ -340,11 +348,11 @@ func write(writer Writer, order binary.ByteOrder, data reflect.Value) error {
} }
if dataLen > 0 { if dataLen > 0 {
for index, key := range data.MapKeys() { for index, key := range data.MapKeys() {
err = write(writer, order, key) err = write(writer, order, key, false)
if err != nil { if err != nil {
return E.Cause(err, "[", index, "].key") return E.Cause(err, "[", index, "].key")
} }
err = write(writer, order, data.MapIndex(key)) err = write(writer, order, data.MapIndex(key), true)
if err != nil { if err != nil {
return E.Cause(err, "[", index, "].value") return E.Cause(err, "[", index, "].value")
} }
@ -357,7 +365,7 @@ func write(writer Writer, order binary.ByteOrder, data reflect.Value) error {
field := data.Field(i) field := data.Field(i)
fieldName := fieldType.Field(i).Name fieldName := fieldType.Field(i).Name
if field.CanSet() || fieldName != "_" { if field.CanSet() || fieldName != "_" {
err := write(writer, order, field) err := write(writer, order, field, false)
if err != nil { if err != nil {
return E.Cause(err, fieldName) return E.Cause(err, fieldName)
} }