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 для protocol buffers.

Указатель

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

Примеры

ByteOrder (Get)
ByteOrder (Put)
PutUvarint
PutVarint
Read
Read (Multi)
Uvarint
Varint
Write
Write (Multi)

Файлы пакета

binary.go native_endian_little.go varint.go

Константы

MaxVarintLenN — максимальная длина целого числа из N бит, закодированного в формате varint.

const (
    MaxVarintLen16 = 3
    MaxVarintLen32 = 5
    MaxVarintLen64 = 10
)

Переменные

BigEndian — реализация с порядком байтов от старшего к младшему для ByteOrder и AppendByteOrder.

var BigEndian bigEndian

LittleEndian — реализация с порядком байтов от младшего к старшему для ByteOrder и AppendByteOrder.

var LittleEndian littleEndian

NativeEndian — реализация с собственным порядком байтов платформы для ByteOrder и AppendByteOrder.

var NativeEndian nativeEndian

func Append 1.23

func Append(buf []byte, order ByteOrder, data any) ([]byte, error)

Append добавляет двоичное представление data в buf. buf может быть nil; в этом случае будет выделен новый буфер. Допустимые значения data см. в описании Write. Функция возвращает буфер, содержащий data (возможно, расширенный), или ошибку.

func AppendUvarint 1.19

func AppendUvarint(buf []byte, x uint64) []byte

AppendUvarint добавляет в buf форму x, закодированную в формате varint, как при вызове PutUvarint, и возвращает расширенный буфер.

func AppendVarint 1.19

func AppendVarint(buf []byte, x int64) []byte

AppendVarint добавляет в buf форму x, закодированную в формате varint, как при вызове PutVarint, и возвращает расширенный буфер.

func Decode 1.23

func Decode(buf []byte, order ByteOrder, data any) (int, error)

Decode декодирует двоичные данные из buf в data в соответствии с заданным порядком байтов. Если buf слишком мал, функция возвращает ошибку; в противном случае она возвращает количество байтов, считанных из buf.

func Encode 1.23

func Encode(buf []byte, order ByteOrder, data any) (int, error)

Encode кодирует двоичное представление data в buf в соответствии с заданным порядком байтов. Если buf слишком мал, функция возвращает ошибку; в противном случае она возвращает количество байтов, записанных в buf.

func 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

func 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

func Read

func Read(r io.Reader, order ByteOrder, data any) error

Read считывает структурированные двоичные данные из r в data. Data должен быть указателем на значение фиксированного размера или срез значений фиксированного размера. Байты, считанные из r, декодируются с использованием заданного порядка байтов и записываются в последовательные поля data. При декодировании логических значений нулевой байт преобразуется в 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

func ReadUvarint

func ReadUvarint(r io.ByteReader) (uint64, error)

ReadUvarint считывает из r закодированное беззнаковое целое число и возвращает его в виде uint64. Ошибка io.EOF возникает только в том случае, если не было прочитано ни одного байта. Если io.EOF возникает после чтения некоторых, но не всех байтов, ReadUvarint возвращает io.ErrUnexpectedEOF.

func ReadVarint

func ReadVarint(r io.ByteReader) (int64, error)

ReadVarint считывает из r закодированное знаковое целое число и возвращает его в виде int64. Ошибка io.EOF возникает только в том случае, если не было прочитано ни одного байта. Если io.EOF возникает после чтения некоторых, но не всех байтов, ReadVarint возвращает io.ErrUnexpectedEOF.

func Size

func Size(v any) int

Size возвращает количество байтов, которое Write запишет для кодирования значения v. Значение должно иметь фиксированный размер, быть срезом значений фиксированного размера или указателем на такие данные. Если v не относится ни к одному из этих типов, Size возвращает -1.

func 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

func 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

func 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

type 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
}

type 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