예제 #1
0
        public bool TryGet(TKey name, out TValue value)
        {
            if (name is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.name);
            }

            bool found = false;
            int  h     = _hashingStrategy.HashCode(name);
            int  i     = Index(h);
            HeaderEntry <TKey, TValue> e = _entries[i];

            value = default;
            // loop until the first header was found
            while (e is object)
            {
                if (e.Hash == h && _hashingStrategy.Equals(name, e._key))
                {
                    value = e._value;
                    found = true;
                }

                e = e.Next;
            }
            return(found);
        }
예제 #2
0
 public void ValidateName(T name)
 {
     if (name is null)
     {
         CThrowHelper.ThrowArgumentNullException(CExceptionArgument.name);
     }
 }
예제 #3
0
        public DefaultHeaders(IHashingStrategy <TKey> nameHashingStrategy,
                              IValueConverter <TValue> valueConverter, INameValidator <TKey> nameValidator, int arraySizeHint)
        {
            if (nameHashingStrategy is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.nameHashingStrategy);
            }
            if (valueConverter is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.valueConverter);
            }
            if (nameValidator is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.nameValidator);
            }

            _hashingStrategy = nameHashingStrategy;
            ValueConverter   = valueConverter;
            _nameValidator   = nameValidator;

            // Enforce a bound of [2, 128] because hashMask is a byte. The max possible value of hashMask is one less
            // than the length of this array, and we want the mask to be > 0.
            _entries  = new HeaderEntry <TKey, TValue> [FindNextPositivePowerOfTwo(Math.Max(2, Math.Min(arraySizeHint, 128)))];
            _hashMask = (byte)(_entries.Length - 1);
            _head     = new HeaderEntry <TKey, TValue>();
        }
예제 #4
0
 public static DecoderResult Failure(Exception cause)
 {
     if (cause is null)
     {
         CThrowHelper.ThrowArgumentNullException(CExceptionArgument.cause);
     }
     return(new DecoderResult(cause));
 }
예제 #5
0
 protected DecoderResult(Exception cause)
 {
     if (cause is null)
     {
         CThrowHelper.ThrowArgumentNullException(CExceptionArgument.cause);
     }
     this.cause = cause;
 }
예제 #6
0
        public bool ContainsObject(TKey name, object value)
        {
            if (value is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.value);
            }

            return(Contains(name, ValueConverter.ConvertObject(value)));
        }
예제 #7
0
        /// <summary>
        /// Create a <see cref="DatagramPacket"/> decoder using the specified <see cref="IByteBuffer"/> decoder.
        /// </summary>
        /// <param name="decoder">the specified <see cref="IByteBuffer"/> decoder</param>
        public DatagramPacketDecoder(MessageToMessageDecoder <IByteBuffer> decoder)
        {
            if (decoder is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.decoder);
            }

            this.decoder = decoder;
        }
예제 #8
0
        /// <summary>
        /// Create an encoder that encodes the content in <see cref="IAddressedEnvelope{T}"/> to <see cref="DatagramPacket"/> using
        /// the specified message encoder.
        /// </summary>
        /// <param name="encoder">the specified message encoder</param>
        public DatagramPacketEncoder(MessageToMessageEncoder <T> encoder)
        {
            if (encoder is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.encoder);
            }

            this.encoder = encoder;
        }
예제 #9
0
        /// <summary>
        /// Allocate a <see cref="IByteBuffer"/> which will be used as argument of <see cref="Encode(IChannelHandlerContext, T, IByteBuffer)"/>.
        /// Sub-classes may override this method to return <see cref="IByteBuffer"/> with a perfect matching <c>initialCapacity</c>.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        protected virtual IByteBuffer AllocateBuffer(IChannelHandlerContext context)
        {
            if (context is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.context);
            }

            return(context.Allocator.Buffer());
        }
