func (c *Container) Next() bool {
	if c.err != nil {
		return false
	}
	var b Block
	c.err = b.readFrom(c.blockData)
	if c.err == nil {
		c.block = &b
		return true
	}
	return false
}
Next advances the Container to the next CRAM block. It returns false
when the data ends, either by reaching the end of the container or
encountering an error.
package cram
import (
	"bytes"
	"compress/bzip2"
	"compress/gzip"
	"encoding/binary"
	"errors"
	"fmt"
	"hash/crc32"
	"io"
	"io/ioutil"
	"os"
	"reflect"
	"github.com/ulikunitz/xz/lzma"
	"github.com/biogo/hts/cram/encoding/itf8"
	"github.com/biogo/hts/cram/encoding/ltf8"
	"github.com/biogo/hts/sam"
)
var cramEOFmarker = []byte{
	0x0f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,  
	0x0f, 0xe0, 0x45, 0x4f, 0x46, 0x00, 0x00, 0x00,  
	0x00, 0x01, 0x00, 0x05, 0xbd, 0xd9, 0x4f, 0x00,  
	0x01, 0x00, 0x06, 0x06, 0x01, 0x00, 0x01, 0x00,  
	0x01, 0x00, 0xee, 0x63, 0x01, 0x4b,    
}
var ErrNoEnd = errors.New("cram: cannot determine offset from end")
func HasEOF(r io.ReaderAt) (bool, error) {
	type sizer interface {
		Size() int64
	}
	type stater interface {
		Stat() (os.FileInfo, error)
	}
	type lenSeeker interface {
		io.Seeker
		Len() int
	}
	var size int64
	switch r := r.(type) {
	case sizer:
		size = r.Size()
	case stater:
		fi, err := r.Stat()
		if err != nil {
			return false, err
		}
		size = fi.Size()
	case lenSeeker:
		var err error
		size, err = r.Seek(0, 1)
		if err != nil {
			return false, err
		}
		size += int64(r.Len())
	default:
		return false, ErrNoEnd
	}
	b := make([]byte, len(cramEOFmarker))
	_, err := r.ReadAt(b, size-int64(len(cramEOFmarker)))
	if err != nil {
		return false, err
	}
	return bytes.Equal(b, cramEOFmarker), nil
}
type Reader struct {
	r io.Reader
	d definition
	c *Container
	err error
}
func NewReader(r io.Reader) (*Reader, error) {
	cr := Reader{r: r}
	err := cr.d.readFrom(r)
	if err != nil {
		return nil, err
	}
	return &cr, nil
}
func (r *Reader) Next() bool {
	if r.err != nil {
		return false
	}
	if r.c != nil {
		io.Copy(ioutil.Discard, r.c.blockData)
	}
	var c Container
	r.err = c.readFrom(r.r)
	r.c = &c
	return r.err == nil
}
func (r *Reader) Container() *Container {
	return r.c
}
func (r *Reader) Err() error {
	if r.err == io.EOF {
		return nil
	}
	return r.err
}
type definition struct {
	Magic   [4]byte `is:"CRAM"`
	Version [2]byte
	ID      [20]byte
}
func (d *definition) readFrom(r io.Reader) error {
	err := binary.Read(r, binary.LittleEndian, d)
	if err != nil {
		return err
	}
	magic := reflect.TypeOf(*d).Field(0).Tag.Get("is")
	if !bytes.Equal(d.Magic[:], []byte(magic)) {
		return fmt.Errorf("cram: not a cram file: magic bytes %q", d.Magic)
	}
	return nil
}
type Container struct {
	blockLen  int32
	refID     int32
	start     int32
	span      int32
	nRec      int32
	recCount  int64
	bases     int64
	blocks    int32
	landmarks []int32
	crc32     uint32
	blockData io.Reader
	block *Block
	err   error
}
func (c *Container) readFrom(r io.Reader) error {
	crc := crc32.NewIEEE()
	er := errorReader{r: io.TeeReader(r, crc)}
	var buf [4]byte
	io.ReadFull(&er, buf[:])
	c.blockLen = int32(binary.LittleEndian.Uint32(buf[:]))
	c.refID = er.itf8()
	c.start = er.itf8()
	c.span = er.itf8()
	c.nRec = er.itf8()
	c.recCount = er.ltf8()
	c.bases = er.ltf8()
	c.blocks = er.itf8()
	c.landmarks = er.itf8slice()
	sum := crc.Sum32()
	_, err := io.ReadFull(&er, buf[:])
	if err != nil {
		return err
	}
	c.crc32 = binary.LittleEndian.Uint32(buf[:])
	if c.crc32 != sum {
		return fmt.Errorf("cram: container crc32 mismatch got:0x%08x want:0x%08x", sum, c.crc32)
	}
	if er.err != nil {
		return er.err
	}
	c.blockData = &io.LimitedReader{R: r, N: int64(c.blockLen)}
	return nil
}