forgejo-federation/vendor/github.com/djherbis/buffer/partition.go

102 lines
1.5 KiB
Go
Raw Normal View History

package buffer
import (
"encoding/gob"
"io"
"math"
)
type partition struct {
List
Pool
}
// NewPartition returns a Buffer which uses a Pool to extend or shrink its size as needed.
// It automatically allocates new buffers with pool.Get() to extend is length, and
// pool.Put() to release unused buffers as it shrinks.
func NewPartition(pool Pool, buffers ...Buffer) Buffer {
return &partition{
Pool: pool,
List: buffers,
}
}
func (buf *partition) Cap() int64 {
return math.MaxInt64
}
func (buf *partition) Read(p []byte) (n int, err error) {
for len(p) > 0 {
if len(buf.List) == 0 {
return n, io.EOF
}
buffer := buf.List[0]
if Empty(buffer) {
buf.Pool.Put(buf.Pop())
continue
}
m, er := buffer.Read(p)
n += m
p = p[m:]
if er != nil && er != io.EOF {
return n, er
}
}
return n, nil
}
func (buf *partition) grow() error {
next, err := buf.Pool.Get()
if err != nil {
return err
}
buf.Push(next)
return nil
}
func (buf *partition) Write(p []byte) (n int, err error) {
for len(p) > 0 {
if len(buf.List) == 0 {
if err := buf.grow(); err != nil {
return n, err
}
}
buffer := buf.List[len(buf.List)-1]
if Full(buffer) {
if err := buf.grow(); err != nil {
return n, err
}
continue
}
m, er := buffer.Write(p)
n += m
p = p[m:]
if er != nil && er != io.ErrShortWrite {
return n, er
}
}
return n, nil
}
func (buf *partition) Reset() {
for len(buf.List) > 0 {
buf.Pool.Put(buf.Pop())
}
}
func init() {
gob.Register(&partition{})
}