예제 #10
0
        /// <summary>
        /// Set the <see cref="ICumulator"/> to use for cumulate the received <see cref="IByteBuffer"/>s.
        /// </summary>
        /// <param name="cumulator"></param>
        public void SetCumulator(ICumulator cumulator)
        {
            if (cumulator is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.cumulator);
            }

            _cumulator = cumulator;
        }
예제 #11
0
        public virtual IHeaders <TKey, TValue> AddObject(TKey name, object value)
        {
            if (value is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.value);
            }

            return(Add(name, ValueConverter.ConvertObject(value)));
        }
예제 #12
0
        public virtual IHeaders <TKey, TValue> SetObject(TKey name, object value)
        {
            if (value is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.value);
            }

            TValue convertedValue = ValueConverter.ConvertObject(value);

            return(Set(name, convertedValue));
        }
예제 #13
0
        public bool TryGetAndRemove(TKey name, out TValue value)
        {
            if (name is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.name);
            }

            int h = _hashingStrategy.HashCode(name);

            return(TryRemove0(h, Index(h), name, out value));
        }
예제 #14
0
        /// <inheritdoc />
        public override void Write(IChannelHandlerContext context, object message, IPromise promise)
        {
            if (context is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.context);
            }

            IByteBuffer buffer = null;

            try
            {
                if (this.AcceptOutboundMessage(message))
                {
                    var input = (T)message;
                    buffer = this.AllocateBuffer(context);
                    try
                    {
                        this.Encode(context, input, buffer);
                    }
                    finally
                    {
                        _ = ReferenceCountUtil.Release(input);
                    }

                    if (buffer.IsReadable())
                    {
                        _ = context.WriteAsync(buffer, promise);
                    }
                    else
                    {
                        _ = buffer.Release();
                        _ = context.WriteAsync(Unpooled.Empty, promise);
                    }

                    buffer = null;
                }
                else
                {
                    _ = context.WriteAsync(message, promise);
                }
            }
            catch (EncoderException)
            {
                throw;
            }
            catch (Exception ex)
            {
                CThrowHelper.ThrowEncoderException(ex);
            }
            finally
            {
                _ = (buffer?.Release());
            }
        }
예제 #15
0
            public ValueEnumerator(DefaultHeaders <TKey, TValue> headers, TKey name)
            {
                if (name is null)
                {
                    CThrowHelper.ThrowArgumentNullException(CExceptionArgument.name);
                }

                _hashingStrategy = headers._hashingStrategy;
                _hash            = _hashingStrategy.HashCode(name);
                _name            = name;
                _node            = _head = headers._entries[headers.Index(_hash)];
                _current         = default;
            }
예제 #16
0
        public virtual IHeaders <TKey, TValue> Add(TKey name, TValue value)
        {
            if (value == null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.value);
            }

            _nameValidator.ValidateName(name);
            int h = _hashingStrategy.HashCode(name);
            int i = Index(h);

            Add0(h, i, name, value);
            return(this);
        }
예제 #17
0
        public TValue SetValue(TValue newValue)
        {
            if (_isReadonly)
            {
                CThrowHelper.ThrowNotSupportedException_Readonly();
            }
            if (newValue == null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.newValue);
            }

            TValue oldValue = _value;

            _value = newValue;
            return(oldValue);
        }
예제 #18
0
        public static DateTime? ParseHttpDate(ICharSequence txt, int start, int end)
        {
            if (txt is null) { CThrowHelper.ThrowArgumentNullException(CExceptionArgument.txt); }

            int length = end - start;
            if (0u >= (uint)length)
            {
                return null;
            }
            else if (length < 0)
            {
                CThrowHelper.ThrowArgumentException_CannotHaveEndStart();
            }
            else if (length > 64)
            {
                CThrowHelper.ThrowArgumentException_CannotParseMoreThan64Chars();
            }

            return Formatter().Parse0(txt, start, end);
        }
