Files

49 lines
1.0 KiB
Go

package protocol
import (
"bytes"
"encoding/json"
"io"
)
// Marshal 将值编码为 UTF-8 JSON,不转义 HTML 与非 ASCII,且不含尾部换行。
func Marshal(v any) ([]byte, error) {
var buf bytes.Buffer
if err := Encode(&buf, v); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
// Encode 写入 JSON。json.Encoder 默认会追加 '\n',这里去掉,保证整帧字节数与线上一致。
func Encode(w io.Writer, v any) error {
var buf bytes.Buffer
enc := json.NewEncoder(&buf)
enc.SetEscapeHTML(false)
if err := enc.Encode(v); err != nil {
return err
}
b := buf.Bytes()
if n := len(b); n > 0 && b[n-1] == '\n' {
b = b[:n-1]
}
_, err := w.Write(b)
return err
}
// Unmarshal 解码 JSON。
func Unmarshal(data []byte, v any) error {
dec := json.NewDecoder(bytes.NewReader(data))
dec.UseNumber()
return dec.Decode(v)
}
// FrameBytes 返回整帧编码后的字节数。
func FrameBytes(v any) (int, error) {
b, err := Marshal(v)
if err != nil {
return 0, err
}
return len(b), nil
}