mirror of
https://gitclone.com/github.com/MetaCubeX/Clash.Meta
synced 2024-11-14 05:11:17 +08:00
73 lines
1.4 KiB
Go
73 lines
1.4 KiB
Go
package provider
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
|
|
"github.com/klauspost/compress/zstd"
|
|
)
|
|
|
|
var MrsMagicBytes = [4]byte{'M', 'R', 'S', 1} // MRSv1
|
|
|
|
func rulesMrsParse(buf []byte, strategy ruleStrategy) (ruleStrategy, error) {
|
|
if _strategy, ok := strategy.(mrsRuleStrategy); ok {
|
|
reader, err := zstd.NewReader(bytes.NewReader(buf))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer reader.Close()
|
|
|
|
// header
|
|
var header [4]byte
|
|
_, err = io.ReadFull(reader, header[:])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if header != MrsMagicBytes {
|
|
return nil, fmt.Errorf("invalid MrsMagic bytes")
|
|
}
|
|
|
|
// behavior
|
|
var _behavior [1]byte
|
|
_, err = io.ReadFull(reader, _behavior[:])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if _behavior[0] != strategy.Behavior().Byte() {
|
|
return nil, fmt.Errorf("invalid behavior")
|
|
}
|
|
|
|
// count
|
|
var count int64
|
|
err = binary.Read(reader, binary.BigEndian, &count)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// extra (reserved for future using)
|
|
var length int64
|
|
err = binary.Read(reader, binary.BigEndian, &length)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if length < 0 {
|
|
return nil, errors.New("length is invalid")
|
|
}
|
|
if length > 0 {
|
|
extra := make([]byte, length)
|
|
_, err = io.ReadFull(reader, extra)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
err = _strategy.FromMrs(reader, int(count))
|
|
return strategy, err
|
|
} else {
|
|
return nil, ErrInvalidFormat
|
|
}
|
|
}
|