lunixbochs / struc

Better binary packing for Go
MIT License
564 stars 42 forks source link

struc: support Custom slice types #60

Open mewmew opened 6 years ago

mewmew commented 6 years ago

Useful for implementing e.g. NULL-terminated slices whose length is unknown and cannot be determined by a field in the struct.

mewmew commented 6 years ago

Without this PR, I was running into the following error when trying to parse SYM files.

2018/07/14 09:49:45 struc: field `Dims` is a slice with no length or sizeof field

Where the type of Dims implements the struc.Custom interface.

// Dimensions specifies array dimensions.
type Dimensions []uint16

func (dims *Dimensions) Pack(p []byte, opt *struc.Options) (int, error) {
    panic("not yet implemented")
}

func (dims *Dimensions) Unpack(r io.Reader, length int, opt *struc.Options) error {
    for {
        var dim uint16
        if err := binary.Read(r, binary.LittleEndian, &dim); err != nil {
            if errors.Cause(err) == io.EOF {
                return errors.WithStack(io.ErrUnexpectedEOF)
            }
            return errors.WithStack(err)
        }
        *dims = append(*dims, dim)
        if dim == 0 {
            break
        }
    }
    return nil
}

func (dims *Dimensions) Size(opt *struc.Options) int {
    return 2 * len(*dims)
}

func (dims *Dimensions) String() string {
    var s string
    for i, dim := range *dims {
        if dim == 0 {
            break
        }
        if i != 0 {
            s += ","
        }
        s += strconv.Itoa(int(dim))
    }
    return s
}
lunixbochs commented 6 years ago

Cool, can you add a test case for double round trip encoding/decoding such a slice? Ideally with a field after it to ensure the length stuff is ok.

mewmew commented 6 years ago

Cool, can you add a test case for double round trip encoding/decoding such a slice? Ideally with a field after it to ensure the length stuff is ok.

I actually tried, but couldn't get size to work. I was going to ask you if there is something in particular that needs to be changed to support it.

Would you mind taking a look? :)

Cheers, /u

lunixbochs commented 6 years ago

This context is probably relevant: https://github.com/lunixbochs/struc/issues/52#issuecomment-371729658