Spec-Zone.ru › Go

Пакет binary

  • import "encoding/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.

Индекс

  • Константы
  • Переменные
  • функция Append(buf []byte, order ByteOrder, data any) ([]byte, error)
  • функция AppendUvarint(buf []byte, x uint64) []byte
  • функция AppendVarint(buf []byte, x int64) []byte
  • функция Decode(buf []byte, order ByteOrder, data any) (int, error)
  • функция Encode(buf []byte, order ByteOrder, data any) (int, error)
  • функция PutUvarint(buf []byte, x uint64) int
  • функция PutVarint(buf []byte, x int64) int
  • функция Read(r io.Reader, order ByteOrder, data any) error
  • функция ReadUvarint(r io.ByteReader) (uint64, error)
  • функция ReadVarint(r io.ByteReader) (int64, error)
  • функция Size(v any) int
  • функция Uvarint(buf []byte) (uint64, int)
  • функция Varint(buf []byte) (int64, int)
  • функция Write(w io.Writer, order ByteOrder, data any) error
  • тип AppendByteOrder
  • тип ByteOrder

Примеры

ByteOrder (Получение)
ByteOrder (Запись)
PutUvarint
PutVarint
Read
Read (Множественное)
Uvarint
Varint
Write
Write (Множественное)

Файлы пакета

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/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API