forked from zach-klippenstein/goadb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dir_entries.go
119 lines (100 loc) · 2.41 KB
/
dir_entries.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package adb
import (
"fmt"
"os"
"time"
"github.com/yosemite-open/go-adb/wire"
)
// DirEntry holds information about a directory entry on a device.
type DirEntry struct {
Name string
Mode os.FileMode
Size int32
ModifiedAt time.Time
}
// DirEntries iterates over directory entries.
type DirEntries struct {
scanner wire.SyncScanner
currentEntry *DirEntry
err error
}
// ReadAllDirEntries reads all the remaining directory entries into a slice,
// closes self, and returns any error.
// If err is non-nil, result will contain any entries read until the error occurred.
func (entries *DirEntries) ReadAll() (result []*DirEntry, err error) {
defer entries.Close()
for entries.Next() {
result = append(result, entries.Entry())
}
err = entries.Err()
return
}
func (entries *DirEntries) Next() bool {
if entries.err != nil {
return false
}
entry, done, err := readNextDirListEntry(entries.scanner)
if err != nil {
entries.err = err
entries.Close()
return false
}
entries.currentEntry = entry
if done {
entries.Close()
return false
}
return true
}
func (entries *DirEntries) Entry() *DirEntry {
return entries.currentEntry
}
func (entries *DirEntries) Err() error {
return entries.err
}
// Close closes the connection to the adb.
// Next() will call Close() before returning false.
func (entries *DirEntries) Close() error {
return entries.scanner.Close()
}
func readNextDirListEntry(s wire.SyncScanner) (entry *DirEntry, done bool, err error) {
status, err := s.ReadStatus("dir-entry")
if err != nil {
return
}
if status == "DONE" {
done = true
return
} else if status != "DENT" {
err = fmt.Errorf("error reading dir entries: expected dir entry ID 'DENT', but got '%s'", status)
return
}
mode, err := s.ReadFileMode()
if err != nil {
err = fmt.Errorf("error reading dir entries: error reading file mode: %v", err)
return
}
size, err := s.ReadInt32()
if err != nil {
err = fmt.Errorf("error reading dir entries: error reading file size: %v", err)
return
}
mtime, err := s.ReadTime()
if err != nil {
err = fmt.Errorf("error reading dir entries: error reading file time: %v", err)
return
}
name, err := s.ReadString()
if err != nil {
err = fmt.Errorf("error reading dir entries: error reading file name: %v", err)
return
}
done = false
entry = &DirEntry{
Name: name,
Mode: mode,
Size: size,
ModifiedAt: mtime,
}
return
}