Update vendoring (#722)

* Update vendor github.com/beevik/ntp@v0.2.0

* Update vendor github.com/mdlayher/netlink/...

* Update vendor github.com/mdlayher/wifi/...

Adds vendor github.com/mdlayher/genetlink

* Update vendor github.com/prometheus/common/...

* Update vendor github.com/prometheus/procfs/...

* Update vendor golang.org/x/sys/unix

* Update vendor golang.org/x/sys/windows
This commit is contained in:
Ben Kochie 2017-11-02 12:30:34 +01:00 committed by GitHub
commit 4d7aa57da0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 587 additions and 283 deletions

View file

@ -1,7 +1,7 @@
MIT License
===========
Copyright (C) 2016 Matt Layher
Copyright (C) 2016-2017 Matt Layher
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View file

@ -4,6 +4,12 @@ netlink [![Build Status](https://travis-ci.org/mdlayher/netlink.svg?branch=maste
Package `netlink` provides low-level access to Linux netlink sockets.
MIT Licensed.
For more information about how netlink works, check out my blog series
on [Linux, Netlink, and Go](https://medium.com/@mdlayher/linux-netlink-and-go-part-1-netlink-4781aaeeaca8).
If you're looking for package `genetlink`, it's been moved to its own
repository at [`github.com/mdlayher/genetlink`](https://github.com/mdlayher/genetlink).
Why?
----
@ -18,4 +24,4 @@ I wanted in a netlink package:
- Doesn't need root to work
My goal for this package is to use it as a building block for the creation
of other netlink protocol family packages.
of other netlink family packages.

View file

@ -9,10 +9,13 @@ import (
var (
// errInvalidAttribute specifies if an Attribute's length is incorrect.
errInvalidAttribute = errors.New("invalid attribute; length too short or too large")
// errInvalidAttributeFlags specifies if an Attribute's flag configuration is invalid.
// From a comment in Linux/include/uapi/linux/netlink.h, Nested and NetByteOrder are mutually exclusive.
errInvalidAttributeFlags = errors.New("invalid attribute; type cannot have both nested and net byte order flags")
)
// An Attribute is a netlink attribute. Attributes are packed and unpacked
// to and from the Data field of Message for some netlink protocol families.
// to and from the Data field of Message for some netlink families.
type Attribute struct {
// Length of an Attribute, including this field and Type.
Length uint16
@ -22,19 +25,50 @@ type Attribute struct {
// An arbitrary payload which is specified by Type.
Data []byte
// Whether the attribute's data contains nested attributes. Note that not
// all netlink families set this value. The programmer should consult
// documentation and inspect an attribute's data to determine if nested
// attributes are present.
Nested bool
// Whether the attribute's data is in network (true) or native (false) byte order.
NetByteOrder bool
}
// #define NLA_F_NESTED
const nlaNested uint16 = 0x8000
// #define NLA_F_NET_BYTE_ORDER
const nlaNetByteOrder uint16 = 0x4000
// Masks all bits except for Nested and NetByteOrder.
const nlaTypeMask = ^(nlaNested | nlaNetByteOrder)
// MarshalBinary marshals an Attribute into a byte slice.
func (a Attribute) MarshalBinary() ([]byte, error) {
if int(a.Length) < nlaHeaderLen {
return nil, errInvalidAttribute
}
if a.NetByteOrder && a.Nested {
return nil, errInvalidAttributeFlags
}
b := make([]byte, nlaAlign(int(a.Length)))
nlenc.PutUint16(b[0:2], a.Length)
nlenc.PutUint16(b[2:4], a.Type)
copy(b[4:], a.Data)
switch {
case a.Nested:
nlenc.PutUint16(b[2:4], a.Type|nlaNested)
case a.NetByteOrder:
nlenc.PutUint16(b[2:4], a.Type|nlaNetByteOrder)
default:
nlenc.PutUint16(b[2:4], a.Type)
}
copy(b[nlaHeaderLen:], a.Data)
return b, nil
}
@ -46,23 +80,33 @@ func (a *Attribute) UnmarshalBinary(b []byte) error {
}
a.Length = nlenc.Uint16(b[0:2])
a.Type = nlenc.Uint16(b[2:4])
// Only hold the rightmost 14 bits in Type
a.Type = nlenc.Uint16(b[2:4]) & nlaTypeMask
// Boolean flags extracted from the two leftmost bits of Type
a.Nested = (nlenc.Uint16(b[2:4]) & nlaNested) > 0
a.NetByteOrder = (nlenc.Uint16(b[2:4]) & nlaNetByteOrder) > 0
if nlaAlign(int(a.Length)) > len(b) {
return errInvalidAttribute
}
if a.NetByteOrder && a.Nested {
return errInvalidAttributeFlags
}
switch {
// No length, no data
case a.Length == 0:
a.Data = make([]byte, 0)
// Not enough length for any data
case a.Length < 4:
case int(a.Length) < nlaHeaderLen:
return errInvalidAttribute
// Data present
case a.Length >= 4:
a.Data = make([]byte, len(b[4:a.Length]))
copy(a.Data, b[4:a.Length])
case int(a.Length) >= nlaHeaderLen:
a.Data = make([]byte, len(b[nlaHeaderLen:a.Length]))
copy(a.Data, b[nlaHeaderLen:a.Length])
}
return nil

View file

@ -2,7 +2,9 @@ package netlink
import (
"errors"
"io"
"math/rand"
"os"
"sync/atomic"
"golang.org/x/net/bpf"
@ -15,12 +17,20 @@ var (
errShortErrorMessage = errors.New("not enough data for netlink error code")
)
// Errors which can be returned by a Socket that does not implement
// all exposed methods of Conn.
var (
errReadWriteCloserNotSupported = errors.New("raw read/write/closer not supported")
errMulticastGroupsNotSupported = errors.New("multicast groups not supported")
errBPFFiltersNotSupported = errors.New("BPF filters not supported")
)
// A Conn is a connection to netlink. A Conn can be used to send and
// receives messages to and from netlink.
type Conn struct {
// osConn is the operating system-specific implementation of
// sock is the operating system-specific implementation of
// a netlink sockets connection.
c osConn
sock Socket
// seq is an atomically incremented integer used to provide sequence
// numbers when Conn.Send is called.
@ -30,44 +40,45 @@ type Conn struct {
pid uint32
}
// An osConn is an operating-system specific implementation of netlink
// A Socket is an operating-system specific implementation of netlink
// sockets used by Conn.
type osConn interface {
type Socket interface {
Close() error
Send(m Message) error
Receive() ([]Message, error)
JoinGroup(group uint32) error
LeaveGroup(group uint32) error
SetBPF(filter []bpf.RawInstruction) error
}
// Dial dials a connection to netlink, using the specified protocol number.
// Dial dials a connection to netlink, using the specified netlink family.
// Config specifies optional configuration for Conn. If config is nil, a default
// configuration will be used.
func Dial(proto int, config *Config) (*Conn, error) {
// Use OS-specific dial() to create osConn
c, pid, err := dial(proto, config)
func Dial(family int, config *Config) (*Conn, error) {
// Use OS-specific dial() to create Socket
c, pid, err := dial(family, config)
if err != nil {
return nil, err
}
return newConn(c, pid), nil
return NewConn(c, pid), nil
}
// newConn is the internal constructor for Conn, used in tests.
func newConn(c osConn, pid uint32) *Conn {
// NewConn creates a Conn using the specified Socket and PID for netlink
// communications.
//
// NewConn is primarily useful for tests. Most applications should use
// Dial instead.
func NewConn(c Socket, pid uint32) *Conn {
seq := rand.Uint32()
return &Conn{
c: c,
seq: &seq,
pid: pid,
sock: c,
seq: &seq,
pid: pid,
}
}
// Close closes the connection.
func (c *Conn) Close() error {
return c.c.Close()
return c.sock.Close()
}
// Execute sends a single Message to netlink using Conn.Send, receives one or more
@ -127,7 +138,7 @@ func (c *Conn) Send(m Message) (Message, error) {
m.Header.PID = c.pid
}
if err := c.c.Send(m); err != nil {
if err := c.sock.Send(m); err != nil {
return Message{}, err
}
@ -145,8 +156,13 @@ func (c *Conn) Receive() ([]Message, error) {
return nil, err
}
// When using nltest, it's possible for zero messages to be returned by receive.
if len(msgs) == 0 {
return msgs, nil
}
// Trim the final message with multi-part done indicator if
// present
// present.
if m := msgs[len(msgs)-1]; m.Header.Flags&HeaderFlagsMulti != 0 && m.Header.Type == HeaderTypeDone {
return msgs[:len(msgs)-1], nil
}
@ -157,7 +173,7 @@ func (c *Conn) Receive() ([]Message, error) {
// receive is the internal implementation of Conn.Receive, which can be called
// recursively to handle multi-part messages.
func (c *Conn) receive() ([]Message, error) {
msgs, err := c.c.Receive()
msgs, err := c.sock.Receive()
if err != nil {
return nil, err
}
@ -190,19 +206,93 @@ func (c *Conn) receive() ([]Message, error) {
return append(msgs, mmsgs...), nil
}
// An fder is a Socket that supports retrieving its raw file descriptor.
type fder interface {
Socket
FD() int
}
var _ io.ReadWriteCloser = &fileReadWriteCloser{}
// A fileReadWriteCloser is a limited *os.File which only allows access to its
// Read and Write methods.
type fileReadWriteCloser struct {
f *os.File
}
// Read implements io.ReadWriteCloser.
func (rwc *fileReadWriteCloser) Read(b []byte) (int, error) { return rwc.f.Read(b) }
// Write implements io.ReadWriteCloser.
func (rwc *fileReadWriteCloser) Write(b []byte) (int, error) { return rwc.f.Write(b) }
// Close implements io.ReadWriteCloser.
func (rwc *fileReadWriteCloser) Close() error { return rwc.f.Close() }
// ReadWriteCloser returns a raw io.ReadWriteCloser backed by the connection
// of the Conn.
//
// ReadWriteCloser is intended for advanced use cases, such as those that do
// not involve standard netlink message passing.
//
// Once invoked, it is the caller's responsibility to ensure that operations
// performed using Conn and the raw io.ReadWriteCloser do not conflict with
// each other. In almost all scenarios, only one of the two should be used.
func (c *Conn) ReadWriteCloser() (io.ReadWriteCloser, error) {
fc, ok := c.sock.(fder)
if !ok {
return nil, errReadWriteCloserNotSupported
}
return &fileReadWriteCloser{
// Backing the io.ReadWriteCloser with an *os.File enables easy reading
// and writing without more system call boilerplate.
f: os.NewFile(uintptr(fc.FD()), "netlink"),
}, nil
}
// A groupJoinLeaver is a Socket that supports joining and leaving
// netlink multicast groups.
type groupJoinLeaver interface {
Socket
JoinGroup(group uint32) error
LeaveGroup(group uint32) error
}
// JoinGroup joins a netlink multicast group by its ID.
func (c *Conn) JoinGroup(group uint32) error {
return c.c.JoinGroup(group)
gc, ok := c.sock.(groupJoinLeaver)
if !ok {
return errMulticastGroupsNotSupported
}
return gc.JoinGroup(group)
}
// LeaveGroup leaves a netlink multicast group by its ID.
func (c *Conn) LeaveGroup(group uint32) error {
return c.c.LeaveGroup(group)
gc, ok := c.sock.(groupJoinLeaver)
if !ok {
return errMulticastGroupsNotSupported
}
return gc.LeaveGroup(group)
}
// A bpfSetter is a Socket that supports setting BPF filters.
type bpfSetter interface {
Socket
bpf.Setter
}
// SetBPF attaches an assembled BPF program to a Conn.
func (c *Conn) SetBPF(filter []bpf.RawInstruction) error {
return c.c.SetBPF(filter)
bc, ok := c.sock.(bpfSetter)
if !ok {
return errBPFFiltersNotSupported
}
return bc.SetBPF(filter)
}
// nextSequence atomically increments Conn's sequence number and returns

View file

@ -17,7 +17,7 @@ var (
errInvalidFamily = errors.New("received invalid netlink family")
)
var _ osConn = &conn{}
var _ Socket = &conn{}
// A conn is the Linux implementation of a netlink sockets connection.
type conn struct {
@ -29,6 +29,7 @@ type conn struct {
type socket interface {
Bind(sa unix.Sockaddr) error
Close() error
FD() int
Getsockname() (unix.Sockaddr, error)
Recvmsg(p, oob []byte, flags int) (n int, oobn int, recvflags int, from unix.Sockaddr, err error)
Sendmsg(p, oob []byte, to unix.Sockaddr, flags int) error
@ -154,6 +155,11 @@ func (c *conn) Close() error {
return c.s.Close()
}
// FD retrieves the file descriptor of the Conn.
func (c *conn) FD() int {
return c.s.FD()
}
// JoinGroup joins a multicast group by ID.
func (c *conn) JoinGroup(group uint32) error {
return c.s.SetSockopt(
@ -211,6 +217,7 @@ type sysSocket struct {
func (s *sysSocket) Bind(sa unix.Sockaddr) error { return unix.Bind(s.fd, sa) }
func (s *sysSocket) Close() error { return unix.Close(s.fd) }
func (s *sysSocket) FD() int { return s.fd }
func (s *sysSocket) Getsockname() (unix.Sockaddr, error) { return unix.Getsockname(s.fd) }
func (s *sysSocket) Recvmsg(p, oob []byte, flags int) (int, int, int, unix.Sockaddr, error) {
return unix.Recvmsg(s.fd, p, oob, flags)

View file

@ -16,14 +16,14 @@ var (
runtime.GOOS, runtime.GOARCH)
)
var _ osConn = &conn{}
var _ Socket = &conn{}
// A conn is the no-op implementation of a netlink sockets connection.
type conn struct{}
// dial is the entry point for Dial. dial always returns an error.
func dial(family int, config *Config) (*conn, error) {
return nil, errUnimplemented
func dial(family int, config *Config) (*conn, uint32, error) {
return nil, 0, errUnimplemented
}
// Send always returns an error.

View file

@ -1,139 +0,0 @@
package genetlink
import "github.com/mdlayher/netlink"
// Controller is the generic netlink controller family ID, used to issue
// requests to the controller.
const Controller = 0x10
// Protocol is the netlink protocol constant used to specify generic netlink.
const Protocol = 0x10
// A Conn is a generic netlink connection. A Conn can be used to send and
// receive generic netlink messages to and from netlink.
type Conn struct {
// Family provides functions to help retrieve generic netlink families.
Family *FamilyService
c conn
}
var _ conn = &netlink.Conn{}
// A conn is a netlink connection, which can be swapped for tests.
type conn interface {
Close() error
JoinGroup(group uint32) error
LeaveGroup(group uint32) error
Send(m netlink.Message) (netlink.Message, error)
Receive() ([]netlink.Message, error)
}
// Dial dials a generic netlink connection. Config specifies optional
// configuration for the underlying netlink connection. If config is
// nil, a default configuration will be used.
func Dial(config *netlink.Config) (*Conn, error) {
c, err := netlink.Dial(Protocol, config)
if err != nil {
return nil, err
}
return newConn(c), nil
}
// newConn is the internal constructor for Conn, used in tests.
func newConn(c conn) *Conn {
gc := &Conn{
c: c,
}
gc.Family = &FamilyService{c: gc}
return gc
}
// Close closes the connection.
func (c *Conn) Close() error {
return c.c.Close()
}
// JoinGroup joins a netlink multicast group by its ID.
func (c *Conn) JoinGroup(group uint32) error {
return c.c.JoinGroup(group)
}
// LeaveGroup leaves a netlink multicast group by its ID.
func (c *Conn) LeaveGroup(group uint32) error {
return c.c.LeaveGroup(group)
}
// Send sends a single Message to netlink, wrapping it in a netlink.Message
// using the specified generic netlink family and flags. On success, Send
// returns a copy of the netlink.Message with all parameters populated, for
// later validation.
func (c *Conn) Send(m Message, family uint16, flags netlink.HeaderFlags) (netlink.Message, error) {
nm := netlink.Message{
Header: netlink.Header{
Type: netlink.HeaderType(family),
Flags: flags,
},
}
mb, err := m.MarshalBinary()
if err != nil {
return netlink.Message{}, err
}
nm.Data = mb
reqnm, err := c.c.Send(nm)
if err != nil {
return netlink.Message{}, err
}
return reqnm, nil
}
// Receive receives one or more Messages from netlink. The netlink.Messages
// used to wrap each Message are available for later validation.
func (c *Conn) Receive() ([]Message, []netlink.Message, error) {
msgs, err := c.c.Receive()
if err != nil {
return nil, nil, err
}
gmsgs := make([]Message, 0, len(msgs))
for _, nm := range msgs {
var gm Message
if err := (&gm).UnmarshalBinary(nm.Data); err != nil {
return nil, nil, err
}
gmsgs = append(gmsgs, gm)
}
return gmsgs, msgs, nil
}
// Execute sends a single Message to netlink using Conn.Send, receives one or
// more replies using Conn.Receive, and then checks the validity of the replies
// against the request using netlink.Validate.
//
// See the documentation of Conn.Send, Conn.Receive, and netlink.Validate for
// details about each function.
func (c *Conn) Execute(m Message, family uint16, flags netlink.HeaderFlags) ([]Message, error) {
req, err := c.Send(m, family, flags)
if err != nil {
return nil, err
}
msgs, replies, err := c.Receive()
if err != nil {
return nil, err
}
if err := netlink.Validate(req, replies); err != nil {
return nil, err
}
return msgs, nil
}

View file

@ -1,2 +0,0 @@
// Package genetlink implements generic netlink interactions and data types.
package genetlink

View file

@ -1,208 +0,0 @@
package genetlink
import (
"errors"
"fmt"
"math"
"github.com/mdlayher/netlink"
"github.com/mdlayher/netlink/nlenc"
)
// Constants used to request information from generic netlink controller.
// Reference: http://lxr.free-electrons.com/source/include/linux/genetlink.h?v=3.3#L35
const (
ctrlVersion = 1
ctrlCommandGetFamily = 3
)
var (
// errInvalidFamilyVersion is returned when a family's version is greater
// than an 8-bit integer.
errInvalidFamilyVersion = errors.New("invalid family version attribute")
// errInvalidMulticastGroupArray is returned when a multicast group array
// of attributes is malformed.
errInvalidMulticastGroupArray = errors.New("invalid multicast group attribute array")
)
// A Family is a generic netlink family.
type Family struct {
ID uint16
Version uint8
Name string
Groups []MulticastGroup
}
// A MulticastGroup is a generic netlink multicast group, which can be joined
// for notifications from generic netlink families when specific events take
// place.
type MulticastGroup struct {
ID uint32
Name string
}
// A FamilyService is used to retrieve generic netlink family information.
type FamilyService struct {
c *Conn
}
// Get retrieves a generic netlink family with the specified name. If the
// family does not exist, the error value can be checked using os.IsNotExist.
func (s *FamilyService) Get(name string) (Family, error) {
b, err := netlink.MarshalAttributes([]netlink.Attribute{{
Type: attrFamilyName,
Data: nlenc.Bytes(name),
}})
if err != nil {
return Family{}, err
}
req := Message{
Header: Header{
Command: ctrlCommandGetFamily,
Version: ctrlVersion,
},
Data: b,
}
msgs, err := s.c.Execute(req, Controller, netlink.HeaderFlagsRequest)
if err != nil {
return Family{}, err
}
// TODO(mdlayher): consider interpreting generic netlink header values
families, err := buildFamilies(msgs)
if err != nil {
return Family{}, err
}
if len(families) != 1 {
// If this were to ever happen, netlink must be in a state where
// its answers cannot be trusted
panic(fmt.Sprintf("netlink returned multiple families for name: %q", name))
}
return families[0], nil
}
// List retrieves all registered generic netlink families.
func (s *FamilyService) List() ([]Family, error) {
req := Message{
Header: Header{
Command: ctrlCommandGetFamily,
Version: ctrlVersion,
},
}
flags := netlink.HeaderFlagsRequest | netlink.HeaderFlagsDump
msgs, err := s.c.Execute(req, Controller, flags)
if err != nil {
return nil, err
}
return buildFamilies(msgs)
}
// buildFamilies builds a slice of Families by parsing attributes from the
// input Messages.
func buildFamilies(msgs []Message) ([]Family, error) {
families := make([]Family, 0, len(msgs))
for _, m := range msgs {
attrs, err := netlink.UnmarshalAttributes(m.Data)
if err != nil {
return nil, err
}
var f Family
if err := (&f).parseAttributes(attrs); err != nil {
return nil, err
}
families = append(families, f)
}
return families, nil
}
// Attribute IDs mapped to specific family fields.
const (
// TODO(mdlayher): parse additional attributes
// Family attributes
attrUnspecified = 0
attrFamilyID = 1
attrFamilyName = 2
attrVersion = 3
attrMulticastGroups = 7
// Multicast group-specific attributes
attrMGName = 1
attrMGID = 2
)
// parseAttributes parses netlink attributes into a Family's fields.
func (f *Family) parseAttributes(attrs []netlink.Attribute) error {
for _, a := range attrs {
switch a.Type {
case attrFamilyID:
f.ID = nlenc.Uint16(a.Data)
case attrFamilyName:
f.Name = nlenc.String(a.Data)
case attrVersion:
v := nlenc.Uint32(a.Data)
if v > math.MaxUint8 {
return errInvalidFamilyVersion
}
f.Version = uint8(v)
case attrMulticastGroups:
groups, err := parseMulticastGroups(a.Data)
if err != nil {
return err
}
f.Groups = groups
}
}
return nil
}
// parseMulticastGroups parses an array of multicast group nested attributes
// into a slice of MulticastGroups.
func parseMulticastGroups(b []byte) ([]MulticastGroup, error) {
attrs, err := netlink.UnmarshalAttributes(b)
if err != nil {
return nil, err
}
groups := make([]MulticastGroup, 0, len(attrs))
for i, a := range attrs {
// The type attribute is essentially an array index here; it starts
// at 1 and should increment for each new array element
if int(a.Type) != i+1 {
return nil, errInvalidMulticastGroupArray
}
nattrs, err := netlink.UnmarshalAttributes(a.Data)
if err != nil {
return nil, err
}
var g MulticastGroup
for _, na := range nattrs {
switch na.Type {
case attrMGName:
g.Name = nlenc.String(na.Data)
case attrMGID:
g.ID = nlenc.Uint32(na.Data)
}
}
groups = append(groups, g)
}
return groups, nil
}

View file

@ -1,20 +0,0 @@
//+build gofuzz
package genetlink
func Fuzz(data []byte) int {
return fuzzMessage(data)
}
func fuzzMessage(data []byte) int {
var m Message
if err := (&m).UnmarshalBinary(data); err != nil {
return 0
}
if _, err := m.MarshalBinary(); err != nil {
panic(err)
}
return 1
}

View file

@ -1,65 +0,0 @@
package genetlink
import (
"errors"
)
var (
// errInvalidMessage is returned when a Message is malformed.
errInvalidMessage = errors.New("generic netlink message is invalid or too short")
)
// A Header is a generic netlink header. A Header is sent and received with
// each generic netlink message to indicate metadata regarding a Message.
type Header struct {
// Command specifies a command to issue to netlink.
Command uint8
// Version specifies the version of a command to use.
Version uint8
}
// headerLen is the length of a Header.
const headerLen = 4
// A Message is a generic netlink message. It contains a Header and an
// arbitrary byte payload, which may be decoded using information from the
// Header.
//
// Data is encoded using the native endianness of the host system. Use
// the netlink.Uint* and netlink.PutUint* functions to encode and decode
// integers.
type Message struct {
Header Header
Data []byte
}
// MarshalBinary marshals a Message into a byte slice.
func (m Message) MarshalBinary() ([]byte, error) {
b := make([]byte, headerLen)
b[0] = m.Header.Command
b[1] = m.Header.Version
// b[2] and b[3] are padding bytes and set to zero
return append(b, m.Data...), nil
}
// UnmarshalBinary unmarshals the contents of a byte slice into a Message.
func (m *Message) UnmarshalBinary(b []byte) error {
if len(b) < headerLen {
return errInvalidMessage
}
// Don't allow reserved pad bytes to be set
if b[2] != 0 || b[3] != 0 {
return errInvalidMessage
}
m.Header.Command = b[0]
m.Header.Version = b[1]
m.Data = b[4:]
return nil
}

View file

@ -5,6 +5,16 @@ import (
"unsafe"
)
// PutUint8 encodes a uint8 into b.
// If b is not exactly 1 byte in length, PutUint8 will panic.
func PutUint8(b []byte, v uint8) {
if l := len(b); l != 1 {
panic(fmt.Sprintf("PutUint8: unexpected byte slice length: %d", l))
}
b[0] = v
}
// PutUint16 encodes a uint16 into b using the host machine's native endianness.
// If b is not exactly 2 bytes in length, PutUint16 will panic.
func PutUint16(b []byte, v uint16) {
@ -35,6 +45,26 @@ func PutUint64(b []byte, v uint64) {
*(*uint64)(unsafe.Pointer(&b[0])) = v
}
// PutInt32 encodes a int32 into b using the host machine's native endianness.
// If b is not exactly 4 bytes in length, PutInt32 will panic.
func PutInt32(b []byte, v int32) {
if l := len(b); l != 4 {
panic(fmt.Sprintf("PutInt32: unexpected byte slice length: %d", l))
}
*(*int32)(unsafe.Pointer(&b[0])) = v
}
// Uint8 decodes a uint8 from b.
// If b is not exactly 1 byte in length, Uint8 will panic.
func Uint8(b []byte) uint8 {
if l := len(b); l != 1 {
panic(fmt.Sprintf("Uint8: unexpected byte slice length: %d", l))
}
return b[0]
}
// Uint16 decodes a uint16 from b using the host machine's native endianness.
// If b is not exactly 2 bytes in length, Uint16 will panic.
func Uint16(b []byte) uint16 {
@ -75,6 +105,14 @@ func Int32(b []byte) int32 {
return *(*int32)(unsafe.Pointer(&b[0]))
}
// Uint8Bytes encodes a uint8 into a newly-allocated byte slice. It is a
// shortcut for allocating a new byte slice and filling it using PutUint8.
func Uint8Bytes(v uint8) []byte {
b := make([]byte, 1)
PutUint8(b, v)
return b
}
// Uint16Bytes encodes a uint16 into a newly-allocated byte slice using the
// host machine's native endianness. It is a shortcut for allocating a new
// byte slice and filling it using PutUint16.
@ -101,3 +139,12 @@ func Uint64Bytes(v uint64) []byte {
PutUint64(b, v)
return b
}
// Int32Bytes encodes a int32 into a newly-allocated byte slice using the
// host machine's native endianness. It is a shortcut for allocating a new
// byte slice and filling it using PutInt32.
func Int32Bytes(v int32) []byte {
b := make([]byte, 4)
PutInt32(b, v)
return b
}