decode.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package oscar
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "io"
  7. "reflect"
  8. )
  9. func Unmarshal(v any, r io.Reader) error {
  10. return unmarshal(reflect.TypeOf(v).Elem(), reflect.ValueOf(v).Elem(), "", r)
  11. }
  12. func unmarshal(t reflect.Type, v reflect.Value, tag reflect.StructTag, r io.Reader) error {
  13. switch v.Kind() {
  14. case reflect.Struct:
  15. switch v.Interface().(type) {
  16. case TLVRestBlock:
  17. val := TLVRestBlock{}
  18. if err := val.Read(r); err != nil {
  19. return err
  20. }
  21. v.Set(reflect.ValueOf(val))
  22. case TLVLBlock:
  23. val := TLVLBlock{}
  24. if err := val.Read(r); err != nil {
  25. return err
  26. }
  27. v.Set(reflect.ValueOf(val))
  28. case TLVBlock:
  29. val := TLVBlock{}
  30. if err := val.Read(r); err != nil {
  31. return err
  32. }
  33. v.Set(reflect.ValueOf(val))
  34. default:
  35. for i := 0; i < v.NumField(); i++ {
  36. if err := unmarshal(t.Field(i).Type, v.Field(i), t.Field(i).Tag, r); err != nil {
  37. return err
  38. }
  39. }
  40. }
  41. case reflect.String:
  42. var bufLen int
  43. if lenTag, ok := tag.Lookup("len_prefix"); ok {
  44. switch lenTag {
  45. case "uint8":
  46. var l uint8
  47. if err := binary.Read(r, binary.BigEndian, &l); err != nil {
  48. return err
  49. }
  50. bufLen = int(l)
  51. case "uint16":
  52. var l uint16
  53. if err := binary.Read(r, binary.BigEndian, &l); err != nil {
  54. return err
  55. }
  56. bufLen = int(l)
  57. default:
  58. panic("invalid len_prefix")
  59. }
  60. } else {
  61. panic("string length not set")
  62. }
  63. buf := make([]byte, bufLen)
  64. if _, err := r.Read(buf); err != nil {
  65. return err
  66. }
  67. // todo is there a more efficient way?
  68. v.SetString(string(buf))
  69. case reflect.Uint8:
  70. var l uint8
  71. if err := binary.Read(r, binary.BigEndian, &l); err != nil {
  72. return err
  73. }
  74. v.Set(reflect.ValueOf(l))
  75. case reflect.Uint16:
  76. var l uint16
  77. if err := binary.Read(r, binary.BigEndian, &l); err != nil {
  78. return err
  79. }
  80. v.Set(reflect.ValueOf(l))
  81. case reflect.Uint32:
  82. var l uint32
  83. if err := binary.Read(r, binary.BigEndian, &l); err != nil {
  84. return err
  85. }
  86. v.Set(reflect.ValueOf(l))
  87. case reflect.Uint64:
  88. var l uint64
  89. if err := binary.Read(r, binary.BigEndian, &l); err != nil {
  90. return err
  91. }
  92. v.Set(reflect.ValueOf(l))
  93. case reflect.Slice:
  94. if lenTag, ok := tag.Lookup("len_prefix"); ok {
  95. var bufLen int
  96. switch lenTag {
  97. case "uint8":
  98. var l uint8
  99. if err := binary.Read(r, binary.BigEndian, &l); err != nil {
  100. return err
  101. }
  102. bufLen = int(l)
  103. case "uint16":
  104. var l uint16
  105. if err := binary.Read(r, binary.BigEndian, &l); err != nil {
  106. return err
  107. }
  108. bufLen = int(l)
  109. default:
  110. panic("length not set")
  111. }
  112. buf := make([]byte, bufLen)
  113. if _, err := r.Read(buf); err != nil {
  114. return err
  115. }
  116. b := bytes.NewBuffer(buf)
  117. slice := reflect.New(v.Type()).Elem()
  118. for b.Len() > 0 {
  119. v1 := reflect.New(v.Type().Elem()).Interface()
  120. if err := Unmarshal(v1, b); err != nil {
  121. return err
  122. }
  123. slice = reflect.Append(slice, reflect.ValueOf(v1).Elem())
  124. }
  125. v.Set(slice)
  126. } else if countTag, ok := tag.Lookup("count_prefix"); ok {
  127. var count int
  128. switch countTag {
  129. case "uint8":
  130. var l uint8
  131. if err := binary.Read(r, binary.BigEndian, &l); err != nil {
  132. return err
  133. }
  134. count = int(l)
  135. case "uint16":
  136. var l uint16
  137. if err := binary.Read(r, binary.BigEndian, &l); err != nil {
  138. return err
  139. }
  140. count = int(l)
  141. default:
  142. panic("count not set")
  143. }
  144. slice := reflect.New(v.Type()).Elem()
  145. for i := 0; i < count; i++ {
  146. v1 := reflect.New(v.Type().Elem()).Interface()
  147. if err := Unmarshal(v1, r); err != nil {
  148. return err
  149. }
  150. slice = reflect.Append(slice, reflect.ValueOf(v1).Elem())
  151. }
  152. v.Set(slice)
  153. } else {
  154. slice := reflect.New(v.Type()).Elem()
  155. for {
  156. v1 := reflect.New(v.Type().Elem()).Interface()
  157. if err := Unmarshal(v1, r); err != nil {
  158. if err == io.EOF {
  159. break
  160. }
  161. return err
  162. }
  163. slice = reflect.Append(slice, reflect.ValueOf(v1).Elem())
  164. }
  165. v.Set(slice)
  166. }
  167. case reflect.Array:
  168. buf := make([]byte, v.Len())
  169. if _, err := r.Read(buf); err != nil {
  170. return err
  171. }
  172. array := reflect.New(v.Type()).Elem()
  173. for j := 0; j < len(buf); j++ {
  174. array.Index(j).SetUint(uint64(buf[j]))
  175. }
  176. v.Set(array)
  177. default:
  178. return errors.New("unsupported type for unmarshalling")
  179. }
  180. return nil
  181. }