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  }