-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathbitrate.go
51 lines (46 loc) · 1.33 KB
/
bitrate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package irtt
import (
"encoding/json"
"fmt"
"time"
)
// Bitrate is a bit rate in bits per second.
type Bitrate uint64
func calculateBitrate(n uint64, d time.Duration) Bitrate {
if n == 0 || d == 0 {
return Bitrate(0)
}
return Bitrate(8 * float64(n) / d.Seconds())
}
// String returns a Bitrate string in appropriate units.
func (r Bitrate) String() string {
// Yes, it's exhaustive, just for fun. A 64-int unsigned int can't hold
// Yottabits per second as 1e21 overflows it. If this problem affects
// you, thanks for solving climate change!
if r < 1000 {
return fmt.Sprintf("%d bps", r)
} else if r < 1e6 {
return fmt.Sprintf("%.1f Kbps", float64(r)/float64(1000))
} else if r < 1e9 {
return fmt.Sprintf("%.2f Mbps", float64(r)/float64(1e6))
} else if r < 1e12 {
return fmt.Sprintf("%.3f Gbps", float64(r)/float64(1e9))
} else if r < 1e15 {
return fmt.Sprintf("%.3f Pbps", float64(r)/float64(1e12))
} else if r < 1e18 {
return fmt.Sprintf("%.3f Ebps", float64(r)/float64(1e15))
}
return fmt.Sprintf("%.3f Zbps", float64(r)/float64(1e18))
}
// MarshalJSON implements the json.Marshaler interface.
func (r Bitrate) MarshalJSON() ([]byte, error) {
type Alias DurationStats
j := &struct {
BPS uint64 `json:"bps"`
String string `json:"string"`
}{
BPS: uint64(r),
String: r.String(),
}
return json.Marshal(j)
}