Skip to content

Commit 89b293f

Browse files
committed
Use decode method
1 parent 80d1d62 commit 89b293f

File tree

2 files changed

+87
-65
lines changed

2 files changed

+87
-65
lines changed

serialization/serialization.go

Lines changed: 78 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,39 @@ func (f FieldIntFixed) String() string {
8787
return fmt.Sprintf("0x%x", f.Value)
8888
}
8989

90+
func (f *FieldIntFixed) decode(data []byte, pos uint64) (uint64, error) {
91+
var b bytes.Buffer
92+
b.Grow(f.Length * 2) // output is between 1 and 2 times that of the input
93+
94+
for {
95+
if len(data) < int(pos)+1 {
96+
return pos, errors.New("data truncated")
97+
}
98+
if data[pos]%2 == 0 {
99+
b.WriteByte(data[pos] >> 1)
100+
} else {
101+
if len(data) < int(pos)+2 {
102+
return pos, errors.New("data truncated")
103+
}
104+
switch data[pos+1] {
105+
case 0x2:
106+
b.WriteByte((data[pos] >> 2) + 0x80)
107+
case 0x3:
108+
b.WriteByte((data[pos] >> 2) + 0xc0)
109+
default:
110+
return pos, fmt.Errorf("unknown decoding for %v", data[pos])
111+
}
112+
pos++
113+
}
114+
pos++
115+
if b.Len() == f.Length {
116+
break
117+
}
118+
}
119+
f.Value = b.Bytes()
120+
return pos, nil
121+
}
122+
90123
// FieldIntVar is using the signed integer variant of the 'varlen_integer_format'
91124
// and encodes a value as a byte sequence of 1-9 bytes depending on the value.
92125
type FieldIntVar struct {
@@ -97,6 +130,20 @@ func (f FieldIntVar) String() string {
97130
return fmt.Sprintf("%d", f.Value)
98131
}
99132

133+
func (f *FieldIntVar) decode(data []byte, pos uint64) (uint64, error) {
134+
var val interface{}
135+
val, pos, err := decodeVar(data, pos, false)
136+
if err != nil {
137+
return pos, err
138+
}
139+
if intval, ok := val.(int64); ok {
140+
f.Value = intval
141+
} else {
142+
return pos, errors.New("unexpected type, expecting int64")
143+
}
144+
return pos, nil
145+
}
146+
100147
// FieldUintVar is using the unsigned integer variant of the 'varlen_integer_format'
101148
// and encodes a value as a byte sequence of 1-9 bytes depending on the value.
102149
type FieldUintVar struct {
@@ -107,11 +154,38 @@ func (f FieldUintVar) String() string {
107154
return fmt.Sprintf("%d", f.Value)
108155
}
109156

157+
func (f *FieldUintVar) decode(data []byte, pos uint64) (uint64, error) {
158+
var val interface{}
159+
val, pos, err := decodeVar(data, pos, true)
160+
if err != nil {
161+
return pos, err
162+
}
163+
if uintval, ok := val.(uint64); ok {
164+
f.Value = uintval
165+
} else {
166+
return pos, errors.New("unexpected type, expecting uint64")
167+
}
168+
return pos, nil
169+
}
170+
110171
// FieldString is a 'string_format' field
111172
type FieldString struct {
112173
Value string
113174
}
114175

176+
func (f *FieldString) decode(data []byte, pos uint64) (uint64, error) {
177+
if len(data) < int(pos)+1 {
178+
return pos, errors.New("string truncated, expected at least one byte")
179+
}
180+
strLen := int(data[pos] >> 1)
181+
pos++
182+
if len(data) < int(pos)+strLen {
183+
return pos, fmt.Errorf("string truncated, expected length: %d", strLen)
184+
}
185+
f.Value = string(data[pos : pos+uint64(strLen)])
186+
return pos + uint64(strLen), nil
187+
}
188+
115189
func (f FieldString) String() string {
116190
return f.Value
117191
}
@@ -151,37 +225,25 @@ func Unmarshal(data []byte, v interface{}) error {
151225
var err error
152226
switch f := m.Fields[i].Type.(type) {
153227
case FieldIntFixed:
154-
f.Value, n, err = decodeFixed(data, pos, f.Length)
228+
n, err = f.decode(data, pos)
155229
if err != nil {
156230
return err
157231
}
158232
m.Fields[i].Type = f
159233
case FieldUintVar:
160-
var val interface{}
161-
val, n, err = decodeVar(data, pos, true)
234+
n, err = f.decode(data, pos)
162235
if err != nil {
163236
return err
164237
}
165-
if uintval, ok := val.(uint64); ok {
166-
f.Value = uintval
167-
} else {
168-
return errors.New("unexpected type, expecting uint64")
169-
}
170238
m.Fields[i].Type = f
171239
case FieldIntVar:
172-
var val interface{}
173-
val, n, err = decodeVar(data, pos, false)
240+
n, err = f.decode(data, pos)
174241
if err != nil {
175242
return err
176243
}
177-
if intval, ok := val.(int64); ok {
178-
f.Value = intval
179-
} else {
180-
return errors.New("unexpected type, expecting int64")
181-
}
182244
m.Fields[i].Type = f
183245
case FieldString:
184-
f.Value, n, err = decodeString(data, pos)
246+
n, err = f.decode(data, pos)
185247
if err != nil {
186248
return err
187249
}
@@ -198,50 +260,6 @@ func Unmarshal(data []byte, v interface{}) error {
198260
return nil
199261
}
200262

201-
func decodeString(data []byte, pos uint64) (string, uint64, error) {
202-
if len(data) < int(pos)+1 {
203-
return "", pos, errors.New("string truncated, expected at least one byte")
204-
}
205-
strLen := int(data[pos] >> 1)
206-
pos++
207-
if len(data) < int(pos)+strLen {
208-
return "", pos, fmt.Errorf("string truncated, expected length: %d", strLen)
209-
}
210-
return string(data[pos : pos+uint64(strLen)]), pos + uint64(strLen), nil
211-
}
212-
213-
func decodeFixed(data []byte, pos uint64, intlen int) ([]byte, uint64, error) {
214-
var b bytes.Buffer
215-
b.Grow(intlen * 2) // output is between 1 and 2 times that of the input
216-
217-
for {
218-
if len(data) < int(pos)+1 {
219-
return b.Bytes(), pos, errors.New("data truncated")
220-
}
221-
if data[pos]%2 == 0 {
222-
b.WriteByte(data[pos] >> 1)
223-
} else {
224-
if len(data) < int(pos)+2 {
225-
return b.Bytes(), pos, errors.New("data truncated")
226-
}
227-
switch data[pos+1] {
228-
case 0x2:
229-
b.WriteByte((data[pos] >> 2) + 0x80)
230-
case 0x3:
231-
b.WriteByte((data[pos] >> 2) + 0xc0)
232-
default:
233-
return nil, pos, fmt.Errorf("unknown decoding for %v", data[pos])
234-
}
235-
pos++
236-
}
237-
pos++
238-
if b.Len() == intlen {
239-
break
240-
}
241-
}
242-
return b.Bytes(), pos, nil
243-
}
244-
245263
func decodeVar(data []byte, pos uint64, unsigned bool) (interface{}, uint64, error) {
246264
if len(data) < int(pos)+1 {
247265
return 0, pos, errors.New("data truncated")

serialization/serialization_test.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,14 @@ func TestDecodeFixed(t *testing.T) {
7070
}
7171

7272
for _, tc := range testcases {
73-
actual, _, err := decodeFixed(tc.input, 0, tc.len)
73+
f := FieldIntFixed{
74+
Length: tc.len,
75+
}
76+
_, err := f.decode(tc.input, 0)
7477
if tc.err == "" {
7578
require.NoError(t, err)
76-
require.Equal(t, tc.result, actual)
77-
require.Equal(t, tc.len, len(actual))
79+
require.Equal(t, tc.result, f.Value)
80+
require.Equal(t, tc.len, len(f.Value))
7881
} else {
7982
require.ErrorContains(t, err, tc.err)
8083
}
@@ -110,10 +113,11 @@ func TestDecodeString(t *testing.T) {
110113
}
111114

112115
for _, tc := range testcases {
113-
s, _, err := decodeString(tc.input, 0)
116+
f := FieldString{}
117+
_, err := f.decode(tc.input, 0)
114118
if tc.err == "" {
115119
require.NoError(t, err)
116-
require.Equal(t, tc.result, s)
120+
require.Equal(t, tc.result, f.Value)
117121
} else {
118122
require.ErrorContains(t, err, tc.err)
119123
}

0 commit comments

Comments
 (0)