69 lines
1.3 KiB
Go
69 lines
1.3 KiB
Go
package streams
|
|
|
|
import (
|
|
"io"
|
|
)
|
|
|
|
type MetadataInjector struct {
|
|
io.Writer
|
|
offset int
|
|
MetadataInterval int
|
|
metadata Metadata
|
|
}
|
|
|
|
func NewMetadataInjector(w io.Writer, metadataInterval int) *MetadataInjector {
|
|
return &MetadataInjector{
|
|
Writer: w,
|
|
MetadataInterval: metadataInterval,
|
|
}
|
|
}
|
|
|
|
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)
|
|
|
|
if len(mi.metadata) > 0 {
|
|
mi.metadata = Metadata{}
|
|
}
|
|
|
|
return mi.Writer.Write(metadataBuf)
|
|
}
|
|
|
|
func (mi *MetadataInjector) Write(data []byte) (n int, err error) {
|
|
for n < len(data) {
|
|
restLen := len(data) - n
|
|
toWrite := mi.MetadataInterval - mi.offset
|
|
if toWrite > restLen {
|
|
toWrite = restLen
|
|
}
|
|
|
|
if toWrite <= 0 {
|
|
_, err = mi.writeMetadata()
|
|
if err != nil {
|
|
return
|
|
}
|
|
mi.offset = 0
|
|
continue
|
|
}
|
|
|
|
outBytes := make([]byte, toWrite)
|
|
copy(outBytes, data[n:n+toWrite])
|
|
cn, cerr := mi.Writer.Write(outBytes)
|
|
n += cn
|
|
mi.offset += cn
|
|
if cerr != nil {
|
|
err = cerr
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|