10 const tagmapKeySize = 24
12 type tagmapKey [tagmapKeySize]byte
17 id tagID // 0-based position in input tagset
21 type tagLibrary struct {
22 tagmap map[tagmapKey]tagInfo
26 func (taglib *tagLibrary) Load(rdr io.Reader) error {
28 scanner := bufio.NewScanner(rdr)
30 data := scanner.Bytes()
31 if len(data) > 0 && data[0] == '>' {
33 seqs = append(seqs, append([]byte(nil), data...))
36 if err := scanner.Err(); err != nil {
39 return taglib.setTags(seqs)
42 func (taglib *tagLibrary) FindAll(buf []byte, fn func(id tagID, pos, taglen int)) {
44 for i := 0; i <= len(buf)-taglib.keylen; i++ {
45 copy(key[:taglib.keylen], buf[i:])
46 if taginfo, ok := taglib.tagmap[key]; !ok {
48 } else if len(taginfo.tagseq) > taglib.keylen && (len(buf) < i+len(taginfo.tagseq) || !bytes.Equal(taginfo.tagseq, buf[i:i+len(taginfo.tagseq)])) {
49 // key portion matches, but not the entire tag
52 fn(taginfo.id, i, len(taginfo.tagseq))
53 i += len(taginfo.tagseq) - 1 // don't try to match overlapping tags
58 func (taglib *tagLibrary) Len() int {
59 return len(taglib.tagmap)
62 func (taglib *tagLibrary) setTags(tags [][]byte) error {
63 taglib.keylen = tagmapKeySize
64 for _, t := range tags {
65 if l := len(t); taglib.keylen > l {
69 taglib.tagmap = map[tagmapKey]tagInfo{}
70 for i, t := range tags {
73 copy(key[:], t[:taglib.keylen])
74 if _, ok := taglib.tagmap[key]; ok {
75 return fmt.Errorf("first %d bytes of tag %d (%s) are not unique", taglib.keylen, i, key)
77 taglib.tagmap[key] = tagInfo{tagID(i), t}