]> git.r.bdr.sh - rbdr/mobius/blame - hotline/file_path.go
Add initial support for resource and info forks
[rbdr/mobius] / hotline / file_path.go
CommitLineData
6988a057
JH
1package hotline
2
3import (
00d1ef67 4 "bytes"
6988a057 5 "encoding/binary"
00d1ef67 6 "errors"
050407a3 7 "io"
00d1ef67 8 "path"
7e2e07da 9 "strings"
6988a057
JH
10)
11
12const pathSeparator = "/" // File path separator TODO: make configurable to support Windows
13
14// FilePathItem represents the file or directory portion of a delimited file path (e.g. foo and bar in "/foo/bar")
15// 00 00
16// 09
17// 73 75 62 66 6f 6c 64 65 72 // "subfolder"
18type FilePathItem struct {
19 Len byte
20 Name []byte
21}
22
6988a057 23type FilePath struct {
00d1ef67 24 ItemCount [2]byte
72dd37f1 25 Items []FilePathItem
6988a057
JH
26}
27
72dd37f1 28func (fp *FilePath) UnmarshalBinary(b []byte) error {
050407a3
JH
29 reader := bytes.NewReader(b)
30 err := binary.Read(reader, binary.BigEndian, &fp.ItemCount)
31 if err != nil && !errors.Is(err, io.EOF) {
00d1ef67
JH
32 return err
33 }
050407a3
JH
34 if errors.Is(err, io.EOF) {
35 return nil
36 }
6988a057 37
72dd37f1 38 for i := uint16(0); i < fp.Len(); i++ {
050407a3
JH
39 // skip two bytes for the file path delimiter
40 _, _ = reader.Seek(2, io.SeekCurrent)
41
42 // read the length of the next pathItem
43 segLen, err := reader.ReadByte()
44 if err != nil {
45 return err
46 }
47
48 pBytes := make([]byte, segLen)
49
50 _, err = reader.Read(pBytes)
51 if err != nil && !errors.Is(err, io.EOF) {
52 return err
53 }
54
55 fp.Items = append(fp.Items, FilePathItem{Len: segLen, Name: pBytes})
6988a057
JH
56 }
57
72dd37f1
JH
58 return nil
59}
60
7e2e07da
JH
61func (fp *FilePath) IsDropbox() bool {
62 if fp.Len() == 0 {
63 return false
64 }
65
66 return strings.Contains(strings.ToLower(string(fp.Items[fp.Len()-1].Name)), "drop box")
67}
68
69func (fp *FilePath) IsUploadDir() bool {
70 if fp.Len() == 0 {
71 return false
72 }
73
25f0d77d 74 return strings.Contains(strings.ToLower(string(fp.Items[fp.Len()-1].Name)), "upload")
7e2e07da
JH
75}
76
72dd37f1 77func (fp *FilePath) Len() uint16 {
00d1ef67 78 return binary.BigEndian.Uint16(fp.ItemCount[:])
6988a057
JH
79}
80
81func (fp *FilePath) String() string {
00d1ef67 82 out := []string{"/"}
72dd37f1 83 for _, i := range fp.Items {
6988a057
JH
84 out = append(out, string(i.Name))
85 }
00d1ef67
JH
86
87 return path.Join(out...)
6988a057 88}
c5d9af5a 89
92a7e455
JH
90func readPath(fileRoot string, filePath, fileName []byte) (fullPath string, err error) {
91 var fp FilePath
92 if filePath != nil {
93 if err = fp.UnmarshalBinary(filePath); err != nil {
94 return "", err
95 }
96 }
97
98 fullPath = path.Join(
99 "/",
100 fileRoot,
101 fp.String(),
102 path.Join("/", string(fileName)),
103 )
104
105 return fullPath, nil
106}