// Write writes r to the BAM stream. func (bw *Writer) Write(r *sam.Record) error { if len(r.Name) == 0 || len(r.Name) > 254 { return errors.New("bam: name absent or too long") } if r.Qual != nil && len(r.Qual) != r.Seq.Length { return errors.New("bam: sequence/quality length mismatch") } tags := buildAux(r.AuxFields) recLen := bamFixedRemainder + len(r.Name) + 1 + // Null terminated. len(r.Cigar)<<2 + // CigarOps are 4 bytes. len(r.Seq.Seq) + len(r.Qual) + len(tags) bw.buf.Reset() wb := errWriter{w: &bw.buf} bin := binaryWriter{w: &wb} // Write record header data. bin.writeInt32(int32(recLen)) bin.writeInt32(int32(r.Ref.ID())) bin.writeInt32(int32(r.Pos)) bin.writeUint8(byte(len(r.Name) + 1)) bin.writeUint8(r.MapQ) bin.writeUint16(uint16(r.Bin())) //r.bin bin.writeUint16(uint16(len(r.Cigar))) bin.writeUint16(uint16(r.Flags)) bin.writeInt32(int32(r.Seq.Length)) bin.writeInt32(int32(r.MateRef.ID())) bin.writeInt32(int32(r.MatePos)) bin.writeInt32(int32(r.TempLen)) // Write variable length data. wb.Write(append([]byte(r.Name), 0)) writeCigarOps(&bin, r.Cigar) wb.Write(doublets(r.Seq.Seq).Bytes()) if r.Qual != nil { wb.Write(r.Qual) } else { for i := 0; i < r.Seq.Length; i++ { wb.WriteByte(0xff) } } wb.Write(tags) if wb.err != nil { return wb.err } _, err := bw.bg.Write(bw.buf.Bytes()) return err }
// Add records the SAM record as having being located at the given chunk. func (i *Index) Add(r *sam.Record, c bgzf.Chunk) error { return i.idx.Add(r, uint32(r.Bin()), c, isPlaced(r), isMapped(r)) }