binary

package
v1.32.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 25, 2024 License: MIT Imports: 11 Imported by: 12

Documentation

Overview

Package binary implements the Thrift Binary protocol.

See "go.uber.org/thriftrw/protocol".Binary for a higher-level Encode/Decode API.

Index

Constants

This section is empty.

Variables

View Source
var Default = new(Protocol)

Default is the default implementation of the Thrift Binary Protocol.

View Source
var NoEnvelopeResponder = &noEnvelopeResponder{}

NoEnvelopeResponder responds to a request without an envelope.

Functions

func IsDecodeError

func IsDecodeError(e error) bool

IsDecodeError checks if an error is a protocol decode error.

func ReturnWriter

func ReturnWriter(w *Writer)

ReturnWriter returns a previously borrowed Writer back to the system.

Types

type EnvelopeV0Responder added in v1.29.0

type EnvelopeV0Responder struct {
	Name  string
	SeqID int32
}

EnvelopeV0Responder responds to requests with a non-strict (unversioned) envelope.

func (EnvelopeV0Responder) EncodeResponse added in v1.29.0

func (r EnvelopeV0Responder) EncodeResponse(v wire.Value, t wire.EnvelopeType, w io.Writer) error

EncodeResponse writes the response to the writer using a non-strict envelope.

func (EnvelopeV0Responder) WriteResponse added in v1.29.0

func (r EnvelopeV0Responder) WriteResponse(et wire.EnvelopeType, w io.Writer, ev stream.Enveloper) error

WriteResponse writes an envelope to the writer (non-strict envelope) and returns a borrowed stream.Writer. Callers must call Close() on stream.Writer once finished.

type EnvelopeV1Responder added in v1.29.0

type EnvelopeV1Responder struct {
	Name  string
	SeqID int32
}

EnvelopeV1Responder responds to requests with a strict, version 1 envelope.

func (EnvelopeV1Responder) EncodeResponse added in v1.29.0

func (r EnvelopeV1Responder) EncodeResponse(v wire.Value, t wire.EnvelopeType, w io.Writer) error

EncodeResponse writes the response to the writer using a strict, version 1 envelope.

func (EnvelopeV1Responder) WriteResponse added in v1.29.0

func (r EnvelopeV1Responder) WriteResponse(et wire.EnvelopeType, w io.Writer, ev stream.Enveloper) error

WriteResponse writes an envelope to the writer (strict envelope) and returns a borrowed stream.Writer. Callers must call Close() on stream.Writer once finished.

type Protocol added in v1.29.0

type Protocol struct{}

Protocol implements the Thrift Binary Protocol.

func (*Protocol) Decode added in v1.29.0

func (*Protocol) Decode(r io.ReaderAt, t wire.Type) (wire.Value, error)

Decode reads a Value of the given type from the given Reader.

func (*Protocol) DecodeEnveloped added in v1.29.0

func (*Protocol) DecodeEnveloped(r io.ReaderAt) (wire.Envelope, error)

DecodeEnveloped reads an enveloped value from the given Reader. Enveloped values are assumed to be TStructs.

func (*Protocol) DecodeRequest added in v1.29.0

func (p *Protocol) DecodeRequest(et wire.EnvelopeType, r io.ReaderAt) (wire.Value, envelope.Responder, error)

DecodeRequest specializes Decode and replaces DecodeEnveloped for the specific purpose of decoding request structs that may or may not have an envelope. This allows a Thrift request handler to transparently accept requests regardless of whether the caller submits an envelope. The caller specifies the expected envelope type, one of OneWay or Unary, on which the decoder asserts if the envelope is present.

This is possible because we can distinguish an envelope from a bare request struct by looking at the first byte and the length of the message.

1. A message of length 1 containing only 0x00 can only be an empty struct. 0x00 is the type ID for STOP, indicating the end of the struct.

2. A message of length >1 starting with 0x00 can only be a non-strict envelope (not versioned), assuming the message name is less than 16MB long. In this case, the first four bytes indicate the length of the method name, which is unlikely to overflow into the high byte.

