goadb/wire/sync_scanner.go

93 lines
2.5 KiB
Go
Raw Normal View History

package wire
import (
"encoding/binary"
"io"
"os"
"time"
2015-07-12 06:18:58 +00:00
"github.com/zach-klippenstein/goadb/util"
)
type SyncScanner interface {
io.Closer
StatusReader
ReadInt32() (int32, error)
ReadFileMode() (os.FileMode, error)
ReadTime() (time.Time, error)
// Reads an octet length, followed by length bytes.
ReadString() (string, error)
// Reads an octet length, and returns a reader that will read length
// bytes (see io.LimitReader). The returned reader should be fully
// read before reading anything off the Scanner again.
ReadBytes() (io.Reader, error)
}
type realSyncScanner struct {
io.Reader
}
func NewSyncScanner(r io.Reader) SyncScanner {
return &realSyncScanner{r}
}
func (s *realSyncScanner) ReadStatus(req string) (string, error) {
return readStatusFailureAsError(s.Reader, req, readInt32)
}
func (s *realSyncScanner) ReadInt32() (int32, error) {
value, err := readInt32(s.Reader)
return int32(value), util.WrapErrorf(err, util.NetworkError, "error reading int from sync scanner")
}
2015-07-12 06:18:58 +00:00
func (s *realSyncScanner) ReadFileMode() (os.FileMode, error) {
var value uint32
2015-07-12 06:18:58 +00:00
err := binary.Read(s.Reader, binary.LittleEndian, &value)
if err != nil {
return 0, util.WrapErrorf(err, util.NetworkError, "error reading filemode from sync scanner")
}
2015-07-12 06:18:58 +00:00
return ParseFileModeFromAdb(value), nil
}
func (s *realSyncScanner) ReadTime() (time.Time, error) {
seconds, err := s.ReadInt32()
if err != nil {
2015-07-12 06:18:58 +00:00
return time.Time{}, util.WrapErrorf(err, util.NetworkError, "error reading time from sync scanner")
}
return time.Unix(int64(seconds), 0).UTC(), nil
}
func (s *realSyncScanner) ReadString() (string, error) {
length, err := s.ReadInt32()
if err != nil {
2015-07-12 06:18:58 +00:00
return "", util.WrapErrorf(err, util.NetworkError, "error reading length from sync scanner")
}
bytes := make([]byte, length)
2015-07-12 06:18:58 +00:00
n, rawErr := io.ReadFull(s.Reader, bytes)
if rawErr != nil && rawErr != io.ErrUnexpectedEOF {
return "", util.WrapErrorf(rawErr, util.NetworkError, "error reading string from sync scanner")
} else if rawErr == io.ErrUnexpectedEOF {
return "", errIncompleteMessage("bytes", n, int(length))
}
return string(bytes), nil
}
func (s *realSyncScanner) ReadBytes() (io.Reader, error) {
length, err := s.ReadInt32()
if err != nil {
2015-07-12 06:18:58 +00:00
return nil, util.WrapErrorf(err, util.NetworkError, "error reading bytes from sync scanner")
}
return io.LimitReader(s.Reader, int64(length)), nil
}
func (s *realSyncScanner) Close() error {
if closer, ok := s.Reader.(io.Closer); ok {
2015-07-12 06:18:58 +00:00
return util.WrapErrorf(closer.Close(), util.NetworkError, "error closing sync scanner")
}
return nil
}