blob: 48d7561ecfd84a8e48692b357fe4b6d3154d0e44 [file] [log] [blame]
Keith Rarick50b8ccc2014-11-12 11:43:30 -08001// Copyright 2014 The Go Authors.
2// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
3// Licensed under the same terms as Go itself:
4// https://code.google.com/p/go/source/browse/LICENSE
5
6package http2
7
8import (
9 "errors"
10)
11
12// buffer is an io.ReadWriteCloser backed by a fixed size buffer.
13// It never allocates, but moves old data as new data is written.
14type buffer struct {
15 buf []byte
16 r, w int
17 closed bool
18 err error // err to return to reader
19}
20
21var (
22 errReadEmpty = errors.New("read from empty buffer")
23 errWriteFull = errors.New("write on full buffer")
24)
25
26// Read copies bytes from the buffer into p.
27// It is an error to read when no data is available.
28func (b *buffer) Read(p []byte) (n int, err error) {
29 n = copy(p, b.buf[b.r:b.w])
30 b.r += n
31 if b.closed && b.r == b.w {
32 err = b.err
33 } else if b.r == b.w && n == 0 {
34 err = errReadEmpty
35 }
36 return n, err
37}
38
39// Len returns the number of bytes of the unread portion of the buffer.
40func (b *buffer) Len() int {
41 return b.w - b.r
42}
43
44// Write copies bytes from p into the buffer.
45// It is an error to write more data than the buffer can hold.
46func (b *buffer) Write(p []byte) (n int, err error) {
47 if b.closed {
48 return 0, errors.New("closed")
49 }
50
51 // Slide existing data to beginning.
52 if b.r > 0 && len(p) > len(b.buf)-b.w {
53 copy(b.buf, b.buf[b.r:b.w])
54 b.w -= b.r
55 b.r = 0
56 }
57
58 // Write new data.
59 n = copy(b.buf[b.w:], p)
60 b.w += n
61 if n < len(p) {
62 err = errWriteFull
63 }
64 return n, err
65}
66
67// Close marks the buffer as closed. Future calls to Write will
68// return an error. Future calls to Read, once the buffer is
69// empty, will return err.
70func (b *buffer) Close(err error) {
71 if !b.closed {
72 b.closed = true
73 b.err = err
74 }
75}