+ trunc := fmt.Sprintf("%.21s", ft.FileName)
+ return fmt.Sprintf("%-21s %.3s%% %6s\n", trunc, ft.percentComplete(), ft.formattedTransferSize())
+}
+
+func (ft *FileTransfer) percentComplete() string {
+ ft.bytesSentCounter.mux.Lock()
+ defer ft.bytesSentCounter.mux.Unlock()
+ return fmt.Sprintf(
+ "%v",
+ math.RoundToEven(float64(ft.bytesSentCounter.Total)/float64(binary.BigEndian.Uint32(ft.TransferSize))*100),
+ )
+}
+
+func (ft *FileTransfer) formattedTransferSize() string {
+ sizeInKB := float32(binary.BigEndian.Uint32(ft.TransferSize)) / 1024
+ if sizeInKB > 1024 {
+ return fmt.Sprintf("%.1fM", sizeInKB/1024)
+ } else {
+ return fmt.Sprintf("%.0fK", sizeInKB)
+ }
+}
+
+func (ft *FileTransfer) ItemCount() int {
+ return int(binary.BigEndian.Uint16(ft.FolderItemCount))
+}
+
+type folderUpload struct {
+ DataSize [2]byte
+ IsFolder [2]byte
+ PathItemCount [2]byte
+ FileNamePath []byte
+}
+
+func (fu *folderUpload) FormattedPath() string {
+ pathItemLen := binary.BigEndian.Uint16(fu.PathItemCount[:])
+
+ var pathSegments []string
+ pathData := fu.FileNamePath
+
+ // TODO: implement scanner interface instead?
+ for i := uint16(0); i < pathItemLen; i++ {
+ segLen := pathData[2]
+ pathSegments = append(pathSegments, string(pathData[3:3+segLen]))
+ pathData = pathData[3+segLen:]
+ }