From 5889f1fa2818f34025ca6e2feecb26928c6e6341 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sat, 16 Jul 2022 14:53:11 -0600 Subject: Re-jigger the KMP search to be more independent of the underlying data types --- lib/diskio/seq.go | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 lib/diskio/seq.go (limited to 'lib/diskio/seq.go') diff --git a/lib/diskio/seq.go b/lib/diskio/seq.go new file mode 100644 index 0000000..3c5f4ae --- /dev/null +++ b/lib/diskio/seq.go @@ -0,0 +1,68 @@ +// Copyright (C) 2022 Luke Shumaker +// +// SPDX-License-Identifier: GPL-2.0-or-later + +package diskio + +import ( + "fmt" + "io" +) + +// interface ///////////////////////////////////////////////////////// + +type Sequence[K ~int64, V any] interface { + // Get the value at 'pos' in the sequence. Positions start at + // 0 and increment naturally. Return an error that is io.EOF + // if 'pos' is past the end of the sequence'. + Get(pos K) (V, error) +} + +// implementation: slice ///////////////////////////////////////////// + +type SliceSequence[K ~int64, V any] []V + +var _ Sequence[assertAddr, byte] = SliceSequence[assertAddr, byte]([]byte(nil)) + +func (s SliceSequence[K, V]) Get(i K) (V, error) { + if i >= K(len(s)) { + var v V + return v, io.EOF + } + return s[int(i)], nil +} + +// implementation: string //////////////////////////////////////////// + +type StringSequence[K ~int64] string + +var _ Sequence[assertAddr, byte] = StringSequence[assertAddr]("") + +func (s StringSequence[K]) Get(i K) (byte, error) { + if i >= K(len(s)) { + return 0, io.EOF + } + return s[int(i)], nil +} + +// implementation: io.ByteReader ///////////////////////////////////// + +type ByteReaderSequence[K ~int64] struct { + R io.ByteReader + pos K +} + +var _ Sequence[assertAddr, byte] = &ByteReaderSequence[assertAddr]{R: nil} + +func (s *ByteReaderSequence[K]) Get(i K) (byte, error) { + if i != s.pos { + return 0, fmt.Errorf("%T.Get(%v): can only call .Get(%v)", + s, i, s.pos) + } + chr, err := s.R.ReadByte() + if err != nil { + return chr, err + } + s.pos++ + return chr, nil +} -- cgit v1.2.3-54-g00ecf