Skip to content

Commit

Permalink
Merge branch 'master' into feature/writer
Browse files Browse the repository at this point in the history
  • Loading branch information
ghostiam committed Apr 3, 2024
2 parents 7cbfe48 + a0aeda1 commit acd4649
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ type test struct {
OffsetStart byte `bin:"offsetStart:42"` // move to 42 bytes from start position and read byte
OffsetEnd byte `bin:"offsetEnd:-42"` // move to -42 bytes from end position and read byte
OffsetStart byte `bin:"offsetStart:42, offset:10"` // also worked and equally `offsetStart:52`
OffsetWithRestore byte `bin:"offset:42, offsetRestore"` // move to 42 bytes from current position and read byte, then restore position to the previous one (before offset)

// Calculations supported +,-,/,* and are performed from left to right that is 2+2*2=8 not 6!!!
CalcTagValue []byte `bin:"len:10+5+2+3"` // equally len:20
Expand Down
16 changes: 16 additions & 0 deletions binstruct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -917,3 +917,19 @@ func Test_InnerSubField(t *testing.T) {
require.Equal(t, int8(5), v.Child.Len)
require.Equal(t, []byte{0x01, 0x02, 0x03, 0x04, 0x05}, v.S)
}

func Test_OffsetRestore(t *testing.T) {
var v struct {
Offset uint8
Size uint8
Data []byte `bin:"offsetStart:Offset,len:Size,offsetRestore"`
Other []byte `bin:"len:3"`
}

err := UnmarshalBE([]byte{0x05, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05}, &v)
require.NoError(t, err)
require.Equal(t, uint8(5), v.Offset)
require.Equal(t, uint8(2), v.Size)
require.Equal(t, []byte{0x04, 0x05}, v.Data)
require.Equal(t, []byte{0x01, 0x02, 0x03}, v.Other)
}
18 changes: 13 additions & 5 deletions tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
tagTypeOffsetFromCurrent = "offset"
tagTypeOffsetFromStart = "offsetStart"
tagTypeOffsetFromEnd = "offsetEnd"
tagTypeOffsetRestore = "offsetRestore"
)

type tag struct {
Expand Down Expand Up @@ -59,6 +60,9 @@ func parseTag(t string) ([]tag, error) {
case v == tagTypeIgnore:
tags = append(tags, tag{Type: tagTypeIgnore})

case v == tagTypeOffsetRestore:
tags = append(tags, tag{Type: tagTypeOffsetRestore})

case strings.HasPrefix(v, "["):
v = v + "," + t
var arrBalance int
Expand Down Expand Up @@ -130,11 +134,12 @@ type fieldOffset struct {
}

type fieldReadData struct {
Ignore bool
Length *int64
Offsets []fieldOffset
FuncName string
Order binary.ByteOrder
Ignore bool
Length *int64
Offsets []fieldOffset
OffsetRestore bool
FuncName string
Order binary.ByteOrder

ElemFieldData *fieldReadData // if type Element
}
Expand Down Expand Up @@ -258,6 +263,9 @@ func parseReadDataFromTags(structValue reflect.Value, tags []tag) (*fieldReadDat
Whence: io.SeekEnd,
})

case tagTypeOffsetRestore:
data.OffsetRestore = true

case tagTypeFunc:
data.FuncName = t.Value

Expand Down
3 changes: 2 additions & 1 deletion tag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,13 @@ func Test_parseTag(t *testing.T) {
},
{
name: "multi tag",
tag: "len:1, offset:2, offsetStart:3, offsetEnd:4",
tag: "len:1, offset:2, offsetStart:3, offsetEnd:4, offsetRestore",
want: []tag{
{Type: "len", Value: "1"},
{Type: "offset", Value: "2"},
{Type: "offsetStart", Value: "3"},
{Type: "offsetEnd", Value: "4"},
{Type: "offsetRestore"},
},
},
{
Expand Down
9 changes: 9 additions & 0 deletions unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package binstruct
import (
"errors"
"fmt"
"io"
"reflect"
"strings"
)
Expand Down Expand Up @@ -80,6 +81,14 @@ func (u *unmarshal) setValueToField(
r = r.WithOrder(fieldData.Order)
}

if fieldData.OffsetRestore {
currentOffset, err := r.Seek(0, io.SeekCurrent)
if err != nil {
return fmt.Errorf("get current offset: %w", err)
}
defer r.Seek(currentOffset, io.SeekStart)
}

err := setOffset(r, fieldData)
if err != nil {
return fmt.Errorf("set offset: %w", err)
Expand Down

0 comments on commit acd4649

Please sign in to comment.