feat: create working client

This commit is contained in:
2026-08-05 13:06:36 +02:00
parent 67916c5d1c
commit aa9d403d09
11 changed files with 3406 additions and 1 deletions

71
download.go Normal file
View File

@@ -0,0 +1,71 @@
package zw
import (
"context"
"io"
"io/fs"
"sync"
"sync/atomic"
)
type downloadReader struct {
recv func() ([]byte, error)
cancel context.CancelFunc
pending []byte
terminal error
cancelOnce sync.Once
closed atomic.Bool
}
func (r *downloadReader) Read(destination []byte) (int, error) {
if len(destination) == 0 {
return 0, nil
}
if r.closed.Load() {
return 0, fs.ErrClosed
}
if len(r.pending) > 0 {
n := copy(destination, r.pending)
r.pending = r.pending[n:]
return n, nil
}
if r.terminal != nil {
return 0, r.terminal
}
for {
chunk, err := r.recv()
if err != nil {
if r.closed.Load() {
return 0, fs.ErrClosed
}
if err == io.EOF {
r.terminal = io.EOF
} else {
r.terminal = convertRPCError(err)
}
r.cancelOnce.Do(r.cancel)
return 0, r.terminal
}
if len(chunk) == 0 {
continue
}
n := copy(destination, chunk)
r.pending = chunk[n:]
return n, nil
}
}
func (r *downloadReader) Close() error {
r.closed.Store(true)
r.cancelOnce.Do(r.cancel)
return nil
}