2022-07-04 19:39:58 +08:00
|
|
|
package geosite
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2024-06-24 09:49:15 +08:00
|
|
|
"encoding/binary"
|
2022-07-04 19:39:58 +08:00
|
|
|
"sort"
|
|
|
|
|
2024-06-24 09:49:15 +08:00
|
|
|
"github.com/sagernet/sing/common/varbin"
|
2022-07-04 19:39:58 +08:00
|
|
|
)
|
|
|
|
|
2024-06-24 09:49:15 +08:00
|
|
|
func Write(writer varbin.Writer, domains map[string][]Item) error {
|
2022-07-04 19:39:58 +08:00
|
|
|
keys := make([]string, 0, len(domains))
|
|
|
|
for code := range domains {
|
|
|
|
keys = append(keys, code)
|
|
|
|
}
|
|
|
|
sort.Strings(keys)
|
|
|
|
|
|
|
|
content := &bytes.Buffer{}
|
|
|
|
index := make(map[string]int)
|
|
|
|
for _, code := range keys {
|
|
|
|
index[code] = content.Len()
|
2024-06-24 09:49:15 +08:00
|
|
|
err := varbin.Write(content, binary.BigEndian, domains[code])
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2022-07-04 19:39:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-24 09:49:15 +08:00
|
|
|
err := writer.WriteByte(0)
|
2022-07-04 19:39:58 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-06-24 09:49:15 +08:00
|
|
|
_, err = varbin.WriteUvarint(writer, uint64(len(keys)))
|
2022-07-04 19:39:58 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, code := range keys {
|
2024-06-24 09:49:15 +08:00
|
|
|
err = varbin.Write(writer, binary.BigEndian, code)
|
2022-07-04 19:39:58 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-06-24 09:49:15 +08:00
|
|
|
_, err = varbin.WriteUvarint(writer, uint64(index[code]))
|
2022-07-04 19:39:58 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-06-24 09:49:15 +08:00
|
|
|
_, err = varbin.WriteUvarint(writer, uint64(len(domains[code])))
|
2022-07-04 19:39:58 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = writer.Write(content.Bytes())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|