예제 #1
0
        public static List <ArgumentDescriptor> GetArguments(ReadOnlySpan <byte> message)
        {
            var arguments = new List <ArgumentDescriptor>();

            // Without a complete header, we are not able to retrieve the arguments descriptors
            if (message.Length <= ProtobufHubProtocolConstants.MESSAGE_HEADER_LENGTH)
            {
                return(arguments);
            }

            var protobufMessageLength = BinaryPrimitivesExtensions.ReadInt32(message.Slice(ProtobufHubProtocolConstants.TYPE_AND_TOTAL_LENGTH_HEADER, ProtobufHubProtocolConstants.PROTOBUF_MESSAGE_LENGTH_PLACEHOLDER_SIZE));

            message = message.Slice(ProtobufHubProtocolConstants.MESSAGE_HEADER_LENGTH + protobufMessageLength);

            while (!message.IsEmpty)
            {
                var argumentType   = BinaryPrimitivesExtensions.ReadInt32(message.Slice(0, ProtobufHubProtocolConstants.ARG_TYPE_PLACEHOLDER_SIZE));
                var argumentLength = BinaryPrimitivesExtensions.ReadInt32(message.Slice(ProtobufHubProtocolConstants.ARG_TYPE_PLACEHOLDER_SIZE, ProtobufHubProtocolConstants.ARG_LENGTH_PLACEHOLDER_SIZE));
                var argument       = message.Slice(ProtobufHubProtocolConstants.ARGUMENT_HEADER_LENGTH, argumentLength).ToArray();

                var messageArgument = new ArgumentDescriptor(argumentType, argument);
                arguments.Add(messageArgument);

                message = message.Slice(ProtobufHubProtocolConstants.ARGUMENT_HEADER_LENGTH + argumentLength);
            }

            return(arguments);
        }
예제 #2
0
        public static ReadOnlySpan <byte> PackMessage(int messageType, ReadOnlySpan <byte> protobufMessage, List <ArgumentDescriptor> arguments)
        {
            var argumentLength = arguments?.Sum(argument => argument.Argument.Length + ProtobufHubProtocolConstants.ARGUMENT_HEADER_LENGTH);

            var totalLength = ProtobufHubProtocolConstants.TYPE_PLACEHOLDER_SIZE                      // messageType
                              + ProtobufHubProtocolConstants.TOTAL_LENGTH_PLACEHOLDER_SIZE            // totalLength
                              + ProtobufHubProtocolConstants.PROTOBUF_MESSAGE_LENGTH_PLACEHOLDER_SIZE // ProtobufMessageLength
                              + protobufMessage.Length
                              + (argumentLength ?? 0);

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

            try
            {
                byteArray[0] = (byte)messageType;

                // Span share memory adress with byteArray
                var span = byteArray.AsSpan(ProtobufHubProtocolConstants.TYPE_PLACEHOLDER_SIZE);
                //var messageTotalLength = totalLength - ProtobufHubProtocolConstants.TYPE_AND_TOTAL_LENGTH_HEADER;
                //MemoryMarshal.Write(span, ref messageTotalLength);
                BinaryPrimitivesExtensions.WriteInt32(span, totalLength - ProtobufHubProtocolConstants.TYPE_AND_TOTAL_LENGTH_HEADER);

                span = byteArray.AsSpan(ProtobufHubProtocolConstants.TYPE_AND_TOTAL_LENGTH_HEADER);
                //var protobufMessageLength = protobufMessage.Length;
                //MemoryMarshal.Write(span, ref protobufMessageLength);
                BinaryPrimitivesExtensions.WriteInt32(span, protobufMessage.Length);

                span = byteArray.AsSpan(ProtobufHubProtocolConstants.MESSAGE_HEADER_LENGTH);

                protobufMessage.CopyTo(span);

                var currentLength = protobufMessage.Length + ProtobufHubProtocolConstants.MESSAGE_HEADER_LENGTH;

                for (var i = 0; i < arguments?.Count; i++)
                {
                    span = byteArray.AsSpan(currentLength);
                    //var argType = arguments[i].Type;
                    //MemoryMarshal.Write(span, ref argType);
                    BinaryPrimitivesExtensions.WriteInt32(span, arguments[i].Type);

                    span = byteArray.AsSpan(currentLength + ProtobufHubProtocolConstants.ARG_TYPE_PLACEHOLDER_SIZE);
                    //var argLength = arguments[i].Argument.Length;
                    //MemoryMarshal.Write(span, ref argLength);
                    BinaryPrimitivesExtensions.WriteInt32(span, arguments[i].Argument.Length);


                    span = byteArray.AsSpan(currentLength + ProtobufHubProtocolConstants.ARGUMENT_HEADER_LENGTH);
                    arguments[i].Argument.CopyTo(span);

                    currentLength = currentLength + ProtobufHubProtocolConstants.ARGUMENT_HEADER_LENGTH + arguments[i].Argument.Length;
                }

                return(byteArray.AsSpan(0, totalLength));
            }
            finally
            {
                ArrayPool <byte> .Shared.Return(byteArray);
            }
        }
예제 #3
0
 public static byte GetMessageType(ReadOnlySpan <byte> message)
 {
     if (message.Length <= 0)
     {
         return(0);
     }
     return(BinaryPrimitivesExtensions.ReadByte(message.Slice(0, ProtobufHubProtocolConstants.TYPE_PLACEHOLDER_SIZE)));
 }
예제 #4
0
        public static int GetTotalMessageLength(ReadOnlySpan <byte> message)
        {
            // We need at least 5 bytes to be get the total length
            if (message.Length < ProtobufHubProtocolConstants.TYPE_AND_TOTAL_LENGTH_HEADER)
            {
                return(0);
            }

            return(BinaryPrimitivesExtensions.ReadInt32(message.Slice(ProtobufHubProtocolConstants.TYPE_PLACEHOLDER_SIZE, ProtobufHubProtocolConstants.TOTAL_LENGTH_PLACEHOLDER_SIZE)));
        }
예제 #5
0
        // Without a complete header, we are not able to retrieve the protobuf object message
        public static ReadOnlySpan <byte> GetProtobufMessage(ReadOnlySpan <byte> message)
        {
            if (message.Length <= ProtobufHubProtocolConstants.MESSAGE_HEADER_LENGTH)
            {
                return(new ReadOnlySpan <byte>());
            }

            var protobufMessageLength = BinaryPrimitivesExtensions.ReadInt32(message.Slice(ProtobufHubProtocolConstants.TYPE_AND_TOTAL_LENGTH_HEADER, ProtobufHubProtocolConstants.PROTOBUF_MESSAGE_LENGTH_PLACEHOLDER_SIZE));

            return(message.Slice(ProtobufHubProtocolConstants.MESSAGE_HEADER_LENGTH, protobufMessageLength));
        }
        private object DeserializeNotProtobufObjectArgument(ArgumentDescriptor argumentDescriptor)
        {
            switch (argumentDescriptor.Type)
            {
            case 2:
                return(Encoding.UTF8.GetString(argumentDescriptor.Argument));

            case 3:
                return(BinaryPrimitivesExtensions.ReadInt32(argumentDescriptor.Argument));

            case 4:
                return(BinaryPrimitivesExtensions.ReadDouble(argumentDescriptor.Argument));

            default:
                return(null);
            }
        }