github.com/sagernet/sing-box@v1.9.0-rc.20/common/geosite/writer.go (about)

     1  package geosite
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"sort"
     7  
     8  	"github.com/sagernet/sing/common/rw"
     9  )
    10  
    11  func Write(writer io.Writer, domains map[string][]Item) error {
    12  	keys := make([]string, 0, len(domains))
    13  	for code := range domains {
    14  		keys = append(keys, code)
    15  	}
    16  	sort.Strings(keys)
    17  
    18  	content := &bytes.Buffer{}
    19  	index := make(map[string]int)
    20  	for _, code := range keys {
    21  		index[code] = content.Len()
    22  		for _, domain := range domains[code] {
    23  			content.WriteByte(domain.Type)
    24  			err := rw.WriteVString(content, domain.Value)
    25  			if err != nil {
    26  				return err
    27  			}
    28  		}
    29  	}
    30  
    31  	err := rw.WriteByte(writer, 0)
    32  	if err != nil {
    33  		return err
    34  	}
    35  
    36  	err = rw.WriteUVariant(writer, uint64(len(keys)))
    37  	if err != nil {
    38  		return err
    39  	}
    40  
    41  	for _, code := range keys {
    42  		err = rw.WriteVString(writer, code)
    43  		if err != nil {
    44  			return err
    45  		}
    46  		err = rw.WriteUVariant(writer, uint64(index[code]))
    47  		if err != nil {
    48  			return err
    49  		}
    50  		err = rw.WriteUVariant(writer, uint64(len(domains[code])))
    51  		if err != nil {
    52  			return err
    53  		}
    54  	}
    55  
    56  	_, err = writer.Write(content.Bytes())
    57  	if err != nil {
    58  		return err
    59  	}
    60  
    61  	return nil
    62  }