| package pb |
| |
| import ( |
| "bytes" |
| "fmt" |
| "github.com/mattn/go-runewidth" |
| "math" |
| "regexp" |
| //"unicode/utf8" |
| ) |
| |
| const ( |
| _KiB = 1024 |
| _MiB = 1048576 |
| _GiB = 1073741824 |
| _TiB = 1099511627776 |
| |
| _kB = 1e3 |
| _MB = 1e6 |
| _GB = 1e9 |
| _TB = 1e12 |
| ) |
| |
| var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9;]+\x6d") |
| |
| func CellCount(s string) int { |
| n := runewidth.StringWidth(s) |
| for _, sm := range ctrlFinder.FindAllString(s, -1) { |
| n -= runewidth.StringWidth(sm) |
| } |
| return n |
| } |
| |
| func StripString(s string, w int) string { |
| l := CellCount(s) |
| if l <= w { |
| return s |
| } |
| var buf = bytes.NewBuffer(make([]byte, 0, len(s))) |
| StripStringToBuffer(s, w, buf) |
| return buf.String() |
| } |
| |
| func StripStringToBuffer(s string, w int, buf *bytes.Buffer) { |
| var seqs = ctrlFinder.FindAllStringIndex(s, -1) |
| var maxWidthReached bool |
| mainloop: |
| for i, r := range s { |
| for _, seq := range seqs { |
| if i >= seq[0] && i < seq[1] { |
| buf.WriteRune(r) |
| continue mainloop |
| } |
| } |
| if rw := CellCount(string(r)); rw <= w && !maxWidthReached { |
| w -= rw |
| buf.WriteRune(r) |
| } else { |
| maxWidthReached = true |
| } |
| } |
| for w > 0 { |
| buf.WriteByte(' ') |
| w-- |
| } |
| return |
| } |
| |
| func round(val float64) (newVal float64) { |
| roundOn := 0.5 |
| places := 0 |
| var round float64 |
| pow := math.Pow(10, float64(places)) |
| digit := pow * val |
| _, div := math.Modf(digit) |
| if div >= roundOn { |
| round = math.Ceil(digit) |
| } else { |
| round = math.Floor(digit) |
| } |
| newVal = round / pow |
| return |
| } |
| |
| // Convert bytes to human readable string. Like a 2 MiB, 64.2 KiB, or 2 MB, 64.2 kB |
| // if useSIPrefix is set to true |
| func formatBytes(i int64, useSIPrefix bool) (result string) { |
| if !useSIPrefix { |
| switch { |
| case i >= _TiB: |
| result = fmt.Sprintf("%.02f TiB", float64(i)/_TiB) |
| case i >= _GiB: |
| result = fmt.Sprintf("%.02f GiB", float64(i)/_GiB) |
| case i >= _MiB: |
| result = fmt.Sprintf("%.02f MiB", float64(i)/_MiB) |
| case i >= _KiB: |
| result = fmt.Sprintf("%.02f KiB", float64(i)/_KiB) |
| default: |
| result = fmt.Sprintf("%d B", i) |
| } |
| } else { |
| switch { |
| case i >= _TB: |
| result = fmt.Sprintf("%.02f TB", float64(i)/_TB) |
| case i >= _GB: |
| result = fmt.Sprintf("%.02f GB", float64(i)/_GB) |
| case i >= _MB: |
| result = fmt.Sprintf("%.02f MB", float64(i)/_MB) |
| case i >= _kB: |
| result = fmt.Sprintf("%.02f kB", float64(i)/_kB) |
| default: |
| result = fmt.Sprintf("%d B", i) |
| } |
| } |
| return |
| } |