2016-12-14 18:41:48 +03:00
|
|
|
// Package codec is an interface for encoding messages
|
2021-10-02 19:55:07 +03:00
|
|
|
package codec // import "go.unistack.org/micro/v3/codec"
|
2015-11-27 03:17:36 +03:00
|
|
|
|
2015-11-28 14:22:29 +03:00
|
|
|
import (
|
2020-02-19 02:05:38 +03:00
|
|
|
"errors"
|
2015-11-28 14:22:29 +03:00
|
|
|
"io"
|
2020-11-18 16:50:41 +03:00
|
|
|
|
2021-10-02 19:55:07 +03:00
|
|
|
"go.unistack.org/micro/v3/metadata"
|
2015-11-28 14:22:29 +03:00
|
|
|
)
|
|
|
|
|
2021-02-13 15:35:56 +03:00
|
|
|
// Message types
|
2015-11-28 14:22:29 +03:00
|
|
|
const (
|
|
|
|
Error MessageType = iota
|
|
|
|
Request
|
|
|
|
Response
|
2019-07-07 14:44:09 +03:00
|
|
|
Event
|
2015-11-28 14:22:29 +03:00
|
|
|
)
|
|
|
|
|
2020-02-19 02:05:38 +03:00
|
|
|
var (
|
2020-11-03 02:02:32 +03:00
|
|
|
// ErrInvalidMessage returned when invalid messge passed to codec
|
2020-02-19 02:05:38 +03:00
|
|
|
ErrInvalidMessage = errors.New("invalid message")
|
2020-11-23 16:18:47 +03:00
|
|
|
// ErrUnknownContentType returned when content-type is unknown
|
|
|
|
ErrUnknownContentType = errors.New("unknown content-type")
|
2020-02-19 02:05:38 +03:00
|
|
|
)
|
|
|
|
|
2020-11-25 10:43:13 +03:00
|
|
|
var (
|
2020-12-08 00:38:37 +03:00
|
|
|
// DefaultMaxMsgSize specifies how much data codec can handle
|
2021-09-30 01:24:16 +03:00
|
|
|
DefaultMaxMsgSize = 1024 * 1024 * 4 // 4Mb
|
2021-02-13 15:35:56 +03:00
|
|
|
// DefaultCodec is the global default codec
|
2022-05-03 14:38:44 +03:00
|
|
|
DefaultCodec = NewCodec()
|
2021-05-25 22:20:39 +03:00
|
|
|
// DefaultTagName specifies struct tag name to control codec Marshal/Unmarshal
|
|
|
|
DefaultTagName = "codec"
|
2020-11-25 10:43:13 +03:00
|
|
|
)
|
|
|
|
|
2021-02-14 11:28:50 +03:00
|
|
|
// MessageType specifies message type for codec
|
2015-11-28 14:22:29 +03:00
|
|
|
type MessageType int
|
|
|
|
|
2020-11-23 16:18:47 +03:00
|
|
|
// Codec encodes/decodes various types of messages used within micro.
|
2015-12-02 04:38:56 +03:00
|
|
|
// ReadHeader and ReadBody are called in pairs to read requests/responses
|
|
|
|
// from the connection. Close is called when finished with the
|
|
|
|
// connection. ReadBody may be called with a nil argument to force the
|
|
|
|
// body to be read and discarded.
|
2015-11-27 03:17:36 +03:00
|
|
|
type Codec interface {
|
2021-09-22 00:57:10 +03:00
|
|
|
ReadHeader(r io.Reader, m *Message, mt MessageType) error
|
|
|
|
ReadBody(r io.Reader, v interface{}) error
|
|
|
|
Write(w io.Writer, m *Message, v interface{}) error
|
|
|
|
Marshal(v interface{}, opts ...Option) ([]byte, error)
|
|
|
|
Unmarshal(b []byte, v interface{}, opts ...Option) error
|
2019-01-10 12:42:02 +03:00
|
|
|
String() string
|
|
|
|
}
|
|
|
|
|
2015-11-28 14:22:29 +03:00
|
|
|
// Message represents detailed information about
|
|
|
|
// the communication, likely followed by the body.
|
|
|
|
// In the case of an error, body may be nil.
|
|
|
|
type Message struct {
|
2021-03-06 19:45:13 +03:00
|
|
|
Header metadata.Metadata
|
2019-01-11 00:25:31 +03:00
|
|
|
Target string
|
2019-01-18 13:12:57 +03:00
|
|
|
Method string
|
2019-01-11 00:25:31 +03:00
|
|
|
Endpoint string
|
|
|
|
Error string
|
2021-09-30 21:00:02 +03:00
|
|
|
ID string
|
2021-03-06 19:45:13 +03:00
|
|
|
Body []byte
|
|
|
|
Type MessageType
|
2015-11-28 14:22:29 +03:00
|
|
|
}
|
2020-11-24 15:14:47 +03:00
|
|
|
|
2020-12-08 00:38:37 +03:00
|
|
|
// NewMessage creates new codec message
|
2020-11-24 15:14:47 +03:00
|
|
|
func NewMessage(t MessageType) *Message {
|
|
|
|
return &Message{Type: t, Header: metadata.New(0)}
|
|
|
|
}
|
2021-10-01 01:08:24 +03:00
|
|
|
|
|
|
|
// MarshalAppend calls codec.Marshal(v) and returns the data appended to buf.
|
|
|
|
// If codec implements MarshalAppend, that is called instead.
|
|
|
|
func MarshalAppend(buf []byte, c Codec, v interface{}, opts ...Option) ([]byte, error) {
|
|
|
|
if nc, ok := c.(interface {
|
|
|
|
MarshalAppend([]byte, interface{}, ...Option) ([]byte, error)
|
|
|
|
}); ok {
|
|
|
|
return nc.MarshalAppend(buf, v, opts...)
|
|
|
|
}
|
|
|
|
|
|
|
|
mbuf, err := c.Marshal(v, opts...)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return append(buf, mbuf...), nil
|
|
|
|
}
|
2023-04-02 14:10:57 +03:00
|
|
|
|
|
|
|
// RawMessage is a raw encoded JSON value.
|
|
|
|
// It implements Marshaler and Unmarshaler and can be used to delay decoding or precompute a encoding.
|
|
|
|
type RawMessage []byte
|
|
|
|
|
|
|
|
// MarshalJSON returns m as the JSON encoding of m.
|
|
|
|
func (m *RawMessage) MarshalJSON() ([]byte, error) {
|
|
|
|
if m == nil {
|
|
|
|
return []byte("null"), nil
|
2024-09-10 10:43:45 +03:00
|
|
|
} else if len(*m) == 0 {
|
|
|
|
return []byte("null"), nil
|
2023-04-02 14:10:57 +03:00
|
|
|
}
|
|
|
|
return *m, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalJSON sets *m to a copy of data.
|
|
|
|
func (m *RawMessage) UnmarshalJSON(data []byte) error {
|
|
|
|
if m == nil {
|
|
|
|
return errors.New("RawMessage UnmarshalJSON on nil pointer")
|
|
|
|
}
|
|
|
|
*m = append((*m)[0:0], data...)
|
|
|
|
return nil
|
|
|
|
}
|