Skip to content

Commit

Permalink
Add serialize support for domain matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
nekohasekai committed Nov 29, 2023
1 parent 2dcabf4 commit eb56a60
Showing 1 changed file with 77 additions and 2 deletions.
79 changes: 77 additions & 2 deletions common/domain/matcher.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package domain

import (
"encoding/binary"
"github.com/sagernet/sing/common/rw"
"io"
"sort"
"unicode/utf8"
)
Expand All @@ -27,15 +30,87 @@ func NewMatcher(domains []string, domainSuffix []string) *Matcher {
domainList = append(domainList, reverseDomain(domain))
}
sort.Strings(domainList)
return &Matcher{
newSuccinctSet(domainList),
return &Matcher{newSuccinctSet(domainList)}
}

func ReadMatcher(reader io.Reader) (*Matcher, error) {
var version uint8
err := binary.Read(reader, binary.BigEndian, &version)
if err != nil {
return nil, err
}
leavesLength, err := rw.ReadUVariant(reader)
if err != nil {
return nil, err
}
leaves := make([]uint64, leavesLength)
err = binary.Read(reader, binary.BigEndian, leaves)
if err != nil {
return nil, err
}
labelBitmapLength, err := rw.ReadUVariant(reader)
if err != nil {
return nil, err
}
labelBitmap := make([]uint64, labelBitmapLength)
err = binary.Read(reader, binary.BigEndian, labelBitmap)
if err != nil {
return nil, err
}
labelsLength, err := rw.ReadUVariant(reader)
if err != nil {
return nil, err
}
labels := make([]byte, labelsLength)
_, err = io.ReadFull(reader, labels)
if err != nil {
return nil, err
}
set := &succinctSet{
leaves: leaves,
labelBitmap: labelBitmap,
labels: labels,
}
set.init()
return &Matcher{set}, nil
}

func (m *Matcher) Match(domain string) bool {
return m.set.Has(reverseDomain(domain))
}

func (m *Matcher) Write(writer io.Writer) error {
err := binary.Write(writer, binary.BigEndian, byte(1))
if err != nil {
return err
}
err = rw.WriteUVariant(writer, uint64(len(m.set.leaves)))
if err != nil {
return err
}
err = binary.Write(writer, binary.BigEndian, m.set.leaves)
if err != nil {
return err
}
err = rw.WriteUVariant(writer, uint64(len(m.set.labelBitmap)))
if err != nil {
return err
}
err = binary.Write(writer, binary.BigEndian, m.set.labelBitmap)
if err != nil {
return err
}
err = rw.WriteUVariant(writer, uint64(len(m.set.labels)))
if err != nil {
return err
}
_, err = writer.Write(m.set.labels)
if err != nil {
return err
}
return nil
}

func reverseDomain(domain string) string {
l := len(domain)
b := make([]byte, l)
Expand Down

0 comments on commit eb56a60

Please sign in to comment.