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 }