-
Notifications
You must be signed in to change notification settings - Fork 5
/
reader.go
79 lines (60 loc) · 1.2 KB
/
reader.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
package riff
import (
"errors"
"io"
)
type RIFFReader interface {
io.Reader
io.ReaderAt
}
type Reader struct {
RIFFReader
}
type RIFFChunk struct {
FileSize uint32
FileType []byte
Chunks []*Chunk
}
type Chunk struct {
ChunkID []byte
ChunkSize uint32
RIFFReader
}
func NewReader(r RIFFReader) *Reader {
return &Reader{r}
}
func (r *Reader) Read() (chunk *RIFFChunk, err error) {
chunk, err = readRIFFChunk(r)
return
}
func readRIFFChunk(r *Reader) (chunk *RIFFChunk, err error) {
bytes := newByteReader(r)
if err != nil {
err = errors.New("Can't read RIFF file")
return
}
chunkId := bytes.readBytes(4)
if string(chunkId[:]) != "RIFF" {
err = errors.New("Given bytes is not a RIFF format")
return
}
fileSize := bytes.readLEUint32()
fileType := bytes.readBytes(4)
chunk = &RIFFChunk{fileSize, fileType, make([]*Chunk, 0)}
for bytes.offset < fileSize {
chunkId = bytes.readBytes(4)
chunkSize := bytes.readLEUint32()
offset := bytes.offset
if chunkSize%2 == 1 {
chunkSize += 1
}
bytes.offset += chunkSize
chunk.Chunks = append(
chunk.Chunks,
&Chunk{
chunkId,
chunkSize,
io.NewSectionReader(r, int64(offset), int64(chunkSize))})
}
return
}