package tag import ( "bytes" "smesh.lol/pkg/lol/chk" "smesh.lol/pkg/lol/log" ) type S []*T func NewS(t ...*T) *S { s := S(t) return &s } func NewSWithCap(c int) *S { ss := (make)(S, 0, c) return &ss } func (s *S) Len() int { if s == nil { return 0 } return len(*s) } func (s *S) Less(i, j int) bool { return bytes.Compare((*s)[i].T[0], (*s)[j].T[0]) < 0 } func (s *S) Swap(i, j int) { (*s)[i].T, (*s)[j].T = (*s)[j].T, (*s)[i].T } func (s *S) Append(t ...*T) { *s = append(*s, t...) } func (s *S) ContainsAny(tagName []byte, values [][]byte) bool { if s == nil || len(tagName) < 1 { return false } isBinaryTag := len(tagName) == 1 && (tagName[0] == 'e' || tagName[0] == 'p') for _, v := range *s { if v.Len() < 2 { continue } if !bytes.Equal(v.Key(), tagName) { continue } var tagValue []byte if isBinaryTag { tagValue = v.ValueHex() } else { tagValue = v.Value() } for _, candidate := range values { if bytes.HasPrefix(tagValue, candidate) { return true } } } return false } func (s *S) MarshalJSON() ([]byte, error) { b := []byte{'['} for i, ss := range *s { b = ss.Marshal(b) if i < len(*s)-1 { b = append(b, ',') } } b = append(b, ']') return b, nil } func (s *S) Marshal(dst []byte) (b []byte) { if s == nil { log.I.F([]byte("tags cannot be used without initialization")) return } b = dst b = append(b, '[') for i, ss := range *s { b = ss.Marshal(b) if i < len(*s)-1 { b = append(b, ',') } } b = append(b, ']') return } func (s *S) UnmarshalJSON(b []byte) error { _, err := s.Unmarshal(b) return err } func (s *S) Unmarshal(b []byte) (r []byte, err error) { r = b[:] *s = (make)(S, 0, 16) for len(r) > 0 { switch r[0] { case '[': r = r[1:] goto inTags case ',': r = r[1:] case ']': r = r[1:] return default: r = r[1:] } inTags: for len(r) > 0 { switch r[0] { case '[': tt := New() if r, err = tt.Unmarshal(r); chk.E(err) { return } *s = append(*s, tt) case ',': r = r[1:] case ']': r = r[1:] return default: r = r[1:] } } } return } func (s *S) GetFirst(t []byte) *T { if s == nil || len(*s) < 1 { return nil } for _, tt := range *s { if tt.Len() == 0 { continue } if bytes.Equal(tt.T[0], t) { return tt } } return nil } func (s *S) GetAll(t []byte) []*T { if s == nil || len(*s) < 1 { return nil } all := []*T{:0:4} for _, tt := range *s { if len(tt.T) < 1 { continue } if bytes.Equal(tt.T[0], t) { all = append(all, tt) } } return all } func (s *S) GetTagElement(i int) *T { if s == nil || len(*s) < i { return nil } return (*s)[i] }