Skip to content

Commit cd013bb

Browse files
authored
fix padding (#30)
Signed-off-by: Song Gao <disxiaofei@163.com>
1 parent aef31de commit cd013bb

7 files changed

Lines changed: 74 additions & 298 deletions

File tree

ast/typeref/string.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import (
1111

1212
type StringType struct {
1313
SelfType string `json:"self_type"`
14-
Length *int `json:"length,omitempty"`
14+
// If Length is nil, this is a dynamic string, otherwise this is a fixed length string
15+
Length *int `json:"length,omitempty"`
1516
}
1617

1718
func NewStringType() StringType {

converter/array_converter_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func TestParseArrayTypes(t *testing.T) {
4949
require.Nil(t, typeResult.Err)
5050
require.Equal(t, typ.ArrayType, typeResult.Output.TypeRefType())
5151
converter := createTestConverter(false) // big endian
52-
result, remain, err := converter.ParseDataByType(test.data, typeResult.Output, ast.Module{}, true)
52+
result, remain, err := converter.ParseDataByType(test.data, typeResult.Output, ast.Module{})
5353
require.NoError(t, err)
5454
require.Equal(t, test.expected, result)
5555
require.Empty(t, remain)
@@ -85,7 +85,7 @@ func TestParseArrayTypesLittleEndian(t *testing.T) {
8585
require.Nil(t, typeResult.Err)
8686
require.Equal(t, typ.ArrayType, typeResult.Output.TypeRefType())
8787
converter := createTestConverter(true) // little endian
88-
result, remain, err := converter.ParseDataByType(test.data, typeResult.Output, ast.Module{}, true)
88+
result, remain, err := converter.ParseDataByType(test.data, typeResult.Output, ast.Module{})
8989
require.NoError(t, err)
9090
require.Equal(t, test.expected, result)
9191
require.Empty(t, remain)
@@ -121,7 +121,7 @@ func TestParseArrayError(t *testing.T) {
121121
converter := createTestConverter(false)
122122

123123
// 解析数据应该失败
124-
result, remain, err := converter.ParseDataByType(test.data, typeResult.Output, ast.Module{}, true)
124+
result, remain, err := converter.ParseDataByType(test.data, typeResult.Output, ast.Module{})
125125
require.Error(t, err)
126126
require.Nil(t, result)
127127
require.Nil(t, remain)

converter/converter.go

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,11 @@ func (c *IDLConverter) Decode(schemaID string, data []byte) (map[string]interfac
231231
return nil, err
232232
}
233233
c.TotalBytes = len(data)
234-
v, _, err := c.ParseBytesToStruct(data, *targetSts, *targetModule, true)
234+
v, _, err := c.ParseBytesToStruct(data, *targetSts, *targetModule)
235235
return v, err
236236
}
237237

238-
func (c *IDLConverter) ParseDataByType(data []byte, t typeref.TypeRef, module ast.Module, isLastField bool) (interface{}, []byte, error) {
238+
func (c *IDLConverter) ParseDataByType(data []byte, t typeref.TypeRef, module ast.Module) (interface{}, []byte, error) {
239239

240240
var result interface{}
241241
var remained []byte
@@ -247,7 +247,7 @@ func (c *IDLConverter) ParseDataByType(data []byte, t typeref.TypeRef, module as
247247
if !ok {
248248
return nil, nil, fmt.Errorf("type %v is not array type", t.TypeRefType())
249249
}
250-
result, remained, err = c.ParseArray(data, arrayType, module, isLastField)
250+
result, remained, err = c.ParseArray(data, arrayType, module)
251251
case typ.OctetType:
252252
otResult, newRemained, newErr := c.ParseOctet(data)
253253
result, remained, err = otResult, newRemained, newErr
@@ -280,16 +280,16 @@ func (c *IDLConverter) ParseDataByType(data []byte, t typeref.TypeRef, module as
280280
result, remained, err = doubleResult, newRemained, newErr
281281
case typ.SequenceType:
282282
seq := t.(typeref.Sequence)
283-
result, remained, err = c.ParseBytesToList(data, seq, module, isLastField)
283+
result, remained, err = c.ParseBytesToList(data, seq, module)
284284
case typ.StringType:
285285
st, ok := t.(typeref.StringType)
286286
if !ok {
287287
return nil, nil, fmt.Errorf("type %v is not string type", t.TypeRefType())
288288
}
289-
result, remained, err = c.ParseString(data, st, module, isLastField)
289+
result, remained, err = c.ParseString(data, st, module)
290290
case typ.SelfDefinedTypeType:
291291
definedType := t.(typeref.TypeName)
292-
result, remained, err = c.ParseSelfDefineType(data, definedType, module, isLastField)
292+
result, remained, err = c.ParseSelfDefineType(data, definedType, module)
293293
default:
294294
return nil, nil, fmt.Errorf("unsupported type:%v", t.TypeName())
295295
}
@@ -299,17 +299,23 @@ func (c *IDLConverter) ParseDataByType(data []byte, t typeref.TypeRef, module as
299299
return result, remained, nil
300300
}
301301

302-
func (c *IDLConverter) ParseArray(data []byte, arrayType typeref.ArrayType, module ast.Module, isParLast bool) ([]interface{}, []byte, error) {
302+
func (c *IDLConverter) ParseArray(data []byte, arrayType typeref.ArrayType, module ast.Module) ([]interface{}, []byte, error) {
303303
remained := data
304304
var err error
305305
var v interface{}
306306
result := make([]interface{}, 0, arrayType.ArraySize)
307307
for i := 0; i < arrayType.ArraySize; i++ {
308-
v, remained, err = c.ParseDataByType(remained, arrayType.InnerType, module, isParLast && i == arrayType.ArraySize-1)
308+
v, remained, err = c.ParseDataByType(remained, arrayType.InnerType, module)
309309
if err != nil {
310310
return nil, nil, fmt.Errorf("Parse array element %v error:%v", i, err.Error())
311311
}
312312
result = append(result, v)
313+
if len(remained) > 0 && isNeedPaddingType(arrayType.InnerType) {
314+
remained, err = c.consumePadding(remained)
315+
if err != nil {
316+
return nil, nil, fmt.Errorf("Parse array element %v error:%v", i, err.Error())
317+
}
318+
}
313319
}
314320
return result, remained, nil
315321
}
@@ -364,7 +370,7 @@ func (c *IDLConverter) ParseDouble(data []byte) (float64, []byte, error) {
364370
return result, remained, err
365371
}
366372

367-
func (c *IDLConverter) ParseString(data []byte, st typeref.StringType, _ ast.Module, isLast bool) (interface{}, []byte, error) {
373+
func (c *IDLConverter) ParseString(data []byte, st typeref.StringType, _ ast.Module) (interface{}, []byte, error) {
368374
var result interface{}
369375
var remained []byte
370376
var err error
@@ -376,26 +382,26 @@ func (c *IDLConverter) ParseString(data []byte, st typeref.StringType, _ ast.Mod
376382
if err != nil {
377383
return nil, nil, err
378384
}
379-
remained, err = c.consumePadding(remained, isLast)
380-
if err != nil {
381-
return nil, nil, fmt.Errorf("consuming dynamic string field meet error:%v", err.Error())
382-
}
385+
//remained, err = c.consumePadding(remained, isLast)
386+
//if err != nil {
387+
// return nil, nil, fmt.Errorf("consuming dynamic string field meet error:%v", err.Error())
388+
//}
383389
}
384390
return result, remained, nil
385391
}
386392

387-
func (c *IDLConverter) ParseSelfDefineType(data []byte, definedType typeref.TypeName, module ast.Module, isParLast bool) (interface{}, []byte, error) {
393+
func (c *IDLConverter) ParseSelfDefineType(data []byte, definedType typeref.TypeName, module ast.Module) (interface{}, []byte, error) {
388394
for _, content := range module.Content {
389395
if content.GetName() == definedType.Name && content.ModuleContentType() == typ.StructType {
390396
st := content.(struct_type.Struct)
391-
return c.ParseBytesToStruct(data, st, module, isParLast)
397+
return c.ParseBytesToStruct(data, st, module)
392398
}
393399
}
394400
return nil, nil, fmt.Errorf("unsupported type:%v", definedType.Name)
395401
}
396402

397-
func (c *IDLConverter) consumePadding(remained []byte, isLast bool) ([]byte, error) {
398-
if len(remained) > 0 && !isLast {
403+
func (c *IDLConverter) consumePadding(remained []byte) ([]byte, error) {
404+
if len(remained) > 0 {
399405
consumedBytes := c.TotalBytes - len(remained)
400406
extraBytesLength := consumedBytes % c.PaddingLength
401407
paddingBytesLength := c.PaddingLength - extraBytesLength

converter/converter_test.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func TestParseDataByType_Octet(t *testing.T) {
114114
t.Run(tt.name, func(t *testing.T) {
115115
octetType := typeref.NewOctetType()
116116
converter := createTestConverter(tt.isLittleEndian)
117-
result, remain, err := converter.ParseDataByType(tt.data, octetType, ast.Module{}, true)
117+
result, remain, err := converter.ParseDataByType(tt.data, octetType, ast.Module{})
118118

119119
if tt.expectError {
120120
require.Error(t, err)
@@ -132,7 +132,7 @@ func TestParseDataByType_UnsupportedType(t *testing.T) {
132132
mockType := &mockUnsupportedType{}
133133
converter := createTestConverter(false)
134134

135-
result, remain, err := converter.ParseDataByType([]byte{1, 2, 3}, mockType, ast.Module{}, true)
135+
result, remain, err := converter.ParseDataByType([]byte{1, 2, 3}, mockType, ast.Module{})
136136

137137
require.Error(t, err)
138138
require.Contains(t, err.Error(), "unsupported type")
@@ -211,7 +211,7 @@ func TestParseDataByType_Short(t *testing.T) {
211211
t.Run(tt.name, func(t *testing.T) {
212212
shortType := typeref.NewShortType()
213213
converter := createTestConverter(tt.isLittleEndian)
214-
result, remain, err := converter.ParseDataByType(tt.data, shortType, ast.Module{}, true)
214+
result, remain, err := converter.ParseDataByType(tt.data, shortType, ast.Module{})
215215

216216
if tt.expectError {
217217
require.Error(t, err)
@@ -272,7 +272,7 @@ func TestParseDataByType_UnsignedShort(t *testing.T) {
272272
t.Run(tt.name, func(t *testing.T) {
273273
unsignedShortType := typeref.NewUnsignedShortType()
274274
converter := createTestConverter(tt.isLittleEndian)
275-
result, remain, err := converter.ParseDataByType(tt.data, unsignedShortType, ast.Module{}, true)
275+
result, remain, err := converter.ParseDataByType(tt.data, unsignedShortType, ast.Module{})
276276

277277
if tt.expectError {
278278
require.Error(t, err)
@@ -333,7 +333,7 @@ func TestParseDataByType_Long(t *testing.T) {
333333
t.Run(tt.name, func(t *testing.T) {
334334
longType := typeref.NewLongType()
335335
converter := createTestConverter(tt.isLittleEndian)
336-
result, remain, err := converter.ParseDataByType(tt.data, longType, ast.Module{}, true)
336+
result, remain, err := converter.ParseDataByType(tt.data, longType, ast.Module{})
337337

338338
if tt.expectError {
339339
require.Error(t, err)
@@ -382,7 +382,7 @@ func TestParseDataByType_UnsignedLong(t *testing.T) {
382382
t.Run(tt.name, func(t *testing.T) {
383383
unsignedLongType := typeref.NewUnsignedLong()
384384
converter := createTestConverter(false)
385-
result, remain, err := converter.ParseDataByType(tt.data, unsignedLongType, ast.Module{}, true)
385+
result, remain, err := converter.ParseDataByType(tt.data, unsignedLongType, ast.Module{})
386386

387387
if tt.expectError {
388388
require.Error(t, err)
@@ -431,7 +431,7 @@ func TestParseDataByType_LongLong(t *testing.T) {
431431
t.Run(tt.name, func(t *testing.T) {
432432
longLongType := typeref.NewLongLongType()
433433
converter := createTestConverter(false)
434-
result, remain, err := converter.ParseDataByType(tt.data, longLongType, ast.Module{}, true)
434+
result, remain, err := converter.ParseDataByType(tt.data, longLongType, ast.Module{})
435435

436436
if tt.expectError {
437437
require.Error(t, err)
@@ -480,7 +480,7 @@ func TestParseDataByType_UnsignedLongLong(t *testing.T) {
480480
t.Run(tt.name, func(t *testing.T) {
481481
unsignedLongLongType := typeref.NewUnsignedLongLong()
482482
converter := createTestConverter(false)
483-
result, remain, err := converter.ParseDataByType(tt.data, unsignedLongLongType, ast.Module{}, true)
483+
result, remain, err := converter.ParseDataByType(tt.data, unsignedLongLongType, ast.Module{})
484484

485485
if tt.expectError {
486486
require.Error(t, err)
@@ -536,7 +536,7 @@ func TestParseDataByType_Boolean(t *testing.T) {
536536
t.Run(tt.name, func(t *testing.T) {
537537
booleanType := typeref.NewBooleanType()
538538
converter := createTestConverter(false)
539-
result, remain, err := converter.ParseDataByType(tt.data, booleanType, ast.Module{}, true)
539+
result, remain, err := converter.ParseDataByType(tt.data, booleanType, ast.Module{})
540540

541541
if tt.expectError {
542542
require.Error(t, err)
@@ -605,7 +605,7 @@ func TestParseDataByType_Float(t *testing.T) {
605605
t.Run(tt.name, func(t *testing.T) {
606606
floatType := typeref.NewFloatType()
607607
converter := createTestConverter(tt.isLittleEndian)
608-
result, remain, err := converter.ParseDataByType(tt.data, floatType, ast.Module{}, true)
608+
result, remain, err := converter.ParseDataByType(tt.data, floatType, ast.Module{})
609609

610610
if tt.expectError {
611611
require.Error(t, err)
@@ -656,7 +656,7 @@ func TestParseDataByType_SequenceOfShort(t *testing.T) {
656656
sequenceType := typeref.NewSequence(shortType)
657657
converter := createTestConverter(false)
658658

659-
result, remain, err := converter.ParseDataByType(tt.data, sequenceType, ast.Module{}, true)
659+
result, remain, err := converter.ParseDataByType(tt.data, sequenceType, ast.Module{})
660660

661661
if tt.expectError {
662662
require.Error(t, err)
@@ -707,7 +707,7 @@ func TestParseDataByType_SequenceOfBoolean(t *testing.T) {
707707
sequenceType := typeref.NewSequence(booleanType)
708708
converter := createTestConverter(false)
709709

710-
result, remain, err := converter.ParseDataByType(tt.data, sequenceType, ast.Module{}, true)
710+
result, remain, err := converter.ParseDataByType(tt.data, sequenceType, ast.Module{})
711711

712712
if tt.expectError {
713713
require.Error(t, err)
@@ -777,7 +777,7 @@ func TestParseDataByType_String(t *testing.T) {
777777
t.Run(tt.name, func(t *testing.T) {
778778
stringType := typeref.NewStringType()
779779
converter := createTestConverter(false)
780-
result, remain, err := converter.ParseDataByType(tt.data, stringType, ast.Module{}, true)
780+
result, remain, err := converter.ParseDataByType(tt.data, stringType, ast.Module{})
781781

782782
if tt.expectError {
783783
require.Error(t, err)
@@ -856,7 +856,7 @@ func TestParseDataByType_SequenceOfString(t *testing.T) {
856856
sequenceType := typeref.NewSequence(stringType)
857857
converter := createTestConverter(false)
858858

859-
result, remain, err := converter.ParseDataByType(tt.data, sequenceType, ast.Module{}, true)
859+
result, remain, err := converter.ParseDataByType(tt.data, sequenceType, ast.Module{})
860860

861861
if tt.expectError {
862862
require.Error(t, err)

converter/converter_value.go

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,39 @@ import (
77

88
"github.com/yisaer/idl-parser/ast"
99
"github.com/yisaer/idl-parser/ast/struct_type"
10+
"github.com/yisaer/idl-parser/ast/typ"
1011
"github.com/yisaer/idl-parser/ast/typeref"
1112
)
1213

13-
func (c *IDLConverter) ParseBytesToStruct(data []byte, st struct_type.Struct, module ast.Module, isParLast bool) (map[string]interface{}, []byte, error) {
14+
func isNeedPaddingType(t typeref.TypeRef) bool {
15+
switch t.TypeRefType() {
16+
case typ.StringType:
17+
st := t.(typeref.StringType)
18+
return st.Length == nil
19+
case typ.SequenceType:
20+
return true
21+
}
22+
return false
23+
}
24+
25+
func (c *IDLConverter) ParseBytesToStruct(data []byte, st struct_type.Struct, module ast.Module) (map[string]interface{}, []byte, error) {
1426
var v interface{}
1527
var err error
1628
var remained []byte
1729
remained = data
1830
m := make(map[string]any, len(st.Fields))
19-
for index, field := range st.Fields {
20-
v, remained, err = c.ParseDataByType(remained, field.Type, module, isParLast && index == len(st.Fields)-1)
31+
for _, field := range st.Fields {
32+
v, remained, err = c.ParseDataByType(remained, field.Type, module)
2133
if err != nil {
2234
return nil, nil, fmt.Errorf("struct %v parse field %v error:%v", st, field.Name, err.Error())
2335
}
2436
m[field.Name] = v
37+
if len(remained) > 0 && isNeedPaddingType(field.Type) {
38+
remained, err = c.consumePadding(remained)
39+
if err != nil {
40+
return nil, nil, fmt.Errorf("struct %v parse field %v error:%v", st, field.Name, err.Error())
41+
}
42+
}
2543
}
2644
return m, remained, nil
2745
}
@@ -165,23 +183,25 @@ func (c *IDLConverter) ParseBytesToFloat64(data []byte) (float64, []byte, error)
165183
return value, remainData, nil
166184
}
167185

168-
func (c *IDLConverter) ParseBytesToList(data []byte, seqType typeref.Sequence, module ast.Module, isLast bool) ([]interface{}, []byte, error) {
186+
func (c *IDLConverter) ParseBytesToList(data []byte, seqType typeref.Sequence, module ast.Module) ([]interface{}, []byte, error) {
169187
sequenceLen, remained, err := c.ParseBytesToLength(data)
170188
if err != nil {
171189
return nil, nil, err
172190
}
173191
result := make([]interface{}, 0, sequenceLen)
174192
var v interface{}
175193
for i := 0; i < int(sequenceLen); i++ {
176-
v, remained, err = c.ParseDataByType(remained, seqType.InnerType, module, isLast && i == sequenceLen-1)
194+
v, remained, err = c.ParseDataByType(remained, seqType.InnerType, module)
177195
if err != nil {
178196
return nil, nil, fmt.Errorf("parse sequence %v error:%v", seqType.InnerType, err.Error())
179197
}
180198
result = append(result, v)
181-
}
182-
remained, err = c.consumePadding(remained, isLast)
183-
if err != nil {
184-
return nil, nil, err
199+
if len(remained) > 0 && isNeedPaddingType(seqType.InnerType) {
200+
remained, err = c.consumePadding(remained)
201+
if err != nil {
202+
return nil, nil, fmt.Errorf("parse sequence %v error:%v", seqType.InnerType, err.Error())
203+
}
204+
}
185205
}
186206
return result, remained, nil
187207
}

converter/parse_methods_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ func TestParseString(t *testing.T) {
365365
testData := []byte{0x00, 0x00, 0x00, 0x09, 0xEF, 0xBB, 0xBF, 'h', 'e', 'l', 'l', 'o', 0x00, 0x99, 0xAA}
366366

367367
stringType := typeref.StringType{}
368-
result, remained, err := converter.ParseString(testData, stringType, ast.Module{}, false)
368+
result, remained, err := converter.ParseString(testData, stringType, ast.Module{})
369369

370370
if err != nil {
371371
t.Errorf("parseString failed: %v", err)
@@ -400,7 +400,7 @@ func TestParseArray(t *testing.T) {
400400
ArraySize: 3,
401401
InnerType: typeref.ShortType{},
402402
}
403-
result, remained, err := converter.ParseArray(testData, arrayType, ast.Module{}, false)
403+
result, remained, err := converter.ParseArray(testData, arrayType, ast.Module{})
404404

405405
if err != nil {
406406
t.Errorf("parseArray failed: %v", err)
@@ -434,7 +434,7 @@ func TestParseBytesToList(t *testing.T) {
434434
seqType := typeref.Sequence{
435435
InnerType: typeref.ShortType{},
436436
}
437-
result, remained, err := converter.ParseBytesToList(testData, seqType, ast.Module{}, true)
437+
result, remained, err := converter.ParseBytesToList(testData, seqType, ast.Module{})
438438

439439
if err != nil {
440440
t.Errorf("parseBytesToList failed: %v", err)

0 commit comments

Comments
 (0)