buffer.go (1478B)
1 // Copyright 2011 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 5 package tiff 6 7 import "io" 8 9 // buffer buffers an io.Reader to satisfy io.ReaderAt. 10 type buffer struct { 11 r io.Reader 12 buf []byte 13 } 14 15 // fill reads data from b.r until the buffer contains at least end bytes. 16 func (b *buffer) fill(end int) error { 17 m := len(b.buf) 18 if end > m { 19 if end > cap(b.buf) { 20 newcap := 1024 21 for newcap < end { 22 newcap *= 2 23 } 24 newbuf := make([]byte, end, newcap) 25 copy(newbuf, b.buf) 26 b.buf = newbuf 27 } else { 28 b.buf = b.buf[:end] 29 } 30 if n, err := io.ReadFull(b.r, b.buf[m:end]); err != nil { 31 end = m + n 32 b.buf = b.buf[:end] 33 return err 34 } 35 } 36 return nil 37 } 38 39 func (b *buffer) ReadAt(p []byte, off int64) (int, error) { 40 o := int(off) 41 end := o + len(p) 42 if int64(end) != off+int64(len(p)) { 43 return 0, io.ErrUnexpectedEOF 44 } 45 46 err := b.fill(end) 47 return copy(p, b.buf[o:end]), err 48 } 49 50 // Slice returns a slice of the underlying buffer. The slice contains 51 // n bytes starting at offset off. 52 func (b *buffer) Slice(off, n int) ([]byte, error) { 53 end := off + n 54 if err := b.fill(end); err != nil { 55 return nil, err 56 } 57 return b.buf[off:end], nil 58 } 59 60 // newReaderAt converts an io.Reader into an io.ReaderAt. 61 func newReaderAt(r io.Reader) io.ReaderAt { 62 if ra, ok := r.(io.ReaderAt); ok { 63 return ra 64 } 65 return &buffer{ 66 r: r, 67 buf: make([]byte, 0, 1024), 68 } 69 }