67 lines
1.3 KiB
Go
67 lines
1.3 KiB
Go
package main
|
|
|
|
import (
|
|
"io"
|
|
"log"
|
|
"math/rand"
|
|
)
|
|
|
|
func main() {
|
|
reader := NewStreamOfStuff()
|
|
bufferedReader := NewBufferedReader(reader)
|
|
lenBits := make([]byte, 1)
|
|
for i := 0; i < 10; i++ {
|
|
if n, err := bufferedReader.Read(lenBits); err != nil || n != len(lenBits) {
|
|
panic(err)
|
|
}
|
|
payload := make([]byte, int(lenBits[0]))
|
|
if n, err := bufferedReader.Read(payload); err != nil || n != len(payload) {
|
|
panic(err)
|
|
}
|
|
log.Printf("[%d] (%d) %q", i, len(payload), payload)
|
|
}
|
|
}
|
|
|
|
type BufferedReader struct {
|
|
buffer []byte
|
|
reader io.Reader
|
|
}
|
|
|
|
func (r *BufferedReader) Read(b []byte) (int, error) {
|
|
for len(b) > len(r.buffer) {
|
|
more := make([]byte, 8)
|
|
n, err := r.reader.Read(more)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
r.buffer = append(r.buffer, more[:n]...)
|
|
}
|
|
n := len(b)
|
|
if copied := copy(b, r.buffer[:n]); copied != n {
|
|
panic(copied)
|
|
}
|
|
r.buffer = r.buffer[n:]
|
|
return n, nil
|
|
}
|
|
|
|
func NewBufferedReader(r io.Reader) io.Reader {
|
|
return &BufferedReader{
|
|
buffer: []byte{},
|
|
reader: r,
|
|
}
|
|
}
|
|
|
|
func NewStreamOfStuff() io.Reader {
|
|
return jitterReader{}
|
|
}
|
|
|
|
type jitterReader struct{}
|
|
|
|
func (jitterReader jitterReader) Read(b []byte) (int, error) {
|
|
n := rand.Int()%len(b) + 1
|
|
for i := 0; i < n; i++ {
|
|
b[i] = 'a' + byte(rand.Int()%26)
|
|
}
|
|
return n, nil
|
|
}
|