public override void Serialize(SerializationContext context) { int bytesNeed = (int)(Messages.Count * 11 + Messages.Sum(m => m.DataLength)); var buffer = _arrayPool.Rent(bytesNeed); try { var span = buffer.AsSpan(0, bytesNeed); int consumed = 0; foreach (var message in Messages) { span[0] = (byte)message.Header.MessageType; span = span.Slice(sizeof(byte)); NetworkBitConverter.TryGetUInt24Bytes((uint)message.Header.MessageLength, span); span = span.Slice(3); NetworkBitConverter.TryGetBytes(message.Header.Timestamp, span); span = span.Slice(4); NetworkBitConverter.TryGetUInt24Bytes((uint)MessageHeader.MessageStreamId, span); span = span.Slice(3); MessageBuffer.AsSpan(consumed, (int)message.Header.MessageLength).CopyTo(span); consumed += (int)message.Header.MessageLength; span = span.Slice((int)message.Header.MessageLength); } context.WriteBuffer.WriteToBuffer(span); } finally { _arrayPool.Return(buffer); } }
public static ExtensionType Parse(MemoryCursor cursor) { var codeBytes = cursor.Move(2); var code = (ushort)NetworkBitConverter.ParseUnaligned(codeBytes.Span); return(new ExtensionType(code)); }
public void Dispose() { type.WriteBytes(cursor); var payloadLength = cursor - startLengthOfBody; if (payloadLength > MaxLength) { throw new EncodingException(); } var payloadData = cursor.Move(-payloadLength); var headerLength = cursor - startLengthOfMessage; var headerData = cursor.Peek(-headerLength); var encryptedPayloadLength = payloadLength + aead.TagLength; if (encryptedPayloadLength > MaxLength) { throw new EncodingException(); } cursor.Move(encryptedPayloadLength); var tag = cursor.Peek(-aead.TagLength); NetworkBitConverter.WriteUnaligned(lengthBytes, (ulong)encryptedPayloadLength, 2); aead.Encrypt(payloadData.Span, tag.Span, sequenceNumber, headerData.Span); }
public static MemoryBuffer DecryptBytes(MemoryCursor cursor, int startOffsetOfMessage, IAead aead, ulong sequenceNumber) { var headerLength = cursor - startOffsetOfMessage + 2; var lengthBytes = cursor.Move(2); var headerBytes = cursor.Peek(-headerLength); var length = (int)NetworkBitConverter.ParseUnaligned(lengthBytes.Span); if (length > MaxLength) { throw new EncodingException(); } if (length < aead.TagLength) { throw new EncodingException(); } var startOffsetOfBody = cursor.AsOffset(); var encryptedLength = length - aead.TagLength; var encryptedBytes = cursor.Move(encryptedLength); var tag = cursor.Move(aead.TagLength); aead.Decrypt(encryptedBytes.Span, tag.Span, sequenceNumber, headerBytes.Span); return(new MemoryBuffer(startOffsetOfBody, encryptedLength)); }
private bool TryGetReference(Span <byte> buffer, out object value, out int consumedLength) { var index = 0; value = default; consumedLength = default; if (!TryDescribeData(buffer, out var type, out var length)) { return(false); } if (type != Amf0Type.Reference) { return(false); } index = NetworkBitConverter.ToUInt16(buffer.Slice(Amf0CommonValues.MARKER_LENGTH, sizeof(ushort))); consumedLength = Amf0CommonValues.MARKER_LENGTH + sizeof(ushort); if (_referenceTable.Count <= index) { return(false); } value = _referenceTable[index]; return(true); }
public static SignatureScheme Parse(MemoryCursor cursor) { var bytes = cursor.Move(2); var code = (ushort)NetworkBitConverter.ParseUnaligned(bytes.Span); return(new SignatureScheme(code)); }
public void WriteBytes(Vector <double> value, SerializationContext context) { context.Buffer.WriteToBuffer((byte)Amf3Type.VectorDouble); var refIndex = context.ObjectReferenceTable.IndexOf(value); if (refIndex >= 0) { var header = (uint)refIndex << 1; WriteU29BytesImpl(header, context); return; } else { context.ObjectReferenceTable.Add(value); var header = ((uint)value.Count << 1) | 0x01; WriteU29BytesImpl(header, context); context.Buffer.WriteToBuffer(value.IsFixedSize ? (byte)0x01 : (byte)0x00); var buffer = _arrayPool.Rent(sizeof(double)); try { foreach (var i in value) { var contractRet = NetworkBitConverter.TryGetBytes(i, buffer); Contract.Assert(contractRet); context.Buffer.WriteToBuffer(buffer.AsSpan(0, sizeof(double))); } } finally { _arrayPool.Return(buffer); } return; } }
public static NamedGroup Parse(MemoryCursor cursor) { var codeBytes = cursor.Move(2); var code = (ushort)NetworkBitConverter.ParseUnaligned(codeBytes.Span); return(new NamedGroup(code)); }
public void WriteBytes(DateTime dateTime, SerializationContext context) { context.Buffer.WriteToBuffer((byte)Amf3Type.Date); var refIndex = context.ObjectReferenceTable.IndexOf(dateTime); uint header = 0; if (refIndex >= 0) { header = (uint)refIndex << 1; WriteU29BytesImpl(header, context); return; } context.ObjectReferenceTable.Add(dateTime); var timeOffset = new DateTimeOffset(dateTime); var timestamp = timeOffset.ToUnixTimeMilliseconds(); header = 0x01; WriteU29BytesImpl(header, context); var backend = _arrayPool.Rent(sizeof(double)); try { var contractRet = NetworkBitConverter.TryGetBytes(timestamp, backend); Contract.Assert(contractRet); context.Buffer.WriteToBuffer(backend.AsSpan(0, sizeof(double))); } finally { _arrayPool.Return(backend); } }
public int Write(MemoryCursor cursor, int?minLength = null, ValueBuffer?mask = null) { if (minLength < 0) { throw new ArgumentOutOfRangeException(nameof(minLength)); } var length = NetworkBitConverter.GetByteLength(value); if (minLength.HasValue) { length = Math.Max(length, minLength.Value); } var bytes = cursor.Move(length); NetworkBitConverter.WriteUnaligned(bytes.Span, value, length); if (mask.HasValue) { Mask(bytes.Span, mask.Value); } return(length); }
public byte[] MultiplexFlvHeader(bool hasAudio, bool hasVideo) { var header = new byte[13]; header[0] = 0x46; header[1] = 0x4C; header[2] = 0x56; header[3] = 0x01; byte audioFlag = 0x01 << 2; byte videoFlag = 0x01; byte typeFlag = 0x00; if (hasAudio) { typeFlag |= audioFlag; } if (hasVideo) { typeFlag |= videoFlag; } header[4] = typeFlag; NetworkBitConverter.TryGetBytes(9, header.AsSpan(5)); return(header); }
private bool ProcessHandshakeC2(ReadOnlySequence <byte> buffer, ref int consumed) { if (buffer.Length - consumed < 1536) { return(false); } var arr = _arrayPool.Rent(1536); try { buffer.Slice(consumed, 1536).CopyTo(arr); consumed += 1536; var s1Timestamp = NetworkBitConverter.ToUInt32(arr.AsSpan(0, 4)); if (s1Timestamp != _writerTimestampEpoch) { throw new ProtocolViolationException(); } if (!arr.AsSpan(8, 1528).SequenceEqual(_s1Data.AsSpan(0, 1528))) { throw new ProtocolViolationException(); } _ioPipeline.OnHandshakeSuccessful(); return(true); } finally { _arrayPool.Return(_s1Data); _arrayPool.Return(arr); _s1Data = null; Dispose(); } }
private MessageData DeserializeMessage(Span <byte> buffer, out int consumed) { consumed = 0; var header = new MessageHeader(); header.MessageType = (MessageType)buffer[0]; buffer = buffer.Slice(sizeof(byte)); consumed += sizeof(byte); header.MessageLength = NetworkBitConverter.ToUInt24(buffer); buffer = buffer.Slice(3); consumed += 3; header.Timestamp = NetworkBitConverter.ToUInt32(buffer); buffer = buffer.Slice(sizeof(uint)); consumed += sizeof(uint); header.MessageStreamId = header.MessageStreamId; // Override message stream id buffer = buffer.Slice(3); consumed += 3; var offset = consumed; consumed += (int)header.MessageLength; header.Timestamp += MessageHeader.Timestamp; return(new MessageData() { Header = header, DataOffset = offset, DataLength = header.MessageLength }); }
public byte[] MultiplexFlv(Message data) { var dataBuffer = new ByteBuffer(); var buffer = new byte[4]; if (data.MessageHeader.MessageLength == 0) { var messageBuffer = new ByteBuffer(); var context = new Networking.Rtmp.Serialization.SerializationContext() { Amf0Writer = _amf0Writer, Amf3Writer = _amf3Writer, WriteBuffer = messageBuffer }; data.Serialize(context); var length = messageBuffer.Length; data.MessageHeader.MessageLength = (uint)length; var bodyBuffer = new byte[length]; messageBuffer.TakeOutMemory(bodyBuffer); dataBuffer.WriteToBuffer((byte)data.MessageHeader.MessageType); NetworkBitConverter.TryGetUInt24Bytes(data.MessageHeader.MessageLength, buffer); dataBuffer.WriteToBuffer(buffer.AsSpan(0, 3)); NetworkBitConverter.TryGetBytes(data.MessageHeader.Timestamp, buffer); dataBuffer.WriteToBuffer(buffer.AsSpan(1, 3)); dataBuffer.WriteToBuffer(buffer.AsSpan(0, 1)); buffer.AsSpan().Clear(); dataBuffer.WriteToBuffer(buffer.AsSpan(0, 3)); dataBuffer.WriteToBuffer(bodyBuffer); } else { dataBuffer.WriteToBuffer((byte)data.MessageHeader.MessageType); NetworkBitConverter.TryGetUInt24Bytes(data.MessageHeader.MessageLength, buffer); dataBuffer.WriteToBuffer(buffer.AsSpan(0, 3)); NetworkBitConverter.TryGetBytes(data.MessageHeader.Timestamp, buffer); dataBuffer.WriteToBuffer(buffer.AsSpan(1, 3)); dataBuffer.WriteToBuffer(buffer.AsSpan(0, 1)); buffer.AsSpan().Clear(); dataBuffer.WriteToBuffer(buffer.AsSpan(0, 3)); var context = new Networking.Rtmp.Serialization.SerializationContext() { Amf0Writer = _amf0Writer, Amf3Writer = _amf3Writer, WriteBuffer = dataBuffer }; data.Serialize(context); } NetworkBitConverter.TryGetBytes((data.MessageHeader.MessageLength + 11), buffer); dataBuffer.WriteToBuffer(buffer); var rawData = new byte[dataBuffer.Length]; dataBuffer.TakeOutMemory(rawData); return(rawData); }
public static CursorWritingContext StartVectorWriting(MemoryCursor cursor, Range range) { var lengthSizeInBytes = NetworkBitConverter.GetByteLength((ulong)range.End.Value); var lengthBytes = cursor.Move(lengthSizeInBytes).Span; var startLength = cursor.AsOffset(); return(new CursorWritingContext(cursor, startLength, lengthBytes, range)); }
public void Fill(Span <byte> bytes, ValueBuffer?mask = null) { NetworkBitConverter.WriteUnaligned(bytes, value, bytes.Length); if (mask.HasValue) { Mask(bytes, mask.Value); } }
public int Write(byte[] buffer, ref int offset) { offset += LabelEncoding.PutBytes(Name, buffer, offset); offset += NetworkBitConverter.PutBytes((ushort)Type, buffer, offset); offset += NetworkBitConverter.PutBytes((ushort)Class, buffer, offset); return(offset); }
public override void Deserialize(SerializationContext context) { var span = context.ReadBuffer.Span; var eventType = (UserControlEventType)NetworkBitConverter.ToUInt16(span); span = span.Slice(sizeof(ushort)); Contract.Assert(eventType == UserControlEventType.StreamIsRecorded); StreamID = NetworkBitConverter.ToUInt32(span); }
public static MemoryBuffer Slice(MemoryCursor cursor) { var payloadLengthBytes = cursor.Move(2); var payloadLength = (int)NetworkBitConverter.ParseUnaligned(payloadLengthBytes.Span); var startOffsetOfBody = cursor.AsOffset(); cursor.Move(payloadLength); return(new MemoryBuffer(startOffsetOfBody, payloadLength)); }
public bool ReadNet64(out ulong x) { if (position + 8 > count) { x = 0; return(false); } x = NetworkBitConverter.ToUInt64(data, position); position += 8; return(true); }
public bool ReadNet32(out uint x) { if (position + 4 > count) { x = 0; return(false); } x = NetworkBitConverter.ToUInt32(data, position); position += 4; return(true); }
public bool ReadNet16(out ushort x) { if (position + 2 > count) { x = 0; return(false); } x = NetworkBitConverter.ToUInt16(data, position); position += 2; return(true); }
public void Dispose() { var payloadLength = cursor - startLength; if (payloadLength < range.Start.Value || payloadLength > range.End.Value) { throw new EncodingException(); } NetworkBitConverter.WriteUnaligned(lengthBytes, (ulong)payloadLength, lengthBytes.Length); }
public Message Provide(MessageHeader header, SerializationContext context, out int consumed) { var type = (UserControlEventType)NetworkBitConverter.ToUInt16(context.ReadBuffer.Span); if (!_messageFactories.TryGetValue(type, out var t)) { throw new NotSupportedException(); } consumed = 0; return((Message)Activator.CreateInstance(t)); }
public void Dispose() { var payloadLength = cursor - startOffset; if (payloadLength > MaxLength) { throw new EncodingException(); } NetworkBitConverter.WriteUnaligned(lengthBytes, (ulong)payloadLength, 2); }
public static bool GetProtocol(Bytes packet, out ushort protocol) { try { int offset = EthernetAddress.Length * 2; protocol = NetworkBitConverter.ToUInt16(packet, offset); } catch { protocol = 0; return(false); } return(true); } //Get the protocol for this packet
private void WriteStringBytesImpl(string str, SerializationContext context, out bool isLongString, bool marker = false, bool forceLongString = false) { var bytesNeed = 0; var headerLength = 0; var bodyLength = 0; bodyLength = Encoding.UTF8.GetByteCount(str); bytesNeed += bodyLength; if (bodyLength > ushort.MaxValue || forceLongString) { headerLength = Amf0CommonValues.LONG_STRING_HEADER_LENGTH; isLongString = true; if (marker) { context.Buffer.WriteToBuffer((byte)Amf0Type.LongString); } } else { isLongString = false; headerLength = Amf0CommonValues.STRING_HEADER_LENGTH; if (marker) { context.Buffer.WriteToBuffer((byte)Amf0Type.String); } } bytesNeed += headerLength; var bufferBackend = _arrayPool.Rent(bytesNeed); try { var buffer = bufferBackend.AsSpan(0, bytesNeed); if (isLongString) { NetworkBitConverter.TryGetBytes((uint)bodyLength, buffer); } else { var contractRet = NetworkBitConverter.TryGetBytes((ushort)bodyLength, buffer); Contract.Assert(contractRet); } Encoding.UTF8.GetBytes(str, buffer.Slice(headerLength)); context.Buffer.WriteToBuffer(buffer); } finally { _arrayPool.Return(bufferBackend); } }
private bool ProcessHandshakeC0C1(ReadOnlySequence <byte> buffer, ref int consumed) { if (buffer.Length - consumed < 1537) { return(false); } var arr = _arrayPool.Rent(1537); try { buffer.Slice(consumed, 9).CopyTo(arr); consumed += 9; var version = arr[0]; //本文档中规范的版本号为 3。0、1、2 三个值是由早期其他产品使用的,是废弃值;4 - 31 被保留为 RTMP 协议的未来实现版本使用 if (version < 3) { throw new NotSupportedException(); } if (version > 31) { throw new ProtocolViolationException(); } _readerTimestampEpoch = NetworkBitConverter.ToUInt32(arr.AsSpan(1, 4)); _writerTimestampEpoch = 0; _s1Data = _arrayPool.Rent(1528); _random.NextBytes(_s1Data.AsSpan(0, 1528)); // s0s1 arr.AsSpan().Clear(); arr[0] = 3; NetworkBitConverter.TryGetBytes(_writerTimestampEpoch, arr.AsSpan(1, 4)); _s1Data.AsSpan(0, 1528).CopyTo(arr.AsSpan(9)); _ = _ioPipeline.SendRawData(arr.AsMemory(0, 1537)); // s2 NetworkBitConverter.TryGetBytes(_readerTimestampEpoch, arr.AsSpan(0, 4)); NetworkBitConverter.TryGetBytes((uint)0, arr.AsSpan(4, 4)); _ = _ioPipeline.SendRawData(arr.AsMemory(0, 1536)); buffer.Slice(consumed, 1528).CopyTo(arr.AsSpan(8)); consumed += 1528; _ioPipeline.NextProcessState = ProcessState.HandshakeC2; return(true); } finally { _arrayPool.Return(arr); } }
public override void Serialize(SerializationContext context) { var buffer = _arrayPool.Rent(sizeof(uint)); try { NetworkBitConverter.TryGetBytes(BytesReceived, buffer); context.WriteBuffer.WriteToBuffer(buffer.AsSpan(0, sizeof(uint))); } finally { _arrayPool.Return(buffer); } }
public static WritingContext StartVectorWriting(ref Span <byte> bytes, Range range) { var context = new WritingContext(bytes, range); var lengthSizeInBytes = NetworkBitConverter.GetByteLength((ulong)range.End.Value); if (bytes.Length < lengthSizeInBytes) { throw new EncodingException(); } bytes = bytes.Slice(lengthSizeInBytes); return(context); }