mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-05 04:47:40 +03:00
varbin: Unique pointer value format for array or map value
This commit is contained in:
parent
4745c34b4c
commit
0b4c0a1283
1 changed files with 37 additions and 29 deletions
|
@ -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,9 +72,10 @@ 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:
|
||||||
|
if !isArrayMapValue {
|
||||||
pointerValue, err := r.ReadByte()
|
pointerValue, err := r.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -83,10 +84,11 @@ func read(r Reader, order binary.ByteOrder, data reflect.Value) error {
|
||||||
data.SetZero()
|
data.SetZero()
|
||||||
return nil
|
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() {
|
||||||
|
if isArrayOrMapValue {
|
||||||
|
return E.New("nil array or map value")
|
||||||
|
} else {
|
||||||
err := writer.WriteByte(0)
|
err := writer.WriteByte(0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if !isArrayOrMapValue {
|
||||||
err := writer.WriteByte(1)
|
err := writer.WriteByte(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue