/* syncer -- stateful file/device data syncer. Copyright (C) 2015-2020 Sergey Matveev This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 3 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package main import ( "fmt" "strconv" ) const ( BufLine = 80 CharChanged = byte('%') CharUnchanged = byte('.') ) type Printer struct { i int64 total int64 changed int64 frmt string bufSize int outBuf []byte } func NewPrinter(total int64) *Printer { p := Printer{total: total} maxLen := len(fmt.Sprintf("%d", total)) p.frmt = "%" + strconv.Itoa(maxLen) + "d/%d %02d%% %s\n" p.bufSize = BufLine - (2*maxLen + 6) p.outBuf = make([]byte, 0, p.bufSize) return &p } func (p *Printer) Changed() { p.i++ p.changed++ p.outBuf = append(p.outBuf, CharChanged) p.Output() } func (p *Printer) Unchanged() { p.i++ p.outBuf = append(p.outBuf, CharUnchanged) p.Output() } func (p *Printer) Output() { if !(len(p.outBuf) == p.bufSize || p.i == p.total) { return } fmt.Printf(p.frmt, p.i, p.total, 100*p.changed/p.i, string(p.outBuf)) p.outBuf = p.outBuf[:0] }