3. A message of length >1, where the first byte is <0 can only be a strict envelope. The MSB indicates that the message is versioned. Reading the first two bytes and masking out the MSB indicates the version number. At this time, there is only one version.

4. A message of length >1, where the first byte is >=0 can only be a bare struct starting with that field identifier. Valid field identifiers today are in the range 0x00-0x0f. There is some chance that a future version of the protocol will add more field types, but it is very unlikely that the field type will flow into the MSB (128 type identifiers, starting with the 15 valid types today).

func (*Protocol) Encode added in v1.29.0

func (*Protocol) Encode(v wire.Value, w io.Writer) error

Encode the given Value and write the result to the given Writer.

func (*Protocol) EncodeEnveloped added in v1.29.0

func (*Protocol) EncodeEnveloped(e wire.Envelope, w io.Writer) error

EncodeEnveloped encodes the enveloped value and writes the result to the given Writer.

func (*Protocol) ReadRequest added in v1.29.0

func (p *Protocol) ReadRequest(
	ctx context.Context,
	et wire.EnvelopeType,
	r io.Reader,
	body stream.BodyReader,
) (stream.ResponseWriter, error)

ReadRequest reads off the request envelope (if present) from an io.Reader, populating the provided BodyReader to read off the full request struct, asserting the EnvelopeType (either OneWay or Unary) if an envlope exists. A ResponseWriter that understands the enveloping used is returned.

This allows a Thrift request handler to transparently read requests regardless of whether the caller is configured to submit envelopes.

This is possible because we can distinguish an envelope from a bare request struct by looking at the first byte and the length of the message.

1. A message of length 1 containing only 0x00 can only be an empty struct. 0x00 is the type ID for STOP, indicating the end of the struct.

2. A message of length >1 starting with 0x00 can only be a non-strict envelope (not versioned), assuming the message name is less than 16MB long. In this case, the first four bytes indicate the length of the method name, which is unlikely to overflow into the high byte.

3. A message of length >1, where the first byte is <0 can only be a strict envelope. The MSB indicates that the message is versioned. Reading the first two bytes and masking out the MSB indicates the version number. At this time, there is only one version.

4. A message of length >1, where the first byte is >=0 can only be a bare struct starting with that field identifier. Valid field identifiers today are in the range 0x00-0x0f. There is some chance that a future version of the protocol will add more field types, but it is very unlikely that the field type will flow into the MSB (128 type identifiers, starting with the 15 valid types today).

func (*Protocol) Reader added in v1.29.0

func (*Protocol) Reader(r io.Reader) stream.Reader

Reader builds a stream reader that reads from the provided stream using the Thrift Binary Protocol.

func (*Protocol) Writer added in v1.29.0

func (*Protocol) Writer(w io.Writer) stream.Writer

Writer builds a stream writer that writes to the provided stream using the Thrift Binary Protocol.

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader implements a parser for the Thrift Binary Protocol based on an io.ReaderAt.

func NewReader

func NewReader(r io.ReaderAt) Reader

NewReader builds a new Reader based on the given io.ReaderAt.

func (*Reader) ReadEnveloped

func (bw *Reader) ReadEnveloped() (wire.Envelope, error)

ReadEnveloped reads an Apache Thrift envelope

Thrift supports two kinds of envelopes: strict, and non-strict.

Non-strict envelopes: Name (4 byte length prefixed string) Type ID (1 byte) Sequence ID (4 bytes)

Strict envelopes:

Version | Type ID (4 bytes) Name (4 byte length prefixed string) Sequence ID (4 bytes)

When reading payloads, we need to support both strict and non-strict payloads. To do this, we read the first 4 byte. Non-strict payloads will always have a size >= 0, while strict payloads have selected version numbers such that the value will always be negative.

func (*Reader) ReadValue

func (br *Reader) ReadValue(t wire.Type, off int64) (wire.Value, int64, error)

