void Write(IByteBufferAllocator allocator, FullBulkStringRedisMessage message, ICollection <object> output) { Contract.Requires(allocator != null); Contract.Requires(message != null); Contract.Requires(output != null); IByteBuffer buffer = allocator.Buffer( RedisConstants.TypeLength + (message.IsNull ? RedisConstants.NullLength : RedisConstants.LongValueMaximumLength) + RedisConstants.EndOfLineLength); buffer.WriteByte((char)RedisMessageType.BulkString); if (message.IsNull) { buffer.WriteShort(RedisConstants.Null); buffer.WriteShort(RedisConstants.EndOfLine); output.Add(buffer); } else { int readableBytes = message.Content.ReadableBytes; byte[] bytes = this.NumberToBytes(readableBytes); buffer.WriteBytes(bytes); buffer.WriteShort(RedisConstants.EndOfLine); output.Add(buffer); output.Add(message.Content.Retain()); output.Add(allocator .Buffer(RedisConstants.EndOfLineLength) .WriteShort(RedisConstants.EndOfLine)); } }
static void EncodeConnAckMessage(IByteBufferAllocator bufferAllocator, ConnAckPacket message, List <object> output) { IByteBuffer buffer = null; try { buffer = bufferAllocator.Buffer(4); buffer.WriteByte(CalculateFirstByteOfFixedHeader(message)); buffer.WriteByte(2); // remaining length if (message.SessionPresent) { buffer.WriteByte(1); // 7 reserved 0-bits and SP = 1 } else { buffer.WriteByte(0); // 7 reserved 0-bits and SP = 0 } buffer.WriteByte((byte)message.ReturnCode); output.Add(buffer); buffer = null; } finally { buffer?.SafeRelease(); } }
static void EncodeSubAckMessage(IByteBufferAllocator bufferAllocator, SubAckPacket message, List <object> output) { int payloadBufferSize = message.ReturnCodes.Count; int variablePartSize = PacketIdLength + payloadBufferSize; int fixedHeaderBufferSize = 1 + MaxVariableLength; IByteBuffer buf = null; try { buf = bufferAllocator.Buffer(fixedHeaderBufferSize + variablePartSize); buf.WriteByte(CalculateFirstByteOfFixedHeader(message)); WriteVariableLengthInt(buf, variablePartSize); buf.WriteShort(message.PacketId); foreach (QualityOfService qos in message.ReturnCodes) { buf.WriteByte((byte)qos); } output.Add(buf); buf = null; } finally { buf?.SafeRelease(); } }
public MessageFrameBuilder(IByteBufferAllocator alloc, int opcode, FrameType type) { Alloc = alloc; Buffer = alloc.Buffer(); OpCode = opcode; Type = type; }
public IByteBuffer ReadChunk(IByteBufferAllocator allocator) { if (this.IsEndOfInput) { return(null); } long availableBytes = this.input.Length - this.input.Position; int readChunkSize = availableBytes <= 0L ? this.chunkSize : (int)Math.Min(this.chunkSize, availableBytes); bool release = true; IByteBuffer buffer = allocator.Buffer(readChunkSize); try { // transfer to buffer int count = buffer.SetBytesAsync(buffer.WriterIndex, this.input, readChunkSize, CancellationToken.None).Result; buffer.SetWriterIndex(buffer.WriterIndex + count); this.offset += count; release = false; } finally { if (release) { buffer.Release(); } } return(buffer); }
public object Encode(IByteBufferAllocator allocator, object message) { var msg = message as RpcMessage; var name = GetNameBytes(msg.Meta.GetType()); var meta = GetMsgJsonBytes(msg.Meta); var metaLength = 1 + name.Length + meta.Length; var bodyLength = msg.Body != null ? msg.Body.Length : 0; var totalLength = HeaderLength + metaLength + bodyLength; var buffer = allocator.Buffer(totalLength); buffer.WriteIntLE(Magic); buffer.WriteIntLE(metaLength); buffer.WriteIntLE(bodyLength); // 1字节NameLength + Name + M字节Meta buffer.WriteByte(name.Length); buffer.WriteBytes(name); buffer.WriteBytes(meta); if (msg.Body != null && msg.Body.Length > 0) { buffer.WriteBytes(msg.Body); } return(buffer); }
static IByteBuffer EncodeString0(IByteBufferAllocator alloc, string src, Encoding encoding, int extraCapacity) { int length = encoding.GetMaxByteCount(src.Length) + extraCapacity; bool release = true; IByteBuffer dst = alloc.Buffer(length); Contract.Assert(dst.HasArray, "Operation expects allocator to operate array-based buffers."); try { int written = encoding.GetBytes(src, 0, src.Length, dst.Array, dst.ArrayOffset + dst.WriterIndex); dst.SetWriterIndex(dst.WriterIndex + written); release = false; return(dst); } finally { if (release) { dst.Release(); } } }
public void Encrypt(IByteBufferAllocator allocator, EncryptMode mode, Stream src, Stream dst, bool reliable) { using (var data = new BufferWrapper(allocator.Buffer().WithOrder(ByteOrder.LittleEndian))) using (var encryptor = GetAlgorithm(mode).CreateEncryptor()) using (var cs = new CryptoStream(new NonClosingStream(dst), encryptor, CryptoStreamMode.Write)) using (var w = cs.ToBinaryWriter(false)) { var blockSize = AES.BlockSize / 8; var padding = blockSize - (src.Length + 1 + 4) % blockSize; if (reliable) { padding = blockSize - (src.Length + 1 + 4 + 2) % blockSize; } if (reliable) { var counter = (ushort)(Interlocked.Increment(ref _encryptCounter) - 1); data.Buffer.WriteShort(counter); } using (var dataStream = new WriteOnlyByteBufferStream(data.Buffer, false)) src.CopyTo(dataStream); w.Write((byte)padding); using (var dataStream = new ReadOnlyByteBufferStream(data.Buffer, false)) { w.Write(Hash.GetUInt32 <CRC32>(dataStream)); dataStream.Position = 0; dataStream.CopyTo(cs); } w.Fill((int)padding); } }
void WriteArrayHeader(IByteBufferAllocator allocator, long?length, ICollection <object> output) { Contract.Requires(allocator != null); Contract.Requires(output != null); IByteBuffer buffer = allocator.Buffer( RedisConstants.TypeLength + (!length.HasValue ? RedisConstants.NullLength : RedisConstants.LongValueMaximumLength) + RedisConstants.EndOfLineLength); buffer.WriteByte((char)RedisMessageType.ArrayHeader); if (!length.HasValue) { buffer.WriteShort(RedisConstants.Null); } else { byte[] bytes = this.NumberToBytes(length.Value); buffer.WriteBytes(bytes); } buffer.WriteShort(RedisConstants.EndOfLine); output.Add(buffer); }
static void EncodePublishMessage(IByteBufferAllocator bufferAllocator, PublishPacket packet, List <object> output) { IByteBuffer payload = packet.Payload ?? Unpooled.Empty; string topicName = packet.TopicName; Util.ValidateTopicName(topicName); byte[] topicNameBytes = EncodeStringInUtf8(topicName); int variableHeaderBufferSize = StringSizeLength + topicNameBytes.Length + (packet.QualityOfService > QualityOfService.AtMostOnce ? PacketIdLength : 0); int payloadBufferSize = payload.ReadableBytes; int variablePartSize = variableHeaderBufferSize + payloadBufferSize; int fixedHeaderBufferSize = 1 + MaxVariableLength; IByteBuffer buf = bufferAllocator.Buffer(fixedHeaderBufferSize + variablePartSize); buf.WriteByte(CalculateFirstByteOfFixedHeader(packet)); WriteVariableLengthInt(buf, variablePartSize); buf.WriteShort(topicNameBytes.Length); buf.WriteBytes(topicNameBytes); if (packet.QualityOfService > QualityOfService.AtMostOnce) { buf.WriteShort(packet.PacketId); } output.Add(buf); if (payload.IsReadable()) { output.Add(payload.Retain()); } }
/// <summary> /// Create a new object to contain the request data /// </summary> /// <param name="streamId">The stream associated with the request</param> /// <param name="http2Headers">The initial set of HTTP/2 headers to create the request with</param> /// <param name="alloc">The <see cref="IByteBufferAllocator"/> to use to generate the content of the message</param> /// <param name="validateHttpHeaders"><c>true</c> to validate HTTP headers in the http-codec /// <para><c>false</c> not to validate HTTP headers in the http-codec</para></param> /// <returns>A new request object which represents headers/data</returns> /// <exception cref="Http2Exception">see <see cref="AddHttp2ToHttpHeaders(int, IHttp2Headers, IFullHttpMessage, bool)"/></exception> public static IFullHttpRequest ToFullHttpRequest(int streamId, IHttp2Headers http2Headers, IByteBufferAllocator alloc, bool validateHttpHeaders) { // HTTP/2 does not define a way to carry the version identifier that is included in the HTTP/1.1 request line. var method = http2Headers.Method; if (method is null) { ThrowHelper.ThrowArgumentNullException_MethodHeader(); } var path = http2Headers.Path; if (path is null) { ThrowHelper.ThrowArgumentNullException_PathHeader(); } var msg = new DefaultFullHttpRequest(DotNettyHttpVersion.Http11, HttpMethod.ValueOf(AsciiString.Of(method)), path.ToString(), alloc.Buffer(), validateHttpHeaders); try { AddHttp2ToHttpHeaders(streamId, http2Headers, msg, false); } catch (Http2Exception) { _ = msg.Release(); throw; } catch (Exception t) { _ = msg.Release(); ThrowHelper.ThrowStreamError_Http2ToHttp1HeadersConversionError(streamId, t); } return(msg); }
internal static IByteBuffer EncodeString0(IByteBufferAllocator alloc, bool enforceHeap, string src, Encoding encoding, int extraCapacity) { int length = encoding.GetMaxByteCount(src.Length) + extraCapacity; bool release = true; IByteBuffer dst = enforceHeap ? alloc.HeapBuffer(length) : alloc.Buffer(length); Debug.Assert(dst.HasArray, "Operation expects allocator to operate array-based buffers."); try { #if NETCOREAPP || NETSTANDARD_2_0_GREATER int written = encoding.GetBytes(src.AsSpan(), dst.FreeSpan); #else int written = encoding.GetBytes(src, 0, src.Length, dst.Array, dst.ArrayOffset + dst.WriterIndex); #endif dst.SetWriterIndex(dst.WriterIndex + written); release = false; return(dst); } finally { if (release) { dst.Release(); } } }
public static void DoEncode(IByteBufferAllocator bufferAllocator, Packet packet, List <object> output) { IByteBuffer buffer = bufferAllocator.Buffer(); try { // 1 byte PacketType buffer.WriteByte((byte)packet.PacketType); // 4 byte Sequence buffer.WriteInt(packet.Sequence); if (packet is PingPacket pingPacket) { buffer.WriteByte(pingPacket.PingCode); } else if (packet is PongPacket pongPacket) { buffer.WriteByte(pongPacket.PongCode); } else if (packet is MessageReqPacket messageReqPacket) { buffer.WriteShort(messageReqPacket.Code); buffer.WriteInt(messageReqPacket.Body.Length); buffer.WriteBytes(messageReqPacket.Body); } else if (packet is MessageRespPacket messageRespPacket) { buffer.WriteShort(messageRespPacket.Code); buffer.WriteInt(messageRespPacket.Body.Length); buffer.WriteBytes(messageRespPacket.Body); } else if (packet is PushReqPacket pushReqPacket) { buffer.WriteByte((byte)pushReqPacket.PushType); buffer.WriteShort(pushReqPacket.Code); buffer.WriteInt(pushReqPacket.Body.Length); buffer.WriteBytes(pushReqPacket.Body); } else if (packet is PushRespPacket pushRespPacket) { buffer.WriteByte((byte)pushRespPacket.PushType); buffer.WriteShort(pushRespPacket.Code); buffer.WriteInt(pushRespPacket.Body.Length); buffer.WriteBytes(pushRespPacket.Body); } else { throw new ArgumentException("Invalid packet!"); } output.Add(buffer); buffer = null; } finally { buffer?.SafeRelease(); } }
public static IByteBuffer WriteAscii(IByteBufferAllocator alloc, string value) { // ASCII uses 1 byte per char IByteBuffer buf = alloc.Buffer(value.Length); _ = WriteAscii(buf, value); return(buf); }
public static IByteBuffer WriteAscii(IByteBufferAllocator alloc, ICharSequence seq) { // ASCII uses 1 byte per char IByteBuffer buf = alloc.Buffer(seq.Count); _ = WriteAscii(buf, seq); return(buf); }
static void WriteBulkStringContent(IByteBufferAllocator allocator, IBulkStringRedisContent msg, List <object> output) { output.Add(msg.Content.Retain()); if (msg is ILastBulkStringRedisContent) { output.Add(allocator.Buffer(RedisConstants.EndOfLineLength).WriteShort(RedisConstants.EndOfLineShort)); } }
public static IByteBuffer WriteUtf8(IByteBufferAllocator alloc, string value) { // UTF-8 uses max. 3 bytes per char, so calculate the worst case. IByteBuffer buf = alloc.Buffer(Utf8MaxBytes(value)); WriteUtf8(buf, value); return(buf); }
public static IByteBuffer WriteUtf8(IByteBufferAllocator alloc, ICharSequence seq) { // UTF-8 uses max. 3 bytes per char, so calculate the worst case. IByteBuffer buf = alloc.Buffer(Utf8MaxBytes(seq)); WriteUtf8(buf, seq); return(buf); }
static void EncodePacketWithFixedHeaderOnly(IByteBufferAllocator bufferAllocator, Packet packet, List <object> output) { IByteBuffer buffer = bufferAllocator.Buffer(2); buffer.WriteByte(CalculateFirstByteOfFixedHeader(packet)); buffer.WriteByte(0); output.Add(buffer); }
public static IByteBuffer WriteUtf8(IByteBufferAllocator alloc, ICharSequence seq) { // UTF-8 uses max. 3 bytes per char, so calculate the worst case. var maxByteCount = Utf8MaxBytes(seq); IByteBuffer buf = alloc.Buffer(maxByteCount); _ = ReserveAndWriteUtf8(buf, seq, maxByteCount); return(buf); }
internal static IByteBuffer expandCumulation(IByteBufferAllocator alloc, IByteBuffer cumulation, int readable) { IByteBuffer oldCumulation = cumulation; cumulation = alloc.Buffer(oldCumulation.ReadableBytes + readable); cumulation.WriteBytes(oldCumulation); oldCumulation.Release(); return(cumulation); }
void WriteIntegerMessage(IByteBufferAllocator allocator, IntegerRedisMessage msg, List <object> output) { IByteBuffer buf = allocator.Buffer(RedisConstants.TypeLength + RedisConstants.LongMaxLength + RedisConstants.EndOfLineLength); RedisMessageType.Integer.WriteTo(buf); buf.WriteBytes(this.NumberToBytes(msg.Value)); buf.WriteShort(RedisConstants.EndOfLineShort); output.Add(buf); }
static void WriteString(IByteBufferAllocator allocator, RedisMessageType type, string content, List <object> output) { IByteBuffer buf = allocator.Buffer(type.Length + ByteBufferUtil.Utf8MaxBytes(content) + RedisConstants.EndOfLineLength); type.WriteTo(buf); ByteBufferUtil.WriteUtf8(buf, content); buf.WriteShort(RedisConstants.EndOfLineShort); output.Add(buf); }
public IFullHttpMessage CopyIfNeeded(IByteBufferAllocator allocator, IFullHttpMessage msg) { if (msg is IFullHttpRequest request) { var copy = (IFullHttpRequest)request.Replace(allocator.Buffer(0)); _ = copy.Headers.Remove(HttpHeaderNames.Expect); return(copy); } return(null); }
/// <summary> /// Adds a fragment to the block. /// </summary> /// <param name="fragment">the fragment of the headers block to be added.</param> /// <param name="len"></param> /// <param name="alloc">allocator for new blocks if needed.</param> /// <param name="endOfHeaders">flag indicating whether the current frame is the end of the headers. /// This is used for an optimization for when the first fragment is the full /// block. In that case, the buffer is used directly without copying.</param> internal void AddFragment(IByteBuffer fragment, int len, IByteBufferAllocator alloc, bool endOfHeaders) { if (_headerBlock is null) { if (len > _reader._headersDecoder.Configuration.MaxHeaderListSizeGoAway) { HeaderSizeExceeded(); } if (endOfHeaders) { // Optimization - don't bother copying, just use the buffer as-is. Need // to retain since we release when the header block is built. _headerBlock = fragment.ReadRetainedSlice(len); } else { _headerBlock = alloc.Buffer(len).WriteBytes(fragment, len); } return; } if (_reader._headersDecoder.Configuration.MaxHeaderListSizeGoAway - len < _headerBlock.ReadableBytes) { HeaderSizeExceeded(); } if (_headerBlock.IsWritable(len)) { // The buffer can hold the requested bytes, just write it directly. _ = _headerBlock.WriteBytes(fragment, len); } else { // Allocate a new buffer that is big enough to hold the entire header block so far. IByteBuffer buf = alloc.Buffer(_headerBlock.ReadableBytes + len); _ = buf.WriteBytes(_headerBlock).WriteBytes(fragment, len); _ = _headerBlock.Release(); _headerBlock = buf; } }
static void EncodePublishMessage(IByteBufferAllocator bufferAllocator, PublishPacket packet, List <object> output) { //IByteBuffer payload = packet.Payload ?? Unpooled.Empty; IByteBuffer payload; if (packet.Payload == null) { payload = Unpooled.Empty; } else { payload = Unpooled.Buffer(); payload.WriteBytes(packet.Payload); } string topicName = packet.TopicName; Util.ValidateTopicName(topicName); byte[] topicNameBytes = EncodeStringInUtf8(topicName); int variableHeaderBufferSize = StringSizeLength + topicNameBytes.Length + (packet.Qos > MqttQos.AtMostOnce ? PacketIdLength : 0); int payloadBufferSize = payload.ReadableBytes; int variablePartSize = variableHeaderBufferSize + payloadBufferSize; int fixedHeaderBufferSize = 1 + MaxVariableLength; IByteBuffer buf = null; try { buf = bufferAllocator.Buffer(fixedHeaderBufferSize + variablePartSize); buf.WriteByte(CalculateFirstByteOfFixedHeader(packet)); WriteVariableLengthInt(buf, variablePartSize); buf.WriteShort(topicNameBytes.Length); buf.WriteBytes(topicNameBytes); if (packet.Qos > MqttQos.AtMostOnce) { buf.WriteShort(packet.PacketId); } output.Add(buf); buf = null; } finally { buf?.SafeRelease(); } if (payload.IsReadable()) { output.Add(payload.Retain()); } }
void WriteArrayHeader(IByteBufferAllocator allocator, bool isNull, long length, List <object> output) { if (isNull) { IByteBuffer buf = allocator.Buffer(RedisConstants.TypeLength + RedisConstants.NullLength + RedisConstants.EndOfLineLength); RedisMessageType.ArrayHeader.WriteTo(buf); buf.WriteShort(RedisConstants.NullShort); buf.WriteShort(RedisConstants.EndOfLineShort); output.Add(buf); } else { IByteBuffer buf = allocator.Buffer(RedisConstants.TypeLength + RedisConstants.LongMaxLength + RedisConstants.EndOfLineLength); RedisMessageType.ArrayHeader.WriteTo(buf); buf.WriteBytes(this.NumberToBytes(length)); buf.WriteShort(RedisConstants.EndOfLineShort); output.Add(buf); } }
public IByteBuffer Buffer(int initialCapacity, int maxCapacity) { // If the capacity values are negative then clamp them at zero. initialCapacity = initialCapacity >= 0 ? initialCapacity : 0; maxCapacity = maxCapacity >= 0 ? maxCapacity : 0; Debug.Assert(initialCapacity >= 0); Debug.Assert(maxCapacity >= 0); if (initialCapacity == 0 && maxCapacity == 0) { return(DelegateAllocator.Buffer(0, 0)); // Will returned a reusable EmptyBuffer. } // If the capacity values, after adding padding, are too large then clamp them at int.MaxValue. long maxCapLong = (long)maxCapacity + BufferFrontPadding; long initCapLong = (long)initialCapacity + BufferFrontPadding; var clampedMaxCapacity = maxCapLong > int.MaxValue ? int.MaxValue : (int)maxCapLong; var clampedInitialCapacity = initCapLong > int.MaxValue ? int.MaxValue : (int)initCapLong; Debug.Assert(clampedMaxCapacity >= 0 && clampedMaxCapacity <= int.MaxValue); Debug.Assert(clampedInitialCapacity >= 0 && clampedInitialCapacity <= int.MaxValue); // Allocate the buffer, and write the padding mask in the padding section // so that it's easy to see it when debugging. var buffer = DelegateAllocator.Buffer(clampedInitialCapacity, clampedMaxCapacity); var writerIndex = buffer.WriterIndex; var writerIndexAfterPadding = writerIndex + BufferFrontPadding; buffer.SetInt(writerIndex, PaddingMask); buffer.SetWriterIndex(writerIndexAfterPadding); buffer.MarkWriterIndex(); buffer.SetReaderIndex(writerIndexAfterPadding); buffer.MarkReaderIndex(); return(buffer); }
public void BufferWithCapacity(bool preferDirect, int maxCapacity) { IByteBufferAllocator allocator = this.NewAllocator(preferDirect); IByteBuffer buffer = allocator.Buffer(1, maxCapacity); try { AssertBuffer(buffer, this.IsDirectExpected(preferDirect), 1, maxCapacity); } finally { buffer.Release(); } }
public void BufferWithCapacity() { IByteBufferAllocator allocator = this.NewAllocator(); IByteBuffer buffer = allocator.Buffer(1, 8); try { AssertBuffer(buffer, 1, 8); } finally { buffer.Release(); } }
static IByteBuffer ExpandCumulation(IByteBufferAllocator allocator, IByteBuffer cumulation, int readable) { IByteBuffer oldCumulation = cumulation; cumulation = allocator.Buffer(oldCumulation.ReadableBytes + readable); cumulation.WriteBytes(oldCumulation); oldCumulation.Release(); return cumulation; }
public static async Task<PublishPacket> ComposePublishPacketAsync(IChannelHandlerContext context, IMessage message, QualityOfService qos, string topicName, IByteBufferAllocator allocator) { bool duplicate = message.DeliveryCount > 0; var packet = new PublishPacket(qos, duplicate, false); packet.TopicName = topicName; if (qos > QualityOfService.AtMostOnce) { int packetId = unchecked((int)message.SequenceNumber) & 0x3FFF; // clear bits #14 and #15 switch (qos) { case QualityOfService.AtLeastOnce: break; case QualityOfService.ExactlyOnce: packetId |= 0x8000; // set bit #15 break; default: throw new ArgumentOutOfRangeException(nameof(qos), qos, null); } packet.PacketId = packetId + 1; } using (Stream payloadStream = message.Payload) { long streamLength = payloadStream.Length; if (streamLength > int.MaxValue) { throw new InvalidOperationException($"Message size ({streamLength} bytes) is too big to process."); } int length = (int)streamLength; IByteBuffer buffer = allocator.Buffer(length, length); await buffer.WriteBytesAsync(payloadStream, length); Contract.Assert(buffer.ReadableBytes == length); packet.Payload = buffer; } return packet; }
public IByteBuffer Allocate(IByteBufferAllocator alloc) => alloc.Buffer(this.bufferSize);
public IByteBuffer Allocate(IByteBufferAllocator alloc) { return alloc.Buffer(this.bufferSize); }
static IByteBuffer EncodeString0(IByteBufferAllocator alloc, string src, Encoding encoding, int extraCapacity) { int length = encoding.GetMaxByteCount(src.Length) + extraCapacity; bool release = true; IByteBuffer dst = alloc.Buffer(length); Contract.Assert(dst.HasArray, "Operation expects allocator to operate array-based buffers."); try { int written = encoding.GetBytes(src, 0, src.Length, dst.Array, dst.ArrayOffset + dst.WriterIndex); dst.SetWriterIndex(dst.WriterIndex + written); release = false; return dst; } finally { if (release) { dst.Release(); } } }
/// <summary> /// Read the given amount of bytes into a new {@link ByteBuf} that is allocated from the {@link ByteBufAllocator}. /// </summary> public static IByteBuffer ReadBytes(IByteBufferAllocator alloc, IByteBuffer buffer, int length) { bool release = true; IByteBuffer dst = alloc.Buffer(length); try { buffer.ReadBytes(dst); release = false; return dst; } finally { if (release) { dst.Release(); } } }