github.com/suiyunonghen/DxCommonLib@v0.5.3/ring_buffer.go (about) 1 package DxCommonLib 2 3 import ( 4 "errors" 5 ) 6 7 type DxRingBuffer struct { 8 rawData []byte 9 rpos, wpos int 10 markrpos int 11 markwpos int 12 isEmpty bool 13 hasMark bool 14 } 15 16 func (buffer *DxRingBuffer) Capacity() int { 17 return len(buffer.rawData) 18 } 19 20 //DataSize 数据长度 21 func (buffer *DxRingBuffer) DataSize() int { 22 if buffer.isEmpty { 23 return 0 24 } 25 if buffer.wpos > buffer.rpos { 26 return buffer.wpos - buffer.rpos 27 } 28 if buffer.wpos == buffer.rpos { 29 return len(buffer.rawData) 30 } 31 return len(buffer.rawData) - buffer.rpos + buffer.wpos 32 } 33 34 //FreeSize 剩下的空余大小 35 func (buffer *DxRingBuffer) FreeSize() int { 36 if buffer.isEmpty { 37 return len(buffer.rawData) 38 } 39 if buffer.rpos == buffer.wpos { 40 return 0 41 } 42 if buffer.wpos < buffer.rpos { 43 return buffer.rpos - buffer.wpos 44 } 45 return len(buffer.rawData) - buffer.wpos + buffer.rpos 46 } 47 48 func (buffer *DxRingBuffer) MarkReadWrite() { 49 buffer.markrpos = buffer.rpos 50 buffer.markwpos = buffer.wpos 51 buffer.hasMark = true 52 } 53 54 func (buffer *DxRingBuffer) RestoreMark() { 55 if !buffer.hasMark { 56 return 57 } 58 buffer.rpos = buffer.markrpos 59 buffer.wpos = buffer.markwpos 60 buffer.hasMark = false 61 } 62 63 func (buffer *DxRingBuffer) Skip(n int) { 64 if buffer.isEmpty || n <= 0 { 65 return 66 } 67 if buffer.wpos > buffer.rpos { 68 vlen := buffer.wpos - buffer.rpos 69 if vlen > n { 70 buffer.rpos = buffer.rpos + n 71 } else { 72 buffer.isEmpty = true 73 buffer.rpos = buffer.wpos 74 } 75 return 76 } 77 size := len(buffer.rawData) 78 vlen := size - buffer.rpos + buffer.wpos 79 if vlen > n { 80 vlen = n 81 } 82 buffer.rpos = (buffer.rpos + vlen) % size 83 buffer.isEmpty = buffer.rpos == buffer.wpos 84 } 85 86 func (buffer *DxRingBuffer) Read(p []byte) (n int, err error) { 87 btlen := len(p) 88 if buffer.isEmpty || btlen == 0 { 89 return 0, nil 90 } 91 size := len(buffer.rawData) 92 if buffer.wpos > buffer.rpos { 93 n = buffer.wpos - buffer.rpos 94 if n > btlen { 95 n = btlen 96 } 97 copy(p, buffer.rawData[buffer.rpos:buffer.rpos+n]) 98 buffer.rpos = (buffer.rpos + n) % size 99 buffer.isEmpty = buffer.rpos == buffer.wpos 100 return 101 } 102 n = size - buffer.rpos + buffer.wpos 103 if n > btlen { 104 n = btlen 105 } 106 if buffer.rpos+n <= size { 107 copy(p, buffer.rawData[buffer.rpos:buffer.rpos+n]) 108 } else { 109 len1 := size - buffer.rpos 110 copy(p, buffer.rawData[buffer.rpos:size]) 111 len2 := n - len1 112 copy(p[len1:], buffer.rawData[:len2]) 113 } 114 buffer.rpos = (buffer.rpos + n) % size 115 buffer.isEmpty = buffer.rpos == buffer.wpos 116 return n, nil 117 } 118 119 func (buffer *DxRingBuffer) ReadByte() (b byte, err error) { 120 if buffer.isEmpty { 121 return 0, errors.New("IsEmpty") 122 } 123 b = buffer.rawData[buffer.rpos] 124 buffer.rpos++ 125 if buffer.rpos == buffer.Capacity() { 126 buffer.rpos = 0 127 } 128 buffer.isEmpty = buffer.rpos == buffer.wpos 129 return b, nil 130 } 131 132 func (buffer *DxRingBuffer) Write(p []byte) (n int, err error) { 133 n = len(p) 134 if n == 0 { 135 return 136 } 137 free := buffer.FreeSize() 138 if n > free { 139 buffer.malloc(n - free) 140 } 141 size := len(buffer.rawData) 142 if buffer.wpos >= buffer.rpos { 143 c1 := size - buffer.wpos 144 if c1 >= n { 145 copy(buffer.rawData[buffer.wpos:], p) 146 buffer.wpos += n 147 } else { 148 copy(buffer.rawData[buffer.wpos:], p[:c1]) 149 c2 := n - c1 150 copy(buffer.rawData[:c2], p[c1:]) 151 buffer.wpos = c2 152 } 153 } else { 154 copy(buffer.rawData[buffer.wpos:], p) 155 buffer.wpos += n 156 } 157 if buffer.wpos == buffer.rpos { 158 buffer.wpos = 0 159 } 160 buffer.isEmpty = false 161 return 162 } 163 164 func (buffer *DxRingBuffer) WriteByte(b byte) { 165 if buffer.FreeSize() < 1 { 166 buffer.malloc(1) 167 } 168 buffer.rawData[buffer.wpos] = b 169 buffer.wpos++ 170 if buffer.wpos == buffer.Capacity() { 171 buffer.wpos = 0 172 } 173 buffer.isEmpty = false 174 } 175 176 func (buffer *DxRingBuffer) IsFull() bool { 177 return buffer.rpos == buffer.wpos && !buffer.isEmpty 178 } 179 180 func (buffer *DxRingBuffer) IsEmpty() bool { 181 return buffer.isEmpty 182 } 183 184 func (buffer *DxRingBuffer) Reset() { 185 buffer.hasMark = false 186 buffer.rpos = 0 187 buffer.wpos = 0 188 buffer.isEmpty = true 189 } 190 191 func (buffer *DxRingBuffer) malloc(cap int) { 192 newcap := len(buffer.rawData) + cap 193 if newcap < 256 { 194 newcap = newcap * 2 195 } else if newcap < 512 { 196 newcap = newcap + 256 197 } else { 198 newcap = newcap + 512 199 } 200 newbuf := make([]byte, newcap) 201 oldlen := buffer.DataSize() 202 buffer.Read(newbuf) 203 buffer.rpos = 0 204 buffer.wpos = oldlen 205 buffer.rawData = newbuf 206 } 207 208 func NewRingBuffer(size int) *DxRingBuffer { 209 return &DxRingBuffer{ 210 rawData: make([]byte, size), 211 rpos: 0, 212 wpos: 0, 213 isEmpty: true, 214 } 215 }