예제 #19
0
        public bool Contains(TKey name, TValue value, IHashingStrategy <TValue> valueHashingStrategy)
        {
            if (name is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.name);
            }

            int h = _hashingStrategy.HashCode(name);
            int i = Index(h);
            HeaderEntry <TKey, TValue> e = _entries[i];

            while (e is object)
            {
                if (e.Hash == h && _hashingStrategy.Equals(name, e._key) &&
                    valueHashingStrategy.Equals(value, e._value))
                {
                    return(true);
                }
                e = e.Next;
            }
            return(false);
        }
예제 #20
0
        public virtual IList <TValue> GetAll(TKey name)
        {
            if (name is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.name);
            }

            var values = new List <TValue>();
            int h      = _hashingStrategy.HashCode(name);
            int i      = Index(h);
            HeaderEntry <TKey, TValue> e = _entries[i];

            while (e is object)
            {
                if (e.Hash == h && _hashingStrategy.Equals(name, e._key))
                {
                    values.Insert(0, e._value);
                }

                e = e.Next;
            }
            return(values);
        }
예제 #21
0
        public virtual IHeaders <TKey, TValue> SetObject(TKey name, IEnumerable <object> values)
        {
            if (values is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.values);
            }

            _nameValidator.ValidateName(name);
            int h = _hashingStrategy.HashCode(name);
            int i = Index(h);

            _ = TryRemove0(h, i, name, out _);
            // ReSharper disable once PossibleNullReferenceException
            foreach (object v in values)
            {
                if (v is null)
                {
                    break;
                }
                Add0(h, i, name, ValueConverter.ConvertObject(v));
            }

            return(this);
        }
예제 #22
0
        /// <summary>
        /// Called once data should be decoded from the given <see cref="IByteBuffer"/>. This method will call
        /// <see cref="Decode(IChannelHandlerContext, IByteBuffer, List{object})"/> as long as decoding should take place.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="input"></param>
        /// <param name="output"></param>
        protected virtual void CallDecode(IChannelHandlerContext context, IByteBuffer input, List <object> output)
        {
            if (context is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.context);
            }
            if (input is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.input);
            }
            if (output is null)
            {
                CThrowHelper.ThrowArgumentNullException(CExceptionArgument.output);
            }

            try
            {
                while (input.IsReadable())
                {
                    int initialOutputCount = output.Count;
                    if ((uint)initialOutputCount > 0u)
                    {
                        FireChannelRead(context, output, initialOutputCount);
                        output.Clear();

                        // Check if this handler was removed before continuing with decoding.
                        // If it was removed, it is not safe to continue to operate on the buffer.
                        //
                        // See:
                        // - https://github.com/netty/netty/issues/4635
                        if (context.IsRemoved)
                        {
                            break;
                        }
                        initialOutputCount = 0;
                    }

                    int oldInputLength = input.ReadableBytes;
                    DecodeRemovalReentryProtection(context, input, output);

                    // Check if this handler was removed before continuing the loop.
                    // If it was removed, it is not safe to continue to operate on the buffer.
                    //
                    // See https://github.com/netty/netty/issues/1664
                    if (context.IsRemoved)
                    {
                        break;
                    }

                    bool noOutgoingMessages = 0u >= (uint)(oldInputLength - input.ReadableBytes);
                    if (0u >= (uint)(initialOutputCount - output.Count))
                    {
                        // no outgoing messages have been produced

                        if (noOutgoingMessages)
                        {
                            break;
                        }
                        else
                        {
                            continue;
                        }
                    }

                    if (noOutgoingMessages)
                    {
                        CThrowHelper.ThrowDecoderException_ByteToMessageDecoder(GetType());
                    }

                    if (SingleDecode)
                    {
                        break;
                    }
                }
            }
            catch (DecoderException)
            {
                throw;
            }
            catch (Exception cause)
            {
                CThrowHelper.ThrowDecoderException(cause);
            }
        }