aboutsummaryrefslogtreecommitdiff
path: root/protocol/sideband64k
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-03-25 16:22:03 +0000
committerGravatar Runxi Yu2026-03-25 16:22:03 +0000
commit311edcd50f3a84f4b860bde3cb887451d74eaa11 (patch)
treebe7aa5e9a51e636358f33b1c90637b5024b70dc3 /protocol/sideband64k
parentREADME: Split off contrib, benchmarks, remove history for now I guess, etc. (diff)
signatureNo signature
network/protocol: Rename from protocol v0.1.110
Diffstat (limited to 'protocol/sideband64k')
-rw-r--r--protocol/sideband64k/append.go40
-rw-r--r--protocol/sideband64k/append_helpers_test.go30
-rw-r--r--protocol/sideband64k/append_preserves_dst_on_error_test.go34
-rw-r--r--protocol/sideband64k/band.go13
-rw-r--r--protocol/sideband64k/chunk_writer.go64
-rw-r--r--protocol/sideband64k/chunk_writer_write_and_read_from_test.go60
-rw-r--r--protocol/sideband64k/constants.go10
-rw-r--r--protocol/sideband64k/decoder.go158
-rw-r--r--protocol/sideband64k/decoder_data_control_and_keepalive_test.go78
-rw-r--r--protocol/sideband64k/decoder_invalid_band_test.go20
-rw-r--r--protocol/sideband64k/decoder_invalid_empty_payload_test.go20
-rw-r--r--protocol/sideband64k/decoder_malformed_pktline_test.go32
-rw-r--r--protocol/sideband64k/decoder_partial_read_test.go32
-rw-r--r--protocol/sideband64k/decoder_peek_test.go34
-rw-r--r--protocol/sideband64k/decoder_resync_after_over_max_data_test.go51
-rw-r--r--protocol/sideband64k/decoder_resync_after_over_wire_max_test.go37
-rw-r--r--protocol/sideband64k/decoder_unexpected_eof_test.go21
-rw-r--r--protocol/sideband64k/doc.go2
-rw-r--r--protocol/sideband64k/encoder.go98
-rw-r--r--protocol/sideband64k/encoder_buffered_flush_behavior_test.go59
-rw-r--r--protocol/sideband64k/encoder_partial_write_test.go46
-rw-r--r--protocol/sideband64k/encoder_set_max_data_cannot_exceed_wire_limit_test.go23
-rw-r--r--protocol/sideband64k/encoder_writes_frames_test.go58
-rw-r--r--protocol/sideband64k/errors.go27
-rw-r--r--protocol/sideband64k/frame.go12
-rw-r--r--protocol/sideband64k/frame_type.go19
-rw-r--r--protocol/sideband64k/helpers_test.go46
27 files changed, 0 insertions, 1124 deletions
diff --git a/protocol/sideband64k/append.go b/protocol/sideband64k/append.go
deleted file mode 100644
index 4da419f3..00000000
--- a/protocol/sideband64k/append.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package sideband64k
-
-import (
- "fmt"
-
- "codeberg.org/lindenii/furgit/protocol/pktline"
-)
-
-// AppendBand appends one side-band-64k data frame to dst.
-func AppendBand(dst []byte, band Band, payload []byte) ([]byte, error) {
- if !validBand(band) {
- return dst, fmt.Errorf("%w: %d", ErrInvalidBand, band)
- }
-
- maxData := effectiveMaxData(DataMax)
- if len(payload) > maxData {
- return dst, fmt.Errorf("%w: %d > %d", ErrTooLarge, len(payload), maxData)
- }
-
- framed := make([]byte, len(payload)+1)
- framed[0] = byte(band)
- copy(framed[1:], payload)
-
- return pktline.AppendData(dst, framed)
-}
-
-// AppendData appends one band-1 data frame to dst.
-func AppendData(dst, payload []byte) ([]byte, error) {
- return AppendBand(dst, BandData, payload)
-}
-
-// AppendProgress appends one band-2 progress frame to dst.
-func AppendProgress(dst, payload []byte) ([]byte, error) {
- return AppendBand(dst, BandProgress, payload)
-}
-
-// AppendError appends one band-3 error frame to dst.
-func AppendError(dst, payload []byte) ([]byte, error) {
- return AppendBand(dst, BandError, payload)
-}
diff --git a/protocol/sideband64k/append_helpers_test.go b/protocol/sideband64k/append_helpers_test.go
deleted file mode 100644
index 5b64856a..00000000
--- a/protocol/sideband64k/append_helpers_test.go
+++ /dev/null
@@ -1,30 +0,0 @@
-package sideband64k_test
-
-import (
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestAppendHelpers(t *testing.T) {
- t.Parallel()
-
- out, err := sideband64k.AppendData(nil, []byte("a"))
- if err != nil {
- t.Fatalf("AppendData: %v", err)
- }
-
- out, err = sideband64k.AppendProgress(out, []byte("b"))
- if err != nil {
- t.Fatalf("AppendProgress: %v", err)
- }
-
- out, err = sideband64k.AppendError(out, []byte("c"))
- if err != nil {
- t.Fatalf("AppendError: %v", err)
- }
-
- if got, want := string(out), "0006\x01a0006\x02b0006\x03c"; got != want {
- t.Fatalf("got %q, want %q", got, want)
- }
-}
diff --git a/protocol/sideband64k/append_preserves_dst_on_error_test.go b/protocol/sideband64k/append_preserves_dst_on_error_test.go
deleted file mode 100644
index 7c86a8b7..00000000
--- a/protocol/sideband64k/append_preserves_dst_on_error_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package sideband64k_test
-
-import (
- "bytes"
- "errors"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestAppendBandPreservesDstOnError(t *testing.T) {
- t.Parallel()
-
- orig := []byte("seed")
- dst := append([]byte(nil), orig...)
-
- out, err := sideband64k.AppendBand(dst, 4, []byte("x"))
- if !errors.Is(err, sideband64k.ErrInvalidBand) {
- t.Fatalf("got err %v, want ErrInvalidBand", err)
- }
-
- if !bytes.Equal(out, orig) {
- t.Fatalf("got %q, want %q", string(out), string(orig))
- }
-
- out, err = sideband64k.AppendData(dst, bytes.Repeat([]byte{'x'}, sideband64k.DataMax+1))
- if !errors.Is(err, sideband64k.ErrTooLarge) {
- t.Fatalf("got err %v, want ErrTooLarge", err)
- }
-
- if !bytes.Equal(out, orig) {
- t.Fatalf("got %q, want %q", string(out), string(orig))
- }
-}
diff --git a/protocol/sideband64k/band.go b/protocol/sideband64k/band.go
deleted file mode 100644
index 73c61fd8..00000000
--- a/protocol/sideband64k/band.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package sideband64k
-
-// Band identifies the sideband stream within a pkt-line data frame.
-type Band uint8
-
-const (
- // BandData carries primary payload bytes.
- BandData Band = 1
- // BandProgress carries progress or informational messages.
- BandProgress Band = 2
- // BandError carries fatal error messages.
- BandError Band = 3
-)
diff --git a/protocol/sideband64k/chunk_writer.go b/protocol/sideband64k/chunk_writer.go
deleted file mode 100644
index f95f75d8..00000000
--- a/protocol/sideband64k/chunk_writer.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package sideband64k
-
-import "io"
-
-// ChunkWriter packetizes arbitrary stream bytes into side-band-64k data frames
-// for one fixed band.
-//
-// It never writes control packets automatically.
-type ChunkWriter struct {
- enc *Encoder
- band Band
-}
-
-// NewChunkWriter creates a chunking adapter over enc for one band.
-func NewChunkWriter(enc *Encoder, band Band) *ChunkWriter {
- return &ChunkWriter{enc: enc, band: band}
-}
-
-// Write splits p into sideband frames not larger than enc's maxData.
-func (cw *ChunkWriter) Write(p []byte) (int, error) {
- total := 0
- maxData := cw.enc.effectiveMaxData()
-
- for len(p) > 0 {
- n := min(len(p), maxData)
-
- err := cw.enc.WriteBand(cw.band, p[:n])
- if err != nil {
- return total, err
- }
-
- total += n
- p = p[n:]
- }
-
- return total, nil
-}
-
-// ReadFrom reads from r and writes sideband frames to the encoder.
-func (cw *ChunkWriter) ReadFrom(r io.Reader) (int64, error) {
- buf := make([]byte, cw.enc.effectiveMaxData())
-
- var total int64
-
- for {
- n, err := r.Read(buf)
- if n > 0 {
- werr := cw.enc.WriteBand(cw.band, buf[:n])
- if werr != nil {
- return total, werr
- }
-
- total += int64(n)
- }
-
- if err != nil {
- if err == io.EOF {
- return total, nil
- }
-
- return total, err
- }
- }
-}
diff --git a/protocol/sideband64k/chunk_writer_write_and_read_from_test.go b/protocol/sideband64k/chunk_writer_write_and_read_from_test.go
deleted file mode 100644
index ab954d57..00000000
--- a/protocol/sideband64k/chunk_writer_write_and_read_from_test.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package sideband64k_test
-
-import (
- "bufio"
- "bytes"
- "strings"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestChunkWriterWriteAndReadFrom(t *testing.T) {
- t.Parallel()
-
- var out bytes.Buffer
-
- bw := bufio.NewWriter(&out)
- enc := sideband64k.NewEncoder(bw)
- enc.SetMaxData(3)
-
- cw := sideband64k.NewChunkWriter(enc, sideband64k.BandProgress)
-
- n, err := cw.Write([]byte("abcdefg"))
- if err != nil {
- t.Fatalf("Write: %v", err)
- }
-
- if n != 7 {
- t.Fatalf("Write n=%d, want 7", n)
- }
-
- err = enc.FlushIO()
- if err != nil {
- t.Fatalf("FlushIO: %v", err)
- }
-
- if got, want := out.String(), "0008\x02abc0008\x02def0006\x02g"; got != want {
- t.Fatalf("got %q, want %q", got, want)
- }
-
- out.Reset()
-
- rn, err := cw.ReadFrom(strings.NewReader("wxyz"))
- if err != nil {
- t.Fatalf("ReadFrom: %v", err)
- }
-
- if rn != 4 {
- t.Fatalf("ReadFrom n=%d, want 4", rn)
- }
-
- err = enc.FlushIO()
- if err != nil {
- t.Fatalf("FlushIO: %v", err)
- }
-
- if got, want := out.String(), "0008\x02wxy0006\x02z"; got != want {
- t.Fatalf("got %q, want %q", got, want)
- }
-}
diff --git a/protocol/sideband64k/constants.go b/protocol/sideband64k/constants.go
deleted file mode 100644
index f71423ee..00000000
--- a/protocol/sideband64k/constants.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package sideband64k
-
-import "codeberg.org/lindenii/furgit/protocol/pktline"
-
-const (
- // PacketMax is the maximum on-wire pkt-line size used by side-band-64k.
- PacketMax = pktline.LargePacketMax
- // DataMax is the maximum sideband payload size excluding the 1-byte band designator.
- DataMax = pktline.LargePacketDataMax - 1
-)
diff --git a/protocol/sideband64k/decoder.go b/protocol/sideband64k/decoder.go
deleted file mode 100644
index 57541567..00000000
--- a/protocol/sideband64k/decoder.go
+++ /dev/null
@@ -1,158 +0,0 @@
-package sideband64k
-
-import (
- "fmt"
- "io"
-
- "codeberg.org/lindenii/furgit/protocol/pktline"
-)
-
-// ReadOptions controls sideband decoding behavior.
-type ReadOptions struct {
- // ChompLF removes one trailing '\n' from FrameData payloads only.
- ChompLF bool
-}
-
-// Decoder reads side-band-64k frames from an io.Reader.
-//
-// It preserves frame boundaries and supports one-frame lookahead via
-// PeekFrame.
-type Decoder struct {
- dec *pktline.Decoder
- maxData int
- opts ReadOptions
-
- peeked bool
- peek Frame
- peekErr error
-}
-
-// NewDecoder creates a decoder over r.
-func NewDecoder(r io.Reader, opts ReadOptions) *Decoder {
- d := &Decoder{
- dec: pktline.NewDecoder(r, pktline.ReadOptions{}),
- maxData: DataMax,
- opts: opts,
- }
- d.dec.SetMaxData(pktline.LargePacketDataMax)
-
- return d
-}
-
-// SetMaxData sets maximum payload size accepted for one sideband data packet.
-//
-// Non-positive n resets to DataMax.
-func (d *Decoder) SetMaxData(n int) {
- if n <= 0 {
- d.maxData = DataMax
-
- return
- }
-
- d.maxData = n
-}
-
-// ReadFrame reads one frame.
-func (d *Decoder) ReadFrame() (Frame, error) {
- if d.peeked {
- d.peeked = false
-
- return cloneFrame(d.peek), d.peekErr
- }
-
- return d.readFrame()
-}
-
-// PeekFrame returns the next frame without consuming it.
-func (d *Decoder) PeekFrame() (Frame, error) {
- if !d.peeked {
- d.peek, d.peekErr = d.readFrame()
- d.peeked = true
- }
-
- return cloneFrame(d.peek), d.peekErr
-}
-
-func (d *Decoder) readFrame() (Frame, error) {
- f, err := d.dec.ReadFrame()
- if err != nil {
- return Frame{}, err
- }
-
- switch f.Type {
- case pktline.PacketFlush:
- return Frame{Type: FrameFlush}, nil
- case pktline.PacketDelim:
- return Frame{Type: FrameDelim}, nil
- case pktline.PacketResponseEnd:
- return Frame{Type: FrameResponseEnd}, nil
- case pktline.PacketData:
- if len(f.Payload) == 0 {
- return Frame{}, &ProtocolError{Reason: "missing sideband designator"}
- }
-
- payload := f.Payload[1:]
- if len(payload) > d.effectiveMaxData() {
- return Frame{}, fmt.Errorf("%w: %d > %d", ErrTooLarge, len(payload), d.effectiveMaxData())
- }
-
- band := Band(f.Payload[0])
- if !validBand(band) {
- return Frame{}, &ProtocolError{Reason: fmt.Sprintf("%v: %d", ErrInvalidBand, band)}
- }
-
- payload = append([]byte(nil), payload...)
- if d.opts.ChompLF && band == BandData && len(payload) > 0 && payload[len(payload)-1] == '\n' {
- payload = payload[:len(payload)-1]
- }
-
- return Frame{
- Type: frameTypeForBand(band),
- Payload: payload,
- }, nil
- default:
- return Frame{}, &ProtocolError{Reason: "unknown pkt-line frame type"}
- }
-}
-
-func (d *Decoder) effectiveMaxData() int {
- return effectiveMaxData(d.maxData)
-}
-
-func cloneFrame(f Frame) Frame {
- if f.Type == FrameFlush || f.Type == FrameDelim || f.Type == FrameResponseEnd {
- return Frame{Type: f.Type}
- }
-
- out := Frame{Type: f.Type}
- if f.Payload != nil {
- out.Payload = append([]byte(nil), f.Payload...)
- }
-
- return out
-}
-
-func validBand(band Band) bool {
- return band == BandData || band == BandProgress || band == BandError
-}
-
-func frameTypeForBand(band Band) FrameType {
- switch band {
- case BandData:
- return FrameData
- case BandProgress:
- return FrameProgress
- case BandError:
- return FrameError
- default:
- panic("invalid sideband64k band")
- }
-}
-
-func effectiveMaxData(n int) int {
- if n <= 0 || n > DataMax {
- return DataMax
- }
-
- return n
-}
diff --git a/protocol/sideband64k/decoder_data_control_and_keepalive_test.go b/protocol/sideband64k/decoder_data_control_and_keepalive_test.go
deleted file mode 100644
index d829b930..00000000
--- a/protocol/sideband64k/decoder_data_control_and_keepalive_test.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package sideband64k_test
-
-import (
- "strings"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestDecoderDataControlAndKeepalive(t *testing.T) {
- t.Parallel()
-
- input := "0007\x01a\n0005\x010007\x02p\n0007\x03e\n000100020000"
- dec := sideband64k.NewDecoder(strings.NewReader(input), sideband64k.ReadOptions{ChompLF: true})
-
- f, err := dec.ReadFrame()
- if err != nil {
- t.Fatalf("ReadFrame #1: %v", err)
- }
-
- if f.Type != sideband64k.FrameData || string(f.Payload) != "a" {
- t.Fatalf("frame #1 = %#v", f)
- }
-
- f, err = dec.ReadFrame()
- if err != nil {
- t.Fatalf("ReadFrame #2: %v", err)
- }
-
- if f.Type != sideband64k.FrameData || len(f.Payload) != 0 {
- t.Fatalf("frame #2 = %#v, want empty data", f)
- }
-
- f, err = dec.ReadFrame()
- if err != nil {
- t.Fatalf("ReadFrame #3: %v", err)
- }
-
- if f.Type != sideband64k.FrameProgress || string(f.Payload) != "p\n" {
- t.Fatalf("frame #3 = %#v", f)
- }
-
- f, err = dec.ReadFrame()
- if err != nil {
- t.Fatalf("ReadFrame #4: %v", err)
- }
-
- if f.Type != sideband64k.FrameError || string(f.Payload) != "e\n" {
- t.Fatalf("frame #4 = %#v", f)
- }
-
- f, err = dec.ReadFrame()
- if err != nil {
- t.Fatalf("ReadFrame #5: %v", err)
- }
-
- if f.Type != sideband64k.FrameDelim {
- t.Fatalf("frame #5 type = %v, want FrameDelim", f.Type)
- }
-
- f, err = dec.ReadFrame()
- if err != nil {
- t.Fatalf("ReadFrame #6: %v", err)
- }
-
- if f.Type != sideband64k.FrameResponseEnd {
- t.Fatalf("frame #6 type = %v, want FrameResponseEnd", f.Type)
- }
-
- f, err = dec.ReadFrame()
- if err != nil {
- t.Fatalf("ReadFrame #7: %v", err)
- }
-
- if f.Type != sideband64k.FrameFlush {
- t.Fatalf("frame #7 type = %v, want FrameFlush", f.Type)
- }
-}
diff --git a/protocol/sideband64k/decoder_invalid_band_test.go b/protocol/sideband64k/decoder_invalid_band_test.go
deleted file mode 100644
index 2b28a0ef..00000000
--- a/protocol/sideband64k/decoder_invalid_band_test.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package sideband64k_test
-
-import (
- "errors"
- "strings"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestDecoderInvalidBand(t *testing.T) {
- t.Parallel()
-
- dec := sideband64k.NewDecoder(strings.NewReader("0005\x04"), sideband64k.ReadOptions{})
- _, err := dec.ReadFrame()
-
- if _, ok := errors.AsType[*sideband64k.ProtocolError](err); !ok {
- t.Fatalf("got err %v, want ProtocolError", err)
- }
-}
diff --git a/protocol/sideband64k/decoder_invalid_empty_payload_test.go b/protocol/sideband64k/decoder_invalid_empty_payload_test.go
deleted file mode 100644
index 86481166..00000000
--- a/protocol/sideband64k/decoder_invalid_empty_payload_test.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package sideband64k_test
-
-import (
- "errors"
- "strings"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestDecoderInvalidEmptyPayload(t *testing.T) {
- t.Parallel()
-
- dec := sideband64k.NewDecoder(strings.NewReader("0004"), sideband64k.ReadOptions{})
- _, err := dec.ReadFrame()
-
- if _, ok := errors.AsType[*sideband64k.ProtocolError](err); !ok {
- t.Fatalf("got err %v, want ProtocolError", err)
- }
-}
diff --git a/protocol/sideband64k/decoder_malformed_pktline_test.go b/protocol/sideband64k/decoder_malformed_pktline_test.go
deleted file mode 100644
index 9d4030f3..00000000
--- a/protocol/sideband64k/decoder_malformed_pktline_test.go
+++ /dev/null
@@ -1,32 +0,0 @@
-package sideband64k_test
-
-import (
- "errors"
- "strings"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/pktline"
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestDecoderInvalid0003(t *testing.T) {
- t.Parallel()
-
- dec := sideband64k.NewDecoder(strings.NewReader("0003"), sideband64k.ReadOptions{})
- _, err := dec.ReadFrame()
-
- if _, ok := errors.AsType[*pktline.ProtocolError](err); !ok {
- t.Fatalf("got err %v, want pktline.ProtocolError", err)
- }
-}
-
-func TestDecoderRejectsOverMaximumLength(t *testing.T) {
- t.Parallel()
-
- dec := sideband64k.NewDecoder(strings.NewReader("fffe"), sideband64k.ReadOptions{})
- _, err := dec.ReadFrame()
-
- if _, ok := errors.AsType[*pktline.ProtocolError](err); !ok {
- t.Fatalf("got err %v, want pktline.ProtocolError", err)
- }
-}
diff --git a/protocol/sideband64k/decoder_partial_read_test.go b/protocol/sideband64k/decoder_partial_read_test.go
deleted file mode 100644
index 730363d7..00000000
--- a/protocol/sideband64k/decoder_partial_read_test.go
+++ /dev/null
@@ -1,32 +0,0 @@
-package sideband64k_test
-
-import (
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestDecoderHandlesPartialReads(t *testing.T) {
- t.Parallel()
-
- r := &byteReader{data: []byte("0007\x02ok0000")}
- dec := sideband64k.NewDecoder(r, sideband64k.ReadOptions{})
-
- f, err := dec.ReadFrame()
- if err != nil {
- t.Fatalf("ReadFrame #1: %v", err)
- }
-
- if f.Type != sideband64k.FrameProgress || string(f.Payload) != "ok" {
- t.Fatalf("frame #1 = %#v", f)
- }
-
- f, err = dec.ReadFrame()
- if err != nil {
- t.Fatalf("ReadFrame #2: %v", err)
- }
-
- if f.Type != sideband64k.FrameFlush {
- t.Fatalf("frame #2 = %#v", f)
- }
-}
diff --git a/protocol/sideband64k/decoder_peek_test.go b/protocol/sideband64k/decoder_peek_test.go
deleted file mode 100644
index b0b43fa1..00000000
--- a/protocol/sideband64k/decoder_peek_test.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package sideband64k_test
-
-import (
- "strings"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestDecoderPeek(t *testing.T) {
- t.Parallel()
-
- dec := sideband64k.NewDecoder(strings.NewReader("0006\x01x0000"), sideband64k.ReadOptions{})
-
- f, err := dec.PeekFrame()
- if err != nil {
- t.Fatalf("PeekFrame: %v", err)
- }
-
- if f.Type != sideband64k.FrameData || string(f.Payload) != "x" {
- t.Fatalf("peek frame = %#v", f)
- }
-
- f.Payload[0] = 'y'
-
- f, err = dec.ReadFrame()
- if err != nil {
- t.Fatalf("ReadFrame: %v", err)
- }
-
- if f.Type != sideband64k.FrameData || string(f.Payload) != "x" {
- t.Fatalf("read frame = %#v", f)
- }
-}
diff --git a/protocol/sideband64k/decoder_resync_after_over_max_data_test.go b/protocol/sideband64k/decoder_resync_after_over_max_data_test.go
deleted file mode 100644
index dea396d1..00000000
--- a/protocol/sideband64k/decoder_resync_after_over_max_data_test.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package sideband64k_test
-
-import (
- "bufio"
- "bytes"
- "errors"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestDecoderResyncAfterOverMaxData(t *testing.T) {
- t.Parallel()
-
- var b bytes.Buffer
-
- bw := bufio.NewWriter(&b)
- enc := sideband64k.NewEncoder(bw)
-
- err := enc.WriteData([]byte("abcd"))
- if err != nil {
- t.Fatalf("WriteData #1: %v", err)
- }
-
- err = enc.WriteData([]byte("z"))
- if err != nil {
- t.Fatalf("WriteData #2: %v", err)
- }
-
- err = enc.FlushIO()
- if err != nil {
- t.Fatalf("FlushIO: %v", err)
- }
-
- dec := sideband64k.NewDecoder(bytes.NewReader(b.Bytes()), sideband64k.ReadOptions{})
- dec.SetMaxData(1)
-
- _, err = dec.ReadFrame()
- if !errors.Is(err, sideband64k.ErrTooLarge) {
- t.Fatalf("got err %v, want ErrTooLarge", err)
- }
-
- f, err := dec.ReadFrame()
- if err != nil {
- t.Fatalf("ReadFrame #2: %v", err)
- }
-
- if f.Type != sideband64k.FrameData || string(f.Payload) != "z" {
- t.Fatalf("got frame %#v, want data z", f)
- }
-}
diff --git a/protocol/sideband64k/decoder_resync_after_over_wire_max_test.go b/protocol/sideband64k/decoder_resync_after_over_wire_max_test.go
deleted file mode 100644
index f646c6ad..00000000
--- a/protocol/sideband64k/decoder_resync_after_over_wire_max_test.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package sideband64k_test
-
-import (
- "bytes"
- "errors"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/pktline"
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestDecoderResyncAfterOverWireMax(t *testing.T) {
- t.Parallel()
-
- var b bytes.Buffer
-
- _, _ = b.WriteString("ffff")
- _, _ = b.Write(bytes.Repeat([]byte{'a'}, 65531))
- _, _ = b.WriteString("0006\x01z")
-
- dec := sideband64k.NewDecoder(bytes.NewReader(b.Bytes()), sideband64k.ReadOptions{})
-
- _, err := dec.ReadFrame()
-
- if _, ok := errors.AsType[*pktline.ProtocolError](err); !ok {
- t.Fatalf("got err %v, want pktline.ProtocolError", err)
- }
-
- f, err := dec.ReadFrame()
- if err != nil {
- t.Fatalf("ReadFrame #2: %v", err)
- }
-
- if f.Type != sideband64k.FrameData || string(f.Payload) != "z" {
- t.Fatalf("got frame %#v, want data z", f)
- }
-}
diff --git a/protocol/sideband64k/decoder_unexpected_eof_test.go b/protocol/sideband64k/decoder_unexpected_eof_test.go
deleted file mode 100644
index 74d5a6fb..00000000
--- a/protocol/sideband64k/decoder_unexpected_eof_test.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package sideband64k_test
-
-import (
- "errors"
- "io"
- "strings"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestDecoderUnexpectedEOF(t *testing.T) {
- t.Parallel()
-
- dec := sideband64k.NewDecoder(strings.NewReader("0006\x01"), sideband64k.ReadOptions{})
-
- _, err := dec.ReadFrame()
- if !errors.Is(err, io.ErrUnexpectedEOF) {
- t.Fatalf("got err %v, want io.ErrUnexpectedEOF", err)
- }
-}
diff --git a/protocol/sideband64k/doc.go b/protocol/sideband64k/doc.go
deleted file mode 100644
index 55c33650..00000000
--- a/protocol/sideband64k/doc.go
+++ /dev/null
@@ -1,2 +0,0 @@
-// Package sideband64k implements Git side-band-64k multiplexing over pkt-line.
-package sideband64k
diff --git a/protocol/sideband64k/encoder.go b/protocol/sideband64k/encoder.go
deleted file mode 100644
index 75fb1339..00000000
--- a/protocol/sideband64k/encoder.go
+++ /dev/null
@@ -1,98 +0,0 @@
-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)
-}
diff --git a/protocol/sideband64k/encoder_buffered_flush_behavior_test.go b/protocol/sideband64k/encoder_buffered_flush_behavior_test.go
deleted file mode 100644
index 723a55ec..00000000
--- a/protocol/sideband64k/encoder_buffered_flush_behavior_test.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package sideband64k_test
-
-import (
- "bufio"
- "bytes"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestEncoderBufferedFlushBehavior(t *testing.T) {
- t.Parallel()
-
- var out bytes.Buffer
-
- bw := bufio.NewWriter(&out)
- enc := sideband64k.NewEncoder(bw)
-
- err := enc.WriteData([]byte("hello"))
- if err != nil {
- t.Fatalf("WriteData: %v", err)
- }
-
- err = enc.WriteFlush()
- if err != nil {
- t.Fatalf("WriteFlush: %v", err)
- }
-
- if out.Len() != 0 {
- t.Fatalf("WriteFlush should not flush I/O, got %q", out.String())
- }
-
- err = enc.FlushIO()
- if err != nil {
- t.Fatalf("FlushIO: %v", err)
- }
-
- if got, want := out.String(), "000a\x01hello0000"; got != want {
- t.Fatalf("got %q, want %q", got, want)
- }
-
- out.Reset()
- bw = bufio.NewWriter(&out)
- enc = sideband64k.NewEncoder(bw)
-
- err = enc.WriteData([]byte("yo"))
- if err != nil {
- t.Fatalf("WriteData: %v", err)
- }
-
- err = enc.WriteFlushAndFlushIO()
- if err != nil {
- t.Fatalf("WriteFlushAndFlushIO: %v", err)
- }
-
- if got, want := out.String(), "0007\x01yo0000"; got != want {
- t.Fatalf("got %q, want %q", got, want)
- }
-}
diff --git a/protocol/sideband64k/encoder_partial_write_test.go b/protocol/sideband64k/encoder_partial_write_test.go
deleted file mode 100644
index 3cec9324..00000000
--- a/protocol/sideband64k/encoder_partial_write_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package sideband64k_test
-
-import (
- "errors"
- "io"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestEncoderHandlesPartialWrites(t *testing.T) {
- t.Parallel()
-
- dst := &limitWriter{maxPerWrite: 2}
- enc := sideband64k.NewEncoder(dst)
-
- err := enc.WriteProgress([]byte("abc"))
- if err != nil {
- t.Fatalf("WriteProgress: %v", err)
- }
-
- err = enc.WriteFlushAndFlushIO()
- if err != nil {
- t.Fatalf("WriteFlushAndFlushIO: %v", err)
- }
-
- if got, want := dst.buf.String(), "0008\x02abc0000"; got != want {
- t.Fatalf("got %q, want %q", got, want)
- }
-
- if dst.flushes != 1 {
- t.Fatalf("flushes=%d, want 1", dst.flushes)
- }
-}
-
-func TestEncoderReturnsShortWrite(t *testing.T) {
- t.Parallel()
-
- dst := &limitWriter{shortWrite: true}
- enc := sideband64k.NewEncoder(dst)
-
- err := enc.WriteData([]byte("x"))
- if !errors.Is(err, io.ErrShortWrite) {
- t.Fatalf("got err %v, want io.ErrShortWrite", err)
- }
-}
diff --git a/protocol/sideband64k/encoder_set_max_data_cannot_exceed_wire_limit_test.go b/protocol/sideband64k/encoder_set_max_data_cannot_exceed_wire_limit_test.go
deleted file mode 100644
index 2edb609a..00000000
--- a/protocol/sideband64k/encoder_set_max_data_cannot_exceed_wire_limit_test.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package sideband64k_test
-
-import (
- "bytes"
- "errors"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestEncoderSetMaxDataCannotExceedWireLimit(t *testing.T) {
- t.Parallel()
-
- var dst limitWriter
-
- enc := sideband64k.NewEncoder(&dst)
- enc.SetMaxData(sideband64k.DataMax + 100)
-
- err := enc.WriteData(bytes.Repeat([]byte{'x'}, sideband64k.DataMax+1))
- if !errors.Is(err, sideband64k.ErrTooLarge) {
- t.Fatalf("got err %v, want ErrTooLarge", err)
- }
-}
diff --git a/protocol/sideband64k/encoder_writes_frames_test.go b/protocol/sideband64k/encoder_writes_frames_test.go
deleted file mode 100644
index 19fff437..00000000
--- a/protocol/sideband64k/encoder_writes_frames_test.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package sideband64k_test
-
-import (
- "bufio"
- "bytes"
- "testing"
-
- "codeberg.org/lindenii/furgit/protocol/sideband64k"
-)
-
-func TestEncoderWritesFrames(t *testing.T) {
- t.Parallel()
-
- var b bytes.Buffer
-
- bw := bufio.NewWriter(&b)
- enc := sideband64k.NewEncoder(bw)
-
- err := enc.WriteData([]byte("hi"))
- if err != nil {
- t.Fatalf("WriteData: %v", err)
- }
-
- err = enc.WriteProgress([]byte("ok"))
- if err != nil {
- t.Fatalf("WriteProgress: %v", err)
- }
-
- err = enc.WriteError([]byte("no"))
- if err != nil {
- t.Fatalf("WriteError: %v", err)
- }
-
- err = enc.WriteFlush()
- if err != nil {
- t.Fatalf("WriteFlush: %v", err)
- }
-
- err = enc.WriteDelim()
- if err != nil {
- t.Fatalf("WriteDelim: %v", err)
- }
-
- err = enc.WriteResponseEnd()
- if err != nil {
- t.Fatalf("WriteResponseEnd: %v", err)
- }
-
- err = enc.FlushIO()
- if err != nil {
- t.Fatalf("FlushIO: %v", err)
- }
-
- want := "0007\x01hi0007\x02ok0007\x03no000000010002"
- if got := b.String(); got != want {
- t.Fatalf("got %q, want %q", got, want)
- }
-}
diff --git a/protocol/sideband64k/errors.go b/protocol/sideband64k/errors.go
deleted file mode 100644
index 44e7c165..00000000
--- a/protocol/sideband64k/errors.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package sideband64k
-
-import "errors"
-
-var (
- // ErrTooLarge indicates a payload exceeds configured sideband data limits.
- ErrTooLarge = errors.New("sideband64k: payload too large")
- // ErrInvalidBand indicates a data frame has an invalid sideband designator.
- ErrInvalidBand = errors.New("sideband64k: invalid band designator")
-)
-
-// ProtocolError reports invalid side-band-64k framing.
-type ProtocolError struct {
- Reason string
-}
-
-func (e *ProtocolError) Error() string {
- if e == nil {
- return "<nil>"
- }
-
- if e.Reason == "" {
- return "sideband64k: protocol error"
- }
-
- return "sideband64k: protocol error: " + e.Reason
-}
diff --git a/protocol/sideband64k/frame.go b/protocol/sideband64k/frame.go
deleted file mode 100644
index 1335a8e3..00000000
--- a/protocol/sideband64k/frame.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package sideband64k
-
-// Frame is one decoded side-band-64k frame.
-//
-// For FrameData, FrameProgress, and FrameError, Payload holds frame bytes and
-// may be empty.
-//
-// For control frames, Payload is nil.
-type Frame struct {
- Type FrameType
- Payload []byte
-}
diff --git a/protocol/sideband64k/frame_type.go b/protocol/sideband64k/frame_type.go
deleted file mode 100644
index 052d8b10..00000000
--- a/protocol/sideband64k/frame_type.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package sideband64k
-
-// FrameType identifies the kind of decoded sideband frame.
-type FrameType uint8
-
-const (
- // FrameData carries primary payload bytes from band 1.
- FrameData FrameType = iota
- // FrameProgress carries progress bytes from band 2.
- FrameProgress
- // FrameError carries fatal error bytes from band 3.
- FrameError
- // FrameFlush is pkt-line control frame 0000.
- FrameFlush
- // FrameDelim is pkt-line control frame 0001.
- FrameDelim
- // FrameResponseEnd is pkt-line control frame 0002.
- FrameResponseEnd
-)
diff --git a/protocol/sideband64k/helpers_test.go b/protocol/sideband64k/helpers_test.go
deleted file mode 100644
index f9b2608f..00000000
--- a/protocol/sideband64k/helpers_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package sideband64k_test
-
-import (
- "bytes"
- "io"
-)
-
-type limitWriter struct {
- buf bytes.Buffer
- maxPerWrite int
- flushes int
- shortWrite bool
-}
-
-func (w *limitWriter) Write(p []byte) (int, error) {
- if w.shortWrite {
- return 0, nil
- }
-
- if w.maxPerWrite > 0 && len(p) > w.maxPerWrite {
- p = p[:w.maxPerWrite]
- }
-
- return w.buf.Write(p)
-}
-
-func (w *limitWriter) Flush() error {
- w.flushes++
-
- return nil
-}
-
-type byteReader struct {
- data []byte
-}
-
-func (r *byteReader) Read(p []byte) (int, error) {
- if len(r.data) == 0 {
- return 0, io.EOF
- }
-
- p[0] = r.data[0]
- r.data = r.data[1:]
-
- return 1, nil
-}