/// <summary> /// Creates a frame with the specified parameters. /// Fixes common issues with frame creation. /// </summary> /// <param name="bytes">Byte buffer to add to this frame.</param> /// <param name="type">Type of frame to create.</param> /// <param name="config">Socket configurations for the frame to use.</param> /// <returns>Configured frame.</returns> public static MqFrame CreateFrame(byte[] bytes, MqFrameType type, MqConfig config) { if (type == MqFrameType.Ping || type == MqFrameType.Empty || type == MqFrameType.EmptyLast) { bytes = null; } return(new MqFrame(bytes, type, config)); }
/// <summary> /// Creates a new frame wit the specified bytes and configurations. /// </summary> /// <param name="bytes">Byte buffer to use for this frame.</param> /// <param name="type">Initial type of frame to create.</param> /// <param name="config">Socket configurations used for creating and finalizing this frame.</param> public MqFrame(byte[] bytes, MqFrameType type, MqConfig config) { if (config == null) { throw new ArgumentNullException(nameof(config), "Configurations can not be null."); } _config = config; if (bytes?.Length > _config.FrameBufferSize) { throw new ArgumentException( "Byte array passed is larger than the maximum frame size allowed. Must be less than " + config.FrameBufferSize, nameof(bytes)); } _buffer = bytes; FrameType = type; }
/// <summary> /// Creates a frame with the specified bytes and the current configurations. /// </summary> /// <param name="bytes">Bytes to put in the frame.</param> /// <param name="type">Type of frame to create.</param> /// <returns>Configured frame.</returns> public MqFrame CreateFrame(byte[] bytes, MqFrameType type) { return(Utilities.CreateFrame(bytes, type, Config)); }
/// <summary> /// Completes the current frame and adds it to the frame list. /// </summary> private void EnqueueAndReset() { Frames.Enqueue(new MqFrame(_currentFrameData, _currentFrameType, _config)); _currentFrameType = MqFrameType.Unset; _currentFrameData = null; }
/// <summary> /// Writes the specified partial bytes to the FrameBuilder and parses them as they are copied. /// </summary> /// <param name="buffer">Byte buffer to write and parse.</param> /// <param name="offset">Offset in the byte buffer to copy from.</param> /// <param name="count">Number of bytes to write into the builder.</param> private void WriteInternalPart(byte[] buffer, int offset, int count) { // Write the incoming bytes to the stream. WriteInternal(buffer, offset, count); // Loop until we require more data while (true) { if (_currentFrameType == MqFrameType.Unset) { var frameTypeBytes = new byte[1]; // This will always return one byte. ReadInternal(frameTypeBytes, 0, 1); if (frameTypeBytes[0] > _maxTypeEnum) { throw new InvalidDataException( $"FrameBuilder was sent a frame with an invalid type. Type sent: {frameTypeBytes[0]}"); } _currentFrameType = (MqFrameType)frameTypeBytes[0]; } if (_currentFrameType == MqFrameType.Empty || _currentFrameType == MqFrameType.EmptyLast || _currentFrameType == MqFrameType.Ping) { EnqueueAndReset(); break; } // Read the length from the stream if there are enough buffer. if (_currentFrameData == null && _streamLength >= 2) { var frameLen = new byte[2]; ReadInternal(frameLen, 0, frameLen.Length); var currentFrameLength = BitConverter.ToUInt16(frameLen, 0); if (currentFrameLength < 1) { throw new InvalidDataException( $"FrameBuilder was sent a frame with an invalid size of {currentFrameLength}"); } if (currentFrameLength > _internalBuffer.Length) { throw new InvalidDataException( $"Frame size is {currentFrameLength} while the maximum size for frames is 16KB."); } _currentFrameData = new byte[currentFrameLength]; // Set the stream back to the position it was at to begin with. //buffer_stream.Position = original_position; } // Read the data into the frame holder. if (_currentFrameData != null && _streamLength >= _currentFrameData.Length) { ReadInternal(_currentFrameData, 0, _currentFrameData.Length); // Create the frame and enqueue it. EnqueueAndReset(); // If we are at the end of the data, complete this loop and wait for more data. if (_writePosition == _readPosition) { break; } } else { break; } } }