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 80 81 82 83 84 85 86 87 88 89 90
|
package parsers
import (
"bytes"
"strconv"
"strings"
"unsafe"
"github.com/brentp/irelate/interfaces"
)
const empty = ""
// Interval satisfies the Relatable interface.
type Interval struct {
// chrom, start, end, line, source, related[]
chrom string
start uint32
end uint32
source uint32
Fields [][]byte
related []interfaces.Relatable
}
func NewInterval(chrom string, start uint32, end uint32, fields [][]byte, source uint32, related []interfaces.Relatable) *Interval {
return &Interval{chrom: chrom, start: start, end: end, Fields: fields, source: source, related: related}
}
func (i *Interval) Chrom() string { return i.chrom }
func (i *Interval) Start() uint32 { return i.start }
func (i *Interval) End() uint32 { return i.end }
func (i *Interval) Related() []interfaces.Relatable { return i.related }
func (i *Interval) AddRelated(b interfaces.Relatable) {
i.related = append(i.related, b)
}
func (i *Interval) Source() uint32 { return i.source }
func (i *Interval) SetSource(src uint32) { i.source = src }
func (i *Interval) String() string {
return string(bytes.Join(i.Fields, []byte{'\t'}))
}
func unsafeString(b []byte) string {
return *(*string)(unsafe.Pointer(&b))
}
func IntervalFromBedLine(line []byte) (interfaces.Relatable, error) {
line = bytes.TrimRight(line, "\r\n")
fields := bytes.Split([]byte(string(line)), []byte{'\t'})
start, err := strconv.ParseUint(unsafeString(fields[1]), 10, 32)
if err != nil {
return nil, err
}
end, err := strconv.ParseUint(unsafeString(fields[2]), 10, 32)
if err != nil {
return nil, err
}
i := Interval{chrom: string(fields[0]), start: uint32(start), end: uint32(end), related: nil, Fields: fields}
return &i, nil
}
type RefAltInterval struct {
Interval
refalt [2]int
HasEnd bool
}
func (i *RefAltInterval) SetRefAlt(ra []int) {
i.refalt[0] = ra[0]
i.refalt[1] = ra[1]
}
func (i *RefAltInterval) Ref() string {
return string(i.Fields[i.refalt[0]])
}
func (i *RefAltInterval) Alt() []string {
f := string(i.Fields[i.refalt[1]])
return strings.Split(f, ",")
}
func (i *RefAltInterval) End() uint32 {
if i.HasEnd {
return i.Interval.End()
}
return i.Start() + uint32(len(i.Ref()))
}
var _ interfaces.IRefAlt = (*RefAltInterval)(nil)
|