-
Notifications
You must be signed in to change notification settings - Fork 52
/
popularimeter_frame.go
68 lines (54 loc) · 1.54 KB
/
popularimeter_frame.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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package id3v2
import (
"io"
"math/big"
)
// PopularimeterFrame structure is used for Popularimeter (POPM).
// https://id3.org/id3v2.3.0#Popularimeter
type PopularimeterFrame struct {
// Email is the identifier for a POPM frame.
Email string
// The rating is 1-255 where 1 is worst and 255 is best. 0 is unknown.
Rating uint8
// Counter is the number of times this file has been played by this email.
Counter *big.Int
}
func (pf PopularimeterFrame) UniqueIdentifier() string {
return pf.Email
}
func (pf PopularimeterFrame) Size() int {
ratingSize := 1
return len(pf.Email) + 1 + ratingSize + len(pf.counterBytes())
}
// counterBytes returns a byte slice that represents the counter.
func (pf PopularimeterFrame) counterBytes() []byte {
bytes := pf.Counter.Bytes()
// Specification requires at least 4 bytes for counter, pad if necessary.
bytesNeeded := 4 - len(bytes)
if bytesNeeded > 0 {
padding := make([]byte, bytesNeeded)
bytes = append(padding, bytes...)
}
return bytes
}
func (pf PopularimeterFrame) WriteTo(w io.Writer) (n int64, err error) {
return useBufWriter(w, func(bw *bufWriter) {
bw.WriteString(pf.Email)
bw.WriteByte(0)
bw.WriteByte(pf.Rating)
bw.Write(pf.counterBytes())
})
}
func parsePopularimeterFrame(br *bufReader) (Framer, error) {
email := br.ReadText(EncodingISO)
rating := br.ReadByte()
counter := big.NewInt(0)
remainingBytes := br.ReadAll()
counter = counter.SetBytes(remainingBytes)
pf := PopularimeterFrame{
Email: string(email),
Rating: rating,
Counter: counter,
}
return pf, nil
}