-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathvorbis.go
109 lines (98 loc) · 2.5 KB
/
vorbis.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package flacvorbis
import (
"bytes"
"strings"
flac "github.com/go-flac/go-flac"
)
type MetaDataBlockVorbisComment struct {
Vendor string
Comments []string
}
// New creates a new MetaDataBlockVorbisComment
// vendor is set to flacvorbis <version> by default
func New() *MetaDataBlockVorbisComment {
return &MetaDataBlockVorbisComment{
"flacvorbis " + APP_VERSION,
[]string{},
}
}
// Get get all comments with field name specified by the key parameter
// If there is no match, error would still be nil
func (c *MetaDataBlockVorbisComment) Get(key string) ([]string, error) {
res := make([]string, 0)
for _, cmt := range c.Comments {
p := strings.SplitN(cmt, "=", 2)
if len(p) != 2 {
return nil, ErrorMalformedComment
}
if strings.EqualFold(p[0], key) {
res = append(res, p[1])
}
}
return res, nil
}
// Add adds a key-val pair to the comments
func (c *MetaDataBlockVorbisComment) Add(key string, val string) error {
for _, char := range key {
if char < 0x20 || char > 0x7d || char == '=' {
return ErrorInvalidFieldName
}
}
c.Comments = append(c.Comments, key+"="+val)
return nil
}
// Marshal marshals this block back into a flac.MetaDataBlock
func (c MetaDataBlockVorbisComment) Marshal() flac.MetaDataBlock {
data := bytes.NewBuffer([]byte{})
packStr(data, c.Vendor)
data.Write(encodeUint32(uint32(len(c.Comments))))
for _, cmt := range c.Comments {
packStr(data, cmt)
}
return flac.MetaDataBlock{
Type: flac.VorbisComment,
Data: data.Bytes(),
}
}
// ParseFromMetaDataBlock parses an existing picture MetaDataBlock
func ParseFromMetaDataBlock(meta flac.MetaDataBlock) (*MetaDataBlockVorbisComment, error) {
if meta.Type != flac.VorbisComment {
return nil, ErrorNotVorbisComment
}
reader := bytes.NewReader(meta.Data)
res := new(MetaDataBlockVorbisComment)
vendorlen, err := readUint32(reader)
if err != nil {
return nil, err
}
vendorbytes := make([]byte, vendorlen)
nn, err := reader.Read(vendorbytes)
if err != nil {
return nil, err
}
if nn != int(vendorlen) {
return nil, ErrorUnexpEof
}
res.Vendor = string(vendorbytes)
cmtcount, err := readUint32(reader)
if err != nil {
return nil, err
}
res.Comments = make([]string, cmtcount)
for i := range res.Comments {
cmtlen, err := readUint32(reader)
if err != nil {
return nil, err
}
cmtbytes := make([]byte, cmtlen)
nn, err := reader.Read(cmtbytes)
if err != nil {
return nil, err
}
if nn != int(cmtlen) {
return nil, ErrorUnexpEof
}
res.Comments[i] = string(cmtbytes)
}
return res, nil
}