in FixAntenna/NetCore/FixEngine/Transport/NewMessageChopper.cs [126:346]
public void ReadMessage(MsgBuf buf)
{
var message = buf.FixMessage;
if (message == null)
{
message = new FixMessage();
buf.FixMessage = message;
}
if (_parsedOffset == _readOffset)
{
_parsedOffset = _readOffset = 0; // no data left in buffer, roll back to the beginning
}
else
{
if (_readOffset > SocketReadSize / 2)
{
var availData = _readOffset - _parsedOffset;
var tail = SocketReadSize - _readOffset;
if (availData < 256 || tail < 1024) // preventive data move ?
{
Array.Copy(_buffer, _parsedOffset, _buffer, 0, availData);
_readOffset -= _parsedOffset;
_parsedOffset = 0;
}
}
}
_messageStartOffset = _parsedOffset;
while (_parsedOffset + 20 > _readOffset)
{
ReadAvailableBytesToBuffer(buf);
}
message.SetBuffer(_buffer, _messageStartOffset, _readOffset);
var valueStartIndex = 0;
var tag = 0;
var isTagParsing = true;
var readSomeBytes = false;
var userStopParse = false;
var isHeaderTag = true;
var isAdminMsg = false;
var stopParse = false;
OnMessageStart();
while (true)
{
while (_parsedOffset >= _readOffset)
{
ReadAvailableBytesToBuffer(buf);
readSomeBytes = true;
}
if (readSomeBytes)
{
readSomeBytes = false;
if (_readOffset <= SocketReadSize || _messageStartOffset == 0)
{
message.SetBuffer(_buffer, _messageStartOffset, _readOffset);
}
else
{
// end of buffer reached, wrap around now and move remaining data to buffer's head
Array.Copy(_buffer, _messageStartOffset, _buffer, 0, _readOffset - _messageStartOffset);
_readOffset -= _messageStartOffset;
_parsedOffset -= _messageStartOffset;
valueStartIndex -= _messageStartOffset;
_messageStartOffset = 0;
message.ShiftBuffer(_buffer, _messageStartOffset, _readOffset);
}
}
var b = _buffer[_parsedOffset];
if (isTagParsing)
{
if (b >= (byte)'0' && b <= (byte)'9')
{
tag = tag * 10 + (b - '0');
}
else if (b == (byte)'=')
{
if (RawTags.IsWithinRawTags(tag))
{
var rawLength = 0;
if (message.IsMessageIncomplete)
{
byte bv;
for (var i = valueStartIndex; i < _parsedOffset; i++)
{
bv = _buffer[i];
if (bv >= (byte)'0' && bv <= (byte)'9')
{
rawLength = rawLength * 10 + (bv - '0');
}
else
{
break;
}
}
}
else
{
rawLength = RawFixUtil.GetRawTagLengthFromPreviousField(message);
}
if (rawLength > _maxMessageSize)
{
throw new GarbledMessageException(MessageChopperFields.RawDataLengthIsTooBigError + " (" + rawLength + ")");
}
valueStartIndex = _parsedOffset + 1;
_parsedOffset += rawLength;
}
else
{
valueStartIndex = _parsedOffset + 1;
}
isTagParsing = false;
}
else
{
GetMessage(buf);
throw new GarbledMessageException("Invalid tag number");
}
}
else
{
if (b == (byte)'\x0001')
{
if (_isAdvancedParseControl)
{
if (userStopParse)
{
if (isHeaderTag)
{
if (ParseRequiredTags.IsHeader(tag))
{
message.Add(tag, valueStartIndex, _parsedOffset - valueStartIndex);
}
else
{
message.LoadTagValue(35, _tempValue);
isAdminMsg = ParseRequiredTags.IsAdminMsg(_tempValue);
isHeaderTag = false;
if (isAdminMsg)
{
message.Add(tag, valueStartIndex, _parsedOffset - valueStartIndex);
}
}
}
else if (isAdminMsg)
{
message.Add(tag, valueStartIndex, _parsedOffset - valueStartIndex);
}
else if (!stopParse)
{
// can be stop
message.LoadTagValue(9, _tempValue);
var msgLength = (int) _tempValue.LongValue;
// | length considered from this point | length |
_parsedOffset = _tempValue.Offset + _tempValue.Length + 1 + msgLength - 1;
stopParse = true;
}
else if (tag == 10)
{
message.Add(tag, valueStartIndex, _parsedOffset - valueStartIndex);
}
}
else
{
var control = _parserListener.OnTag(tag, _buffer, valueStartIndex, _parsedOffset - valueStartIndex);
if (control == FixParserListenerParseControl.Continue)
{
message.Add(tag, valueStartIndex, _parsedOffset - valueStartIndex);
}
else
{
// IGNORE or STOP
if (ParseRequiredTags.IsRequired(tag))
{
message.Add(tag, valueStartIndex, _parsedOffset - valueStartIndex);
}
else
{
message.IsMessageIncomplete = true;
}
if (control == FixParserListenerParseControl.StopParse)
{
userStopParse = true;
}
}
}
}
else
{
message.Add(tag, valueStartIndex, _parsedOffset - valueStartIndex);
}
if (tag == 10)
{
_parsedOffset++;
message.SetBuffer(_buffer, _messageStartOffset, _parsedOffset - _messageStartOffset);
break;
}
tag = 0;
isTagParsing = true;
}
}
_parsedOffset++;
}
OnMessageEnd();
GetMessage(buf);
}