Skip to content

Commit

Permalink
feat: add .SetMaxLines(int) to Reader
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdecaf committed Nov 21, 2022
1 parent 17572fe commit f55bfcf
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 10 deletions.
16 changes: 12 additions & 4 deletions reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ import (
)

var (
// maxLines is the maximum number of lines a file can have. It is limited by the
// defaultMaxLines is the maximum number of lines a file can have. It is limited by the
// EntryAddendaCount field which has 8 digits, and the BatchCount field which has
// 6 digits in the File Control Record. So we can have at most the 2 file records,
// 2 records for each of 10^6 batches, 10^8 entry and addenda records, and 8 lines
// of 9's to round up to the nearest multiple of 10.
maxLines = 2 + 2000000 + 100000000 + 8
defaultMaxLines int = 2 + 2_000_000 + 100_000_000 + 8
)

// Reader reads records from an ACH-encoded file.
Expand All @@ -57,6 +57,9 @@ type Reader struct {
// line number of the file being parsed
lineNum int

// maxLines is the maximum number of lines to be consumed
maxLines int

// recordName holds the current record name being parsed.
recordName string

Expand Down Expand Up @@ -132,10 +135,15 @@ func ReadFiles(paths []string) ([]*File, error) {
// NewReader returns a new ACH Reader that reads from r.
func NewReader(r io.Reader) *Reader {
return &Reader{
scanner: bufio.NewScanner(r),
maxLines: defaultMaxLines,
scanner: bufio.NewScanner(r),
}
}

func (r *Reader) SetMaxLines(max int) {
r.maxLines = max
}

// Read reads each line in the underlying io.Reader and returns a File and any errors encountered.
//
// Read enforces ACH formatting rules and the first character of each line determines which parser is used.
Expand All @@ -150,7 +158,7 @@ func (r *Reader) Read() (File, error) {
for r.scanner.Scan() {
line := r.scanner.Text()
r.lineNum++
if r.lineNum > maxLines {
if r.lineNum > r.maxLines {
r.errors.Add(ErrFileTooLong)
return r.File, r.errors
}
Expand Down
9 changes: 3 additions & 6 deletions reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1774,23 +1774,20 @@ func TestTwoFileADVControls(t *testing.T) {

// testACHFileTooLongErr checks that it errors on a file that is too long
func testACHFileTooLongErr(t testing.TB) {
// To make testing this more manageable, we'll artificially cap the size of the file to 200 lines
maxLines = 200

f, err := os.Open(filepath.Join("test", "testdata", "20110729A.ach"))
if err != nil {
t.Errorf("%T: %s", err, err)
}
defer f.Close()

r := NewReader(f)
// To make testing this more manageable, we'll artificially cap the size of the file to 200 lines
r.SetMaxLines(200)
_, err = r.Read()

if !base.Has(err, ErrFileTooLong) {
t.Errorf("%T: %s", err, err)
}

// reset maxLines to its original value
maxLines = 2 + 2000000 + 100000000 + 8
}

// TestCategoryAssignment ensures entry categories are set correctly
Expand Down

0 comments on commit f55bfcf

Please sign in to comment.