Платформа ЦРНП "Мирокод" для разработки проектов
https://git.mirocod.ru
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
2.1 KiB
99 lines
2.1 KiB
package buffer |
|
|
|
import ( |
|
"encoding/gob" |
|
"io" |
|
) |
|
|
|
type swap struct { |
|
A BufferAt |
|
B BufferAt |
|
} |
|
|
|
// NewSwap creates a Buffer which writes to a until you write past a.Cap() |
|
// then it io.Copy's from a to b and writes to b. |
|
// Once the Buffer is empty again, it starts over writing to a. |
|
// Note that if b.Cap() <= a.Cap() it will cause a panic, b is expected |
|
// to be larger in order to accommodate writes past a.Cap(). |
|
func NewSwap(a, b Buffer) Buffer { |
|
return NewSwapAt(toBufferAt(a), toBufferAt(b)) |
|
} |
|
|
|
// NewSwapAt creates a BufferAt which writes to a until you write past a.Cap() |
|
// then it io.Copy's from a to b and writes to b. |
|
// Once the Buffer is empty again, it starts over writing to a. |
|
// Note that if b.Cap() <= a.Cap() it will cause a panic, b is expected |
|
// to be larger in order to accommodate writes past a.Cap(). |
|
func NewSwapAt(a, b BufferAt) BufferAt { |
|
if b.Cap() <= a.Cap() { |
|
panic("Buffer b must be larger than a.") |
|
} |
|
return &swap{A: a, B: b} |
|
} |
|
|
|
func (buf *swap) Len() int64 { |
|
return buf.A.Len() + buf.B.Len() |
|
} |
|
|
|
func (buf *swap) Cap() int64 { |
|
return buf.B.Cap() |
|
} |
|
|
|
func (buf *swap) Read(p []byte) (n int, err error) { |
|
if buf.A.Len() > 0 { |
|
return buf.A.Read(p) |
|
} |
|
return buf.B.Read(p) |
|
} |
|
|
|
func (buf *swap) ReadAt(p []byte, off int64) (n int, err error) { |
|
if buf.A.Len() > 0 { |
|
return buf.A.ReadAt(p, off) |
|
} |
|
return buf.B.ReadAt(p, off) |
|
} |
|
|
|
func (buf *swap) Write(p []byte) (n int, err error) { |
|
switch { |
|
case buf.B.Len() > 0: |
|
n, err = buf.B.Write(p) |
|
|
|
case buf.A.Len()+int64(len(p)) > buf.A.Cap(): |
|
_, err = io.Copy(buf.B, buf.A) |
|
if err == nil { |
|
n, err = buf.B.Write(p) |
|
} |
|
|
|
default: |
|
n, err = buf.A.Write(p) |
|
} |
|
|
|
return n, err |
|
} |
|
|
|
func (buf *swap) WriteAt(p []byte, off int64) (n int, err error) { |
|
switch { |
|
case buf.B.Len() > 0: |
|
n, err = buf.B.WriteAt(p, off) |
|
|
|
case off+int64(len(p)) > buf.A.Cap(): |
|
_, err = io.Copy(buf.B, buf.A) |
|
if err == nil { |
|
n, err = buf.B.WriteAt(p, off) |
|
} |
|
|
|
default: |
|
n, err = buf.A.WriteAt(p, off) |
|
} |
|
|
|
return n, err |
|
} |
|
|
|
func (buf *swap) Reset() { |
|
buf.A.Reset() |
|
buf.B.Reset() |
|
} |
|
|
|
func init() { |
|
gob.Register(&swap{}) |
|
}
|
|
|