/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.f1x.io.disruptor; import org.f1x.io.parsers.BodyLengthParser; import org.f1x.util.ByteRingReader; @Deprecated public class ByteRingProducer implements Runnable { private static final int SIZE_OF_INT32 = 4; //8=FIX.X.X|9=A|35=?|34=?|10=123| //123456789012345678901234567890 private static final int MINIMUM_FIX_MESSAGE_SIZE = 30; // minimum size of valid message (we only need to be sure this block contains MsgLen field // We encode length using 4 bytes (maximum size of *single* FIX message is limited to 4Gb) private final ByteRing ring; private final RingBufferBlockProcessor byteProducer; private final ByteRingReader reader; public ByteRingProducer(ByteRing ring, RingBufferBlockProcessor byteProducer) { this.ring = ring; this.reader = ring.createByteRingReader(); this.byteProducer = byteProducer; } @Override public void run() { while (true) { //TODO: Nicer break condition readSingleMessage(); } } private void readSingleMessage () { // Step 1: Claim space for the prefix that will contain parsed message length and the first (MINIMUM_FIX_MESSAGE_SIZE) bytes of the message final int blockSize = MINIMUM_FIX_MESSAGE_SIZE + SIZE_OF_INT32; final long high = ring.next(blockSize); final long low = high - blockSize + 1; final int messageOffset = ring.index(low + SIZE_OF_INT32); ring.processBlock(low + SIZE_OF_INT32, MINIMUM_FIX_MESSAGE_SIZE, byteProducer); // Step 2: Parse BodyLength(9) to figure out length of entire message reader.reset(messageOffset, MINIMUM_FIX_MESSAGE_SIZE); final int remainingMessageSize = BodyLengthParser.getRemainingMessageSize(reader); // Step 3: Store total message length ring.writeInt(low, MINIMUM_FIX_MESSAGE_SIZE + remainingMessageSize); // Step 4: Claim space for the rest of the message final long high1 = ring.next(remainingMessageSize); final long low1 = high1 - remainingMessageSize + 1; ring.processBlock(low1, remainingMessageSize, byteProducer); ring.publish(high); // publish whole message with 4-byte length prefix } }