Skip to content

Commit

Permalink
add optional DownloadCallback when calling ToFile
Browse files Browse the repository at this point in the history
  • Loading branch information
imroc committed Jun 7, 2017
1 parent e6d3257 commit 040f08e
Showing 1 changed file with 39 additions and 2 deletions.
41 changes: 39 additions & 2 deletions resp.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ func (r *Resp) ToXML(v interface{}) error {
return xml.Unmarshal(data, v)
}

// ToFile download the response body to file
func (r *Resp) ToFile(name string) error {
// ToFile download the response body to file with optional download callback
func (r *Resp) ToFile(name string, callback ...DownloadCallback) error {
file, err := os.Create(name)
if err != nil {
return err
Expand All @@ -110,10 +110,42 @@ func (r *Resp) ToFile(name string) error {
return err
}

if len(callback) > 0 && r.resp.ContentLength > 0 {
return r.download(file, r.resp.ContentLength, callback...)
}

_, err = io.Copy(file, r.resp.Body)
return err
}

func (r *Resp) download(file *os.File, totalLength int64, callback ...DownloadCallback) error {
p := make([]byte, 1024)
b := r.resp.Body
var currentLength int64
for {
l, err := b.Read(p)
if l > 0 {
_, _err := file.Write(p[:l])
if _err != nil {
return _err
}
currentLength += int64(l)
for _, cb := range callback {
cb.OnProgress(currentLength, totalLength)
}
}
if err != nil {
if err == io.EOF {
for _, cb := range callback {
cb.OnComplete(file)
}
return nil
}
return err
}
}
}

var regNewline = regexp.MustCompile(`\n|\r`)

func (r *Resp) autoFormat(s fmt.State) {
Expand Down Expand Up @@ -177,5 +209,10 @@ func (r *Resp) Format(s fmt.State, verb rune) {
} else { // auto
r.autoFormat(s)
}
}

// DownloadCallback is the callback when downloading
type DownloadCallback interface {
OnComplete(file *os.File)
OnProgress(currentLength int64, totalLength int64)
}

0 comments on commit 040f08e

Please sign in to comment.