uplink/app/streams/metadata_injector.go

69 lines
1.3 KiB
Go
Raw Normal View History

2018-04-10 14:34:30 +00:00
package streams
2018-04-10 11:48:51 +00:00
import (
"io"
)
type MetadataInjector struct {
2018-04-11 12:33:55 +00:00
io.Writer
offset int
2018-04-10 11:48:51 +00:00
MetadataInterval int
2018-04-11 12:33:55 +00:00
metadata Metadata
2018-04-10 11:48:51 +00:00
}
2018-04-11 12:33:55 +00:00
func NewMetadataInjector(w io.Writer, metadataInterval int) *MetadataInjector {
2018-04-10 11:48:51 +00:00
return &MetadataInjector{
2018-04-11 12:33:55 +00:00
Writer: w,
2018-04-10 11:48:51 +00:00
MetadataInterval: metadataInterval,
}
}
2018-04-11 12:33:55 +00:00
func (mi *MetadataInjector) SetMetadata(metadata Metadata) {
mi.metadata = metadata
}
func (mi *MetadataInjector) writeMetadata() (n int, err error) {
// the metadata generated here will be read on the next Read call
metadataBytes := mi.metadata.Bytes()
lenByte := (len(metadataBytes) + 15) / 16
metadataBuf := make([]byte, int(lenByte)*16+1)
metadataBuf[0] = byte(lenByte)
copy(metadataBuf[1:], metadataBytes)
2018-04-10 11:48:51 +00:00
2018-04-11 12:33:55 +00:00
if len(mi.metadata) > 0 {
mi.metadata = Metadata{}
2018-04-10 11:48:51 +00:00
}
2018-04-11 12:33:55 +00:00
return mi.Writer.Write(metadataBuf)
}
func (mi *MetadataInjector) Write(data []byte) (n int, err error) {
for n < len(data) {
2018-07-02 06:09:47 +00:00
restLen := len(data) - n
2018-04-11 12:33:55 +00:00
toWrite := mi.MetadataInterval - mi.offset
2018-07-02 06:09:47 +00:00
if toWrite > restLen {
toWrite = restLen
}
2018-04-11 12:33:55 +00:00
if toWrite <= 0 {
2018-07-02 06:09:47 +00:00
_, err = mi.writeMetadata()
if err != nil {
2018-04-11 12:33:55 +00:00
return
}
mi.offset = 0
continue
}
outBytes := make([]byte, toWrite)
2018-07-02 06:09:47 +00:00
copy(outBytes, data[n:n+toWrite])
2018-04-11 12:33:55 +00:00
cn, cerr := mi.Writer.Write(outBytes)
n += cn
mi.offset += cn
if cerr != nil {
err = cerr
2018-04-10 11:48:51 +00:00
return
}
}
return
}