Пакет binary
Обзор
Пакет binary реализует простое преобразование между числами и последовательностями байтов, а также кодирование и декодирование varint.
Числа преобразуются путём чтения и записи значений фиксированной длины. Значение фиксированной длины — это либо тип арифметического значения фиксированной длины (bool, int8, uint8, int16, float32, complex64, ...) либо массив или структура, содержащие только значения фиксированной длины.
Функции varint кодируют и декодируют отдельные целочисленные значения с помощью кодирования переменной длины; меньшие значения требуют меньше байтов. Для спецификации см. https://developers.google.com/protocol-buffers/docs/encoding.
Этот пакет отдает предпочтение простоте перед эффективностью. Клиенты, которым требуется высокопроизводительная сериализация, особенно для больших структур данных, должны обратиться к более продвинутым решениям, таким как пакет encoding/gob или google.golang.org/protobuf для протоколов Protobuf.
Индекс
Примеры
Файлы пакета
binary.go native_endian_little.go varint.go
Константы
MaxVarintLenN — максимальная длина varint-закодированного целого числа N-разрядности.
const (
MaxVarintLen16 = 3
MaxVarintLen32 = 5
MaxVarintLen64 = 10
) Переменные
BigEndian — реализация BigEndian типов ByteOrder и AppendByteOrder.
var BigEndian bigEndian
LittleEndian — реализация LittleEndian типов ByteOrder и AppendByteOrder.
var LittleEndian littleEndian
NativeEndian — реализация NativeEndian типов ByteOrder и AppendByteOrder.
var NativeEndian nativeEndian
функция Append 1.23
func Append(buf []byte, order ByteOrder, data any) ([]byte, error)
Append добавляет двоичное представление данных в buf. buf может быть null, в этом случае новый буфер будет выделен. См. Write, где указаны допустимые данные. Возвращает буфер (возможно, расширенный) с данными или ошибку.
функция AppendUvarint 1.19
func AppendUvarint(buf []byte, x uint64) []byte
AppendUvarint добавляет varint-закодированную форму x, как сгенерированную PutUvarint, в buf и возвращает расширенный буфер.
функция AppendVarint 1.19
func AppendVarint(buf []byte, x int64) []byte
AppendVarint добавляет varint-закодированную форму x, как сгенерированную PutVarint, в buf и возвращает расширенный буфер.
функция Decode 1.23
func Decode(buf []byte, order ByteOrder, data any) (int, error)
Decode декодирует двоичные данные из buf в данные в соответствии с заданным порядком байтов. Возвращает ошибку, если buf слишком мал, в противном случае количество прочитанных из buf байтов.
функция Encode 1.23
func Encode(buf []byte, order ByteOrder, data any) (int, error)
Encode кодирует двоичное представление данных в buf в соответствии с заданным порядком байтов. Возвращает ошибку, если buf слишком мал, в противном случае количество записанных в buf байтов.
функция PutUvarint
func PutUvarint(buf []byte, x uint64) int
PutUvarint кодирует uint64 в buf и возвращает количество записанных байтов. Если буфер слишком мал, PutUvarint вызовет ошибку.
Пример
Код:
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])
}
Вывод:
01 02 7f 8001 ff01 8002
функция PutVarint
func PutVarint(buf []byte, x int64) int
PutVarint кодирует int64 в buf и возвращает количество записанных байтов. Если буфер слишком мал, PutVarint вызовет ошибку.
Пример
Код:
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])
}
Вывод:
8101 7f 03 01 00 02 04 7e 8001
функция Read
func Read(r io.Reader, order ByteOrder, data any) error
Read считывает структурированные двоичные данные из r в данные. Данные должны быть указателем на значение фиксированной длины или срез значений фиксированной длины. Прочитанные из r байты декодируются с использованием указанного порядка байтов и записываются в последовательные поля данных. При декодировании булевых значений ноль байт декодируется как false, а любой другой ненулевой байт декодируется как true. При чтении в структуры данные полей с пустыми полями (_) пропускаются; т.е. пустые имена полей могут использоваться для заполнения. При чтении в структуру все непустые поля должны быть экспортированы, иначе Read может вызвать ошибку.
Ошибка — io.EOF только если не было прочитано ни одного байта. Если io.EOF происходит после чтения некоторых, но не всех байтов, Read возвращает io.ErrUnexpectedEOF.
Пример
Код:
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)
Вывод:
3.141592653589793
Пример (Множественный)
Код:
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)
Вывод:
3.141592653589793 255 01 02 03 61374
функция ReadUvarint
func ReadUvarint(r io.ByteReader) (uint64, error)
ReadUvarint считывает закодированное целое без знака из r и возвращает его как uint64. Ошибка — io.EOF только если не было прочитано ни одного байта. Если io.EOF происходит после чтения некоторых, но не всех байтов, ReadUvarint возвращает io.ErrUnexpectedEOF.
функция ReadVarint
func ReadVarint(r io.ByteReader) (int64, error)
ReadVarint считывает закодированное целое со знаком из r и возвращает его как int64. Ошибка — io.EOF только если не было прочитано ни одного байта. Если io.EOF происходит после чтения некоторых, но не всех байтов, ReadVarint возвращает io.ErrUnexpectedEOF.
функция Size
func Size(v any) int
Size возвращает количество байтов, которые функция Write сгенерирует для кодирования значения v, которое должно быть значением фиксированной длины, массивом значений фиксированной длины или указателем на такие данные. Если v не соответствует ни одному из этих типов, Size возвращает -1.
функция Uvarint
func Uvarint(buf []byte) (uint64, int)
Uvarint декодирует uint64 из buf и возвращает это значение и количество прочитанных байтов (> 0). В случае ошибки значение равно 0, а количество прочитанных байтов n меньше или равно 0, что означает:
- n == 0: buf слишком мал;
- n < 0: значение больше 64 бит (переполнение), и -n — количество прочитанных байтов.
Пример
Код:
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)
}
Вывод:
1 2 127 128 255 256
функция Varint
func Varint(buf []byte) (int64, int)
Varint декодирует int64 из buf и возвращает это значение и количество прочитанных байтов (> 0). В случае ошибки значение равно 0, а количество прочитанных байтов n меньше или равно 0, что означает:
- n == 0: buf слишком мал;
- n < 0: значение больше 64 бит (переполнение), и -n — количество прочитанных байтов.
Пример
Код:
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)
}
Вывод:
-65 -64 -2 -1 0 1 2 63 64
функция Write
func Write(w io.Writer, order ByteOrder, data any) error
Write записывает двоичное представление данных в w. Данные должны быть значением фиксированной длины, массивом значений фиксированной длины или указателем на такие данные. Булевы значения кодируются как один байт: 1 для true и 0 для false. Байты, записанные в w, кодируются с использованием указанного порядка байтов и читаются из последовательных полей данных. При записи структур нулевые значения записываются для полей с пустыми именами (_) полей.
Пример
Код:
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())
Вывод:
18 2d 44 54 fb 21 09 40
Пример (Множественный)
Код:
buf := new(bytes.Buffer)
var data = []any{
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())
Вывод:
beefcafe
тип AppendByteOrder 1.19
AppendByteOrder определяет, как добавить 16-, 32- или 64-битные целые без знака в срез байтов.
Он реализован в LittleEndian, BigEndian и NativeEndian.
type AppendByteOrder interface {
AppendUint16([]byte, uint16) []byte
AppendUint32([]byte, uint32) []byte
AppendUint64([]byte, uint64) []byte
String() string
} тип ByteOrder
ByteOrder определяет, как преобразовать срезы байтов в 16-, 32- или 64-битные целые без знака.
Он реализован в LittleEndian, BigEndian и NativeEndian.
type ByteOrder interface {
Uint16([]byte) uint16
Uint32([]byte) uint32
Uint64([]byte) uint64
PutUint16([]byte, uint16)
PutUint32([]byte, uint32)
PutUint64([]byte, uint64)
String() string
} Пример (Получение)
Код:
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)
Вывод:
0x03e8 0x07d0
Пример (Запись)
Код:
b := make([]byte, 4)
binary.LittleEndian.PutUint16(b[0:], 0x03e8)
binary.LittleEndian.PutUint16(b[2:], 0x07d0)
fmt.Printf("% x\n", b)
Вывод:
e8 03 d0 07
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/encoding/binary/