Add geosite
This commit is contained in:
@@ -1,19 +1,32 @@
|
||||
package domain
|
||||
|
||||
import "unicode/utf8"
|
||||
import (
|
||||
"sort"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type Matcher struct {
|
||||
set *succinctSet
|
||||
}
|
||||
|
||||
func NewMatcher(domains []string, domainSuffix []string) *Matcher {
|
||||
var domainList []string
|
||||
for _, domain := range domains {
|
||||
domainList = append(domainList, reverseDomain(domain))
|
||||
}
|
||||
domainList := make([]string, 0, len(domains)+len(domainSuffix))
|
||||
seen := make(map[string]bool, len(domainList))
|
||||
for _, domain := range domainSuffix {
|
||||
if seen[domain] {
|
||||
continue
|
||||
}
|
||||
seen[domain] = true
|
||||
domainList = append(domainList, reverseDomainSuffix(domain))
|
||||
}
|
||||
for _, domain := range domains {
|
||||
if seen[domain] {
|
||||
continue
|
||||
}
|
||||
seen[domain] = true
|
||||
domainList = append(domainList, reverseDomain(domain))
|
||||
}
|
||||
sort.Strings(domainList)
|
||||
return &Matcher{
|
||||
newSuccinctSet(domainList),
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ func newSuccinctSet(keys []string) *succinctSet {
|
||||
setBit(&ss.labelBitmap, lIdx, 0)
|
||||
lIdx++
|
||||
}
|
||||
|
||||
setBit(&ss.labelBitmap, lIdx, 1)
|
||||
lIdx++
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package geosite
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
"os"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/rw"
|
||||
@@ -10,12 +10,26 @@ import (
|
||||
|
||||
type Reader struct {
|
||||
reader io.ReadSeeker
|
||||
access sync.Mutex
|
||||
metadataRead bool
|
||||
domainIndex map[string]int
|
||||
domainLength map[string]int
|
||||
}
|
||||
|
||||
func Open(path string) (*Reader, error) {
|
||||
content, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
reader := &Reader{
|
||||
reader: content,
|
||||
}
|
||||
err = reader.readMetadata()
|
||||
if err != nil {
|
||||
content.Close()
|
||||
return nil, err
|
||||
}
|
||||
return reader, nil
|
||||
}
|
||||
|
||||
func (r *Reader) readMetadata() error {
|
||||
version, err := rw.ReadByte(r.reader)
|
||||
if err != nil {
|
||||
@@ -55,19 +69,10 @@ func (r *Reader) readMetadata() error {
|
||||
}
|
||||
r.domainIndex = domainIndex
|
||||
r.domainLength = domainLength
|
||||
r.metadataRead = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Reader) Read(code string) ([]Item, error) {
|
||||
r.access.Lock()
|
||||
defer r.access.Unlock()
|
||||
if !r.metadataRead {
|
||||
err := r.readMetadata()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if _, exists := r.domainIndex[code]; !exists {
|
||||
return nil, E.New("code ", code, " not exists!")
|
||||
}
|
||||
|
||||
@@ -60,3 +60,44 @@ func Compile(code []Item) option.DefaultRule {
|
||||
}
|
||||
return codeRule
|
||||
}
|
||||
|
||||
func Merge(rules []option.DefaultRule) option.DefaultRule {
|
||||
var domainLength int
|
||||
var domainSuffixLength int
|
||||
var domainKeywordLength int
|
||||
var domainRegexLength int
|
||||
for _, subRule := range rules {
|
||||
domainLength += len(subRule.Domain)
|
||||
domainSuffixLength += len(subRule.DomainSuffix)
|
||||
domainKeywordLength += len(subRule.DomainKeyword)
|
||||
domainRegexLength += len(subRule.DomainRegex)
|
||||
}
|
||||
var rule option.DefaultRule
|
||||
if domainLength > 0 {
|
||||
rule.Domain = make([]string, 0, domainLength)
|
||||
}
|
||||
if domainSuffixLength > 0 {
|
||||
rule.DomainSuffix = make([]string, 0, domainSuffixLength)
|
||||
}
|
||||
if domainKeywordLength > 0 {
|
||||
rule.DomainKeyword = make([]string, 0, domainKeywordLength)
|
||||
}
|
||||
if domainRegexLength > 0 {
|
||||
rule.DomainRegex = make([]string, 0, domainRegexLength)
|
||||
}
|
||||
for _, subRule := range rules {
|
||||
if len(subRule.Domain) > 0 {
|
||||
rule.Domain = append(rule.Domain, subRule.Domain...)
|
||||
}
|
||||
if len(subRule.DomainSuffix) > 0 {
|
||||
rule.DomainSuffix = append(rule.DomainSuffix, subRule.DomainSuffix...)
|
||||
}
|
||||
if len(subRule.DomainKeyword) > 0 {
|
||||
rule.DomainKeyword = append(rule.DomainKeyword, subRule.DomainKeyword...)
|
||||
}
|
||||
if len(subRule.DomainRegex) > 0 {
|
||||
rule.DomainRegex = append(rule.DomainRegex, subRule.DomainRegex...)
|
||||
}
|
||||
}
|
||||
return rule
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user