github.com/annwntech/go-micro/v2@v2.9.5/client/grpc/codec.go (about)

     1  package grpc
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strings"
     7  
     8  	b "bytes"
     9  
    10  	"github.com/annwntech/go-micro/v2/codec"
    11  	"github.com/annwntech/go-micro/v2/codec/bytes"
    12  	"github.com/golang/protobuf/jsonpb"
    13  	"github.com/golang/protobuf/proto"
    14  	"github.com/oxtoacart/bpool"
    15  	"google.golang.org/grpc"
    16  	"google.golang.org/grpc/encoding"
    17  )
    18  
    19  type jsonCodec struct{}
    20  type protoCodec struct{}
    21  type bytesCodec struct{}
    22  type wrapCodec struct{ encoding.Codec }
    23  
    24  var (
    25  	JsonpbMarshaler = &jsonpb.Marshaler{
    26  		EnumsAsInts:  false,
    27  		EmitDefaults: true,
    28  		OrigName:     true,
    29  	}
    30  	JsonpbUnmarshaler = &jsonpb.Unmarshaler{
    31  		AllowUnknownFields: false,
    32  	}
    33  )
    34  var useNumber bool
    35  
    36  // create buffer pool with 16 instances each preallocated with 256 bytes
    37  var bufferPool = bpool.NewSizedBufferPool(16, 256)
    38  
    39  var (
    40  	defaultGRPCCodecs = map[string]encoding.Codec{
    41  		"application/json":         jsonCodec{},
    42  		"application/proto":        protoCodec{},
    43  		"application/protobuf":     protoCodec{},
    44  		"application/octet-stream": protoCodec{},
    45  		"application/grpc":         protoCodec{},
    46  		"application/grpc+json":    jsonCodec{},
    47  		"application/grpc+proto":   protoCodec{},
    48  		"application/grpc+bytes":   bytesCodec{},
    49  	}
    50  )
    51  
    52  // UseNumber fix unmarshal Number(8234567890123456789) to interface(8.234567890123457e+18)
    53  func UseNumber() {
    54  	useNumber = true
    55  }
    56  
    57  func (w wrapCodec) String() string {
    58  	return w.Codec.Name()
    59  }
    60  
    61  func (w wrapCodec) Marshal(v interface{}) ([]byte, error) {
    62  	b, ok := v.(*bytes.Frame)
    63  	if ok {
    64  		return b.Data, nil
    65  	}
    66  	return w.Codec.Marshal(v)
    67  }
    68  
    69  func (w wrapCodec) Unmarshal(data []byte, v interface{}) error {
    70  	b, ok := v.(*bytes.Frame)
    71  	if ok {
    72  		b.Data = data
    73  		return nil
    74  	}
    75  	return w.Codec.Unmarshal(data, v)
    76  }
    77  
    78  func (protoCodec) Marshal(v interface{}) ([]byte, error) {
    79  	switch m := v.(type) {
    80  	case *bytes.Frame:
    81  		return m.Data, nil
    82  	case proto.Message:
    83  		return proto.Marshal(m)
    84  	}
    85  	return nil, fmt.Errorf("failed to marshal: %v is not type of *bytes.Frame or proto.Message", v)
    86  }
    87  
    88  func (protoCodec) Unmarshal(data []byte, v interface{}) error {
    89  	m, ok := v.(proto.Message)
    90  	if !ok {
    91  		return fmt.Errorf("failed to unmarshal: %v is not type of proto.Message", v)
    92  	}
    93  	return proto.Unmarshal(data, m)
    94  }
    95  
    96  func (protoCodec) Name() string {
    97  	return "proto"
    98  }
    99  
   100  func (bytesCodec) Marshal(v interface{}) ([]byte, error) {
   101  	b, ok := v.(*[]byte)
   102  	if !ok {
   103  		return nil, fmt.Errorf("failed to marshal: %v is not type of *[]byte", v)
   104  	}
   105  	return *b, nil
   106  }
   107  
   108  func (bytesCodec) Unmarshal(data []byte, v interface{}) error {
   109  	b, ok := v.(*[]byte)
   110  	if !ok {
   111  		return fmt.Errorf("failed to unmarshal: %v is not type of *[]byte", v)
   112  	}
   113  	*b = data
   114  	return nil
   115  }
   116  
   117  func (bytesCodec) Name() string {
   118  	return "bytes"
   119  }
   120  
   121  func (jsonCodec) Marshal(v interface{}) ([]byte, error) {
   122  	if b, ok := v.(*bytes.Frame); ok {
   123  		return b.Data, nil
   124  	}
   125  
   126  	if pb, ok := v.(proto.Message); ok {
   127  		buf := bufferPool.Get()
   128  		defer bufferPool.Put(buf)
   129  		if err := JsonpbMarshaler.Marshal(buf, pb); err != nil {
   130  			return nil, err
   131  		}
   132  		return buf.Bytes(), nil
   133  	}
   134  
   135  	return json.Marshal(v)
   136  }
   137  
   138  func (jsonCodec) Unmarshal(data []byte, v interface{}) error {
   139  	if len(data) == 0 {
   140  		return nil
   141  	}
   142  	if b, ok := v.(*bytes.Frame); ok {
   143  		b.Data = data
   144  		return nil
   145  	}
   146  	if pb, ok := v.(proto.Message); ok {
   147  		return JsonpbUnmarshaler.Unmarshal(b.NewReader(data), pb)
   148  	}
   149  
   150  	dec := json.NewDecoder(b.NewReader(data))
   151  	if useNumber {
   152  		dec.UseNumber()
   153  	}
   154  	return dec.Decode(v)
   155  }
   156  
   157  func (jsonCodec) Name() string {
   158  	return "json"
   159  }
   160  
   161  type grpcCodec struct {
   162  	// headers
   163  	id       string
   164  	target   string
   165  	method   string
   166  	endpoint string
   167  
   168  	s grpc.ClientStream
   169  	c encoding.Codec
   170  }
   171  
   172  func (g *grpcCodec) ReadHeader(m *codec.Message, mt codec.MessageType) error {
   173  	md, err := g.s.Header()
   174  	if err != nil {
   175  		return err
   176  	}
   177  	if m == nil {
   178  		m = new(codec.Message)
   179  	}
   180  	if m.Header == nil {
   181  		m.Header = make(map[string]string, len(md))
   182  	}
   183  	for k, v := range md {
   184  		m.Header[k] = strings.Join(v, ",")
   185  	}
   186  	m.Id = g.id
   187  	m.Target = g.target
   188  	m.Method = g.method
   189  	m.Endpoint = g.endpoint
   190  	return nil
   191  }
   192  
   193  func (g *grpcCodec) ReadBody(v interface{}) error {
   194  	if f, ok := v.(*bytes.Frame); ok {
   195  		return g.s.RecvMsg(f)
   196  	}
   197  	return g.s.RecvMsg(v)
   198  }
   199  
   200  func (g *grpcCodec) Write(m *codec.Message, v interface{}) error {
   201  	// if we don't have a body
   202  	if v != nil {
   203  		return g.s.SendMsg(v)
   204  	}
   205  	// write the body using the framing codec
   206  	return g.s.SendMsg(&bytes.Frame{Data: m.Body})
   207  }
   208  
   209  func (g *grpcCodec) Close() error {
   210  	return g.s.CloseSend()
   211  }
   212  
   213  func (g *grpcCodec) String() string {
   214  	return g.c.Name()
   215  }