public void ShouldFragmentMessageOverTwoFrames() { int msgLength = MaxPayloadLength + 1; int headerLength = _defaultHeader.Capacity; int frameLength = headerLength + 1; int requiredCapacity = BitUtil.Align(headerLength + 1, FrameDescriptor.FRAME_ALIGNMENT) + MaxFrameLength; UnsafeBuffer buffer = new UnsafeBuffer(new byte[msgLength]); int tail = 0; _logMetaDataBuffer.PutLong(TermTailCounterOffset, LogBufferDescriptor.PackTail(TermID, tail)); Assert.That(_termAppender.AppendFragmentedMessage(_headerWriter, buffer, 0, msgLength, MaxPayloadLength, RVS), Is.EqualTo((long)requiredCapacity)); Assert.AreEqual(LogBufferDescriptor.RawTailVolatile(_logMetaDataBuffer, PartionIndex), LogBufferDescriptor.PackTail(TermID, tail + requiredCapacity)); A.CallTo(() => _headerWriter.Write(_termBuffer, tail, MaxFrameLength, TermID)).MustHaveHappened() .Then(A.CallTo(() => _termBuffer.PutBytes(tail + headerLength, buffer, 0, MaxPayloadLength)).MustHaveHappened()) .Then(A.CallTo(() => _termBuffer.PutByte(FrameDescriptor.FlagsOffset(tail), FrameDescriptor.BEGIN_FRAG_FLAG)).MustHaveHappened()) .Then(A.CallTo(() => _termBuffer.PutLong(tail + DataHeaderFlyweight.RESERVED_VALUE_OFFSET, RV)).MustHaveHappened()) .Then(A.CallTo(() => _termBuffer.PutIntOrdered(tail, MaxFrameLength)).MustHaveHappened()) .Then(A.CallTo(() => _headerWriter.Write(_termBuffer, MaxFrameLength, frameLength, TermID)).MustHaveHappened()) .Then(A.CallTo(() => _termBuffer.PutBytes(MaxFrameLength + headerLength, buffer, MaxPayloadLength, 1)).MustHaveHappened()) .Then(A.CallTo(() => _termBuffer.PutByte(FrameDescriptor.FlagsOffset(MaxFrameLength), FrameDescriptor.END_FRAG_FLAG)).MustHaveHappened()) .Then(A.CallTo(() => _termBuffer.PutLong(MaxFrameLength + DataHeaderFlyweight.RESERVED_VALUE_OFFSET, RV)).MustHaveHappened()) .Then(A.CallTo(() => _termBuffer.PutIntOrdered(MaxFrameLength, frameLength)).MustHaveHappened()); }
/// <summary> /// Return an initialised default Data Frame Header. /// </summary> /// <param name="sessionId"> for the header </param> /// <param name="streamId"> for the header </param> /// <param name="termId"> for the header </param> /// <returns> byte array containing the header </returns> public static UnsafeBuffer CreateDefaultHeader(int sessionId, int streamId, int termId) { var buffer = new UnsafeBuffer(new byte[HEADER_LENGTH]); buffer.PutByte(VERSION_FIELD_OFFSET, CURRENT_VERSION); buffer.PutByte(FLAGS_FIELD_OFFSET, (byte)BEGIN_AND_END_FLAGS); buffer.PutShort(TYPE_FIELD_OFFSET, HDR_TYPE_DATA); buffer.PutInt(SESSION_ID_FIELD_OFFSET, sessionId); buffer.PutInt(STREAM_ID_FIELD_OFFSET, streamId); buffer.PutInt(TERM_ID_FIELD_OFFSET, termId); buffer.PutLong(RESERVED_VALUE_OFFSET, DEFAULT_RESERVE_VALUE); return(buffer); }
/// <summary> /// Return an initialised default Data Frame Header. /// </summary> /// <param name="sessionId"> for the header </param> /// <param name="streamId"> for the header </param> /// <param name="termId"> for the header </param> /// <returns> byte array containing the header </returns> public static UnsafeBuffer CreateDefaultHeader(int sessionId, int streamId, int termId) { var buffer = new UnsafeBuffer(BufferUtil.AllocateDirectAligned(HEADER_LENGTH, FrameDescriptor.FRAME_ALIGNMENT)); buffer.PutByte(VERSION_FIELD_OFFSET, CURRENT_VERSION); buffer.PutByte(FLAGS_FIELD_OFFSET, (byte)BEGIN_AND_END_FLAGS); buffer.PutShort(TYPE_FIELD_OFFSET, HDR_TYPE_DATA); buffer.PutInt(SESSION_ID_FIELD_OFFSET, sessionId); buffer.PutInt(STREAM_ID_FIELD_OFFSET, streamId); buffer.PutInt(TERM_ID_FIELD_OFFSET, termId); buffer.PutLong(RESERVED_VALUE_OFFSET, DEFAULT_RESERVE_VALUE); return(buffer); }
/// <summary> /// Set the value of the header flags field. /// </summary> /// <param name="flags"> value to be set in the header. </param> /// <returns> this for a fluent API. </returns> /// <seealso cref="DataHeaderFlyweight"></seealso> public BufferClaim Flags(byte flags) { _buffer.PutByte(HeaderFlyweight.FLAGS_FIELD_OFFSET, flags); return(this); }