ReadValue reads a value off the given type off the wire starting at the given offset.

Returns the Value, the new offset, and an error if there was a decode error.

type Responder added in v1.29.0

type Responder interface {
	EncodeResponse(v wire.Value, t wire.EnvelopeType, w io.Writer) error
}

Responder captures how to respond to a request, concerning whether and what kind of envelope to use, how to match the sequence identifier of the corresponding request.

type StreamReader added in v1.29.0

type StreamReader struct {
	// contains filtered or unexported fields
}

StreamReader provides an implementation of a "stream.Reader".

func NewStreamReader added in v1.29.0

func NewStreamReader(r io.Reader) *StreamReader

NewStreamReader fetches a StreamReader from the system that will write its output to the given io.Reader.

This StreamReader must be closed using `Close()`

func (*StreamReader) Close added in v1.29.0

func (sr *StreamReader) Close() error

Close frees up the resources used by the StreamReader and returns it back to the pool.

func (*StreamReader) ReadBinary added in v1.29.0

func (sr *StreamReader) ReadBinary() ([]byte, error)

ReadBinary reads a Thrift encoded binary type, returning a byte array.

func (*StreamReader) ReadBool added in v1.29.0

func (sr *StreamReader) ReadBool() (bool, error)

ReadBool reads a Thrift encoded bool value, returning a bool.

func (*StreamReader) ReadDouble added in v1.29.0

func (sr *StreamReader) ReadDouble() (float64, error)

ReadDouble reads a Thrift encoded double, returning a float64.

func (*StreamReader) ReadEnvelopeBegin added in v1.29.0

func (sw *StreamReader) ReadEnvelopeBegin() (stream.EnvelopeHeader, error)

ReadEnvelopeBegin reads the start of an Apache Thrift envelope. Thrift supports two kinds of envelopes: strict, and non-strict. See ReadEnveloped method for more information on enveloping.

func (*StreamReader) ReadEnvelopeEnd added in v1.29.0

func (sw *StreamReader) ReadEnvelopeEnd() error

ReadEnvelopeEnd reads the "end" of an envelope. Since there is no real envelope end, this is a no-op.

func (*StreamReader) ReadFieldBegin added in v1.29.0

func (sr *StreamReader) ReadFieldBegin() (fh stream.FieldHeader, ok bool, err error)

ReadFieldBegin reads off a Thrift encoded field-header returning that and a 'bool' representing whether or not a field-value follows. A 'false' without any error means that it has reached the stop-field. There is no guarantee that the field-header is valid in this case.

func (*StreamReader) ReadFieldEnd added in v1.29.0

func (sr *StreamReader) ReadFieldEnd() error

ReadFieldEnd reads the "end" of a Thrift encoded field Since there is no encoding for the end of a field, this is a noop.

func (*StreamReader) ReadInt16 added in v1.29.0

func (sr *StreamReader) ReadInt16() (int16, error)

ReadInt16 reads a Thrift encoded int16 value.

func (*StreamReader) ReadInt32 added in v1.29.0

func (sr *StreamReader) ReadInt32() (int32, error)

ReadInt32 reads a Thrift encoded int32 value.

func (*StreamReader) ReadInt64 added in v1.29.0

func (sr *StreamReader) ReadInt64() (int64, error)

ReadInt64 reads a Thrift encoded int64 value.

func (*StreamReader) ReadInt8 added in v1.29.0

func (sr *StreamReader) ReadInt8() (int8, error)

ReadInt8 reads a Thrift encoded int8 value.

func (*StreamReader) ReadListBegin added in v1.29.0

func (sr *StreamReader) ReadListBegin() (lh stream.ListHeader, err error)

ReadListBegin reads off the list header of a Thrift encoded list.

func (*StreamReader) ReadListEnd added in v1.29.0

func (sr *StreamReader) ReadListEnd() error

ReadListEnd reads the "end" of a Thrift encoded list. Since there is no encoding for the end of a list, this is a noop.

func (*StreamReader) ReadMapBegin added in v1.29.0

