mrs_reader.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package provider
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "fmt"
  7. "io"
  8. "github.com/klauspost/compress/zstd"
  9. )
  10. var MrsMagicBytes = [4]byte{'M', 'R', 'S', 1} // MRSv1
  11. func rulesMrsParse(buf []byte, strategy ruleStrategy) (ruleStrategy, error) {
  12. if _strategy, ok := strategy.(mrsRuleStrategy); ok {
  13. reader, err := zstd.NewReader(bytes.NewReader(buf))
  14. if err != nil {
  15. return nil, err
  16. }
  17. defer reader.Close()
  18. // header
  19. var header [4]byte
  20. _, err = io.ReadFull(reader, header[:])
  21. if err != nil {
  22. return nil, err
  23. }
  24. if header != MrsMagicBytes {
  25. return nil, fmt.Errorf("invalid MrsMagic bytes")
  26. }
  27. // behavior
  28. var _behavior [1]byte
  29. _, err = io.ReadFull(reader, _behavior[:])
  30. if err != nil {
  31. return nil, err
  32. }
  33. if _behavior[0] != strategy.Behavior().Byte() {
  34. return nil, fmt.Errorf("invalid behavior")
  35. }
  36. // count
  37. var count int64
  38. err = binary.Read(reader, binary.BigEndian, &count)
  39. if err != nil {
  40. return nil, err
  41. }
  42. // extra (reserved for future using)
  43. var length int64
  44. err = binary.Read(reader, binary.BigEndian, &length)
  45. if err != nil {
  46. return nil, err
  47. }
  48. if length < 0 {
  49. return nil, errors.New("length is invalid")
  50. }
  51. if length > 0 {
  52. extra := make([]byte, length)
  53. _, err = io.ReadFull(reader, extra)
  54. if err != nil {
  55. return nil, err
  56. }
  57. }
  58. err = _strategy.FromMrs(reader, int(count))
  59. return strategy, err
  60. } else {
  61. return nil, ErrInvalidFormat
  62. }
  63. }