runtime

package
v0.0.19 Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package runtime is the FFFI2 wire-protocol runtime — binary marshalling, channel I/O, deferred-block capture, and procedure dispatch. Forms the transport substrate beneath the typed wrappers in fffi2/typed/.

Index

Constants

This section is empty.

Variables

View Source
var DefaultAllocator = func(l uint32) []byte { return make([]byte, int(l), int(l)) }
View Source
var DefaultErrorHandler = func(err error) {
	log.Error().Err(err).Msg("fffi2 channel error")
}
View Source
var PackageProps = packageprops.Props{
	WASMWASI:         packageprops.WASMCompiles,
	WASMJS:           packageprops.WASMCompiles,
	WASMFreestanding: packageprops.WASMCompiles,
}

PackageProps records this package's curated properties (ADR-0080). Seeded by `wasmsurvey props generate`; curate by hand, then `wasmsurvey props verify`.

View Source
var StringAllocationError = errors.New("allocated string buffer does not have correct length")

Functions

func GetBoolRetr

func GetBoolRetr[D UnmarshallReaderI, T ~bool](unmarshaller D) (r T)

func GetBoolSliceRetr

func GetBoolSliceRetr[D UnmarshallReaderI, T ~bool](unmarshaller D) (r []T)

func GetBytesRetr

func GetBytesRetr[D UnmarshallReaderI, T byte](unmarshaller D) (r []byte)

func GetComplex64Retr

func GetComplex64Retr[D UnmarshallReaderI, T ~complex64](unmarshaller D) (r T)

func GetComplex128Retr

func GetComplex128Retr[D UnmarshallReaderI, T ~complex128](unmarshaller D) (r T)

func GetFloat32Array2Retr

func GetFloat32Array2Retr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r [2]T)

func GetFloat32Array3Retr

func GetFloat32Array3Retr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r [3]T)

func GetFloat32Array4Retr

func GetFloat32Array4Retr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r [4]T)

func GetFloat32Retr

func GetFloat32Retr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r T)

func GetFloat32SliceRetr

func GetFloat32SliceRetr[D UnmarshallReaderI, T ~float32](unmarshaller D) (r []T)

func GetFloat64Retr

func GetFloat64Retr[D UnmarshallReaderI, T ~float64](unmarshaller D) (r T)

func GetFloat64SliceRetr

func GetFloat64SliceRetr[D UnmarshallReaderI, T ~float64](unmarshaller D) (r []T)

func GetInt8Retr

func GetInt8Retr[D UnmarshallReaderI, T ~int8](unmarshaller D) (r T)

func GetInt8SliceRetr

func GetInt8SliceRetr[D UnmarshallReaderI, T ~int8](unmarshaller D) (r []T)

func GetInt16Retr

func GetInt16Retr[D UnmarshallReaderI, T ~int16](unmarshaller D) (r T)

func GetInt16SliceRetr

func GetInt16SliceRetr[D UnmarshallReaderI, T ~int16](unmarshaller D) (r []T)

func GetInt32Retr

func GetInt32Retr[D UnmarshallReaderI, T ~int32](unmarshaller D) (r T)

func GetInt32SliceRetr

func GetInt32SliceRetr[D UnmarshallReaderI, T ~int32](unmarshaller D) (r []T)

func GetInt64Retr

func GetInt64Retr[D UnmarshallReaderI, T ~int64](unmarshaller D) (r T)

func GetInt64SliceRetr

func GetInt64SliceRetr[D UnmarshallReaderI, T ~int64](unmarshaller D) (r []T)

func GetStringRetr

func GetStringRetr[D UnmarshallReaderI, T ~string](unmarshaller D) (r T)

func GetStringRetrMostLikelyEmpty

func GetStringRetrMostLikelyEmpty[D UnmarshallReaderI, T ~string](unmarshaller D) (r T)

func GetUint8Retr

func GetUint8Retr[D UnmarshallReaderI, T ~uint8](unmarshaller D) (r T)

func GetUint8SliceRetr

func GetUint8SliceRetr[D UnmarshallReaderI, T ~uint8](unmarshaller D) (r []T)

func GetUint16Retr

func GetUint16Retr[D UnmarshallReaderI, T ~uint16](unmarshaller D) (r T)

func GetUint16SliceRetr

