/
msgpack.go
87 lines (74 loc) 路 1.94 KB
/
msgpack.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package mtg
import (
"bytes"
"encoding/hex"
"fmt"
"github.com/MixinNetwork/mixin/common"
"github.com/klauspost/compress/zstd"
"github.com/vmihailenco/msgpack/v4"
)
func init() {
zstdEncoder = common.NewZstdEncoder(2)
zstdDecoder = common.NewZstdDecoder(2)
}
var (
// zstd --train /tmp/zstd/* -o config/data/zstd.dic
zstdEncoder *zstd.Encoder
zstdDecoder *zstd.Decoder
CompressionVersionZero = []byte{0, 0, 0, 0}
CompressionVersionLatest = CompressionVersionZero
)
func compress(b []byte) []byte {
b = zstdEncoder.EncodeAll(b, nil)
return append(CompressionVersionLatest, b...)
}
func decompress(b []byte) []byte {
header := len(CompressionVersionLatest)
if len(b) < header*2 {
return nil
}
if !bytes.Equal(b[:header], CompressionVersionZero) {
return nil
}
b, err := zstdDecoder.DecodeAll(b[header:], nil)
if err != nil {
return nil
}
return b
}
func CompressMsgpackMarshalPanic(val any) []byte {
payload := MsgpackMarshalPanic(val)
payload = zstdEncoder.EncodeAll(payload, nil)
return append(CompressionVersionLatest, payload...)
}
func DecompressMsgpackUnmarshal(data []byte, val any) error {
header := len(CompressionVersionLatest)
if len(data) < header*2 {
return MsgpackUnmarshal(data, val)
}
version := data[:header]
if bytes.Equal(version, CompressionVersionZero) {
payload, err := zstdDecoder.DecodeAll(data[header:], nil)
if err != nil {
return err
}
return MsgpackUnmarshal(payload, val)
}
return MsgpackUnmarshal(data, val)
}
func MsgpackMarshalPanic(val any) []byte {
var buf bytes.Buffer
enc := msgpack.NewEncoder(&buf).UseCompactEncoding(true).SortMapKeys(true)
err := enc.Encode(val)
if err != nil {
panic(fmt.Errorf("MsgpackMarshalPanic: %#v %s", val, err.Error()))
}
return buf.Bytes()
}
func MsgpackUnmarshal(data []byte, val any) error {
err := msgpack.Unmarshal(data, val)
if err == nil {
return err
}
return fmt.Errorf("MsgpackUnmarshal: %s %s", hex.EncodeToString(data), err.Error())
}