internal override void Parse()

in src/Proton/Engine/Implementation/ProtonFrameDecodingHandler.cs [360:432]


         internal override void Parse(IEngineHandlerContext context, IProtonBuffer input)
         {
            int dataOffset = (input.ReadUnsignedByte() << 2) & 0x3FF;
            int frameSize = length + FRAME_SIZE_BYTES;

            ValidateDataOffset(dataOffset, frameSize);

            byte type = input.ReadUnsignedByte();
            ushort channel = input.ReadUnsignedShort();

            // Skip over the extended header if present (i.e offset > 8)
            if (dataOffset != 8)
            {
               input.ReadOffset += dataOffset - 8;
            }

            long frameBodySize = frameSize - dataOffset;

            IProtonBuffer payload = null;
            object val;

            if (frameBodySize > 0)
            {
               long startReadIndex = input.ReadOffset;
               val = handler.decoder.ReadObject(input, handler.decoderState);

               // Copy the payload portion of the incoming bytes for now as the incoming may be
               // from a wrapped pooled buffer and for now we have no way of retaining or otherwise
               // ensuring that the buffer remains ours.  Since we might want to store received
               // data at a client level and decode later we could end up losing the data to reuse
               // if it was pooled.
               if (input.IsReadable)
               {
                  long payloadSize = frameBodySize - (input.ReadOffset - startReadIndex);
                  // Check that the remaining bytes aren't part of another frame.
                  if (payloadSize > 0)
                  {
                     payload = handler.configuration.BufferAllocator.Allocate(payloadSize, payloadSize);

                     input.CopyInto(input.ReadOffset, payload, 0, payloadSize);

                     input.ReadOffset += payloadSize;
                     payload.WriteOffset += payloadSize;
                  }
               }
            }
            else
            {
               handler.TransitionToFrameSizeParsingStage();
               context.FireRead(EmptyEnvelope.Instance);
               return;
            }

            if (type == AMQP_FRAME_TYPE)
            {
               IPerformative performative = (IPerformative)val;
               IncomingAmqpEnvelope frame = handler.framePool.Take(performative, channel, payload);
               handler.TransitionToFrameSizeParsingStage();
               context.FireRead(frame);
            }
            else if (type == SASL_FRAME_TYPE)
            {
               ISaslPerformative performative = (ISaslPerformative)val;
               SaslEnvelope saslFrame = new(performative);
               handler.TransitionToFrameSizeParsingStage();
               // Ensure we process transition from SASL to AMQP header state
               handler.HandleRead(context, saslFrame);
            }
            else
            {
               throw new FrameDecodingException(string.Format("unknown frame type: {0}", type));
            }
         }