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