]> Sergey Matveev's repositories - syncer.git/commitdiff
Pretty output printer
authorSergey Matveev <stargrave@stargrave.org>
Sun, 20 Dec 2015 15:50:41 +0000 (18:50 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sun, 20 Dec 2015 15:50:41 +0000 (18:50 +0300)
printer.go [new file with mode: 0644]
syncer.go

diff --git a/printer.go b/printer.go
new file mode 100644 (file)
index 0000000..0313d61
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+syncer -- stateful file/device data syncer.
+Copyright (C) 2015-2016 Sergey Matveev <stargrave@stargrave.org>
+
+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, either version 3 of the License, or
+(at your option) any later version.
+
+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 <http://www.gnu.org/licenses/>.
+*/
+
+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]
+}
index 3a9e68a23a3e1ca3233e4a604aed966fc8ad3ed6..dc48314e044c0dbc731c0dd1bc414b097d9b7d28 100644 (file)
--- a/syncer.go
+++ b/syncer.go
@@ -1,6 +1,6 @@
 /*
 syncer -- stateful file/device data syncer.
-Copyright (C) 2015 Sergey Matveev <stargrave@stargrave.org>
+Copyright (C) 2015-2016 Sergey Matveev <stargrave@stargrave.org>
 
 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
@@ -45,11 +45,6 @@ type SyncEvent struct {
        data []byte
 }
 
-func prn(s string) {
-       os.Stdout.Write([]byte(s))
-       os.Stdout.Sync()
-}
-
 func main() {
        flag.Parse()
        bs := *blkSize * int64(1<<10)
@@ -155,7 +150,7 @@ func main() {
        syncs := make(chan chan SyncEvent, workers)
 
        // Writer
-       prn("[")
+       prn := NewPrinter(blocks)
        finished := make(chan struct{})
        go func() {
                var event SyncEvent
@@ -188,10 +183,10 @@ func main() {
                        sumState := state[i*blake2b.Size : i*blake2b.Size+blake2b.Size]
                        if bytes.Compare(sumState, sum[:]) != 0 {
                                sync <- SyncEvent{i, buf, buf[:n]}
-                               prn("%")
+                               prn.Changed()
                        } else {
                                sync <- SyncEvent{i, buf, nil}
-                               prn(".")
+                               prn.Unchanged()
                        }
                        copy(sumState, sum[:])
                        close(sync)
@@ -199,7 +194,7 @@ func main() {
        }
        close(syncs)
        <-finished
-       prn("]\n")
+       prn.Output()
 
        log.Println("Saving state")
        stateFile.Write(state)