func GetUint16SliceRetr[D UnmarshallReaderI, T ~uint16](unmarshaller D) (r []T)

func GetUint32Retr

func GetUint32Retr[D UnmarshallReaderI, T ~uint32](unmarshaller D) (r T)

func GetUint32SliceRetr

func GetUint32SliceRetr[D UnmarshallReaderI, T ~uint32](unmarshaller D) (r []T)

func GetUint64Retr

func GetUint64Retr[D UnmarshallReaderI, T ~uint64](unmarshaller D) (r T)

func GetUint64SliceRetr

func GetUint64SliceRetr[D UnmarshallReaderI, T ~uint64](unmarshaller D) (r []T)

func GetUintptrRetr

func GetUintptrRetr[D UnmarshallReaderI, T ~uintptr](unmarshaller D) (r T)

func IterateFloat32SliceRetr

func IterateFloat32SliceRetr[D UnmarshallReaderI, T ~float32](unmarshaller D) iter.Seq[T]

func IterateFloat64SliceRetr

func IterateFloat64SliceRetr[D UnmarshallReaderI, T ~float64](unmarshaller D) iter.Seq[T]

func IterateInt64SliceRetr

func IterateInt64SliceRetr[D UnmarshallReaderI, T ~int64](unmarshaller D) iter.Seq[T]

func IterateStringSliceRetr

func IterateStringSliceRetr[D UnmarshallReaderI, T ~string](unmarshaller D) iter.Seq[T]

func IterateUint32SliceRetr

func IterateUint32SliceRetr[D UnmarshallReaderI, T ~uint32](unmarshaller D) iter.Seq[T]

func IterateUint64SliceRetr

func IterateUint64SliceRetr[D UnmarshallReaderI, T ~uint64](unmarshaller D) iter.Seq[T]

func PutBoolArg

func PutBoolArg[D MarshallWriterI, T ~bool](marshaller D, v T)

func PutBoolSliceArg

func PutBoolSliceArg[D MarshallWriterI, T ~bool](marshaller D, vs []T)

func PutBytesArg

func PutBytesArg[D MarshallWriterI](marshaller D, v []byte)

func PutComplex64Arg

func PutComplex64Arg[D MarshallWriterI, T ~complex64](marshaller D, v T)

func PutComplex64Array2Arg

func PutComplex64Array2Arg[D MarshallWriterI, T ~complex64](marshaller D, v [2]T)

func PutComplex128Arg

func PutComplex128Arg[D MarshallWriterI, T ~complex128](marshaller D, v T)

func PutFloat32Arg

func PutFloat32Arg[D MarshallWriterI, T ~float32](marshaller D, v T)

func PutFloat32Array2Arg

func PutFloat32Array2Arg[D MarshallWriterI, T ~float32](marshaller D, v [2]T)

func PutFloat32Array3Arg

func PutFloat32Array3Arg[D MarshallWriterI, T ~float32](marshaller D, v [3]T)

func PutFloat32Array4Arg

func PutFloat32Array4Arg[D MarshallWriterI, T ~float32](marshaller D, v [4]T)

func PutFloat32SliceArg

func PutFloat32SliceArg[D MarshallWriterI, T ~float32](marshaller D, vs []T)

func PutFloat64Arg

func PutFloat64Arg[D MarshallWriterI, T ~float64](marshaller D, v T)

func PutFloat64Array4Arg

func PutFloat64Array4Arg[D MarshallWriterI, T ~float64](marshaller D, v [4]T)

func PutFloat64SliceArg

func PutFloat64SliceArg[D MarshallWriterI, T ~float64](marshaller D, vs []T)

func PutInt8Arg

func PutInt8Arg[D MarshallWriterI, T ~int8](marshaller D, v T)

func PutInt8SliceArg

func PutInt8SliceArg[D MarshallWriterI, T ~int8](marshaller D, vs []T)

func PutInt16Arg

func PutInt16Arg[D MarshallWriterI, T ~int16](marshaller D, v T)

func PutInt16SliceArg

func PutInt16SliceArg[D MarshallWriterI, T ~int16](marshaller D, vs []T)

func PutInt32Arg

func PutInt32Arg[D MarshallWriterI, T ~int32](marshaller D, v T)

func PutInt32SliceArg

