func (r *Reader) commentMetaline(line []byte) (f feat.Feature, err error) { fields := bytes.Split(line, []byte{' '}) if len(fields) < 1 { return nil, &csv.ParseError{Line: r.line, Err: ErrEmptyMetaLine} } switch unsafeString(fields[0]) { case "gff-version": v := mustAtoi(fields, 1, r.line) if v > Version { return nil, &csv.ParseError{Line: r.line, Err: ErrNotHandled} } r.Version = Version return r.Read() case "source-version": if len(fields) <= 1 { return nil, &csv.ParseError{Line: r.line, Err: ErrBadMetaLine} } r.SourceVersion = string(bytes.Join(fields[1:], []byte{' '})) return r.Read() case "date": if len(fields) <= 1 { return nil, &csv.ParseError{Line: r.line, Err: ErrBadMetaLine} } if len(r.TimeFormat) > 0 { r.Date, err = time.Parse(r.TimeFormat, unsafeString(bytes.Join(fields[1:], []byte{' '}))) if err != nil { return nil, err } } return r.Read() case "Type", "type": if len(fields) <= 1 { return nil, &csv.ParseError{Line: r.line, Err: ErrBadMetaLine} } r.Type = feat.ParseMoltype(unsafeString(fields[1])) if len(fields) > 2 { r.Name = string(fields[2]) } return r.Read() case "sequence-region": if len(fields) <= 3 { return nil, &csv.ParseError{Line: r.line, Err: ErrBadMetaLine} } return &Region{ Sequence: Sequence{SeqName: string(fields[1]), Type: r.Type}, RegionStart: feat.OneToZero(mustAtoi(fields, 2, r.line)), RegionEnd: mustAtoi(fields, 3, r.line), }, nil case "DNA", "RNA", "Protein", "dna", "rna", "protein": if len(fields) <= 1 { return nil, &csv.ParseError{Line: r.line, Err: ErrBadMetaLine} } return r.metaSeq(fields[0], fields[1]) default: return nil, &csv.ParseError{Line: r.line, Err: ErrNotHandled} } }
func (r *Reader) metaSeq(moltype, id []byte) (seq.Sequence, error) { var line, body []byte var err error for { line, err = r.r.ReadBytes('\n') if err != nil { if err == io.EOF { return nil, err } return nil, &csv.ParseError{Line: r.line, Err: err} } r.line++ line = bytes.TrimSpace(line) if len(line) == 0 { continue } if len(line) < 2 || !bytes.HasPrefix(line, []byte("##")) { return nil, &csv.ParseError{Line: r.line, Err: ErrBadSequence} } line = bytes.TrimSpace(line[2:]) if unsafeString(line) == "end-"+unsafeString(moltype) { break } else { line = bytes.Join(bytes.Fields(line), nil) body = append(body, line...) } } var alpha alphabet.Alphabet switch feat.ParseMoltype(unsafeString(moltype)) { case feat.DNA: alpha = alphabet.DNA case feat.RNA: alpha = alphabet.RNA case feat.Protein: alpha = alphabet.Protein default: return nil, ErrBadMoltype } s := linear.NewSeq(string(id), alphabet.BytesToLetters(body), alpha) return s, err }