| | | 1 | | // Copyright (c) ZeroC, Inc. |
| | | 2 | | |
| | | 3 | | using Google.Protobuf; |
| | | 4 | | using System.Buffers; |
| | | 5 | | using System.Buffers.Binary; |
| | | 6 | | using System.IO.Pipelines; |
| | | 7 | | |
| | | 8 | | namespace IceRpc.Protobuf.RpcMethods.Internal; |
| | | 9 | | |
| | | 10 | | /// <summary>Provides an extension method for <see cref="IMessage" />.</summary> |
| | | 11 | | internal static class MessageExtensions |
| | | 12 | | { |
| | | 13 | | /// <summary>Encodes an <see cref="IMessage"/> as a length-prefixed message, using the Protobuf encoding.</summary> |
| | | 14 | | /// <param name="message">The <see cref="IMessage" /> to encode.</param> |
| | | 15 | | /// <param name="pipeOptions">The options used to create the pipe.</param> |
| | | 16 | | /// <returns>A <see cref="PipeReader" /> containing the length-prefixed message.</returns> |
| | | 17 | | /// <remarks>The envelope follows the gRPC Length-Prefixed-Message format: a 1-byte compression flag (always |
| | | 18 | | /// 0 — IceRPC does not compress Protobuf payloads), followed by the message length as a 4-byte unsigned |
| | | 19 | | /// big-endian integer, followed by the Protobuf-encoded message bytes. See |
| | | 20 | | /// <see href="https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#data-frames" />.</remarks> |
| | | 21 | | internal static PipeReader EncodeAsLengthPrefixedMessage(this IMessage message, PipeOptions pipeOptions) |
| | 61 | 22 | | { |
| | 61 | 23 | | var pipe = new Pipe(pipeOptions); |
| | 61 | 24 | | pipe.Writer.Write(new Span<byte>([0])); // Not compressed |
| | 61 | 25 | | Span<byte> lengthPlaceholder = pipe.Writer.GetSpan(4); |
| | 61 | 26 | | pipe.Writer.Advance(4); |
| | 61 | 27 | | message.WriteTo(pipe.Writer); |
| | 61 | 28 | | int length = checked((int)pipe.Writer.UnflushedBytes); |
| | 61 | 29 | | BinaryPrimitives.WriteUInt32BigEndian(lengthPlaceholder, (uint)(length - 5)); |
| | 61 | 30 | | pipe.Writer.Complete(); |
| | 61 | 31 | | return pipe.Reader; |
| | 61 | 32 | | } |
| | | 33 | | } |