gbytes.Buffer implements io.Reader Signed-off-by: Alex Suraci <asuraci@pivotal.io>
diff --git a/gbytes/buffer.go b/gbytes/buffer.go index 7e42334..8775b86 100644 --- a/gbytes/buffer.go +++ b/gbytes/buffer.go
@@ -14,6 +14,7 @@ import ( "errors" "fmt" + "io" "regexp" "sync" "time" @@ -67,6 +68,30 @@ } /* +Read implements the io.Reader interface. It advances the +cursor as it reads. + +Returns an error if called after Close. +*/ +func (b *Buffer) Read(d []byte) (int, error) { + b.lock.Lock() + defer b.lock.Unlock() + + if b.closed { + return 0, errors.New("attempt to read from closed buffer") + } + + if uint64(len(b.contents)) <= b.readCursor { + return 0, io.EOF + } + + n := copy(d, b.contents[b.readCursor:]) + b.readCursor += uint64(n) + + return n, nil +} + +/* Close signifies that the buffer will no longer be written to */ func (b *Buffer) Close() error {
diff --git a/gbytes/buffer_test.go b/gbytes/buffer_test.go index 9aa2937..b111138 100644 --- a/gbytes/buffer_test.go +++ b/gbytes/buffer_test.go
@@ -1,7 +1,9 @@ package gbytes_test import ( + "io" "time" + . "github.com/onsi/gomega/gbytes" . "github.com/onsi/ginkgo" @@ -36,6 +38,41 @@ }) }) + Describe("reading from a buffer", func() { + It("should read the current contents of the buffer", func() { + buffer := BufferWithBytes([]byte("abcde")) + + dest := make([]byte, 3) + n, err := buffer.Read(dest) + Ω(err).ShouldNot(HaveOccurred()) + Ω(n).Should(Equal(3)) + Ω(string(dest)).Should(Equal("abc")) + + dest = make([]byte, 3) + n, err = buffer.Read(dest) + Ω(err).ShouldNot(HaveOccurred()) + Ω(n).Should(Equal(2)) + Ω(string(dest[:n])).Should(Equal("de")) + + n, err = buffer.Read(dest) + Ω(err).Should(Equal(io.EOF)) + Ω(n).Should(Equal(0)) + }) + + Context("after the buffer has been closed", func() { + It("returns an error", func() { + buffer := BufferWithBytes([]byte("abcde")) + + buffer.Close() + + dest := make([]byte, 3) + n, err := buffer.Read(dest) + Ω(err).Should(HaveOccurred()) + Ω(n).Should(Equal(0)) + }) + }) + }) + Describe("detecting regular expressions", func() { It("should fire the appropriate channel when the passed in pattern matches, then close it", func(done Done) { go func() {