From 9e97d389c33d5a8b099acfe1c76ef16dd39d74a4 Mon Sep 17 00:00:00 2001 From: kortschak Date: Tue, 15 Sep 2015 11:31:33 +0930 Subject: [PATCH] bgzf/index: use correct end of chunk for identification Fixes #10. --- bgzf/index/index.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/bgzf/index/index.go b/bgzf/index/index.go index 1aa5898..1c9d95b 100644 --- a/bgzf/index/index.go +++ b/bgzf/index/index.go @@ -50,7 +50,11 @@ func NewChunkReader(r *bgzf.Reader, chunks []bgzf.Chunk) (*ChunkReader, error) { // Read satisfies the io.Reader interface. func (r *ChunkReader) Read(p []byte) (int, error) { - if len(r.chunks) == 0 || vOffset(r.r.LastChunk().End) >= vOffset(r.chunks[0].End) { + if len(r.chunks) == 0 { + return 0, io.EOF + } + last := r.r.LastChunk() + if vOffset(last.End) >= vOffset(r.chunks[0].End) { return 0, io.EOF } @@ -58,9 +62,13 @@ func (r *ChunkReader) Read(p []byte) (int, error) { // the current chunk. We do not need to consider reading // beyond the end of the block because the bgzf.Reader is in // blocked mode and so will stop there anyway. - if r.r.LastChunk().End.File == r.chunks[0].End.File { - p = p[:min(len(p), int(r.chunks[0].End.Block-r.r.LastChunk().End.Block))] + // If we are in the same block as the last read, set the + // cursor to the end of that read. + var cursor uint16 + if last.Begin.File == r.chunks[0].Begin.File { + cursor = last.End.Block } + p = p[:min(len(p), int(r.chunks[0].End.Block-cursor))] n, err := r.r.Read(p) if err != nil { @@ -69,13 +77,17 @@ func (r *ChunkReader) Read(p []byte) (int, error) { } return n, err } - if len(r.chunks) != 0 && vOffset(r.r.LastChunk().End) >= vOffset(r.chunks[0].End) { + + // Check for non-progress and terminate when this happens. + this := r.r.LastChunk() + if this == last || vOffset(this.End) >= vOffset(r.chunks[0].End) { r.chunks = r.chunks[1:] if len(r.chunks) == 0 { return n, io.EOF } err = r.r.Seek(r.chunks[0].Begin) } + return n, err }