-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move slicer to its own package (#390)
This commit cleans up the slicer logic by moving the reader into its own package. We also moved LoadIndex from pcap/slicer.go to pcap/index.go. It also simplifies the slicer interface to take an io.ReadSeeker instead of *os.File (which implements ReadSeeker). This is the first refactor toward adding support for pcap-ng.
- Loading branch information
Showing
5 changed files
with
116 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Package slicer provides an io.Reader that returns subsets of a file. | ||
package slicer | ||
|
||
import ( | ||
"io" | ||
) | ||
|
||
// Reader implements io.Reader reading the sliced regions provided to it from | ||
// the underlying file thus extracting subsets of an underlying file without | ||
// modifying or copying the file. | ||
type Reader struct { | ||
slices []Slice | ||
slice Slice | ||
seeker io.ReadSeeker | ||
eof bool | ||
} | ||
|
||
func NewReader(seeker io.ReadSeeker, slices []Slice) (*Reader, error) { | ||
r := &Reader{ | ||
slices: slices, | ||
seeker: seeker, | ||
} | ||
return r, r.next() | ||
} | ||
|
||
func (r *Reader) next() error { | ||
if len(r.slices) == 0 { | ||
r.eof = true | ||
return nil | ||
} | ||
r.slice = r.slices[0] | ||
r.slices = r.slices[1:] | ||
_, err := r.seeker.Seek(int64(r.slice.Offset), 0) | ||
return err | ||
} | ||
|
||
func (r *Reader) Read(b []byte) (int, error) { | ||
if r.eof { | ||
return 0, io.EOF | ||
} | ||
p := b | ||
if uint64(len(p)) > r.slice.Length { | ||
p = p[:r.slice.Length] | ||
} | ||
n, err := r.seeker.Read(p) | ||
if n != 0 { | ||
if err == io.EOF { | ||
err = nil | ||
} | ||
r.slice.Length -= uint64(n) | ||
if r.slice.Length == 0 { | ||
err = r.next() | ||
} | ||
} | ||
return n, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package slicer | ||
|
||
type Slice struct { | ||
Offset uint64 | ||
Length uint64 | ||
} | ||
|
||
func (s Slice) Overlaps(x Slice) bool { | ||
return x.Offset >= s.Offset && x.Offset < s.Offset+x.Length | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package slicer_test | ||
|
||
import ( | ||
"bytes" | ||
"io/ioutil" | ||
"testing" | ||
|
||
"github.com/brimsec/zq/pkg/slicer" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestSlicer(t *testing.T) { | ||
in := []byte("abcdefghijklmnopqrstuvwxyz") | ||
slices := []slicer.Slice{ | ||
{0, 2}, | ||
{0, 26}, | ||
{3, 4}, | ||
{25, 1}, | ||
{25, 2}, | ||
} | ||
expected := []byte("ababcdefghijklmnopqrstuvwxyzdefgzz") | ||
reader, err := slicer.NewReader(bytes.NewReader(in), slices) | ||
assert.NoError(t, err) | ||
out, err := ioutil.ReadAll(reader) | ||
assert.NoError(t, err) | ||
assert.Exactly(t, expected, out) | ||
} |