diff options
| author | Jeff Halter <868228+jhalter@users.noreply.github.com> | 2022-06-03 17:11:06 -0700 |
|---|---|---|
| committer | Jeff Halter <868228+jhalter@users.noreply.github.com> | 2022-06-03 17:11:06 -0700 |
| commit | 16a4ad707a05df25c9d12b8cc89fb3a9e3be0dba (patch) | |
| tree | 7ddeb3bf3496142a530949e64f361e5321c1fac5 /hotline/file_resume_data.go | |
| parent | 481631f6b541a0f00c7c3ba789c13ac934bdefbc (diff) | |
Initial implementation of file transfer resume
Diffstat (limited to 'hotline/file_resume_data.go')
| -rw-r--r-- | hotline/file_resume_data.go | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/hotline/file_resume_data.go b/hotline/file_resume_data.go new file mode 100644 index 0000000..f5b82de --- /dev/null +++ b/hotline/file_resume_data.go @@ -0,0 +1,75 @@ +package hotline + +import ( + "bytes" + "encoding/binary" +) + +// FileResumeData is sent when a client or server would like to resume a transfer from an offset +type FileResumeData struct { + Format [4]byte // "RFLT" + Version [2]byte // Always 1 + RSVD [34]byte // Unused + ForkCount [2]byte // Length of ForkInfoList. Either 2 or 3 depending on whether file has a resource fork + ForkInfoList []ForkInfoList +} + +type ForkInfoList struct { + Fork [4]byte // "DATA" or "MACR" + DataSize [4]byte // offset from which to resume the transfer of data + RSVDA [4]byte // Unused + RSVDB [4]byte // Unused +} + +func NewForkInfoList(b []byte) *ForkInfoList { + return &ForkInfoList{ + Fork: [4]byte{0x44, 0x41, 0x54, 0x41}, + DataSize: [4]byte{b[0], b[1], b[2], b[3]}, + RSVDA: [4]byte{}, + RSVDB: [4]byte{}, + } +} + +func NewFileResumeData(list []ForkInfoList) *FileResumeData { + return &FileResumeData{ + Format: [4]byte{0x52, 0x46, 0x4C, 0x54}, // RFLT + Version: [2]byte{0, 1}, + RSVD: [34]byte{}, + ForkCount: [2]byte{0, uint8(len(list))}, + ForkInfoList: list, + } +} + +func (frd *FileResumeData) BinaryMarshal() ([]byte, error) { + var buf bytes.Buffer + _ = binary.Write(&buf, binary.LittleEndian, frd.Format) + _ = binary.Write(&buf, binary.LittleEndian, frd.Version) + _ = binary.Write(&buf, binary.LittleEndian, frd.RSVD) + _ = binary.Write(&buf, binary.LittleEndian, frd.ForkCount) + for _, fil := range frd.ForkInfoList { + _ = binary.Write(&buf, binary.LittleEndian, fil) + } + + return buf.Bytes(), nil +} + +func (frd *FileResumeData) UnmarshalBinary(b []byte) error { + frd.Format = [4]byte{b[0], b[1], b[2], b[3]} + frd.Version = [2]byte{b[4], b[5]} + frd.ForkCount = [2]byte{b[40], b[41]} + + for i := 0; i < int(frd.ForkCount[1]); i++ { + var fil ForkInfoList + start := 42 + i*16 + end := start + 16 + + r := bytes.NewReader(b[start:end]) + if err := binary.Read(r, binary.BigEndian, &fil); err != nil { + return err + } + + frd.ForkInfoList = append(frd.ForkInfoList, fil) + } + + return nil +} |