Example #1
0
        public void WriteMessage(
            HubMessage message,
            IBufferWriter <byte> output,
            IReadOnlyDictionary <Type, int> protobufTypeToIndexMap
            )
        {
            var itemsMetadata = CreateItems(message)
                                .Select(item => ItemMetadata.Create(item, protobufTypeToIndexMap))
                                .ToList();

            var metadata = new MessageMetadata
            {
                Items = { itemsMetadata }
            };

            var metadataByteSize = metadata.CalculateSize();

            var totalByteSize = 4                      // Total byte size (int)
                                + 4 + metadataByteSize // Metadata byte size (int) and metadata itself
                                + itemsMetadata
                                .Select(itemMetadata => itemMetadata.CalculateTotalSizeBytes())
                                .Sum();     // Total bytes of the protobuf models

            var byteArray = ArrayPool <byte> .Shared.Rent(totalByteSize);

            try
            {
                using (var outputStream = new MemoryStream(byteArray))
                {
                    // Total byte size
                    outputStream.Write(BitConverter.GetBytes(totalByteSize), 0, 4);

                    // Metadata byte size
                    outputStream.Write(BitConverter.GetBytes(metadataByteSize), 0, 4);

                    // Metadata
                    metadata.WriteTo(outputStream);

                    // Other protobufs
                    foreach (var protobufItem in metadata.Items.SelectMany(item => item.NonNullProtobufs))
                    {
                        protobufItem.WriteTo(outputStream);
                    }
                }

                output.Write(new ReadOnlySpan <byte>(byteArray, 0, totalByteSize));
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(byteArray);
            }
        }