func PutInt32SliceArg[D MarshallWriterI, T ~int32](marshaller D, vs []T)

func PutInt64Arg

func PutInt64Arg[D MarshallWriterI, T ~int64](marshaller D, v T)

func PutInt64SliceArg

func PutInt64SliceArg[D MarshallWriterI, T ~int64](marshaller D, vs []T)

func PutRuneArg

func PutRuneArg[D MarshallWriterI, T ~rune](marshaller D, v T)

func PutRuneSliceArg

func PutRuneSliceArg[D MarshallWriterI, T ~rune](marshaller D, vs []T)

func PutStringArg

func PutStringArg[D MarshallWriterI, T ~string](marshaller D, v T)

func PutStringSliceArg

func PutStringSliceArg[D MarshallWriterI, T ~string](marshaller D, vs []T)

func PutStringsArg

func PutStringsArg[D MarshallWriterI, T ~string](marshaller D, vs []T)

func PutUint8Arg

func PutUint8Arg[D MarshallWriterI, T ~uint8](marshaller D, v T)

func PutUint8SliceArg

func PutUint8SliceArg[D MarshallWriterI, T ~uint8](marshaller D, vs []T)

func PutUint16Arg

func PutUint16Arg[D MarshallWriterI, T ~uint16](marshaller D, v T)

func PutUint16SliceArg

func PutUint16SliceArg[D MarshallWriterI, T ~uint16](marshaller D, vs []T)

func PutUint32Arg

func PutUint32Arg[D MarshallWriterI, T ~uint32](marshaller D, v T)

func PutUint32SliceArg

func PutUint32SliceArg[D MarshallWriterI, T ~uint32](marshaller D, vs []T)

func PutUint64Arg

func PutUint64Arg[D MarshallWriterI, T ~uint64](marshaller D, v T)

func PutUint64SliceArg

func PutUint64SliceArg[D MarshallWriterI, T ~uint64](marshaller D, vs []T)

func PutUintptrArg

func PutUintptrArg[D MarshallWriterI, T ~uintptr](marshaller D, v T)

func RegisterScopeHint

func RegisterScopeHint(kind string) *atomic.Uint64

RegisterScopeHint returns the singleton *atomic.Uint64 hint for the given scope-kind name, allocating it on first call. Idempotent: a second call with the same name returns the same pointer, so the codegen can wire `var hintCells = runtime.RegisterScopeHint("cells")` once per package and every scope instance of that kind reads/writes the shared atomic.

Concurrency: safe to call from any goroutine. Registration uses a short writer-lock; subsequent hint reads/writes from a scope's hot path go through the returned *atomic.Uint64 with no further synchronisation.

Types

type ByteOrderI

type ByteOrderI interface {
	binary.ByteOrder
	binary.AppendByteOrder
}

type ChannelI

type ChannelI[U UnmarshallReaderI] interface {
	SyncMultiUseMsg(id uint64, buf []byte)
	SendSingleUseMsg(buf []byte)
	ReceiveMsg() iter.Seq[U]
	FlushMessages()
}

type DeferredBlockScope

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

DeferredBlockScope manages capture of deferred opcode blocks.

All block key bytes and opcode bytes are appended to a single contiguous slab (dataBuf). Individual blocks are tracked as offset+length pairs into the slab, eliminating per-cell allocations.

Lifecycle:

  1. scope := NewDeferredBlockScope(fffi, endianness) (or NewDeferredBlockScopeHinted)
  2. scope.Begin(key...) <- redirect Fffi2 to capture buffer
  3. ... widget.Send() ... <- messages go to capture buffer
  4. scope.End() <- restore Fffi2, store buffer
  5. scope.SpliceInto(r) <- write all blocks into RetainedFffiBuilder
  6. scope.ReleaseWithHint() <- (optional) fold high-water back into hint

func NewDeferredBlockScope

func NewDeferredBlockScope(
	getFffi func() FffiCaptureI,
	endianness binary.ByteOrder,
) *DeferredBlockScope

NewDeferredBlockScope creates a new scope with a fixed-size initial dataBuf. Equivalent to NewDeferredBlockScopeHinted with a nil hint, retained for non-codegen callers and backward compatibility.

getFffi returns the current Fffi2 instance.

func NewDeferredBlockScopeHinted

