Example #1
0
        public bool TryParseMessage(
            ref ReadOnlySequence <byte> input,
            out HubMessage message,
            IReadOnlyDictionary <int, Type> protobufIndexToTypeMap
            )
        {
            // 4 bytes are required to read the length of the message
            if (input.Length < 4)
            {
                message = null;
                return(false);
            }

            var totalByteSize = BitConverter.ToInt32(input.Slice(0, 4).ToArray(), 0);

            if (input.Length < totalByteSize)
            {
                message = null;
                return(false);
            }

            var protobufInput = input.Slice(4);

            var arrayPool = ArrayPool <byte> .Shared;
            var byteArray = arrayPool.Rent((int)protobufInput.Length);

            try
            {
                protobufInput.CopyTo(byteArray);

                using (var inputStream = new MemoryStream(byteArray))
                {
                    var metadata = new MessageMetadata();
                    metadata.MergeFixedDelimitedFrom(inputStream);

                    var items = new List <object>(metadata.Items.Count);
                    foreach (var itemMetadata in metadata.Items)
                    {
                        var item = itemMetadata.CreateItem(inputStream, protobufIndexToTypeMap);
                        items.Add(item);
                    }

                    message = CreateHubMessage(items);
                }

                input = input.Slice(totalByteSize);

                return(true);
            }
            finally
            {
                arrayPool.Return(byteArray);
            }
        }