| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- 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
- }
|