func NewDeferredBlockScopeHinted(
	getFffi func() FffiCaptureI,
	endianness binary.ByteOrder,
	dataHint *atomic.Uint64,
) *DeferredBlockScope

NewDeferredBlockScopeHinted creates a new scope whose dataBuf is pre-sized from the supplied hint (see RegisterScopeHint for the per-kind atomic). A nil hint behaves like NewDeferredBlockScope and falls back to the floor capacity.

Pre-sizing eliminates the per-doubling growSlice traffic that otherwise dominates the per-frame protocol marshalling cost on widgets like c.EndETable's cells block, where dataBuf reliably grows to a kind-specific high-water mark every frame. The hint is updated by DeferredBlockScope.ReleaseWithHint at the end of the scope's life. See ADR-0049 for the design rationale.

func (*DeferredBlockScope) Begin

func (inst *DeferredBlockScope) Begin(keyParts ...any)

Begin starts capturing opcodes for the given key components.

Key components are serialized as their binary representations directly into the slab, avoiding binary.Write interface overhead:

  • uint64 -> 8 bytes LE
  • uint32 -> 4 bytes LE
  • string -> 4 bytes LE length + UTF-8 bytes

func (*DeferredBlockScope) BlockCount

func (inst *DeferredBlockScope) BlockCount() uint32

BlockCount returns the number of captured blocks.

func (*DeferredBlockScope) End

func (inst *DeferredBlockScope) End()

End stops capturing and stores the block.

func (*DeferredBlockScope) ReleaseWithHint

func (inst *DeferredBlockScope) ReleaseWithHint()

ReleaseWithHint finalises the scope and folds its observed dataBuf high-water mark back into the per-kind hint via a peak-ratchet + slow-decay CAS loop:

observed >= old : next = observed                          (ratchet up)
observed <  old : next = old - ((old - observed) >> N)     (decay)

where N = deferredHintDecayShift (≈30-frame half-life at the default shift of 5). The buffers are released to GC; the scope must not be touched afterwards. Defensive: if [End] was forgotten (capturing == true), EndCapture is invoked to restore Fffi2 routing so the next frame does not write into a buffer that has been handed to GC.

Idempotent in the sense that calling on a scope without a hint (dataHint == nil) collapses to a no-op cleanup. See ADR-0049.

func (*DeferredBlockScope) Reset

func (inst *DeferredBlockScope) Reset()

Reset clears all blocks for reuse across frames.

func (*DeferredBlockScope) WriteToFixedKey

func (inst *DeferredBlockScope) WriteToFixedKey(w *bytes.Buffer) (err error)

WriteToFixedKey serializes the block map with a fixed key layout. Reads key and buffer data from the slab via offset+length.

Wire format:

u32: block_count
for each block:
  [key_bytes]          (fixed size, determined by KeyTypes)
  u32: block_byte_length
  [u8; block_byte_length]: framed opcode messages

type Fffi2

type Fffi2[U UnmarshallReaderI] struct {
	// contains filtered or unexported fields
}

func NewFffi2

func NewFffi2[U UnmarshallReaderI](channel ChannelI[U]) *Fffi2[U]

func (*Fffi2[U]) AppendRawToCapture

func (inst *Fffi2[U]) AppendRawToCapture(raw []byte)

AppendRawToCapture writes raw bytes directly to the innermost capture buffer without adding a frame header. Use this only to re-emit bytes that were already captured with framing in a detached buffer — the DockArea iter wrapper uses it to flush buffered tab bodies into its deferred block scope at Send time.

func (*Fffi2[U]) BeginCapture

func (inst *Fffi2[U]) BeginCapture(buf *bytes.Buffer, endianness binary.ByteOrder)

BeginCapture redirects SendIntermediate to write into buf instead of the IPC pipe. Nested calls are supported — each Begin pushes a new capture frame; SendIntermediate writes to the innermost (top of stack), so an etable inside a dockArea tab body correctly nests its cell bodies inside the tab body bytes.

func (*Fffi2[U]) CallFunctionMayThrow

func (inst *Fffi2[U]) CallFunctionMayThrow() (err error)

func (*Fffi2[U]) CallFunctionNoThrow

func (inst *Fffi2[U]) CallFunctionNoThrow()

func (*Fffi2[U]) EndCapture

func (inst *Fffi2[U]) EndCapture()