func (sr *StreamReader) ReadMapBegin() (mh stream.MapHeader, err error)

ReadMapBegin reads off the map header of a Thrift encoded map.

func (*StreamReader) ReadMapEnd added in v1.29.0

func (sr *StreamReader) ReadMapEnd() error

ReadMapEnd reads the "end" of a Thrift encoded list. Since there is no encoding for the end of a map, this is a noop.

func (*StreamReader) ReadSetBegin added in v1.29.0

func (sr *StreamReader) ReadSetBegin() (sh stream.SetHeader, err error)

ReadSetBegin reads off the set header of a Thrift encoded set.

func (*StreamReader) ReadSetEnd added in v1.29.0

func (sr *StreamReader) ReadSetEnd() error

ReadSetEnd reads the "end" of a Thrift encoded list. Since there is no encoding for the end of a set, this is a noop.

func (*StreamReader) ReadString added in v1.29.0

func (sr *StreamReader) ReadString() (string, error)

ReadString reads a Thrift encoded string.

func (*StreamReader) ReadStructBegin added in v1.29.0

func (sr *StreamReader) ReadStructBegin() error

ReadStructBegin reads the "beginning" of a Thrift encoded struct. Since there is no encoding for the beginning of a struct, this is a noop.

func (*StreamReader) ReadStructEnd added in v1.29.0

func (sr *StreamReader) ReadStructEnd() error

ReadStructEnd reads the "end" of a Thrift encoded struct. Since `ReadFieldBegin` will already be interpreting field-type of whether it's a stop field or not, there is no real representation of a struct's end, making this a noop.

func (*StreamReader) Skip added in v1.29.0

func (sr *StreamReader) Skip(t wire.Type) error

Skip skips fully over the provided Thrift type.

type StreamWriter added in v1.29.0

type StreamWriter struct {
	// contains filtered or unexported fields
}

StreamWriter implements basic logic for writing the Thrift Binary Protocol to an io.Writer.

func NewStreamWriter added in v1.29.0

func NewStreamWriter(w io.Writer) *StreamWriter

NewStreamWriter fetches a StreamWriter from the system that will write its output to the given io.Writer.

This StreamWriter must be returned back using ReturnStreamWriter.

func (*StreamWriter) Close added in v1.29.0

func (sw *StreamWriter) Close() error

Close frees up the resources used by the StreamWriter and returns it back to the pool.

func (*StreamWriter) WriteBinary added in v1.29.0

func (sw *StreamWriter) WriteBinary(b []byte) error

WriteBinary encodes binary

func (*StreamWriter) WriteBool added in v1.29.0

func (sw *StreamWriter) WriteBool(b bool) error

WriteBool encodes a boolean

func (*StreamWriter) WriteDouble added in v1.29.0

func (sw *StreamWriter) WriteDouble(d float64) error

WriteDouble encodes a double

func (*StreamWriter) WriteEnvelopeBegin added in v1.29.0

func (sw *StreamWriter) WriteEnvelopeBegin(eh stream.EnvelopeHeader) error

WriteEnvelopeBegin writes the start of a strict envelope (contains an envelope version).

func (*StreamWriter) WriteEnvelopeEnd added in v1.29.0

func (sw *StreamWriter) WriteEnvelopeEnd() error

WriteEnvelopeEnd writes the "end" of an envelope. Since there is no ending to an envelope, this is a no-op.

func (*StreamWriter) WriteFieldBegin added in v1.29.0

func (sw *StreamWriter) WriteFieldBegin(f stream.FieldHeader) error

WriteFieldBegin marks the beginning of a new field in a struct. The first byte denotes the type and the next two bytes denote the field id.

func (*StreamWriter) WriteFieldEnd added in v1.29.0

func (sw *StreamWriter) WriteFieldEnd() error

WriteFieldEnd denotes the end of a field. No-op.

func (*StreamWriter) WriteInt16 added in v1.29.0

func (sw *StreamWriter) WriteInt16(i int16) error

