Encode marshalls and compresses the message using the codec and compressor for the stream.
(s Stream, msg any)
| 40 | |
| 41 | // Encode marshalls and compresses the message using the codec and compressor for the stream. |
| 42 | func (p *PreparedMsg) Encode(s Stream, msg any) error { |
| 43 | ctx := s.Context() |
| 44 | rpcInfo, ok := rpcInfoFromContext(ctx) |
| 45 | if !ok { |
| 46 | return status.Errorf(codes.Internal, "grpc: unable to get rpcInfo") |
| 47 | } |
| 48 | |
| 49 | // check if the context has the relevant information to prepareMsg |
| 50 | if rpcInfo.preloaderInfo.codec == nil { |
| 51 | return status.Errorf(codes.Internal, "grpc: rpcInfo.preloaderInfo.codec is nil") |
| 52 | } |
| 53 | |
| 54 | // prepare the msg |
| 55 | data, err := encode(rpcInfo.preloaderInfo.codec, msg) |
| 56 | if err != nil { |
| 57 | return err |
| 58 | } |
| 59 | |
| 60 | materializedData := data.Materialize() |
| 61 | data.Free() |
| 62 | p.encodedData = mem.BufferSlice{mem.SliceBuffer(materializedData)} |
| 63 | |
| 64 | // TODO: it should be possible to grab the bufferPool from the underlying |
| 65 | // stream implementation with a type cast to its actual type (such as |
| 66 | // addrConnStream) and accessing the buffer pool directly. |
| 67 | var compData mem.BufferSlice |
| 68 | compData, p.pf, err = compress(p.encodedData, rpcInfo.preloaderInfo.cp, rpcInfo.preloaderInfo.comp, mem.DefaultBufferPool()) |
| 69 | if err != nil { |
| 70 | return err |
| 71 | } |
| 72 | |
| 73 | if p.pf.isCompressed() { |
| 74 | materializedCompData := compData.Materialize() |
| 75 | compData.Free() |
| 76 | compData = mem.BufferSlice{mem.SliceBuffer(materializedCompData)} |
| 77 | } |
| 78 | |
| 79 | p.hdr, p.payload = msgHeader(p.encodedData, compData, p.pf) |
| 80 | |
| 81 | return nil |
| 82 | } |