buffer.go raw

   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  }
  70