github.com/xuyutom/docker@v1.6.0/pkg/progressreader/progressreader.go (about)

     1  package progressreader
     2  
     3  import (
     4  	"io"
     5  )
     6  
     7  type StreamFormatter interface {
     8  	FormatProg(string, string, interface{}) []byte
     9  	FormatStatus(string, string, ...interface{}) []byte
    10  	FormatError(error) []byte
    11  }
    12  
    13  type PR_JSONProgress interface {
    14  	GetCurrent() int
    15  	GetTotal() int
    16  }
    17  
    18  type JSONProg struct {
    19  	Current int
    20  	Total   int
    21  }
    22  
    23  func (j *JSONProg) GetCurrent() int {
    24  	return j.Current
    25  }
    26  func (j *JSONProg) GetTotal() int {
    27  	return j.Total
    28  }
    29  
    30  // Reader with progress bar
    31  type Config struct {
    32  	In         io.ReadCloser // Stream to read from
    33  	Out        io.Writer     // Where to send progress bar to
    34  	Formatter  StreamFormatter
    35  	Size       int
    36  	Current    int
    37  	LastUpdate int
    38  	NewLines   bool
    39  	ID         string
    40  	Action     string
    41  }
    42  
    43  func New(newReader Config) *Config {
    44  	return &newReader
    45  }
    46  func (config *Config) Read(p []byte) (n int, err error) {
    47  	read, err := config.In.Read(p)
    48  	config.Current += read
    49  	updateEvery := 1024 * 512 //512kB
    50  	if config.Size > 0 {
    51  		// Update progress for every 1% read if 1% < 512kB
    52  		if increment := int(0.01 * float64(config.Size)); increment < updateEvery {
    53  			updateEvery = increment
    54  		}
    55  	}
    56  	if config.Current-config.LastUpdate > updateEvery || err != nil {
    57  		config.Out.Write(config.Formatter.FormatProg(config.ID, config.Action, &JSONProg{Current: config.Current, Total: config.Size}))
    58  		config.LastUpdate = config.Current
    59  	}
    60  	// Send newline when complete
    61  	if config.NewLines && err != nil && read == 0 {
    62  		config.Out.Write(config.Formatter.FormatStatus("", ""))
    63  	}
    64  	return read, err
    65  }
    66  func (config *Config) Close() error {
    67  	config.Current = config.Size
    68  	config.Out.Write(config.Formatter.FormatProg(config.ID, config.Action, &JSONProg{Current: config.Current, Total: config.Size}))
    69  	return config.In.Close()
    70  }