EndCapture pops the innermost capture scope. After the outermost pop the stack is empty and SendIntermediate resumes sending to the pipe.

func (*Fffi2[U]) IsCapturing

func (inst *Fffi2[U]) IsCapturing() (capturing bool)

IsCapturing reports whether the current goroutine is inside a deferred-block capture scope — i.e. SendIntermediate is buffering into a capture frame rather than flushing to the IPC pipe. Read by Fetcher.invoke as a runtime guard: fetchers must not run inside captures (the fetch request would be buffered while the response read blocks on the pipe — mutual deadlock). See doc/skills/imzero2-fetchers/SKILLS.md.

func (*Fffi2[U]) PipelineProcedureNoThrow

func (inst *Fffi2[U]) PipelineProcedureNoThrow()

func (*Fffi2[U]) ReceiveMsg

func (inst *Fffi2[U]) ReceiveMsg() iter.Seq[U]

func (*Fffi2[U]) SendIntermediate

func (inst *Fffi2[U]) SendIntermediate(buf []byte) (err error)

func (*Fffi2[U]) SyncRetained

func (inst *Fffi2[U]) SyncRetained(id uint64, buf []byte) (err error)

type FffiCaptureI

type FffiCaptureI interface {
	BeginCapture(buf *bytes.Buffer, endianness binary.ByteOrder)
	EndCapture()
	// AppendRawToCapture writes the given framed bytes directly into the
	// innermost capture buffer WITHOUT adding a new frame header. Used when
	// a caller has already captured framed messages into a detached buffer
	// and wants to inject them into an active deferred-block capture scope
	// (e.g. the DockArea iter wrapper, which captures each tab body ahead
	// of Send and flushes all bodies in order at Send time).
	AppendRawToCapture(raw []byte)
	// IsCapturing reports whether a deferred-block capture frame is
	// currently active. Used by callers (notably Fetcher.invoke) that
	// must NOT run inside captures — synchronous fetcher requests would
	// be buffered while the response read blocked on the empty pipe.
	IsCapturing() bool
}

FffiCaptureI is the subset of Fffi2 needed for capture mode.

type FuncProcId

type FuncProcId uint32

type InlineIoChannel

type InlineIoChannel[U UnmarshallReaderI] struct {
	// contains filtered or unexported fields
}

func NewInlineIoChannel

func NewInlineIoChannel[U UnmarshallReaderI](unmarshaller U, in *bufio.Reader, out *bufio.Writer, bin binary.ByteOrder, errHandler func(err error), allocateBuffer func(l uint32) []byte) (inst *InlineIoChannel[U])

func (*InlineIoChannel[U]) FlushMessages

func (inst *InlineIoChannel[U]) FlushMessages()

func (*InlineIoChannel[U]) Marshaller

func (inst *InlineIoChannel[U]) Marshaller() *Marshaller

func (*InlineIoChannel[U]) ReceiveMsg

func (inst *InlineIoChannel[U]) ReceiveMsg() iter.Seq[U]

func (*InlineIoChannel[U]) SendSingleUseMsg

func (inst *InlineIoChannel[U]) SendSingleUseMsg(msg []byte)

func (*InlineIoChannel[U]) SetInOut

func (inst *InlineIoChannel[U]) SetInOut(in *bufio.Reader, out *bufio.Writer)

func (*InlineIoChannel[U]) SyncMultiUseMsg

func (inst *InlineIoChannel[U]) SyncMultiUseMsg(id uint64, msg []byte)

type MarshallWriterI

type MarshallWriterI interface {
	WriteUint8(v uint8)
	WriteBool(v bool)
	WriteUint16(v uint16)
	WriteUint32(v uint32)
	WriteUint64(v uint64)
	WriteInt8(v int8)
	WriteInt16(v int16)
	WriteInt32(v int32)
	WriteInt64(v int64)
	WriteFloat32(v float32)
	WriteFloat64(v float64)
	WriteComplex64(v complex64)
	WriteComplex128(v complex128)
	WriteString(v string)
	WriteBytes(v []byte)
	WriteSliceLength(l int)
	WriteNilSlice()
}

type Marshaller

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

func NewMarshaller

func NewMarshaller(w io.Writer, bin binary.ByteOrder, errHandler func(err error)) *Marshaller

