package main
import (
"errors"
"fmt"
"io"
"time"
)
type CircleByteBuffer struct {
io.Reader
io.Writer
io.Closer
datas []byte
start int
end int
size int
isClose bool
isEnd bool
}
func NewCircleByteBuffer(len int)*CircleByteBuffer{
var e=new(CircleByteBuffer)
e.datas=make([]byte,len)
e.start=0
e.end=0
e.size=len
e.isClose=false
e.isEnd=false
return e
}
func (e*CircleByteBuffer)getLen()int{
if e.start==e.end{
return 0
}else if e.start<e.end{
return e.end-e.start
}else{
return e.start-e.end
}
}
func (e*CircleByteBuffer)getFree()int{
return e.size-e.getLen()
}
func (e*CircleByteBuffer)putByte(b byte)error{
if e.isClose{return io.EOF}
e.datas[e.end]=b
var pos=e.end+1
for pos==e.start{
if e.isClose{return io.EOF}
time.Sleep(time.Microsecond)
}
if pos==e.size {
e.end = 0
}else {
e.end = pos
}
return nil
}
func (e*CircleByteBuffer)getByte()(byte,error){
if e.isClose{return 0, io.EOF}
if e.isEnd&&e.getLen()<=0{return 0, io.EOF}
if e.getLen()<=0 {return 0,errors.New("no datas")}
var ret=e.datas[e.start]
e.start++
if e.start==e.size {
e.start = 0
}
return ret,nil
}
func (e*CircleByteBuffer)geti(i int)byte{
if i>=e.getLen() {
panic("out buffer")
}
var pos=e.start+i
if pos>=e.size {
pos -= e.size
}
return e.datas[pos]
}
/*func (e*CircleByteBuffer)puts(bts []byte){
for i:=0;i<len(bts);i++{
e.put(bts[i])
}
}
func (e*CircleByteBuffer)gets(bts []byte)int{
if bts==nil {return 0}
var ret=0
for i:=0;i<len(bts);i++{
if e.getLen()<=0{break}
bts[i]=e.get()
ret++
}
return ret
}*/
func (e*CircleByteBuffer)Close() error{
e.isClose=true
return nil
}
func (e*CircleByteBuffer)Read(bts []byte)(int,error){
if e.isClose{return 0, io.EOF}
if bts==nil {return 0,errors.New("bts is nil")}
var ret=0
for i:=0;i<len(bts);i++{
b,err:=e.getByte()
if err!=nil{
if err==io.EOF{
return ret, err
}
return ret, nil
}
bts[i]=b
ret++
}
if e.isClose{return ret, io.EOF}
return ret,nil
}
func (e*CircleByteBuffer)Write(bts []byte)(int,error){
if e.isClose{return 0, io.EOF}
if bts==nil {
e.isEnd=true
return 0,io.EOF
}
var ret=0
for i:=0;i<len(bts);i++{
err:=e.putByte(bts[i])
if err!=nil{
fmt.Println("Write bts err:",err)
return ret,err
}
ret++
}
if e.isClose{return ret, io.EOF}
return ret,nil
}
双线程安全,示例:
func main() {
fmt.Println("hello world")
b:=NewCircleByteBuffer(1024)
go func(){
for i:=0;i<10;i++ {
bts:=[]byte{byte(i)}
b.Write(bts)
time.Sleep(time.Second)
}
fmt.Println("Close!")
b.Close()
}()
buf:=make([]byte,512)
for{
n,err:=b.Read(buf)
if n>0{
fmt.Println("Reads:",buf[0:n])
}
if err!=nil{
break
}
}
fmt.Println("end!")
}
输出:
hello world
Reads: [0]
Reads: [1]
Reads: [2]
Reads: [3]
Reads: [4]
Reads: [5]
Reads: [6]
Reads: [7]
Reads: [8]
Reads: [9]
Close!
end!