aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Halter <868228+jhalter@users.noreply.github.com>2026-03-15 20:48:45 -0700
committerJeff Halter <868228+jhalter@users.noreply.github.com>2026-03-15 20:48:45 -0700
commit92f4b7af1073b6cdd0786ce2090d6e446e0903ad (patch)
tree4cfb332a36aa093d6bb4238967f1b0728fbb498f
parentf78ab940a8c09702be3e0ba310ac56e02fa76701 (diff)
Extract shared readFrom helper to deduplicate io.Reader boilerplate
13 types implemented identical offset-based io.Reader patterns with 5-7 lines of copy-and-offset-tracking code each. Extract a shared readFrom(p, offset, data) helper and reduce each Read() method to a one-liner delegating to it.
-rw-r--r--hotline/account.go9
-rw-r--r--hotline/field.go11
-rw-r--r--hotline/file_name_with_info.go10
-rw-r--r--hotline/file_transfer.go9
-rw-r--r--hotline/flattened_file_object.go18
-rw-r--r--hotline/news.go27
-rw-r--r--hotline/read_helper.go15
-rw-r--r--hotline/tracker.go9
-rw-r--r--hotline/transaction.go10
-rw-r--r--hotline/user.go10
-rw-r--r--internal/mobius/agreement.go11
-rw-r--r--internal/mobius/news.go11
-rw-r--r--internal/mobius/read_helper.go14
13 files changed, 43 insertions, 121 deletions
diff --git a/hotline/account.go b/hotline/account.go
index 37fb956..895d8a0 100644
--- a/hotline/account.go
+++ b/hotline/account.go
@@ -55,14 +55,7 @@ func (a *Account) Read(p []byte) (int, error) {
}
buf := slices.Concat(fieldCount, fieldBytes)
- if a.readOffset >= len(buf) {
- return 0, io.EOF // All bytes have been read
- }
-
- n := copy(p, buf[a.readOffset:])
- a.readOffset += n
-
- return n, nil
+ return readFrom(p, &a.readOffset, buf)
}
// HashAndSalt generates a password hash from a users obfuscated plaintext password
diff --git a/hotline/field.go b/hotline/field.go
index 1e6fc16..554f63d 100644
--- a/hotline/field.go
+++ b/hotline/field.go
@@ -5,7 +5,6 @@ import (
"bytes"
"encoding/binary"
"errors"
- "io"
"slices"
)
@@ -157,15 +156,7 @@ func (f *Field) DecodeNewsPath() ([]string, error) {
// Read implements io.Reader for Field
func (f *Field) Read(p []byte) (int, error) {
buf := slices.Concat(f.Type[:], f.FieldSize[:], f.Data)
-
- if f.readOffset >= len(buf) {
- return 0, io.EOF // All bytes have been read
- }
-
- n := copy(p, buf[f.readOffset:])
- f.readOffset += n
-
- return n, nil
+ return readFrom(p, &f.readOffset, buf)
}
// Write implements io.Writer for Field
diff --git a/hotline/file_name_with_info.go b/hotline/file_name_with_info.go
index 3a4a795..ffcdc17 100644
--- a/hotline/file_name_with_info.go
+++ b/hotline/file_name_with_info.go
@@ -3,7 +3,6 @@ package hotline
import (
"bytes"
"encoding/binary"
- "io"
"slices"
)
@@ -40,14 +39,7 @@ func (f *FileNameWithInfo) Read(p []byte) (int, error) {
f.Name,
)
- if f.readOffset >= len(buf) {
- return 0, io.EOF // All bytes have been read
- }
-
- n := copy(p, buf[f.readOffset:])
- f.readOffset += n
-
- return n, nil
+ return readFrom(p, &f.readOffset, buf)
}
func (f *FileNameWithInfo) Write(p []byte) (int, error) {
diff --git a/hotline/file_transfer.go b/hotline/file_transfer.go
index e8acbb3..e5898db 100644
--- a/hotline/file_transfer.go
+++ b/hotline/file_transfer.go
@@ -241,14 +241,7 @@ func (fh *FileHeader) Read(p []byte) (int, error) {
fh.FilePath,
)
- if fh.readOffset >= len(buf) {
- return 0, io.EOF // All bytes have been read
- }
-
- n := copy(p, buf[fh.readOffset:])
- fh.readOffset += n
-
- return n, nil
+ return readFrom(p, &fh.readOffset, buf)
}
func DownloadHandler(w io.Writer, fullPath string, fileTransfer *FileTransfer, fs FileStore, rLogger *slog.Logger, preserveForks bool) error {
diff --git a/hotline/flattened_file_object.go b/hotline/flattened_file_object.go
index 0300c71..130e917 100644
--- a/hotline/flattened_file_object.go
+++ b/hotline/flattened_file_object.go
@@ -151,14 +151,7 @@ func (ffif *FlatFileInformationFork) Read(p []byte) (int, error) {
ffif.Comment,
)
- if ffif.readOffset >= len(buf) {
- return 0, io.EOF // All bytes have been read
- }
-
- n := copy(p, buf[ffif.readOffset:])
- ffif.readOffset += n
-
- return n, nil
+ return readFrom(p, &ffif.readOffset, buf)
}
// Write implements the io.Writer interface for FlatFileInformationFork
@@ -253,14 +246,7 @@ func (ffo *flattenedFileObject) Read(p []byte) (int, error) {
ffo.FlatFileDataForkHeader.DataSize[:],
)
- if ffo.readOffset >= len(buf) {
- return 0, io.EOF // All bytes have been read
- }
-
- n := copy(p, buf[ffo.readOffset:])
- ffo.readOffset += n
-
- return n, nil
+ return readFrom(p, &ffo.readOffset, buf)
}
func (ffo *flattenedFileObject) ReadFrom(r io.Reader) (int64, error) {
diff --git a/hotline/news.go b/hotline/news.go
index f247db0..5e1d6e9 100644
--- a/hotline/news.go
+++ b/hotline/news.go
@@ -132,13 +132,7 @@ func (nald *NewsArtListData) Read(p []byte) (int, error) {
nald.NewsArtList,
)
- if nald.readOffset >= len(buf) {
- return 0, io.EOF // All bytes have been read
- }
- n := copy(p, buf[nald.readOffset:])
- nald.readOffset += n
-
- return n, nil
+ return readFrom(p, &nald.readOffset, buf)
}
func (nald *NewsArtListData) Write(p []byte) (int, error) {
@@ -257,14 +251,7 @@ func (nal *NewsArtList) Read(p []byte) (int, error) {
nal.ArticleSize[:],
)
- if nal.readOffset >= len(out) {
- return 0, io.EOF // All bytes have been read
- }
-
- n := copy(p, out[nal.readOffset:])
- nal.readOffset += n
-
- return n, nil
+ return readFrom(p, &nal.readOffset, out)
}
type NewsFlavorList struct {
@@ -293,15 +280,7 @@ func (newscat *NewsCategoryListData15) Read(p []byte) (int, error) {
[]byte(newscat.Name),
)
- if newscat.readOffset >= len(out) {
- return 0, io.EOF // All bytes have been read
- }
-
- n := copy(p, out)
-
- newscat.readOffset = n
-
- return n, nil
+ return readFrom(p, &newscat.readOffset, out)
}
func (newscat *NewsCategoryListData15) Write(p []byte) (int, error) {
diff --git a/hotline/read_helper.go b/hotline/read_helper.go
new file mode 100644
index 0000000..3154a74
--- /dev/null
+++ b/hotline/read_helper.go
@@ -0,0 +1,15 @@
+package hotline
+
+import "io"
+
+// readFrom is a shared helper for types that implement io.Reader via an
+// offset-based copy from a serialized byte slice. It copies bytes from data
+// starting at *offset into p, advances *offset, and returns io.EOF when done.
+func readFrom(p []byte, offset *int, data []byte) (int, error) {
+ if *offset >= len(data) {
+ return 0, io.EOF
+ }
+ n := copy(p, data[*offset:])
+ *offset += n
+ return n, nil
+}
diff --git a/hotline/tracker.go b/hotline/tracker.go
index ee4fc05..212238d 100644
--- a/hotline/tracker.go
+++ b/hotline/tracker.go
@@ -43,14 +43,7 @@ func (tr *TrackerRegistration) Read(p []byte) (int, error) {
[]byte(tr.Password),
)
- if tr.readOffset >= len(buf) {
- return 0, io.EOF // All bytes have been read
- }
-
- n := copy(p, buf[tr.readOffset:])
- tr.readOffset += n
-
- return n, nil
+ return readFrom(p, &tr.readOffset, buf)
}
// Dialer interface to abstract the dialing operation
diff --git a/hotline/transaction.go b/hotline/transaction.go
index 4637463..037e939 100644
--- a/hotline/transaction.go
+++ b/hotline/transaction.go
@@ -6,7 +6,6 @@ import (
"encoding/binary"
"errors"
"fmt"
- "io"
"math/rand"
"slices"
)
@@ -253,14 +252,7 @@ func (t *Transaction) Read(p []byte) (int, error) {
bbuf.Bytes(),
)
- if t.readOffset >= len(buf) {
- return 0, io.EOF // All bytes have been read
- }
-
- n := copy(p, buf[t.readOffset:])
- t.readOffset += n
-
- return n, nil
+ return readFrom(p, &t.readOffset, buf)
}
// Size returns the total size of the transaction payload
diff --git a/hotline/user.go b/hotline/user.go
index c4e0790..d68997b 100644
--- a/hotline/user.go
+++ b/hotline/user.go
@@ -2,7 +2,6 @@ package hotline
import (
"encoding/binary"
- "io"
"math/big"
"slices"
)
@@ -64,14 +63,7 @@ func (u *User) Read(p []byte) (int, error) {
[]byte(u.Name),
)
- if u.readOffset >= len(b) {
- return 0, io.EOF // All bytes have been read
- }
-
- n := copy(p, b)
- u.readOffset = n
-
- return n, nil
+ return readFrom(p, &u.readOffset, b)
}
func (u *User) Write(p []byte) (int, error) {
diff --git a/internal/mobius/agreement.go b/internal/mobius/agreement.go
index c2a67c5..d9cf2d4 100644
--- a/internal/mobius/agreement.go
+++ b/internal/mobius/agreement.go
@@ -2,7 +2,6 @@ package mobius
import (
"fmt"
- "io"
"os"
"path/filepath"
"strings"
@@ -60,15 +59,7 @@ func (a *Agreement) Read(p []byte) (int, error) {
a.mu.Lock()
defer a.mu.Unlock()
- if a.readOffset >= len(a.data) {
- return 0, io.EOF // All bytes have been read
- }
-
- n := copy(p, a.data[a.readOffset:])
-
- a.readOffset += n
-
- return n, nil
+ return readFrom(p, &a.readOffset, a.data)
}
func (a *Agreement) Seek(offset int64, _ int) (int64, error) {
diff --git a/internal/mobius/news.go b/internal/mobius/news.go
index c63c7f7..c94794c 100644
--- a/internal/mobius/news.go
+++ b/internal/mobius/news.go
@@ -2,7 +2,6 @@ package mobius
import (
"fmt"
- "io"
"os"
"slices"
"strings"
@@ -49,15 +48,7 @@ func (f *FlatNews) Read(p []byte) (int, error) {
f.mu.Lock()
defer f.mu.Unlock()
- if f.readOffset >= len(f.data) {
- return 0, io.EOF // All bytes have been read
- }
-
- n := copy(p, f.data[f.readOffset:])
-
- f.readOffset += n
-
- return n, nil
+ return readFrom(p, &f.readOffset, f.data)
}
// Write implements io.Writer for flat news.
diff --git a/internal/mobius/read_helper.go b/internal/mobius/read_helper.go
new file mode 100644
index 0000000..ab4002a
--- /dev/null
+++ b/internal/mobius/read_helper.go
@@ -0,0 +1,14 @@
+package mobius
+
+import "io"
+
+// readFrom is a shared helper for types that implement io.Reader via an
+// offset-based copy from a serialized byte slice.
+func readFrom(p []byte, offset *int, data []byte) (int, error) {
+ if *offset >= len(data) {
+ return 0, io.EOF
+ }
+ n := copy(p, data[*offset:])
+ *offset += n
+ return n, nil
+}