Created
August 12, 2016 13:14
-
-
Save shaunlee/3f8f6a08913124d806babbe36e633b1d to your computer and use it in GitHub Desktop.
Circle byte buffer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"io" | |
"errors" | |
) | |
var ErrBufferIsNotEnough = errors.New("buffer is not enough") | |
type ByteBuffer struct { | |
data []byte | |
size uint64 | |
head uint64 // write cursor | |
tail uint64 // read cursor | |
} | |
func NewByteBuffer(size uint64) *ByteBuffer { | |
return &ByteBuffer{ | |
data: make([]byte, size), | |
size: size, | |
} | |
} | |
func (p *ByteBuffer) Write(v []byte) (int, error) { | |
length := uint64(len(v)) | |
if length > p.size - (p.head - p.tail) { | |
return 0, ErrBufferIsNotEnough | |
} | |
offset_head := p.head % p.size | |
offset_tail := p.tail % p.size | |
if offset_head < offset_tail { | |
// #_# | |
copy(p.data[offset_head:], v) | |
} else { | |
right := p.size - p.head | |
if right >= length { | |
// #__ | |
copy(p.data[offset_head:], v) | |
} else { | |
// _#_ | |
copy(p.data[offset_head:], v[:right]) | |
copy(p.data[:length - right], v[right:]) | |
} | |
} | |
p.head += length | |
return int(length), nil | |
} | |
func (p *ByteBuffer) Read(v []byte) (int, error) { | |
if p.head - p.tail == 0 { | |
return 0, io.EOF | |
} | |
length := uint64(len(v)) | |
if length > p.head - p.tail { | |
length = p.head - p.tail | |
} | |
offset_head := p.head % p.size | |
offset_tail := p.tail % p.size | |
if offset_head > offset_tail { | |
copy(v, p.data[offset_tail:offset_tail + length]) | |
} else { | |
right := p.size - p.tail | |
if right >= length { | |
copy(v, p.data[offset_tail:]) | |
} else { | |
copy(v[:right], p.data[offset_tail:]) | |
copy(v[right:], p.data[:length - right]) | |
} | |
} | |
p.tail += length | |
return int(length), nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment