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