#ifdef _MSC_VER
#include "stdafx.h"
#else
#include "config.h"
#endif
#include "FieldConvertors.h"
#include "Parser.h"
#include "Utility.h"
#include <algorithm>
namespace FIX {
bool Parser::extractLength(int &length, std::string::size_type &pos, const std::string &buffer)
EXCEPT(MessageParseError) {
if (!buffer.size()) {
return false;
}
std::string::size_type startPos = buffer.find("\0019=", 0);
if (startPos == std::string::npos) {
return false;
}
startPos += 3;
std::string::size_type endPos = buffer.find("\001", startPos);
if (endPos == std::string::npos) {
return false;
}
std::string strLength(buffer, startPos, endPos - startPos);
try {
length = IntConvertor::convert(strLength);
if (length < 0) {
throw MessageParseError();
}
} catch (FieldConvertError &) {
throw MessageParseError();
}
pos = endPos + 1;
return true;
}
bool Parser::readFixMessage(std::string &str) EXCEPT(MessageParseError) {
std::string::size_type pos = 0;
if (m_buffer.length() < 2) {
return false;
}
pos = m_buffer.find("8=");
if (pos == std::string::npos) {
return false;
}
m_buffer.erase(0, pos);
int length = 0;
try {
if (extractLength(length, pos, m_buffer)) {
pos += length;
if (m_buffer.size() < pos) {
return false;
}
pos = m_buffer.find("\00110=", pos - 1);
if (pos == std::string::npos) {
return false;
}
pos += 4;
pos = m_buffer.find("\001", pos);
if (pos == std::string::npos) {
return false;
}
pos += 1;
str.assign(m_buffer, 0, pos);
m_buffer.erase(0, pos);
return true;
}
} catch (MessageParseError &e) {
if (length > 0) {
m_buffer.erase(0, pos + length);
} else {
m_buffer.erase();
}
throw e;
}
return false;
}
}