bytes.go 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. package bytes
  2. import (
  3. "fmt"
  4. "math"
  5. "strconv"
  6. )
  7. var (
  8. global = New()
  9. )
  10. type (
  11. Bytes struct {
  12. iec bool
  13. }
  14. )
  15. // New creates a Bytes instance.
  16. func New() *Bytes {
  17. return &Bytes{}
  18. }
  19. // SetBinaryPrefix sets binary prefix format.
  20. func (g *Bytes) SetBinaryPrefix(on bool) {
  21. g.iec = on
  22. }
  23. // Format formats bytes to string. For example, 1323 bytes will return 1.32 KB.
  24. // If binary prefix is set, it will return 1.29 KiB.
  25. func (g *Bytes) Format(b uint64) string {
  26. unit := uint64(1000)
  27. if g.iec {
  28. unit = 1024
  29. }
  30. if b < unit {
  31. return strconv.FormatUint(b, 10) + " B"
  32. }
  33. bb := float64(b)
  34. uunit := float64(unit)
  35. x := math.Floor(math.Log(bb) / math.Log(uunit))
  36. pre := make([]byte, 1, 2)
  37. pre[0] = "KMGTPE"[uint8(x)-1]
  38. if g.iec {
  39. pre = pre[:2]
  40. pre[1] = 'i'
  41. }
  42. // TODO: Improve performance?
  43. return fmt.Sprintf("%.02f %sB", bb/math.Pow(uunit, x), pre)
  44. }
  45. // BinaryPrefix wraps global Bytes's BinaryPrefix function.
  46. func BinaryPrefix(on bool) {
  47. global.SetBinaryPrefix(on)
  48. }
  49. // Format wraps global Bytes's Format function.
  50. func Format(b uint64) string {
  51. return global.Format(b)
  52. }