Package binary
Overview
Package binary implements simple translation between numbers and byte sequences and encoding and decoding of varints.
Numbers are translated by reading and writing fixed-size values. A fixed-size value is either a fixed-size arithmetic type (bool, int8, uint8, int16, float32, complex64, ...) or an array or struct containing only fixed-size values.
The varint functions encode and decode single integer values using a variable-length encoding; smaller values require fewer bytes. For a specification, see https://developers.google.com/protocol-buffers/docs/encoding.
This package favors simplicity over efficiency. Clients that require high-performance serialization, especially for large data structures, should look at more advanced solutions such as the encoding/gob package or protocol buffers.
Index
Examples
Package files
binary.go varint.go
Constants
MaxVarintLenN is the maximum length of a varint-encoded N-bit integer.
const ( MaxVarintLen16 = 3 MaxVarintLen32 = 5 MaxVarintLen64 = 10 )
Variables
BigEndian is the big-endian implementation of ByteOrder.
var BigEndian bigEndian
LittleEndian is the little-endian implementation of ByteOrder.
var LittleEndian littleEndian
func PutUvarint
func PutUvarint(buf []byte, x uint64) int
PutUvarint encodes a uint64 into buf and returns the number of bytes written. If the buffer is too small, PutUvarint will panic.
Example
Code:
buf := make([]byte, binary.MaxVarintLen64) for _, x := range []uint64{1, 2, 127, 128, 255, 256} { n := binary.PutUvarint(buf, x) fmt.Printf("%x\n", buf[:n]) }
Output:
01 02 7f 8001 ff01 8002
func PutVarint
func PutVarint(buf []byte, x int64) int
PutVarint encodes an int64 into buf and returns the number of bytes written. If the buffer is too small, PutVarint will panic.
Example
Code:
buf := make([]byte, binary.MaxVarintLen64) for _, x := range []int64{-65, -64, -2, -1, 0, 1, 2, 63, 64} { n := binary.PutVarint(buf, x) fmt.Printf("%x\n", buf[:n]) }
Output:
8101 7f 03 01 00 02 04 7e 8001
func Read
func Read(r io.Reader, order ByteOrder, data interface{}) error
Read reads structured binary data from r into data. Data must be a pointer to a fixed-size value or a slice of fixed-size values. Bytes read from r are decoded using the specified byte order and written to successive fields of the data. When decoding boolean values, a zero byte is decoded as false, and any other non-zero byte is decoded as true. When reading into structs, the field data for fields with blank (_) field names is skipped; i.e., blank field names may be used for padding. When reading into a struct, all non-blank fields must be exported or Read may panic.
The error is EOF only if no bytes were read. If an EOF happens after reading some but not all the bytes, Read returns ErrUnexpectedEOF.
Example
Code:
var pi float64 b := []byte{0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40} buf := bytes.NewReader(b) err := binary.Read(buf, binary.LittleEndian, &pi) if err != nil { fmt.Println("binary.Read failed:", err) } fmt.Print(pi)
Output:
3.141592653589793
Example (Multi)
Code:
b := []byte{0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40, 0xff, 0x01, 0x02, 0x03, 0xbe, 0xef} r := bytes.NewReader(b) var data struct { PI float64 Uate uint8 Mine [3]byte Too uint16 } if err := binary.Read(r, binary.LittleEndian, &data); err != nil { fmt.Println("binary.Read failed:", err) } fmt.Println(data.PI) fmt.Println(data.Uate) fmt.Printf("% x\n", data.Mine) fmt.Println(data.Too)
Output:
3.141592653589793 255 01 02 03 61374
func ReadUvarint
func ReadUvarint(r io.ByteReader) (uint64, error)
ReadUvarint reads an encoded unsigned integer from r and returns it as a uint64.
func ReadVarint
func ReadVarint(r io.ByteReader) (int64, error)
ReadVarint reads an encoded signed integer from r and returns it as an int64.
func Size
func Size(v interface{}) int
Size returns how many bytes Write would generate to encode the value v, which must be a fixed-size value or a slice of fixed-size values, or a pointer to such data. If v is neither of these, Size returns -1.
func Uvarint
func Uvarint(buf []byte) (uint64, int)
Uvarint decodes a uint64 from buf and returns that value and the number of bytes read (> 0). If an error occurred, the value is 0 and the number of bytes n is <= 0 meaning:
n == 0: buf too small n < 0: value larger than 64 bits (overflow) and -n is the number of bytes read
Example
Code:
inputs := [][]byte{ {0x01}, {0x02}, {0x7f}, {0x80, 0x01}, {0xff, 0x01}, {0x80, 0x02}, } for _, b := range inputs { x, n := binary.Uvarint(b) if n != len(b) { fmt.Println("Uvarint did not consume all of in") } fmt.Println(x) }
Output:
1 2 127 128 255 256
func Varint
func Varint(buf []byte) (int64, int)
Varint decodes an int64 from buf and returns that value and the number of bytes read (> 0). If an error occurred, the value is 0 and the number of bytes n is <= 0 with the following meaning:
n == 0: buf too small n < 0: value larger than 64 bits (overflow) and -n is the number of bytes read
Example
Code:
inputs := [][]byte{ {0x81, 0x01}, {0x7f}, {0x03}, {0x01}, {0x00}, {0x02}, {0x04}, {0x7e}, {0x80, 0x01}, } for _, b := range inputs { x, n := binary.Varint(b) if n != len(b) { fmt.Println("Varint did not consume all of in") } fmt.Println(x) }
Output:
-65 -64 -2 -1 0 1 2 63 64
func Write
func Write(w io.Writer, order ByteOrder, data interface{}) error
Write writes the binary representation of data into w. Data must be a fixed-size value or a slice of fixed-size values, or a pointer to such data. Boolean values encode as one byte: 1 for true, and 0 for false. Bytes written to w are encoded using the specified byte order and read from successive fields of the data. When writing structs, zero values are written for fields with blank (_) field names.
Example
Code:
buf := new(bytes.Buffer) var pi float64 = math.Pi err := binary.Write(buf, binary.LittleEndian, pi) if err != nil { fmt.Println("binary.Write failed:", err) } fmt.Printf("% x", buf.Bytes())
Output:
18 2d 44 54 fb 21 09 40
Example (Multi)
Code:
buf := new(bytes.Buffer) var data = []interface{}{ uint16(61374), int8(-54), uint8(254), } for _, v := range data { err := binary.Write(buf, binary.LittleEndian, v) if err != nil { fmt.Println("binary.Write failed:", err) } } fmt.Printf("%x", buf.Bytes())
Output:
beefcafe
type ByteOrder
A ByteOrder specifies how to convert byte sequences into 16-, 32-, or 64-bit unsigned integers.
type ByteOrder interface { Uint16([]byte) uint16 Uint32([]byte) uint32 Uint64([]byte) uint64 PutUint16([]byte, uint16) PutUint32([]byte, uint32) PutUint64([]byte, uint64) String() string }
Example (Get)
Code:
b := []byte{0xe8, 0x03, 0xd0, 0x07} x1 := binary.LittleEndian.Uint16(b[0:]) x2 := binary.LittleEndian.Uint16(b[2:]) fmt.Printf("%#04x %#04x\n", x1, x2)
Output:
0x03e8 0x07d0
Example (Put)
Code:
b := make([]byte, 4) binary.LittleEndian.PutUint16(b[0:], 0x03e8) binary.LittleEndian.PutUint16(b[2:], 0x07d0) fmt.Printf("% x\n", b)
Output:
e8 03 d0 07
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/encoding/binary/