func (*Marshaller) GetWrittenBytes

func (inst *Marshaller) GetWrittenBytes() int

func (*Marshaller) ResetWrittenBytes

func (inst *Marshaller) ResetWrittenBytes()

func (*Marshaller) WriteBool

func (inst *Marshaller) WriteBool(v bool)

func (*Marshaller) WriteBytes

func (inst *Marshaller) WriteBytes(v []byte)

func (*Marshaller) WriteComplex64

func (inst *Marshaller) WriteComplex64(v complex64)

func (*Marshaller) WriteComplex128

func (inst *Marshaller) WriteComplex128(v complex128)

func (*Marshaller) WriteFloat32

func (inst *Marshaller) WriteFloat32(v float32)

func (*Marshaller) WriteFloat64

func (inst *Marshaller) WriteFloat64(v float64)

func (*Marshaller) WriteInt8

func (inst *Marshaller) WriteInt8(v int8)

func (*Marshaller) WriteInt16

func (inst *Marshaller) WriteInt16(v int16)

func (*Marshaller) WriteInt32

func (inst *Marshaller) WriteInt32(v int32)

func (*Marshaller) WriteInt64

func (inst *Marshaller) WriteInt64(v int64)

func (*Marshaller) WriteNilSlice

func (inst *Marshaller) WriteNilSlice()

func (*Marshaller) WriteSliceLength

func (inst *Marshaller) WriteSliceLength(l int)

func (*Marshaller) WriteString

func (inst *Marshaller) WriteString(v string)

func (*Marshaller) WriteUint8

func (inst *Marshaller) WriteUint8(v uint8)

func (*Marshaller) WriteUint16

func (inst *Marshaller) WriteUint16(v uint16)

func (*Marshaller) WriteUint32

func (inst *Marshaller) WriteUint32(v uint32)

func (*Marshaller) WriteUint64

func (inst *Marshaller) WriteUint64(v uint64)

func (*Marshaller) WriteVerbatim

func (inst *Marshaller) WriteVerbatim(v []byte)

type ScopeHintSnapshot

type ScopeHintSnapshot struct {
	// Kind is the IDL deferred-block name (e.g. "cells", "tabBody").
	Kind string
	// Bytes is the current hint value — the observed high-water mark
	// for this kind, smoothed by the peak-and-slow-decay update rule
	// applied at each [DeferredBlockScope.ReleaseWithHint] call.
	Bytes uint64
}

ScopeHintSnapshot is one entry from ScopeHintsSnapshot.

func ScopeHintsSnapshot

func ScopeHintsSnapshot() []ScopeHintSnapshot

ScopeHintsSnapshot returns the current per-kind wire-byte hints in kind-name order. Safe to call from any goroutine (e.g. a pprof HTTP handler, a slow-frame logger). The returned slice is owned by the caller; the underlying registry is not held across the call.

Per ADR-0049, the hint table doubles as a passive observability surface: each entry reports what a single scope of that kind cost the FFFI2 wire on its most-expensive recent frame, smoothed to damp one-off spikes.

type UnmarshallReaderI

type UnmarshallReaderI interface {
	SetInput(r io.Reader)
	SetEndianness(endi binary.ByteOrder)
	SetErrorHandler(f func(err error))
	SetAllocateBufferFunc(f func(l uint32) []byte)

	// Err reports the first read failure since the reader was last given a
	// stream, or nil while it is intact. None of the Read methods below can
	// signal failure themselves — each returns a zero value, which is
	// indistinguishable from a zero the peer sent — so this is what
	// separates decoded data from the wreckage of a broken stream.
	Err() (err error)

	ReadUInt8() (v uint8)
	ReadUInt16() (v uint16)
	ReadUInt32MostLikelyZero() (v uint32)
	ReadUInt32() (v uint32)
	ReadUInt64() (v uint64)
	ReadInt8() (v int8)
	ReadInt16() (v int16)
	ReadInt32() (v int32)
	ReadInt64() (v int64)
	ReadFloat32() (v float32)
	ReadFloat64() (v float64)
	ReadComplex64() (v complex64)
	ReadComplex128() (v complex128)
	ReadUintptr() (v uintptr)
	ReadString() (v string)
	ReadStringMostLikelyEmpty() (v string)
	ReadBytes() (v []byte)
	ReadBool() (v bool)
	ReadSliceLength() (l int, isNil bool)
}

