diff options
| author | 2026-03-10 13:28:59 +0800 | |
|---|---|---|
| committer | 2026-03-10 13:28:59 +0800 | |
| commit | af08c84539f9353718604988ba27ae3c466860fc (patch) | |
| tree | 0f1f2536f57af69b55ae06e78efbe26a7a0b3633 /protocol/sideband64k/encoder.go | |
| parent | forgejo, github: Update issue templates (diff) | |
| signature | No signature | |
*: Move sideband64k and pktline to protocol/
Diffstat (limited to 'protocol/sideband64k/encoder.go')
| -rw-r--r-- | protocol/sideband64k/encoder.go | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/protocol/sideband64k/encoder.go b/protocol/sideband64k/encoder.go new file mode 100644 index 00000000..75fb1339 --- /dev/null +++ b/protocol/sideband64k/encoder.go @@ -0,0 +1,98 @@ +package sideband64k + +import ( + "fmt" + + "codeberg.org/lindenii/furgit/protocol/pktline" +) + +// Encoder writes side-band-64k frames to a flush-capable output transport. +// +// It writes exactly one frame per method call and does not auto-chunk data. +type Encoder struct { + enc *pktline.Encoder + maxData int +} + +// NewEncoder creates an encoder over w. +func NewEncoder(w pktline.WriteFlusher) *Encoder { + return &Encoder{ + enc: pktline.NewEncoder(w), + maxData: DataMax, + } +} + +// SetMaxData sets the maximum payload size accepted by WriteBand. +// +// Non-positive n resets to DataMax. +func (e *Encoder) SetMaxData(n int) { + if n <= 0 { + e.maxData = DataMax + + return + } + + e.maxData = n +} + +// WriteBand writes one side-band-64k data frame for the given band. +func (e *Encoder) WriteBand(band Band, p []byte) error { + if !validBand(band) { + return fmt.Errorf("%w: %d", ErrInvalidBand, band) + } + + maxData := e.effectiveMaxData() + if len(p) > maxData { + return fmt.Errorf("%w: %d > %d", ErrTooLarge, len(p), maxData) + } + + framed := make([]byte, len(p)+1) + framed[0] = byte(band) + copy(framed[1:], p) + + return e.enc.WriteData(framed) +} + +// WriteData writes one band-1 data frame. +func (e *Encoder) WriteData(p []byte) error { + return e.WriteBand(BandData, p) +} + +// WriteProgress writes one band-2 progress frame. +func (e *Encoder) WriteProgress(p []byte) error { + return e.WriteBand(BandProgress, p) +} + +// WriteError writes one band-3 error frame. +func (e *Encoder) WriteError(p []byte) error { + return e.WriteBand(BandError, p) +} + +// WriteFlush writes control frame 0000 (flush-pkt). +func (e *Encoder) WriteFlush() error { + return e.enc.WriteFlush() +} + +// WriteDelim writes control frame 0001 (delim-pkt). +func (e *Encoder) WriteDelim() error { + return e.enc.WriteDelim() +} + +// WriteResponseEnd writes control frame 0002 (response-end-pkt). +func (e *Encoder) WriteResponseEnd() error { + return e.enc.WriteResponseEnd() +} + +// FlushIO flushes buffered output in the underlying transport. +func (e *Encoder) FlushIO() error { + return e.enc.FlushIO() +} + +// WriteFlushAndFlushIO writes a flush-pkt (0000) then flushes transport I/O. +func (e *Encoder) WriteFlushAndFlushIO() error { + return e.enc.WriteFlushAndFlushIO() +} + +func (e *Encoder) effectiveMaxData() int { + return effectiveMaxData(e.maxData) +} |
