| // Copyright 2014 The Go Authors. | |
| // See https://code.google.com/p/go/source/browse/CONTRIBUTORS | |
| // Licensed under the same terms as Go itself: | |
| // https://code.google.com/p/go/source/browse/LICENSE | |
| package http2 | |
| import ( | |
| "errors" | |
| ) | |
| // buffer is an io.ReadWriteCloser backed by a fixed size buffer. | |
| // It never allocates, but moves old data as new data is written. | |
| type buffer struct { | |
| buf []byte | |
| r, w int | |
| closed bool | |
| err error // err to return to reader | |
| } | |
| var ( | |
| errReadEmpty = errors.New("read from empty buffer") | |
| errWriteFull = errors.New("write on full buffer") | |
| ) | |
| // Read copies bytes from the buffer into p. | |
| // It is an error to read when no data is available. | |
| func (b *buffer) Read(p []byte) (n int, err error) { | |
| n = copy(p, b.buf[b.r:b.w]) | |
| b.r += n | |
| if b.closed && b.r == b.w { | |
| err = b.err | |
| } else if b.r == b.w && n == 0 { | |
| err = errReadEmpty | |
| } | |
| return n, err | |
| } | |
| // Len returns the number of bytes of the unread portion of the buffer. | |
| func (b *buffer) Len() int { | |
| return b.w - b.r | |
| } | |
| // Write copies bytes from p into the buffer. | |
| // It is an error to write more data than the buffer can hold. | |
| func (b *buffer) Write(p []byte) (n int, err error) { | |
| if b.closed { | |
| return 0, errors.New("closed") | |
| } | |
| // Slide existing data to beginning. | |
| if b.r > 0 && len(p) > len(b.buf)-b.w { | |
| copy(b.buf, b.buf[b.r:b.w]) | |
| b.w -= b.r | |
| b.r = 0 | |
| } | |
| // Write new data. | |
| n = copy(b.buf[b.w:], p) | |
| b.w += n | |
| if n < len(p) { | |
| err = errWriteFull | |
| } | |
| return n, err | |
| } | |
| // Close marks the buffer as closed. Future calls to Write will | |
| // return an error. Future calls to Read, once the buffer is | |
| // empty, will return err. | |
| func (b *buffer) Close(err error) { | |
| if !b.closed { | |
| b.closed = true | |
| b.err = err | |
| } | |
| } |