]> git.r.bdr.sh - rbdr/mobius/blob - hotline/file_name_with_info.go
Adopt more fixed size array types for struct fields
[rbdr/mobius] / hotline / file_name_with_info.go
1 package hotline
2
3 import (
4 "bytes"
5 "encoding/binary"
6 "io"
7 "slices"
8 )
9
10 type FileNameWithInfo struct {
11 fileNameWithInfoHeader
12 Name []byte // File Name
13
14 readOffset int // Internal offset to track read progress
15 }
16
17 // fileNameWithInfoHeader contains the fixed length fields of FileNameWithInfo
18 type fileNameWithInfoHeader struct {
19 Type [4]byte // File type code
20 Creator [4]byte // File creator code
21 FileSize [4]byte // File Size in bytes
22 RSVD [4]byte
23 NameScript [2]byte // ??
24 NameSize [2]byte // Length of Name field
25 }
26
27 func (f *fileNameWithInfoHeader) nameLen() int {
28 return int(binary.BigEndian.Uint16(f.NameSize[:]))
29 }
30
31 // Read implements io.Reader for FileNameWithInfo
32 func (f *FileNameWithInfo) Read(p []byte) (int, error) {
33 buf := slices.Concat(
34 f.Type[:],
35 f.Creator[:],
36 f.FileSize[:],
37 f.RSVD[:],
38 f.NameScript[:],
39 f.NameSize[:],
40 f.Name,
41 )
42
43 if f.readOffset >= len(buf) {
44 return 0, io.EOF // All bytes have been read
45 }
46
47 n := copy(p, buf[f.readOffset:])
48 f.readOffset += n
49
50 return n, nil
51 }
52
53 func (f *FileNameWithInfo) Write(p []byte) (int, error) {
54 err := binary.Read(bytes.NewReader(p), binary.BigEndian, &f.fileNameWithInfoHeader)
55 if err != nil {
56 return 0, err
57 }
58 headerLen := binary.Size(f.fileNameWithInfoHeader)
59 f.Name = p[headerLen : headerLen+f.nameLen()]
60
61 return len(p), nil
62 }