public boolean write(final int msgTypeId, final DirectBuffer srcBuffer, final int offset, final int length)
    {
        checkTypeId(msgTypeId);
        checkMsgLength(length);

        final AtomicBuffer buffer = this.buffer;
        final int recordLength = length + HEADER_LENGTH;
        final int recordIndex = claimCapacity(buffer, recordLength);

        if (INSUFFICIENT_CAPACITY == recordIndex)
        {
            return false;
        }

        buffer.putIntOrdered(lengthOffset(recordIndex), -recordLength);
        MemoryAccess.releaseFence();

        buffer.putBytes(encodedMsgOffset(recordIndex), srcBuffer, offset, length);
        buffer.putInt(typeOffset(recordIndex), msgTypeId);
        buffer.putIntOrdered(lengthOffset(recordIndex), recordLength);

        return true;
    }
@Test
    void shouldInsertPaddingAndWriteToBuffer()
    {
        final int padding = 200;
        final int messageLength = 400;
        final int recordLength = messageLength + HEADER_LENGTH;
        final int alignedRecordLength = align(recordLength, ALIGNMENT);

        final long tail = 2 * CAPACITY - padding;
        final long head = tail;

        // free space is (200 + 300) more than message length (400)
        // but contiguous space (300) is less than message length (400)
        final long headCache = CAPACITY + 300;

        when(buffer.getLongVolatile(HEAD_COUNTER_INDEX)).thenReturn(head);
        when(buffer.getLongVolatile(TAIL_COUNTER_INDEX)).thenReturn(tail);
        when(buffer.getLongVolatile(HEAD_COUNTER_CACHE_INDEX)).thenReturn(headCache);
        when(buffer.compareAndSetLong(TAIL_COUNTER_INDEX, tail, tail + alignedRecordLength + padding))
            .thenReturn(true);

        final UnsafeBuffer srcBuffer = new UnsafeBuffer(new byte[messageLength]);

        assertTrue(ringBuffer.write(MSG_TYPE_ID, srcBuffer, 0, messageLength));
    }