github.com/cloudwego/kitex@v0.9.0/pkg/remote/default_bytebuf.go (about) 1 /* 2 * Copyright 2021 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package remote 18 19 import ( 20 "errors" 21 "fmt" 22 "io" 23 "sync" 24 ) 25 26 // Mask bits. 27 const ( 28 BitReadable = 1 << iota 29 BitWritable 30 ) 31 32 var bytebufPool sync.Pool 33 34 func init() { 35 bytebufPool.New = newDefaultByteBuffer 36 } 37 38 // NewWriterBuffer is used to create a defaultByteBuffer using the given size. 39 // NOTICE: defaultByteBuffer is only used for testing. 40 func NewWriterBuffer(size int) ByteBuffer { 41 return newWriterByteBuffer(size) 42 } 43 44 // NewReaderBuffer is used to create a defaultByteBuffer using the given buf. 45 func NewReaderBuffer(buf []byte) ByteBuffer { 46 return newReaderByteBuffer(buf) 47 } 48 49 // NewReaderWriterBuffer is used to create a defaultByteBuffer using the given size. 50 func NewReaderWriterBuffer(size int) ByteBuffer { 51 return newReaderWriterByteBuffer(size) 52 } 53 54 type defaultByteBuffer struct { 55 buff []byte 56 readIdx int 57 writeIdx int 58 status int 59 } 60 61 var _ ByteBuffer = &defaultByteBuffer{} 62 63 func newDefaultByteBuffer() interface{} { 64 return &defaultByteBuffer{} 65 } 66 67 func newReaderByteBuffer(buf []byte) ByteBuffer { 68 bytebuf := bytebufPool.Get().(*defaultByteBuffer) 69 bytebuf.buff = buf 70 bytebuf.readIdx = 0 71 bytebuf.writeIdx = len(buf) 72 bytebuf.status = BitReadable 73 return bytebuf 74 } 75 76 func newWriterByteBuffer(estimatedLength int) ByteBuffer { 77 if estimatedLength <= 0 { 78 estimatedLength = 256 // default buffer size 79 } 80 bytebuf := bytebufPool.Get().(*defaultByteBuffer) 81 bytebuf.buff = make([]byte, estimatedLength) 82 bytebuf.status = BitWritable 83 bytebuf.writeIdx = 0 84 return bytebuf 85 } 86 87 func newReaderWriterByteBuffer(estimatedLength int) ByteBuffer { 88 if estimatedLength <= 0 { 89 estimatedLength = 256 // default buffer size 90 } 91 bytebuf := bytebufPool.Get().(*defaultByteBuffer) 92 bytebuf.buff = make([]byte, estimatedLength) 93 bytebuf.readIdx = 0 94 bytebuf.writeIdx = 0 95 bytebuf.status = BitReadable | BitWritable 96 return bytebuf 97 } 98 99 // Next reads n bytes sequentially, returns the original address. 100 func (b *defaultByteBuffer) Next(n int) (buf []byte, err error) { 101 if b.status&BitReadable == 0 { 102 return nil, errors.New("unreadable buffer, cannot support Next") 103 } 104 buf, err = b.Peek(n) 105 b.readIdx += n 106 return buf, err 107 } 108 109 // Peek returns the next n bytes without advancing the reader. 110 func (b *defaultByteBuffer) Peek(n int) (buf []byte, err error) { 111 if b.status&BitReadable == 0 { 112 return nil, errors.New("unreadable buffer, cannot support Peek") 113 } 114 if err = b.readableCheck(n); err != nil { 115 return nil, err 116 } 117 return b.buff[b.readIdx : b.readIdx+n], nil 118 } 119 120 // Skip is used to skip n bytes, it's much faster than Next. 121 // Skip will not cause release. 122 func (b *defaultByteBuffer) Skip(n int) (err error) { 123 if b.status&BitReadable == 0 { 124 return errors.New("unreadable buffer, cannot support Skip") 125 } 126 if err = b.readableCheck(n); err != nil { 127 return err 128 } 129 b.readIdx += n 130 return nil 131 } 132 133 // ReadableLen returns the total length of readable buffer. 134 func (b *defaultByteBuffer) ReadableLen() (n int) { 135 if b.status&BitReadable == 0 { 136 return -1 137 } 138 return b.writeIdx - b.readIdx 139 } 140 141 // Read implement io.Reader 142 func (b *defaultByteBuffer) Read(p []byte) (n int, err error) { 143 if b.status&BitReadable == 0 { 144 return -1, errors.New("unreadable buffer, cannot support Read") 145 } 146 pl := len(p) 147 var buf []byte 148 readable := b.ReadableLen() 149 if readable == 0 { 150 return 0, io.EOF 151 } 152 if pl <= readable { 153 buf, err = b.Next(pl) 154 if err != nil { 155 return 156 } 157 n = pl 158 } else { 159 buf, err = b.Next(readable) 160 if err != nil { 161 return 162 } 163 n = readable 164 } 165 copy(p, buf) 166 return 167 } 168 169 // ReadString is a more efficient way to read string than Next. 170 func (b *defaultByteBuffer) ReadString(n int) (s string, err error) { 171 if b.status&BitReadable == 0 { 172 return "", errors.New("unreadable buffer, cannot support ReadString") 173 } 174 var buf []byte 175 if buf, err = b.Next(n); err != nil { 176 return "", err 177 } 178 return string(buf), nil 179 } 180 181 // ReadBinary like ReadString. 182 // Returns a copy of original buffer. 183 func (b *defaultByteBuffer) ReadBinary(n int) (p []byte, err error) { 184 if b.status&BitReadable == 0 { 185 return p, errors.New("unreadable buffer, cannot support ReadBinary") 186 } 187 var buf []byte 188 if buf, err = b.Next(n); err != nil { 189 return p, err 190 } 191 p = make([]byte, n) 192 copy(p, buf) 193 return p, nil 194 } 195 196 // Malloc n bytes sequentially in the writer buffer. 197 func (b *defaultByteBuffer) Malloc(n int) (buf []byte, err error) { 198 if b.status&BitWritable == 0 { 199 return nil, errors.New("unwritable buffer, cannot support Malloc") 200 } 201 b.ensureWritable(n) 202 currWIdx := b.writeIdx 203 b.writeIdx += n 204 return b.buff[currWIdx:b.writeIdx], nil 205 } 206 207 // MallocLen returns the total length of the buffer malloced. 208 func (b *defaultByteBuffer) MallocLen() (length int) { 209 if b.status&BitWritable == 0 { 210 return -1 211 } 212 return b.writeIdx 213 } 214 215 // WriteString is a more efficient way to write string, using the unsafe method to convert the string to []byte. 216 func (b *defaultByteBuffer) WriteString(s string) (n int, err error) { 217 if b.status&BitWritable == 0 { 218 return -1, errors.New("unwritable buffer, cannot support WriteString") 219 } 220 n = len(s) 221 b.ensureWritable(n) 222 copy(b.buff[b.writeIdx:b.writeIdx+n], s) 223 b.writeIdx += n 224 return 225 } 226 227 // Write implement io.Writer 228 func (b *defaultByteBuffer) Write(p []byte) (n int, err error) { 229 if b.status&BitWritable == 0 { 230 return -1, errors.New("unwritable buffer, cannot support Write") 231 } 232 return b.WriteBinary(p) 233 } 234 235 // WriteBinary writes the []byte into buff. 236 func (b *defaultByteBuffer) WriteBinary(p []byte) (n int, err error) { 237 if b.status&BitWritable == 0 { 238 return -1, errors.New("unwritable buffer, cannot support WriteBinary") 239 } 240 n = len(p) 241 b.ensureWritable(n) 242 copy(b.buff[b.writeIdx:b.writeIdx+n], p) 243 b.writeIdx += n 244 return 245 } 246 247 // ReadLen returns the size already read. 248 func (b *defaultByteBuffer) ReadLen() (n int) { 249 return b.readIdx 250 } 251 252 // Flush writes any malloc data to the underlying io.Writer. 253 // The malloced buffer must be set correctly. 254 func (b *defaultByteBuffer) Flush() (err error) { 255 if b.status&BitWritable == 0 { 256 return errors.New("unwritable buffer, cannot support Flush") 257 } 258 return nil 259 } 260 261 // AppendBuffer appends buf to the original buffer. 262 func (b *defaultByteBuffer) AppendBuffer(buf ByteBuffer) (err error) { 263 subBuf := buf.(*defaultByteBuffer) 264 n := subBuf.writeIdx 265 b.ensureWritable(n) 266 copy(b.buff[b.writeIdx:b.writeIdx+n], subBuf.buff) 267 b.writeIdx += n 268 buf.Release(nil) 269 return 270 } 271 272 // Bytes is used to get the bytes written. 273 func (b *defaultByteBuffer) Bytes() (buf []byte, err error) { 274 if b.status&BitWritable == 0 { 275 return nil, errors.New("unwritable buffer, cannot support Bytes") 276 } 277 buf = make([]byte, b.writeIdx) 278 copy(buf, b.buff[:b.writeIdx]) 279 return buf, nil 280 } 281 282 // NewBuffer returns a new writable remote.ByteBuffer. 283 func (b *defaultByteBuffer) NewBuffer() ByteBuffer { 284 return NewWriterBuffer(256) 285 } 286 287 // Release will free the buffer already read. 288 // After release, buffer read by Next/Skip/Peek is invalid. 289 func (b *defaultByteBuffer) Release(e error) (err error) { 290 b.zero() 291 bytebufPool.Put(b) 292 return 293 } 294 295 func (b *defaultByteBuffer) zero() { 296 b.status = 0 297 b.buff = nil 298 b.readIdx = 0 299 b.writeIdx = 0 300 } 301 302 func (b *defaultByteBuffer) readableCheck(n int) error { 303 readableLen := b.ReadableLen() 304 if b.readIdx >= b.writeIdx && n > 0 { 305 return io.EOF 306 } 307 if readableLen < n { 308 return fmt.Errorf("default byteBuffer not enough, read[%d] but remain[%d]", n, readableLen) 309 } 310 return nil 311 } 312 313 func (b *defaultByteBuffer) writableLen() (n int) { 314 if b.status&BitWritable == 0 { 315 return -1 316 } 317 return cap(b.buff) - b.writeIdx 318 } 319 320 func (b *defaultByteBuffer) ensureWritable(minWritableBytes int) { 321 if b.writableLen() >= minWritableBytes { 322 return 323 } 324 minNewCapacity := b.writeIdx + minWritableBytes 325 newCapacity := cap(b.buff) 326 for newCapacity < minNewCapacity { 327 newCapacity <<= 1 328 } 329 330 buf := make([]byte, newCapacity) 331 copy(buf, b.buff) 332 b.buff = buf 333 }