2016-01-15 15:54:27 +00:00
|
|
|
package adb
|
2015-04-12 20:34:20 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2015-04-24 13:20:47 +00:00
|
|
|
"os"
|
|
|
|
"time"
|
2015-04-12 20:34:20 +00:00
|
|
|
|
2020-07-13 06:18:10 +00:00
|
|
|
"goadb/wire"
|
2015-04-12 20:34:20 +00:00
|
|
|
)
|
|
|
|
|
2015-04-24 13:20:47 +00:00
|
|
|
// DirEntry holds information about a directory entry on a device.
|
|
|
|
type DirEntry struct {
|
|
|
|
Name string
|
|
|
|
Mode os.FileMode
|
|
|
|
Size int32
|
|
|
|
ModifiedAt time.Time
|
|
|
|
}
|
|
|
|
|
2015-04-12 20:34:20 +00:00
|
|
|
// DirEntries iterates over directory entries.
|
|
|
|
type DirEntries struct {
|
|
|
|
scanner wire.SyncScanner
|
|
|
|
|
|
|
|
currentEntry *DirEntry
|
|
|
|
err error
|
|
|
|
}
|
|
|
|
|
2015-09-06 19:50:07 +00:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2015-04-12 20:34:20 +00:00
|
|
|
func (entries *DirEntries) Next() bool {
|
|
|
|
if entries.err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
entry, done, err := readNextDirListEntry(entries.scanner)
|
|
|
|
if err != nil {
|
|
|
|
entries.err = err
|
2015-04-29 17:23:51 +00:00
|
|
|
entries.Close()
|
2015-04-12 20:34:20 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
entries.currentEntry = entry
|
|
|
|
if done {
|
2015-04-29 17:23:51 +00:00
|
|
|
entries.Close()
|
2015-04-12 20:34:20 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
func (entries *DirEntries) Entry() *DirEntry {
|
|
|
|
return entries.currentEntry
|
|
|
|
}
|
|
|
|
|
|
|
|
func (entries *DirEntries) Err() error {
|
|
|
|
return entries.err
|
|
|
|
}
|
|
|
|
|
2015-04-29 17:23:51 +00:00
|
|
|
// Close closes the connection to the adb.
|
|
|
|
// Next() will call Close() before returning false.
|
|
|
|
func (entries *DirEntries) Close() error {
|
|
|
|
return entries.scanner.Close()
|
2015-04-12 20:34:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func readNextDirListEntry(s wire.SyncScanner) (entry *DirEntry, done bool, err error) {
|
2015-12-28 23:28:53 +00:00
|
|
|
status, err := s.ReadStatus("dir-entry")
|
2015-04-12 20:34:20 +00:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-12-28 23:28:53 +00:00
|
|
|
if status == "DONE" {
|
2015-04-12 20:34:20 +00:00
|
|
|
done = true
|
|
|
|
return
|
2015-12-28 23:28:53 +00:00
|
|
|
} else if status != "DENT" {
|
|
|
|
err = fmt.Errorf("error reading dir entries: expected dir entry ID 'DENT', but got '%s'", status)
|
2015-04-12 20:34:20 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
mode, err := s.ReadFileMode()
|
|
|
|
if err != nil {
|
2015-04-29 17:23:51 +00:00
|
|
|
err = fmt.Errorf("error reading dir entries: error reading file mode: %v", err)
|
2015-04-12 20:34:20 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
size, err := s.ReadInt32()
|
|
|
|
if err != nil {
|
2015-04-29 17:23:51 +00:00
|
|
|
err = fmt.Errorf("error reading dir entries: error reading file size: %v", err)
|
2015-04-12 20:34:20 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
mtime, err := s.ReadTime()
|
|
|
|
if err != nil {
|
2015-04-29 17:23:51 +00:00
|
|
|
err = fmt.Errorf("error reading dir entries: error reading file time: %v", err)
|
2015-04-12 20:34:20 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
name, err := s.ReadString()
|
|
|
|
if err != nil {
|
2015-04-29 17:23:51 +00:00
|
|
|
err = fmt.Errorf("error reading dir entries: error reading file name: %v", err)
|
2015-04-12 20:34:20 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
done = false
|
|
|
|
entry = &DirEntry{
|
|
|
|
Name: name,
|
|
|
|
Mode: mode,
|
|
|
|
Size: size,
|
|
|
|
ModifiedAt: mtime,
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|