type Unmarshaller

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

func NewUnmarshaller

func NewUnmarshaller(r io.Reader, bin binary.ByteOrder, errHandler func(err error), allocateBuffer func(l uint32) []byte) *Unmarshaller

func (*Unmarshaller) ClearErr added in v0.0.17

func (inst *Unmarshaller) ClearErr()

ClearErr drops the sticky failure and re-arms reading. Only sound once the stream is known to be resynchronised, since a failed read leaves the position somewhere inside a frame. SetInput does this implicitly.

func (*Unmarshaller) Err added in v0.0.17

func (inst *Unmarshaller) Err() (err error)

Err returns the first read failure since the last SetInput or ClearErr, or nil while the stream is intact. Every Read* method returns a zero value on failure, so a caller that must trust what it decoded has to check this — typically once per frame rather than per field.

func (*Unmarshaller) GetReadBytes

func (inst *Unmarshaller) GetReadBytes() int

func (*Unmarshaller) ReadBool

func (inst *Unmarshaller) ReadBool() (v bool)

func (*Unmarshaller) ReadBytes

func (inst *Unmarshaller) ReadBytes() (v []byte)

func (*Unmarshaller) ReadComplex64

func (inst *Unmarshaller) ReadComplex64() (v complex64)

func (*Unmarshaller) ReadComplex128

func (inst *Unmarshaller) ReadComplex128() (v complex128)

func (*Unmarshaller) ReadFloat32

func (inst *Unmarshaller) ReadFloat32() (v float32)

func (*Unmarshaller) ReadFloat64

func (inst *Unmarshaller) ReadFloat64() (v float64)

func (*Unmarshaller) ReadInt8

func (inst *Unmarshaller) ReadInt8() (v int8)

func (*Unmarshaller) ReadInt16

func (inst *Unmarshaller) ReadInt16() (v int16)

func (*Unmarshaller) ReadInt32

func (inst *Unmarshaller) ReadInt32() (v int32)

func (*Unmarshaller) ReadInt64

func (inst *Unmarshaller) ReadInt64() (v int64)

func (*Unmarshaller) ReadSliceLength

func (inst *Unmarshaller) ReadSliceLength() (l int, isNil bool)

ReadSliceLength returns the element count, or isNil for the nil-slice sentinel. A failed read yields (0, false) — an empty, non-nil slice — which is a perfectly ordinary answer, so callers that must distinguish "the peer sent nothing" from "the stream died" have to consult Err.

func (*Unmarshaller) ReadString

func (inst *Unmarshaller) ReadString() (v string)

func (*Unmarshaller) ReadStringMostLikelyEmpty

func (inst *Unmarshaller) ReadStringMostLikelyEmpty() (v string)

func (*Unmarshaller) ReadUInt8

func (inst *Unmarshaller) ReadUInt8() (v uint8)

func (*Unmarshaller) ReadUInt16

func (inst *Unmarshaller) ReadUInt16() (v uint16)

func (*Unmarshaller) ReadUInt32

func (inst *Unmarshaller) ReadUInt32() (v uint32)

func (*Unmarshaller) ReadUInt32MostLikelyZero

func (inst *Unmarshaller) ReadUInt32MostLikelyZero() (v uint32)

func (*Unmarshaller) ReadUInt64

func (inst *Unmarshaller) ReadUInt64() (v uint64)

func (*Unmarshaller) ReadUintptr

func (inst *Unmarshaller) ReadUintptr() (v uintptr)

func (*Unmarshaller) ResetReadBytes

func (inst *Unmarshaller) ResetReadBytes()

func (*Unmarshaller) SetAllocateBufferFunc

func (inst *Unmarshaller) SetAllocateBufferFunc(f func(l uint32) []byte)

func (*Unmarshaller) SetEndianness

func (inst *Unmarshaller) SetEndianness(endi binary.ByteOrder)

func (*Unmarshaller) SetErrorHandler

func (inst *Unmarshaller) SetErrorHandler(f func(err error))

func (*Unmarshaller) SetInput

func (inst *Unmarshaller) SetInput(r io.Reader)

SetInput attaches a new reader and re-arms reading: any previous failure described the stream being replaced.

Jump to

Keyboard shortcuts

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