diff options
author | Christopher Koch <chrisko@google.com> | 2018-12-28 20:19:14 -0800 |
---|---|---|
committer | insomniac <insomniacslk@users.noreply.github.com> | 2019-01-10 23:01:22 +0000 |
commit | e87114a6e449d7a2e458b5529923e5668dfa3a11 (patch) | |
tree | 7c5ec350c8eb859400a159b881081ffe0dbd4ef0 /dhcpv4/bsdp/boot_image.go | |
parent | 108ed92e1c9901936541020bc3214533acce77bb (diff) |
dhcpv4: simplify option parsing.
option's codes and lengths were being parsed twice: once in ParseOption
and once in each option type's Parse implementation. Consolidate such
that it only happens once.
Additionally, only pass data to options that they should parse -- we
know the length before the Parse function is called, so the option only
gets to see the data it needs to see.
Also, use uio.Lexer to simplify parsing code in general. Easier to read
and reason about.
Diffstat (limited to 'dhcpv4/bsdp/boot_image.go')
-rw-r--r-- | dhcpv4/bsdp/boot_image.go | 45 |
1 files changed, 18 insertions, 27 deletions
diff --git a/dhcpv4/bsdp/boot_image.go b/dhcpv4/bsdp/boot_image.go index 88a9404..fa9b1a6 100644 --- a/dhcpv4/bsdp/boot_image.go +++ b/dhcpv4/bsdp/boot_image.go @@ -3,6 +3,8 @@ package bsdp import ( "encoding/binary" "fmt" + + "github.com/u-root/u-root/pkg/uio" ) // BootImageType represents the different BSDP boot image types. @@ -60,16 +62,14 @@ func (b BootImageID) String() string { return s + " " + t + " image" } -// BootImageIDFromBytes deserializes a collection of 4 bytes to a BootImageID. -func BootImageIDFromBytes(bytes []byte) (*BootImageID, error) { - if len(bytes) < 4 { - return nil, fmt.Errorf("not enough bytes to serialize BootImageID") - } - return &BootImageID{ - IsInstall: bytes[0]&0x80 != 0, - ImageType: BootImageType(bytes[0] & 0x7f), - Index: binary.BigEndian.Uint16(bytes[2:]), - }, nil +// Unmarshal reads b's binary representation from buf. +func (b *BootImageID) Unmarshal(buf *uio.Lexer) error { + byte0 := buf.Read8() + _ = buf.Read8() + b.IsInstall = byte0&0x80 != 0 + b.ImageType = BootImageType(byte0 & 0x7f) + b.Index = buf.Read16() + return buf.Error() } // BootImage describes a boot image - contains the boot image ID and the name. @@ -87,25 +87,16 @@ func (b *BootImage) ToBytes() []byte { } // String converts a BootImage to a human-readable representation. -func (b *BootImage) String() string { +func (b BootImage) String() string { return fmt.Sprintf("%v %v", b.Name, b.ID.String()) } -// BootImageFromBytes returns a deserialized BootImage struct from bytes. -func BootImageFromBytes(bytes []byte) (*BootImage, error) { - // Should at least contain 4 bytes of BootImageID + byte for length of - // boot image name. - if len(bytes) < 5 { - return nil, fmt.Errorf("not enough bytes to serialize BootImage") - } - imageID, err := BootImageIDFromBytes(bytes[:4]) - if err != nil { - return nil, err - } - nameLength := int(bytes[4]) - if 5+nameLength > len(bytes) { - return nil, fmt.Errorf("not enough bytes for BootImage") +// Unmarshal reads data from buf into b. +func (b *BootImage) Unmarshal(buf *uio.Lexer) error { + if err := (&b.ID).Unmarshal(buf); err != nil { + return err } - name := string(bytes[5 : 5+nameLength]) - return &BootImage{ID: *imageID, Name: name}, nil + nameLength := buf.Read8() + b.Name = string(buf.Consume(int(nameLength))) + return buf.Error() } |