WriteInt16 encodes an int16

func (*StreamWriter) WriteInt32 added in v1.29.0

func (sw *StreamWriter) WriteInt32(i int32) error

WriteInt32 encodes an int32

func (*StreamWriter) WriteInt64 added in v1.29.0

func (sw *StreamWriter) WriteInt64(i int64) error

WriteInt64 encodes an int64

func (*StreamWriter) WriteInt8 added in v1.29.0

func (sw *StreamWriter) WriteInt8(i int8) error

WriteInt8 encodes an int8

func (*StreamWriter) WriteLegacyEnvelopeBegin added in v1.29.0

func (sw *StreamWriter) WriteLegacyEnvelopeBegin(eh stream.EnvelopeHeader) error

WriteLegacyEnvelopeBegin writes the start of a non-strict envelope (lacks an envelope version).

func (*StreamWriter) WriteLegacyEnvelopeEnd added in v1.29.0

func (sw *StreamWriter) WriteLegacyEnvelopeEnd() error

WriteLegacyEnvelopeEnd writes the "end" of a legacy envelope. Since there is no ending to a legacy envelope, this is a no-op.

func (*StreamWriter) WriteListBegin added in v1.29.0

func (sw *StreamWriter) WriteListBegin(l stream.ListHeader) error

WriteListBegin marks the beginning of a new list. The first byte denotes the type of the items and the next four bytes denote the length of the list.

func (*StreamWriter) WriteListEnd added in v1.29.0

func (sw *StreamWriter) WriteListEnd() error

WriteListEnd marks the end of a list. No-op.

func (*StreamWriter) WriteMapBegin added in v1.29.0

func (sw *StreamWriter) WriteMapBegin(m stream.MapHeader) error

WriteMapBegin marks the beginning of a new map. The first byte denotes the type of the keys, the second byte denotes the type of the values, and the next four bytes denote the length of the map.

func (*StreamWriter) WriteMapEnd added in v1.29.0

func (sw *StreamWriter) WriteMapEnd() error

WriteMapEnd marks the end of a map. No-op.

func (*StreamWriter) WriteSetBegin added in v1.29.0

func (sw *StreamWriter) WriteSetBegin(s stream.SetHeader) error

WriteSetBegin marks the beginning of a new set. The first byte denotes the type of the items and the next four bytes denote the length of the set.

func (*StreamWriter) WriteSetEnd added in v1.29.0

func (sw *StreamWriter) WriteSetEnd() error

WriteSetEnd marks the end of a set. No-op.

func (*StreamWriter) WriteString added in v1.29.0

func (sw *StreamWriter) WriteString(s string) error

WriteString encodes a string

func (*StreamWriter) WriteStructBegin added in v1.29.0

func (sw *StreamWriter) WriteStructBegin() error

WriteStructBegin denotes the beginning of a struct. No-op.

func (*StreamWriter) WriteStructEnd added in v1.29.0

func (sw *StreamWriter) WriteStructEnd() error

WriteStructEnd uses the zero byte to mark the end of a struct.

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

Writer implements basic logic for writing the Thrift Binary Protocol to an io.Writer.

func BorrowWriter

func BorrowWriter(w io.Writer) *Writer

BorrowWriter fetches a Writer from the system that will write its output to the given io.Writer.

This Writer must be returned back using ReturnWriter.

func (*Writer) WriteEnveloped

func (bw *Writer) WriteEnveloped(e wire.Envelope) error

WriteEnveloped writes enveloped value using the strict envelope.

func (*Writer) WriteLegacyEnveloped added in v1.9.0

func (bw *Writer) WriteLegacyEnveloped(e wire.Envelope) error

WriteLegacyEnveloped writes enveloped value using the non-strict envelope (non-strict lacks an envelope version).

func (*Writer) WriteValue

func (bw *Writer) WriteValue(v wire.Value) error

WriteValue writes the given Thrift value to the underlying stream using the Thrift Binary Protocol.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL