github.com/coreos/mantle@v0.13.0/lang/bufpipe/fixed_buffer.go (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  // Licensed under the same terms as Go itself:
     5  // https://github.com/golang/go/blob/master/LICENSE
     6  
     7  package bufpipe
     8  
     9  import (
    10  	"errors"
    11  )
    12  
    13  // fixedBuffer is an io.ReadWriter backed by a fixed size buffer.
    14  // It never allocates, but moves old data as new data is written.
    15  type fixedBuffer struct {
    16  	buf  []byte
    17  	r, w int
    18  }
    19  
    20  var (
    21  	errReadEmpty = errors.New("read from empty fixedBuffer")
    22  	errWriteFull = errors.New("write on full fixedBuffer")
    23  )
    24  
    25  // Read copies bytes from the buffer into p.
    26  // It is an error to read when no data is available.
    27  func (b *fixedBuffer) Read(p []byte) (n int, err error) {
    28  	if b.r == b.w {
    29  		return 0, errReadEmpty
    30  	}
    31  	n = copy(p, b.buf[b.r:b.w])
    32  	b.r += n
    33  	if b.r == b.w {
    34  		b.r = 0
    35  		b.w = 0
    36  	}
    37  	return n, nil
    38  }
    39  
    40  // Len returns the number of bytes of the unread portion of the buffer.
    41  func (b *fixedBuffer) Len() int {
    42  	return b.w - b.r
    43  }
    44  
    45  // Write copies bytes from p into the buffer.
    46  // It is an error to write more data than the buffer can hold.
    47  func (b *fixedBuffer) Write(p []byte) (n int, err error) {
    48  	// Slide existing data to beginning.
    49  	if b.r > 0 && len(p) > len(b.buf)-b.w {
    50  		copy(b.buf, b.buf[b.r:b.w])
    51  		b.w -= b.r
    52  		b.r = 0
    53  	}
    54  
    55  	// Write new data.
    56  	n = copy(b.buf[b.w:], p)
    57  	b.w += n
    58  	if n < len(p) {
    59  		err = errWriteFull
    60  	}
    61  	return n, err
    62  }