예제 #1
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);
            }
        }