public static string DecodeString(IByteBuffer src, int readerIndex, int len, Encoding encoding) { if (len == 0) { return(string.Empty); } if (src.IoBufferCount == 1) { ArraySegment <byte> ioBuf = src.GetIoBuffer(readerIndex, len); return(encoding.GetString(ioBuf.Array, ioBuf.Offset, ioBuf.Count)); } else { int maxLength = encoding.GetMaxCharCount(len); IByteBuffer buffer = src.Allocator.HeapBuffer(maxLength); try { buffer.WriteBytes(src, readerIndex, len); ArraySegment <byte> ioBuf = src.GetIoBuffer(); return(encoding.GetString(ioBuf.Array, ioBuf.Offset, ioBuf.Count)); } finally { // Release the temporary buffer again. buffer.Release(); } } }
protected override void ScheduleMessageWrite(object message) { var envelope = message as IAddressedEnvelope <IByteBuffer>; if (envelope == null) { throw new InvalidOperationException( $"Unexpected type: {message.GetType().FullName}, expecting DatagramPacket or IAddressedEnvelope."); } IByteBuffer data = envelope.Content; int length = data.ReadableBytes; if (length == 0) { return; } SocketChannelAsyncOperation operation = this.PrepareWriteOperation(data.GetIoBuffer(data.ReaderIndex, length)); operation.RemoteEndPoint = envelope.Recipient; this.SetState(StateFlags.WriteScheduled); bool pending = this.Socket.SendToAsync(operation); if (!pending) { ((ISocketChannelUnsafe)this.Unsafe).FinishWrite(operation); } }
protected override void Encode(IChannelHandlerContext context, IMessageLite message, List <object> output) { Contract.Requires(context != null); Contract.Requires(message != null); Contract.Requires(output != null); IByteBuffer buffer = null; try { int size = message.SerializedSize; if (size <= 0) { return; } buffer = context.Allocator.Buffer(size); ArraySegment <byte> data = buffer.GetIoBuffer(buffer.WriterIndex, size); CodedOutputStream stream = CodedOutputStream.CreateInstance(data.Array, data.Offset, size); message.WriteTo(stream); buffer.SetWriterIndex(buffer.WriterIndex + size); output.Add(buffer); buffer = null; } catch (Exception exception) { throw new CodecException(exception); } finally { buffer?.Release(); } }
protected override void ChannelRead0(IChannelHandlerContext context, IByteBuffer message) { int msgType = message.GetInt(4); int svrID = msgType / 10000; int msgLen = message.GetInt(0); var msgData = message.GetIoBuffer(8, msgLen - 8); Log.Info("msg : {0}", msgType); IGateMessage gate = null; if (svrID == 1) { gate = clusterClient.GetGrain <IGateMaster>(0); } if (svrID == 3) { gate = clusterClient.GetGrain <IGateBattle>(0); } if (gate != null) { Task.Run(async() => { var response = await gate.SendMessage(msgType, msgData.ToArray()); if (response != null) { //约定response msg id = req + 1 await Send(msgType + 1, response); } }); } }
public void TestNioBuffersExpand2() { TestChannel channel = new TestChannel(); ChannelOutboundBuffer buffer = new ChannelOutboundBuffer(channel); CompositeByteBuffer comp = Unpooled.CompositeBuffer(256); IByteBuffer buf = Unpooled.DirectBuffer().WriteBytes(Encoding.ASCII.GetBytes("buf1")); for (int i = 0; i < 65; i++) { comp.AddComponent(true, buf.Copy()); } buffer.AddMessage(comp, comp.ReadableBytes, channel.VoidPromise()); Assert.Equal(0, buffer.NioBufferCount); // Should still be 0 as not flushed yet buffer.AddFlush(); var buffers = buffer.GetSharedBufferList(); Assert.Equal(65, buffer.NioBufferCount); for (int i = 0; i < buffer.NioBufferCount; i++) { if (i < 65) { Assert.Equal(buffers[i], buf.GetIoBuffer(buf.ReaderIndex, buf.ReadableBytes)); } else { Assert.Null(buffers[i].Array); } } Release(buffer); buf.Release(); }
protected override bool DoWriteMessage(object msg, ChannelOutboundBuffer input) { EndPoint remoteAddress = null; IByteBuffer data = null; var envelope = msg as IAddressedEnvelope <IByteBuffer>; if (envelope != null) { remoteAddress = envelope.Recipient; data = envelope.Content; } else if (msg is IByteBuffer) { data = (IByteBuffer)msg; remoteAddress = this.RemoteAddressInternal; } if (data == null || remoteAddress == null) { return(false); } int length = data.ReadableBytes; if (length == 0) { return(true); } ArraySegment <byte> bytes = data.GetIoBuffer(data.ReaderIndex, length); int writtenBytes = this.Socket.SendTo(bytes.Array, bytes.Offset, bytes.Count, SocketFlags.None, remoteAddress); return(writtenBytes > 0); }
public void TestNioBuffersMaxCount() { TestChannel channel = new TestChannel(); ChannelOutboundBuffer buffer = new ChannelOutboundBuffer(channel); CompositeByteBuffer comp = Unpooled.CompositeBuffer(256); IByteBuffer buf = Unpooled.DirectBuffer().WriteBytes(Encoding.ASCII.GetBytes("buf1")); for (int i = 0; i < 65; i++) { comp.AddComponent(true, buf.Copy()); } Assert.Equal(65, comp.IoBufferCount); buffer.AddMessage(comp, comp.ReadableBytes, channel.VoidPromise()); Assert.Equal(0, buffer.NioBufferCount); // Should still be 0 as not flushed yet buffer.AddFlush(); int maxCount = 10; // less than comp.nioBufferCount() var buffers = buffer.GetSharedBufferList(maxCount, int.MaxValue); Assert.True(buffer.NioBufferCount <= maxCount); // Should not be greater than maxCount for (int i = 0; i < buffer.NioBufferCount; i++) { Assert.Equal(buffers[i], buf.GetIoBuffer(buf.ReaderIndex, buf.ReadableBytes)); } Release(buffer); buf.Release(); }
protected override void Encode(IChannelHandlerContext context, IMessage message, IByteBuffer output) { int iCode = PtlCodeHelper.Instance.GetCode(message.GetType()); if (iCode <= 0) { return; } int bodyLength = message.CalculateSize(); if (bodyLength == 0) { return; } int headerLength = sizeof(int) * 2; int totalLength = bodyLength + headerLength; output.EnsureWritable(totalLength); output.WriteInt(totalLength); //长度 output.WriteInt(iCode); //协议号 var buffer = output.GetIoBuffer(output.WriterIndex, bodyLength); using (MemoryStream memStream = new MemoryStream(buffer.Array, buffer.Offset, buffer.Count)) { message.WriteTo(memStream); output.SetWriterIndex(output.WriterIndex + (int)memStream.Length); } }
public static ArraySegment <byte> GetIoBuffer(this IByteBuffer buf) { if (buf is IByteBuffer2 buffer2) { return(buffer2.GetIoBuffer()); } return(buf.GetIoBuffer(buf.ReaderIndex, buf.ReadableBytes)); }
protected override void ScheduleSocketRead() { try { SocketChannelAsyncOperation operation = this.ReadOperation; operation.RemoteEndPoint = this.anyRemoteEndPoint; IRecvByteBufAllocatorHandle handle = this.Unsafe.RecvBufAllocHandle; IByteBuffer buffer = handle.Allocate(this.config.Allocator); handle.AttemptedBytesRead = buffer.WritableBytes; operation.UserToken = buffer; ArraySegment <byte> bytes = buffer.GetIoBuffer(0, buffer.WritableBytes); operation.SetBuffer(bytes.Array, bytes.Offset, bytes.Count); bool pending; #if NETSTANDARD1_3 pending = this.Socket.ReceiveFromAsync(operation); #else if (this.isConnected) { if (ExecutionContext.IsFlowSuppressed()) { pending = this.Socket.ReceiveAsync(operation); } else { using (ExecutionContext.SuppressFlow()) { pending = this.Socket.ReceiveAsync(operation); } } } else { if (ExecutionContext.IsFlowSuppressed()) { pending = this.Socket.ReceiveFromAsync(operation); } else { using (ExecutionContext.SuppressFlow()) { pending = this.Socket.ReceiveFromAsync(operation); } } } #endif if (!pending) { this.EventLoop.Execute(ReceiveFromCompletedSyncCallback, this.Unsafe, operation); } } catch (Exception e) { this.Pipeline.FireExceptionCaught(e); } }
public static bool IsText(IByteBuffer buf, int index, int length, Encoding encoding) { if (buf is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.buf); } if (encoding is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.encoding); } int maxIndex = buf.ReaderIndex + buf.ReadableBytes; if (index < 0 || length < 0 || index > maxIndex - length) { ThrowHelper.ThrowIndexOutOfRangeException_IsText(index, length); } switch (encoding.CodePage) { case TextEncodings.UTF8CodePage: return(IsUtf8(buf, index, length)); case TextEncodings.ASCIICodePage: return(IsAscii(buf, index, length)); default: try { if (buf.IsSingleIoBuffer) { ArraySegment <byte> segment = buf.GetIoBuffer(); _ = encoding.GetChars(segment.Array, segment.Offset, segment.Count); } else { IByteBuffer heapBuffer = buf.Allocator.HeapBuffer(length); try { _ = heapBuffer.WriteBytes(buf, index, length); ArraySegment <byte> segment = heapBuffer.GetIoBuffer(); _ = encoding.GetChars(segment.Array, segment.Offset, segment.Count); } finally { _ = heapBuffer.Release(); } } return(true); } catch { return(false); } } }
public static byte[] ToArray(this IByteBuffer buffer) { if (!buffer.IsReadable()) { return(ArrayExtensions.ZeroBytes); } var segment = buffer.GetIoBuffer(); var result = new byte[segment.Count]; Array.Copy(segment.Array, segment.Offset, result, 0, segment.Count); return(result); }
public static bool IsText(IByteBuffer buf, int index, int length, Encoding encoding) { Contract.Requires(buf != null); Contract.Requires(encoding != null); int maxIndex = buf.ReaderIndex + buf.ReadableBytes; if (index < 0 || length < 0 || index > maxIndex - length) { throw new IndexOutOfRangeException($"index: {index}length: {length}"); } if (ReferenceEquals(Encoding.UTF8, encoding)) { return(IsUtf8(buf, index, length)); } else if (ReferenceEquals(Encoding.ASCII, encoding)) { return(IsAscii(buf, index, length)); } else { try { if (buf.IoBufferCount == 1) { ArraySegment <byte> segment = buf.GetIoBuffer(); encoding.GetChars(segment.Array, segment.Offset, segment.Count); } else { IByteBuffer heapBuffer = buf.Allocator.HeapBuffer(length); try { heapBuffer.WriteBytes(buf, index, length); ArraySegment <byte> segment = heapBuffer.GetIoBuffer(); encoding.GetChars(segment.Array, segment.Offset, segment.Count); } finally { heapBuffer.Release(); } } return(true); } catch { return(false); } } }
public static string DecodeString(IByteBuffer src, int readerIndex, int len, Encoding encoding) { if (0u >= (uint)len) { return(string.Empty); } #if NET451 if (src.IsSingleIoBuffer) { ArraySegment <byte> ioBuf = src.GetIoBuffer(readerIndex, len); return(encoding.GetString(ioBuf.Array, ioBuf.Offset, ioBuf.Count)); } else { int maxLength = encoding.GetMaxCharCount(len); IByteBuffer buffer = src.Allocator.HeapBuffer(maxLength); try { buffer.WriteBytes(src, readerIndex, len); ArraySegment <byte> ioBuf = buffer.GetIoBuffer(); return(encoding.GetString(ioBuf.Array, ioBuf.Offset, ioBuf.Count)); } finally { // Release the temporary buffer again. buffer.Release(); } } #else var source = src.GetReadableSpan(readerIndex, len); #if NETCOREAPP || NETSTANDARD_2_0_GREATER return(encoding.GetString(source)); #else unsafe { fixed(byte *bytes = &MemoryMarshal.GetReference(source)) { return(encoding.GetString(bytes, source.Length)); } } #endif #endif }
public override ArraySegment <byte>[] GetIoBuffers(int index, int length) { this.CheckIndex(index, length); if (length == 0) { return(new[] { EmptyNioBuffer }); } var buffers = new List <ArraySegment <byte> >(this.components.Count); int i = this.ToComponentIndex(index); while (length > 0) { ComponentEntry c = this.components[i]; IByteBuffer s = c.Buffer; int adjustment = c.Offset; int localLength = Math.Min(length, s.Capacity - (index - adjustment)); switch (s.IoBufferCount) { case 0: throw new NotSupportedException(); case 1: buffers.Add(s.GetIoBuffer(index - adjustment, localLength)); break; default: buffers.AddRange(s.GetIoBuffers(index - adjustment, localLength)); break; } index += localLength; length -= localLength; i++; } return(buffers.ToArray()); }
public void TestNioBuffersExpand() { TestChannel channel = new TestChannel(); ChannelOutboundBuffer buffer = new ChannelOutboundBuffer(channel); IByteBuffer buf = Unpooled.DirectBuffer().WriteBytes(Encoding.ASCII.GetBytes("buf1")); for (int i = 0; i < 64; i++) { buffer.AddMessage(buf.Copy(), buf.ReadableBytes, channel.VoidPromise()); } Assert.Equal(0, buffer.NioBufferCount); // Should still be 0 as not flushed yet buffer.AddFlush(); var buffers = buffer.GetSharedBufferList(); Assert.Equal(64, buffer.NioBufferCount); for (int i = 0; i < buffer.NioBufferCount; i++) { Assert.Equal(buffers[i], buf.GetIoBuffer(buf.ReaderIndex, buf.ReadableBytes)); } Release(buffer); buf.Release(); }
/// <summary>Unwraps inbound SSL records.</summary> private void Unwrap(IChannelHandlerContext ctx, IByteBuffer packet, int offset, int length) { bool pending = false; IByteBuffer outputBuffer = null; try { #if NETCOREAPP || NETSTANDARD_2_0_GREATER ReadOnlyMemory <byte> inputIoBuffer = packet.GetReadableMemory(offset, length); _mediationStream.SetSource(inputIoBuffer, ctx.Allocator); #else ArraySegment <byte> inputIoBuffer = packet.GetIoBuffer(offset, length); _mediationStream.SetSource(inputIoBuffer.Array, inputIoBuffer.Offset, ctx.Allocator); #endif if (!EnsureAuthenticationCompleted(ctx)) { _mediationStream.ExpandSource(length); return; } _mediationStream.ExpandSource(length); var currentReadFuture = _pendingSslStreamReadFuture; if (currentReadFuture is object) { // restoring context from previous read Debug.Assert(_pendingSslStreamReadBuffer is object); outputBuffer = _pendingSslStreamReadBuffer; var outputBufferLength = outputBuffer.WritableBytes; _pendingSslStreamReadFuture = null; _pendingSslStreamReadBuffer = null; // there was a read pending already, so we make sure we completed that first if (currentReadFuture.IsCompleted) { if (currentReadFuture.IsFailure()) { // The decryption operation failed ExceptionDispatchInfo.Capture(currentReadFuture.Exception.InnerException).Throw(); } int read = currentReadFuture.Result; if (0u >= (uint)read) { // Stream closed NotifyClosePromise(null); return; } // Now output the result of previous read and decide whether to do an extra read on the same source or move forward outputBuffer.Advance(read); _firedChannelRead = true; ctx.FireChannelRead(outputBuffer); currentReadFuture = null; outputBuffer = null; if (0u >= (uint)_mediationStream.SourceReadableBytes) { // we just made a frame available for reading but there was already pending read so SslStream read it out to make further progress there if (read < outputBufferLength) { // SslStream returned non-full buffer and there's no more input to go through -> // typically it means SslStream is done reading current frame so we skip return; } // we've read out `read` bytes out of current packet to fulfil previously outstanding read outputBufferLength = length - read; if ((uint)(outputBufferLength - 1) > SharedConstants.TooBigOrNegative) // <= 0 { // after feeding to SslStream current frame it read out more bytes than current packet size outputBufferLength = c_fallbackReadBufferSize; } } outputBuffer = ctx.Allocator.Buffer(outputBufferLength); currentReadFuture = ReadFromSslStreamAsync(outputBuffer, outputBufferLength); } } else { // there was no pending read before so we estimate buffer of `length` bytes to be sufficient outputBuffer = ctx.Allocator.Buffer(length); currentReadFuture = ReadFromSslStreamAsync(outputBuffer, length); } // read out the rest of SslStream's output (if any) at risk of going async // using FallbackReadBufferSize - buffer size we're ok to have pinned with the SslStream until it's done reading while (true) { if (currentReadFuture is object) { if (!currentReadFuture.IsCompleted) { break; } if (currentReadFuture.IsFailure()) { // The decryption operation failed ExceptionDispatchInfo.Capture(currentReadFuture.Exception.InnerException).Throw(); } int read = currentReadFuture.Result; if (0u >= (uint)read) { // Stream closed NotifyClosePromise(null); return; } outputBuffer.Advance(read); _firedChannelRead = true; ctx.FireChannelRead(outputBuffer); currentReadFuture = null; outputBuffer = null; if (0u >= (uint)_mediationStream.SourceReadableBytes) { return; } } outputBuffer = ctx.Allocator.Buffer(c_fallbackReadBufferSize); currentReadFuture = ReadFromSslStreamAsync(outputBuffer, c_fallbackReadBufferSize); } pending = true; _pendingSslStreamReadBuffer = outputBuffer; _pendingSslStreamReadFuture = currentReadFuture; } finally { _mediationStream.ResetSource(ctx.Allocator); if (!pending && outputBuffer is object) { if (outputBuffer.IsReadable()) { _firedChannelRead = true; ctx.FireChannelRead(outputBuffer); } else { outputBuffer.SafeRelease(); } } } }
public virtual ArraySegment <byte> GetIoBuffer(int index, int length) => Buf.GetIoBuffer(index, length);
Task <int> ReadFromSslStreamAsync(IByteBuffer outputBuffer, int outputBufferLength) { ArraySegment <byte> outlet = outputBuffer.GetIoBuffer(outputBuffer.WriterIndex, outputBufferLength); return(this.sslStream.ReadAsync(outlet.Array, outlet.Offset, outlet.Count)); }
/// <summary>Unwraps inbound SSL records.</summary> void Unwrap(IChannelHandlerContext ctx, IByteBuffer packet, int offset, int length, List <int> packetLengths, List <object> output) { Contract.Requires(packetLengths.Count > 0); //bool notifyClosure = false; // todo: netty/issues/137 bool pending = false; IByteBuffer outputBuffer = null; try { ArraySegment <byte> inputIoBuffer = packet.GetIoBuffer(offset, length); this.mediationStream.SetSource(inputIoBuffer.Array, inputIoBuffer.Offset); int packetIndex = 0; while (!this.EnsureAuthenticated()) { this.mediationStream.ExpandSource(packetLengths[packetIndex]); if (++packetIndex == packetLengths.Count) { return; } } Task <int> currentReadFuture = this.pendingSslStreamReadFuture; int outputBufferLength; if (currentReadFuture != null) { // restoring context from previous read Contract.Assert(this.pendingSslStreamReadBuffer != null); outputBuffer = this.pendingSslStreamReadBuffer; outputBufferLength = outputBuffer.WritableBytes; this.pendingSslStreamReadFuture = null; this.pendingSslStreamReadBuffer = null; } else { outputBufferLength = 0; } // go through packets one by one (because SslStream does not consume more than 1 packet at a time) for (; packetIndex < packetLengths.Count; packetIndex++) { int currentPacketLength = packetLengths[packetIndex]; this.mediationStream.ExpandSource(currentPacketLength); if (currentReadFuture != null) { // there was a read pending already, so we make sure we completed that first if (!currentReadFuture.IsCompleted) { // we did feed the whole current packet to SslStream yet it did not produce any result -> move to the next packet in input continue; } int read = currentReadFuture.Result; if (read == 0) { //Stream closed return; } // Now output the result of previous read and decide whether to do an extra read on the same source or move forward AddBufferToOutput(outputBuffer, read, output); currentReadFuture = null; outputBuffer = null; if (this.mediationStream.SourceReadableBytes == 0) { // we just made a frame available for reading but there was already pending read so SslStream read it out to make further progress there if (read < outputBufferLength) { // SslStream returned non-full buffer and there's no more input to go through -> // typically it means SslStream is done reading current frame so we skip continue; } // we've read out `read` bytes out of current packet to fulfil previously outstanding read outputBufferLength = currentPacketLength - read; if (outputBufferLength <= 0) { // after feeding to SslStream current frame it read out more bytes than current packet size outputBufferLength = FallbackReadBufferSize; } } else { // SslStream did not get to reading current frame so it completed previous read sync // and the next read will likely read out the new frame outputBufferLength = currentPacketLength; } } else { // there was no pending read before so we estimate buffer of `currentPacketLength` bytes to be sufficient outputBufferLength = currentPacketLength; } outputBuffer = ctx.Allocator.Buffer(outputBufferLength); currentReadFuture = this.ReadFromSslStreamAsync(outputBuffer, outputBufferLength); } // read out the rest of SslStream's output (if any) at risk of going async // using FallbackReadBufferSize - buffer size we're ok to have pinned with the SslStream until it's done reading while (true) { if (currentReadFuture != null) { if (!currentReadFuture.IsCompleted) { break; } int read = currentReadFuture.Result; AddBufferToOutput(outputBuffer, read, output); } outputBuffer = ctx.Allocator.Buffer(FallbackReadBufferSize); currentReadFuture = this.ReadFromSslStreamAsync(outputBuffer, FallbackReadBufferSize); } pending = true; this.pendingSslStreamReadBuffer = outputBuffer; this.pendingSslStreamReadFuture = currentReadFuture; } catch (Exception ex) { this.HandleFailure(ex); throw; } finally { this.mediationStream.ResetSource(); if (!pending && outputBuffer != null) { if (outputBuffer.IsReadable()) { output.Add(outputBuffer); } else { outputBuffer.SafeRelease(); } } } }
/// <summary>Unwraps inbound SSL records.</summary> private void Unwrap(IChannelHandlerContext ctx, IByteBuffer packet, int offset, int length, List <int> packetLengths, List <object> output) { if (0u >= (uint)packetLengths.Count) { ThrowHelper.ThrowArgumentException(); } //bool notifyClosure = false; // todo: netty/issues/137 bool pending = false; IByteBuffer outputBuffer = null; try { #if NETCOREAPP || NETSTANDARD_2_0_GREATER ReadOnlyMemory <byte> inputIoBuffer = packet.GetReadableMemory(offset, length); _mediationStream.SetSource(inputIoBuffer); #else ArraySegment <byte> inputIoBuffer = packet.GetIoBuffer(offset, length); _mediationStream.SetSource(inputIoBuffer.Array, inputIoBuffer.Offset); #endif int packetIndex = 0; while (!EnsureAuthenticated(ctx)) { _mediationStream.ExpandSource(packetLengths[packetIndex]); if ((uint)(++packetIndex) >= (uint)packetLengths.Count) { return; } } var currentReadFuture = _pendingSslStreamReadFuture; int outputBufferLength; if (currentReadFuture is object) { // restoring context from previous read Debug.Assert(_pendingSslStreamReadBuffer is object); outputBuffer = _pendingSslStreamReadBuffer; outputBufferLength = outputBuffer.WritableBytes; _pendingSslStreamReadFuture = null; _pendingSslStreamReadBuffer = null; } else { outputBufferLength = 0; } // go through packets one by one (because SslStream does not consume more than 1 packet at a time) for (; packetIndex < packetLengths.Count; packetIndex++) { int currentPacketLength = packetLengths[packetIndex]; _mediationStream.ExpandSource(currentPacketLength); if (currentReadFuture is object) { // there was a read pending already, so we make sure we completed that first if (!currentReadFuture.IsCompleted) { // we did feed the whole current packet to SslStream yet it did not produce any result -> move to the next packet in input continue; } int read = currentReadFuture.Result; if (0u >= (uint)read) { //Stream closed return; } // Now output the result of previous read and decide whether to do an extra read on the same source or move forward AddBufferToOutput(outputBuffer, read, output); currentReadFuture = null; outputBuffer = null; if (0u >= (uint)_mediationStream.SourceReadableBytes) { // we just made a frame available for reading but there was already pending read so SslStream read it out to make further progress there if (read < outputBufferLength) { // SslStream returned non-full buffer and there's no more input to go through -> // typically it means SslStream is done reading current frame so we skip continue; } // we've read out `read` bytes out of current packet to fulfil previously outstanding read outputBufferLength = currentPacketLength - read; if ((uint)(outputBufferLength - 1) > SharedConstants.TooBigOrNegative) // <= 0 { // after feeding to SslStream current frame it read out more bytes than current packet size outputBufferLength = c_fallbackReadBufferSize; } } else { // SslStream did not get to reading current frame so it completed previous read sync // and the next read will likely read out the new frame outputBufferLength = currentPacketLength; } } else { // there was no pending read before so we estimate buffer of `currentPacketLength` bytes to be sufficient outputBufferLength = currentPacketLength; } outputBuffer = ctx.Allocator.Buffer(outputBufferLength); currentReadFuture = ReadFromSslStreamAsync(outputBuffer, outputBufferLength); } // read out the rest of SslStream's output (if any) at risk of going async // using FallbackReadBufferSize - buffer size we're ok to have pinned with the SslStream until it's done reading while (true) { if (currentReadFuture is object) { if (!currentReadFuture.IsCompleted) { break; } int read = currentReadFuture.Result; AddBufferToOutput(outputBuffer, read, output); } outputBuffer = ctx.Allocator.Buffer(c_fallbackReadBufferSize); currentReadFuture = ReadFromSslStreamAsync(outputBuffer, c_fallbackReadBufferSize); } pending = true; _pendingSslStreamReadBuffer = outputBuffer; _pendingSslStreamReadFuture = currentReadFuture; } finally { _mediationStream.ResetSource(); if (!pending && outputBuffer is object) { if (outputBuffer.IsReadable()) { output.Add(outputBuffer); } else { outputBuffer.SafeRelease(); } } } }
public ArraySegment <byte> GetIoBuffer(int index, int length) { CheckIndex(index, length); return(_buffer.GetIoBuffer(index, length)); }
public void HandlePacket(EndPoint sender, IByteBuffer content) { Console.WriteLine(content.GetString(content.ArrayOffset, content.ReadableBytes, Encoding.UTF8)); try { var identificator = GetHeader(content); var DeserializedPacket = MessagePackSerializer.Deserialize(packetFactory.GetPacketById(identificator), content.GetIoBuffer().ToArray()); } catch (Exception e) { Console.WriteLine(e); } }
public IPacket Deserialize(IByteBuffer byteBuffer) { try { var packet = MessagePackSerializer.Deserialize <BasicPacketCapsule>(byteBuffer.GetIoBuffer().ToArray()); var packetType = _packetFactory.GetPacketById(packet.Identifier); if (packetType == null) { _log.Warn($"Packet with identifier: [{packet.Identifier}] couldn't be found."); return(null); } return(MessagePackSerializer.Deserialize(packetType, packet.Packet) as IPacket); } catch (Exception e) { _log.Error("[DESERIALIZE]", e); return(null); } }
bool Add(IByteBuffer buf) { if (this.count == MaximumLimit) { return(false); } int len = buf.ReadableBytes; if (len == 0) { return(true); } if (this.maxBytes - len < this.size && this.count > 0) { return(false); } IntPtr addr = IntPtr.Zero; if (buf.HasMemoryAddress) { addr = buf.AddressOfPinnedMemory(); } if (addr != IntPtr.Zero) { this.Add(addr, buf.ReaderIndex, len); } else { int bufferCount = buf.IoBufferCount; if (MaximumLimit - bufferCount < this.count) { return(false); } if (bufferCount == 1) { ArraySegment <byte> arraySegment = buf.GetIoBuffer(); byte[] array = arraySegment.Array; GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); this.handles.Add(handle); addr = handle.AddrOfPinnedObject(); this.Add(addr, arraySegment.Offset, arraySegment.Count); } else { ArraySegment <byte>[] segments = buf.GetIoBuffers(); for (int i = 0; i < segments.Length; i++) { GCHandle handle = GCHandle.Alloc(segments[i].Array, GCHandleType.Pinned); this.handles.Add(handle); addr = handle.AddrOfPinnedObject(); this.Add(addr, segments[i].Offset, segments[i].Count); } } } return(true); }
internal void Prepare() { IByteBuffer byteBuffer = this.buffer; int index = byteBuffer.ReaderIndex; int length = byteBuffer.ReadableBytes; IntPtr addr = byteBuffer.AddressOfPinnedMemory(); if (addr != IntPtr.Zero) { this.bufs[0] = new uv_buf_t(addr + index, length); this.size = 1; return; } if (byteBuffer.HasArray) { byte[] array = byteBuffer.Array; GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); this.handles.Add(handle); addr = handle.AddrOfPinnedObject(); this.bufs[0] = new uv_buf_t(addr + this.buffer.ArrayOffset + index, length); this.size = 1; return; } if (byteBuffer.IoBufferCount == 1) { ArraySegment <byte> arraySegment = byteBuffer.GetIoBuffer(index, length); byte[] array = arraySegment.Array; GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); this.handles.Add(handle); addr = handle.AddrOfPinnedObject(); this.bufs[0] = new uv_buf_t(addr + arraySegment.Offset, arraySegment.Count); this.size = 1; return; } ArraySegment <byte>[] segments = byteBuffer.GetIoBuffers(index, length); if (segments.Length > this.bufs.Length) { if (this.pin.IsAllocated) { this.pin.Free(); } this.bufs = new uv_buf_t[segments.Length]; this.pin = GCHandle.Alloc(this.bufs, GCHandleType.Pinned); } for (int i = 0; i < segments.Length; i++) { GCHandle handle = GCHandle.Alloc(segments[i].Array, GCHandleType.Pinned); this.handles.Add(handle); addr = handle.AddrOfPinnedObject(); this.bufs[i] = new uv_buf_t(addr + segments[i].Offset, segments[i].Count); } this.size = segments.Length; }