Example #1
0
//-------------------------------------------------------------------------------------------------
size_t Message::encode(f8String& to) const
{
	char output[MAX_MSG_LENGTH + HEADER_CALC_OFFSET], *ptr(output);
	const size_t msgLen(encode(&ptr));
	to.assign(ptr, msgLen);
	return to.size();
}
Example #2
0
	/*! Construct from string ctor.
	  \param from string to construct field from
	  \param rlm pointer to the realmbase for this field (if available) */
	Field (const f8String& from, const RealmBase *rlm=0) : BaseField(field)
	{
		if (from.size() == _sec_only) // 19981231-23:59:59
			Poco::DateTimeParser::parse(_fmt_sec, from, _value, _tzdiff);
		else if (from.size() == _with_ms) // 19981231-23:59:59.123
			Poco::DateTimeParser::parse(_fmt_ms, from, _value, _tzdiff);
	}
Example #3
0
//-------------------------------------------------------------------------------------------------
unsigned MessageBase::extract_header(const f8String& from, char *len, char *mtype)
{
	const char *dptr(from.data());
	const size_t flen(from.size());
	char tag[MAX_MSGTYPE_FIELD_LEN], val[MAX_FLD_LENGTH];
	unsigned s_offset(0), result;

	if ((result = extract_element(dptr, flen, tag, val)))
	{
		if (*tag != '8')
			return 0;
		s_offset += result;
		if ((result = extract_element(dptr + s_offset, flen - s_offset, tag, len)))
		{
			if (*tag != '9')
				return 0;
			s_offset += result;
			if ((result = extract_element(dptr + s_offset, flen - s_offset, tag, mtype)))
			{
				if (*tag != '3' || *(tag + 1) != '5')
					return 0;
				s_offset += result;
			}
		}
	}
	return s_offset;
}
Example #4
0
	/*! Send message over socket.
	    \param msg message string to send
	    \return number of bytes sent */
	int send(const f8String& msg)
	{
		unsigned remaining(msg.size()), wrdone(0);
		const char *data(msg.data());

		while (remaining > 0)
		{
			const int wrtSz(_sock->sendBytes(data + wrdone, remaining));
			if (wrtSz < 0)
			{
				switch(errno)
				{
				case EAGAIN:
#if defined EWOULDBLOCK && EAGAIN != EWOULDBLOCK
				case EWOULDBLOCK:
#endif
					continue;
				default:
					throw PeerResetConnection("send: connection gone");
				}
			}

			wrdone += wrtSz;
			remaining -= wrtSz;
		}

		return wrdone;
	}
Example #5
0
//-------------------------------------------------------------------------------------------------
bool FilePersister::put(const unsigned seqnum, const f8String& what)
{
	if (!_opened || !seqnum)
		return false;

	if (_index.find(seqnum) != _index.end())
	{
		glout_error << "Error: seqnum " << seqnum << " already persisted in: " << _dbIname;
		return false;
	}
	if (lseek(_iod, 0, SEEK_END) < 0)
	{
		glout_error << "Error: could not seek to index end for seqnum persitence: " << _dbIname;
		return false;
	}
	off_t offset;
	if ((offset = lseek(_fod, 0, SEEK_END)) < 0)
	{
		glout_error << "Error: could not seek to end for seqnum persitence: " << _dbFname;
		return false;
	}
	IPrec iprec(seqnum, offset, static_cast<unsigned>(what.size()));
	if (write (_iod, static_cast<void *>(&iprec), sizeof(IPrec)) != sizeof(IPrec))
	{
		glout_error << "Error: could not write index record for seqnum " << seqnum << " to: " << _dbIname;
		return false;
	}
	if (write (_fod, what.data(), static_cast<unsigned>(what.size())) != static_cast<ssize_t>(what.size()))
	{
		glout_error << "Error: could not write record for seqnum " << seqnum << " to: " << _dbFname;
		return false;
	}

	return _index.insert({seqnum, iprec._prec}).second;
}
Example #6
0
//-------------------------------------------------------------------------------------------------
unsigned Message::encode(f8String& to) const
{
	char msg[MAX_MSG_LENGTH], hmsg[MAX_MSG_LENGTH];
	size_t sz(0), hsz(0);

#if defined CODECTIMING
	ostringstream gerr;
	gerr << "encode(" << _msgType << "):";
	IntervalTimer itm;
#endif

	if (!_header)
		throw MissingMessageComponent("header");
	Fields::const_iterator fitr(_header->_fields.find(Common_MsgType));
	static_cast<msg_type *>(fitr->second)->set(_msgType);
	_header->encode(msg, sz);
	MessageBase::encode(msg, sz);
	if (!_trailer)
		throw MissingMessageComponent("trailer");
	_trailer->encode(msg, sz);
	const unsigned msgLen(sz);	// checksummable msglength

	if ((fitr = _header->_fields.find(Common_BeginString)) == _header->_fields.end())
		throw MissingMandatoryField(Common_BeginString);
	_header->_fp.clear(Common_BeginString, FieldTrait::suppress);
	fitr->second->encode(hmsg, hsz);
#if defined MSGRECYCLING
	_header->_fp.set(Common_BeginString, FieldTrait::suppress); // in case we want to reuse
#endif

	if ((fitr = _header->_fields.find(Common_BodyLength)) == _header->_fields.end())
		throw MissingMandatoryField(Common_BodyLength);
	_header->_fp.clear(Common_BodyLength, FieldTrait::suppress);
	static_cast<body_length *>(fitr->second)->set(msgLen);
	fitr->second->encode(hmsg, hsz);
#if defined MSGRECYCLING
	_header->_fp.set(Common_BodyLength, FieldTrait::suppress); // in case we want to reuse
#endif

	::memcpy(hmsg + hsz, msg, sz);
	hsz += sz;

	if ((fitr = _trailer->_fields.find(Common_CheckSum)) == _trailer->_fields.end())
		throw MissingMandatoryField(Common_CheckSum);
	static_cast<check_sum *>(fitr->second)->set(fmt_chksum(calc_chksum(hmsg, hsz)));
	_trailer->_fp.clear(Common_CheckSum, FieldTrait::suppress);
	fitr->second->encode(hmsg, hsz);
#if defined MSGRECYCLING
	_trailer->_fp.set(Common_CheckSum, FieldTrait::suppress); // in case we want to reuse
#endif

#if defined CODECTIMING
	gerr << itm.Calculate();
	GlobalLogger::log(gerr.str());
#endif

	to.assign(hmsg, hsz);
	return to.size();
}
Example #7
0
//-------------------------------------------------------------------------------------------------
unsigned MessageBase::decode(const f8String& from, unsigned s_offset, unsigned ignore, bool permissive_mode)
{
	const unsigned fsize(static_cast<unsigned>(from.size()) - ignore), npos(0xffffffff);
	unsigned pos(static_cast<unsigned>(_pos.size())), last_valid_pos(npos);
	const char *dptr(from.data());
	char tag[FIX8_MAX_FLD_LENGTH], val[FIX8_MAX_FLD_LENGTH];
	size_t last_valid_offset(0);

	for (unsigned result; s_offset <= fsize && (result = extract_element(dptr + s_offset, fsize - s_offset, tag, val));)
	{
		const unsigned short tv(fast_atoi<unsigned short>(tag));
		Presence::const_iterator itr(_fp.get_presence().find(tv));
		if (itr == _fp.get_presence().end())
		{
			if (permissive_mode)
			{
				if (last_valid_pos == npos)
				{
					last_valid_pos = pos;
					last_valid_offset = s_offset;
				}
				_unknown.append(dptr + s_offset, result);
				s_offset += result;
				continue;
			}
			break;
		}
		s_offset += result;
		if (itr->_field_traits.has(FieldTrait::present))
		{
			if (!itr->_field_traits.has(FieldTrait::automatic))
				throw DuplicateField(tv);
		}
		else
		{
			const BaseEntry *be(_ctx.find_be(tv));
			if (!be)
				throw UnknownField(tv);
			BaseField *bf(be->_create._do(val, be->_rlm, -1));
			add_field_decoder(tv, ++pos, bf);
			itr->_field_traits.set(FieldTrait::present);
			// check if repeating group and num elements > 0
			if (itr->_field_traits.has(FieldTrait::group) && has_group_count(bf))
				s_offset = decode_group(nullptr, tv, from, s_offset, ignore);
		}
	}

	const unsigned short missing(_fp.find_missing());
	if (missing)
	{
		const BaseEntry *tbe(_ctx.find_be(missing));
		ostringstream ostr;
		ostr << tbe->_name << " (" << missing << ')';
		throw MissingMandatoryField(ostr.str());
	}

	return permissive_mode && last_valid_pos == pos ? static_cast<unsigned>(last_valid_offset) : s_offset;
}
Example #8
0
//-------------------------------------------------------------------------------------------------
Message *Message::factory(const F8MetaCntx& ctx, const f8String& from)
{
	Message *msg(0);
	f8String len, mtype;
	if (extract_header(from, len, mtype))
	{
		const unsigned mlen(fast_atoi<unsigned>(len.c_str()));
		const BaseMsgEntry *bme(ctx._bme.find_ptr(mtype));
		if (!bme)
			throw InvalidMessage(mtype);
		msg = bme->_create();
#if defined PERMIT_CUSTOM_FIELDS
		if (ctx._ube)
			ctx._ube->post_msg_ctor(msg);
#endif
#if defined CODECTIMING
		ostringstream gerr;
		gerr << "decode(" << mtype << "):";
		IntervalTimer itm;
#endif
		msg->decode(from);
#if defined CODECTIMING
		gerr << itm.Calculate();
		GlobalLogger::log(gerr.str());
#endif

		static_cast<body_length *>(msg->_header->_fields.find(Common_BodyLength)->second)->set(mlen);
		Fields::const_iterator fitr(msg->_header->_fields.find(Common_MsgType));
		static_cast<msg_type *>(fitr->second)->set(mtype);
#if defined POPULATE_METADATA
		msg->check_set_rlm(fitr->second);
#endif

		const char *pp(from.data() + from.size() - 7);
		if (*pp != '1' || *(pp + 1) != '0') // 10=XXX^A
			throw InvalidMessage(from);
		if (!ctx.has_flag(F8MetaCntx::noverifychksum)) // permit chksum calculation to be skipped
		{
			const f8String chksum(pp + 3, 3);
			static_cast<check_sum *>(msg->_trailer->_fields.find(Common_CheckSum)->second)->set(chksum);
			const unsigned chkval(fast_atoi<unsigned>(chksum.c_str())), mchkval(calc_chksum(from, 0, from.size() - 7));
			if (chkval != mchkval)
				throw BadCheckSum(mchkval);
		}
	}
	else
	{
		//cerr << "Message::factory throwing" << endl;
		throw InvalidMessage(from);
	}

	return msg;
}
Example #9
0
//-------------------------------------------------------------------------------------------------
bool MemcachedPersister::initialise(const f8String& config_str, const f8String& key_base, bool purge)
{
	if (_cache)
		return true;
	_key_base = key_base;
	_cache = memcached(config_str.c_str(), config_str.size());
	if (!(_server_count = memcached_server_count(_cache)))
	{
		glout_error << "Error: no memcached servers were configured for " << _key_base;
		return false;
	}
	return purge ? memcached_success(memcached_flush(_cache, 0)) : true;
}
Example #10
0
//-------------------------------------------------------------------------------------------------
unsigned MessageBase::decode_group(GroupBase *grpbase, const unsigned short fnum, const f8String& from,
	unsigned s_offset, unsigned ignore)
{
	unsigned result;
	if (!(grpbase = find_add_group(fnum, grpbase)))
		throw InvalidRepeatingGroup(fnum, FILE_LINE);
	const unsigned fsize(static_cast<unsigned>(from.size()) - ignore);
	const char *dptr(from.data());
	char tag[FIX8_MAX_FLD_LENGTH], val[FIX8_MAX_FLD_LENGTH];

	for (bool ok(true); ok && s_offset < fsize; )
	{
		unique_ptr<MessageBase> grp(grpbase->create_group(false)); // shallow create

		for (unsigned pos(0); s_offset < fsize && (result = extract_element(dptr + s_offset, fsize - s_offset, tag, val));)
		{
			const unsigned tv(fast_atoi<unsigned>(tag));
			Presence::const_iterator itr(grp->_fp.get_presence().end());
			if (grp->_fp.get(tv, itr, FieldTrait::present))	// already present; next group?
				break;
			if (pos == 0 && grp->_fp.getPos(tv, itr) != 1)	// first field in group is mandatory
				throw MissingRepeatingGroupField(tv);
			const BaseEntry *be(_ctx.find_be(tv));
			if (!be || !grp->_fp.has(tv, itr))	// unknown field or field not found in sub-group - end of repeats?
			{
				ok = false;
				break;
			}
			s_offset += result;
			BaseField *bf(be->_create._do(val, be->_rlm, -1));
			grp->add_field(tv, itr, ++pos, bf, false);
			grp->_fp.set(tv, itr, FieldTrait::present);	// is present
			// nested group (check if not zero elements)
			if (grp->_fp.is_group(tv, itr) && has_group_count(bf))
				s_offset = grp->decode_group(grpbase, tv, from, s_offset, ignore);
		}

		const unsigned short missing(grp->_fp.find_missing());
		if (missing)
		{
			const BaseEntry *tbe(_ctx.find_be(missing));
			ostringstream ostr;
			ostr << tbe->_name << " (" << missing << ')';
			throw MissingMandatoryField(ostr.str());
		}
		*grpbase << grp.release();
	}

	return s_offset;
}
Example #11
0
void extract_element_test(f8String msg, f8String expect_tag, f8String expect_val)
{
    char cVal[MAX_FLD_LENGTH];
    char cTag[MAX_FLD_LENGTH];
    MessageBase::extract_element(msg.c_str(), static_cast<unsigned>(msg.length()), cTag, cVal);
    EXPECT_EQ(expect_val, f8String(cVal));
    EXPECT_EQ(expect_tag, f8String(cTag));

    f8String sVal;
    f8String sTag;
    MessageBase::extract_element(msg.c_str(), static_cast<unsigned>(msg.length()), sTag, sVal);
    EXPECT_EQ(expect_val, sVal);
    EXPECT_EQ(expect_tag, sTag);
}
Example #12
0
//-------------------------------------------------------------------------------------------------
unsigned MessageBase::decode_group(const unsigned short fnum, const f8String& from, const unsigned offset)
{
	unsigned s_offset(offset), result;
	GroupBase *grpbase(find_group(fnum));
	if (!grpbase)
		throw InvalidRepeatingGroup(fnum);
	const unsigned fsize(from.size());
	const char *dptr(from.data());
	char tag[MAX_FLD_LENGTH], val[MAX_FLD_LENGTH];

	for (bool ok(true); ok && s_offset < fsize; )
	{
		scoped_ptr<MessageBase> grp(grpbase->create_group());

		for (unsigned pos(0); s_offset < fsize && (result = extract_element(dptr + s_offset, fsize - s_offset, tag, val));)
		{
			const unsigned tv(fast_atoi<unsigned>(tag));
			Presence::const_iterator itr(grp->_fp.get_presence().end());
			if (grp->_fp.get(tv, itr, FieldTrait::present))	// already present; next group?
				break;
			if (pos == 0 && grp->_fp.getPos(tv, itr) != 1)	// first field in group is mandatory
				throw MissingRepeatingGroupField(tv);
			const BaseEntry *be(_ctx._be.find_ptr(tv));
			if (!be)
				throw InvalidField(tv);
			if (!grp->_fp.has(tv, itr))	// field not found in sub-group - end of repeats?
			{
				ok = false;
				break;
			}
			s_offset += result;
			grp->add_field(tv, itr, ++pos, be->_create(val, be->_rlm, -1), false);
			grp->_fp.set(tv, itr, FieldTrait::present);	// is present
			if (grp->_fp.is_group(tv, itr)) // nested group
				s_offset = grp->decode_group(tv, from, s_offset);
		}

		const unsigned short missing(grp->_fp.find_missing());
		if (missing)
		{
			const BaseEntry& tbe(_ctx._be.find_ref(missing));
			ostringstream ostr;
			ostr << tbe._name << " (" << missing << ')';
			throw MissingMandatoryField(ostr.str());
		}
		*grpbase += grp.release();
	}

	return s_offset;
}
Example #13
0
//-------------------------------------------------------------------------------------------------
bool FilePersister::get(const unsigned seqnum, f8String& to) const
{
	if (!_opened || !seqnum || _index.empty())
		return false;
	Index::const_iterator itr(_index.find(seqnum));
	if (itr == _index.end())
	{
		glout_warn << "Warning: index does not contain seqnum: " << seqnum << " in: " << _dbIname;
		return false;
	}

	if (lseek(_fod, itr->second._offset, SEEK_SET) < 0)
	{
		glout_error << "Error: could not seek to correct index location for get: " << _dbFname;
		return false;
	}

	char buff[FIX8_MAX_MSG_LENGTH];
	if (read (_fod, buff, itr->second._size) != itr->second._size)
	{
		glout_error << "Error: could not read message record for seqnum " << seqnum << " from: " << _dbFname;
		return false;
	}

	to.assign(buff, itr->second._size);
	return true;
}
Example #14
0
//-------------------------------------------------------------------------------------------------
Message *Message::factory(const F8MetaCntx& ctx, const f8String& from)
{
	Message *msg(0);
	char mtype[MAX_MSGTYPE_FIELD_LEN] = {}, len[MAX_MSGTYPE_FIELD_LEN] = {};
	if (extract_header(from, len, mtype))
	{
		const unsigned mlen(fast_atoi<unsigned>(len));
		const BaseMsgEntry *bme(ctx._bme.find_ptr(mtype));
		if (!bme)
			throw InvalidMessage(mtype);
		msg = bme->_create();
#if defined CODECTIMING
		IntervalTimer itm;
#endif
		msg->decode(from);
#if defined CODECTIMING
		_decode_timings._cpu_used += itm.Calculate().AsDouble();
		++_decode_timings._msg_count;
#endif

		static_cast<body_length *>(msg->_header->_fields.find(Common_BodyLength)->second)->set(mlen);
		Fields::const_iterator fitr(msg->_header->_fields.find(Common_MsgType));
		static_cast<msg_type *>(fitr->second)->set(mtype);
#if defined POPULATE_METADATA
		msg->check_set_rlm(fitr->second);
#endif

		const char *pp(from.data() + from.size() - 7);
		if (*pp != '1' || *(pp + 1) != '0') // 10=XXX^A
			throw InvalidMessage(from);
		if (!ctx.has_flag(F8MetaCntx::noverifychksum)) // permit chksum calculation to be skipped
		{
			const f8String chksum(pp + 3, 3);
			static_cast<check_sum *>(msg->_trailer->_fields.find(Common_CheckSum)->second)->set(chksum);
			const unsigned chkval(fast_atoi<unsigned>(chksum.c_str())), mchkval(calc_chksum(from, 0, from.size() - 7));
			if (chkval != mchkval)
				throw BadCheckSum(mchkval);
		}
	}
	else
	{
		//cerr << "Message::factory throwing" << endl;
		throw InvalidMessage(from);
	}

	return msg;
}
Example #15
0
//-------------------------------------------------------------------------------------------------
unsigned MessageBase::decode(const f8String& from, const unsigned offset)
{
	unsigned s_offset(offset), result;
	const unsigned fsize(from.size());
	const char *dptr(from.data());
	char tag[MAX_FLD_LENGTH], val[MAX_FLD_LENGTH];

	for (unsigned pos(_pos.size()); s_offset <= fsize && (result = extract_element(dptr + s_offset, fsize - s_offset, tag, val));)
	{
		const unsigned tv(fast_atoi<unsigned>(tag));
		const BaseEntry *be(_ctx._be.find_ptr(tv));
#if defined PERMIT_CUSTOM_FIELDS
		if (!be && (!_ctx._ube || (be = _ctx._ube->find_ptr(tv)) == 0))
#else
		if (!be)
#endif
			throw InvalidField(tv);
		Presence::const_iterator itr(_fp.get_presence().end());
		if (!_fp.has(tv, itr))
			break;
		s_offset += result;
		if (_fp.get(tv, itr, FieldTrait::present))
		{
			if (!_fp.get(tv, itr, FieldTrait::automatic))
				throw DuplicateField(tv);
		}
		else
		{
			add_field(tv, itr, ++pos, be->_create(val, be->_rlm, -1), false);
			if (_fp.is_group(tv, itr))
				s_offset = decode_group(tv, from, s_offset);
		}
	}

	const unsigned short missing(_fp.find_missing());
	if (missing)
	{
		const BaseEntry& tbe(_ctx._be.find_ref(missing));
		ostringstream ostr;
		ostr << tbe._name << " (" << missing << ')';
		throw MissingMandatoryField(ostr.str());
	}

	return s_offset;
}
Example #16
0
//-------------------------------------------------------------------------------------------------
Message *Message::factory(const F8MetaCntx& ctx, const f8String& from, bool no_chksum, bool permissive_mode)
{
	char mtype[MAX_MSGTYPE_FIELD_LEN] = {}, len[MAX_MSGTYPE_FIELD_LEN] = {};
	const size_t hlen(extract_header(from, len, mtype));

	if (!hlen)
	{
		//cerr << "Message::factory throwing" << endl;
		throw InvalidMessage(from);
	}

	const unsigned mlen(fast_atoi<unsigned>(len));
	const BaseMsgEntry *bme(ctx._bme.find_ptr(mtype));
	if (!bme)
		throw InvalidMessage(mtype);
	Message *msg(bme->_create._do());
#if defined CODECTIMING
	IntervalTimer itm;
#endif
	msg->decode(from, hlen, 7, permissive_mode); // skip already decoded mandatory 8, 9, 35 and 10
#if defined CODECTIMING
	_decode_timings._cpu_used += itm.Calculate().AsDouble();
	++_decode_timings._msg_count;
#endif

	msg->_header->get_body_length()->set(mlen);
	msg->_header->get_msg_type()->set(mtype);
#if defined POPULATE_METADATA
	msg->check_set_rlm(fitr->second);
#endif

	const char *pp(from.data() + from.size() - 7);
	if (*pp != '1' || *(pp + 1) != '0') // 10=XXX^A
		throw InvalidMessage(from);
	if (!no_chksum) // permit chksum calculation to be skipped
	{
		const f8String chksum(pp + 3, 3);
		msg->_trailer->get_check_sum()->set(chksum);
		const unsigned chkval(fast_atoi<unsigned>(chksum.c_str())), mchkval(calc_chksum(from, 0, from.size() - 7));
		if (chkval != mchkval)
			throw BadCheckSum(mchkval);
	}

	return msg;
}
Example #17
0
//-------------------------------------------------------------------------------------------------
bool FilePersister::put(const unsigned seqnum, const f8String& what)
{
	if (!_opened || !seqnum)
		return false;

	if (_index.find(seqnum) != _index.end())
	{
		ostringstream eostr;
		eostr << "Error seqnum " << seqnum << " already persisted in: " << _dbIname;
		GlobalLogger::log(eostr.str());
		return false;
	}
	if (lseek(_iod, 0, SEEK_END) < 0)
	{
		ostringstream eostr;
		eostr << "Error could not seek to index end for seqnum persitence: " << _dbIname;
		GlobalLogger::log(eostr.str());
		return false;
	}
	off_t offset;
	if ((offset = lseek(_fod, 0, SEEK_END)) < 0)
	{
		ostringstream eostr;
		eostr << "Error could not seek to end for seqnum persitence: " << _dbFname;
		GlobalLogger::log(eostr.str());
		return false;
	}
	IPrec iprec(seqnum, offset, what.size());
	if (write (_iod, static_cast<void *>(&iprec), sizeof(IPrec)) != sizeof(IPrec))
	{
		ostringstream eostr;
		eostr << "Error could not write index record for seqnum " << seqnum << " to: " << _dbIname;
		GlobalLogger::log(eostr.str());
		return false;
	}
	if (write (_fod, what.data(), sizeof(what.size())) != sizeof(what.size()))
	{
		ostringstream eostr;
		eostr << "Error could not write record for seqnum " << seqnum << " to: " << _dbFname;
		GlobalLogger::log(eostr.str());
		return false;
	}

	return _index.insert(Index::value_type(seqnum, iprec._prec)).second;
}
Example #18
0
//-------------------------------------------------------------------------------------------------
unsigned MessageBase::decode(const f8String& from, unsigned s_offset, unsigned ignore)
{
	unsigned result;
	const unsigned fsize(from.size() - ignore);
	const char *dptr(from.data());
	char tag[MAX_FLD_LENGTH], val[MAX_FLD_LENGTH];

	for (unsigned pos(_pos.size()); s_offset <= fsize && (result = extract_element(dptr + s_offset, fsize - s_offset, tag, val));)
	{
		const unsigned short tv(fast_atoi<unsigned short>(tag));
		Presence::const_iterator itr(_fp.get_presence().find(tv));
		if (itr == _fp.get_presence().end())
			break;
		s_offset += result;
		if (itr->_field_traits.has(FieldTrait::present))
		{
			if (!itr->_field_traits.has(FieldTrait::automatic))
				throw DuplicateField(tv);
		}
		else
		{
			const BaseEntry *be(_ctx.find_be(tv));
			if (!be)
				throw InvalidField(tv);
			BaseField *bf(be->_create._do(val, be->_rlm, -1));
			add_field_decoder(tv, ++pos, bf);
			itr->_field_traits.set(FieldTrait::present);
			// check if repeating group and num elements > 0
			if (itr->_field_traits.has(FieldTrait::group) && static_cast<Field<int, 0> *>(bf)->get() > 0)
				s_offset = decode_group(tv, from, s_offset, ignore);
		}
	}

	const unsigned short missing(_fp.find_missing());
	if (missing)
	{
		const BaseEntry *tbe(_ctx.find_be(missing));
		ostringstream ostr;
		ostr << tbe->_name << " (" << missing << ')';
		throw MissingMandatoryField(ostr.str());
	}

	return s_offset;
}
Example #19
0
//-------------------------------------------------------------------------------------------------
bool FIXReader::read(f8String& to)	// read a complete FIX message
{
	char msg_buf[_max_msg_len] = {};
	int result(sockRead(msg_buf, _bg_sz));

	if (result == static_cast<int>(_bg_sz))
	{
		char bt;
		size_t offs(_bg_sz);
		do	// get the last chrs of bodylength and ^A
		{
			if (sockRead(&bt, 1) != 1)
				return false;
			if (!isdigit(bt) && bt != default_field_separator)
				throw IllegalMessage(msg_buf);
			msg_buf[offs++] = bt;
		}
		while (bt != default_field_separator && offs < _max_msg_len);
		to.assign(msg_buf, offs);

		f8String tag, bgstr, len;
		unsigned result;
		if ((result = MessageBase::extract_element(to.data(), to.size(), tag, bgstr)))
		{
			if (tag != "8")
				throw IllegalMessage(to);

			if (bgstr != _session.get_ctx()._beginStr)	// invalid FIX version
				throw InvalidVersion(bgstr);

			if ((result = MessageBase::extract_element(to.data() + result, to.size() - result, tag, len)))
			{
				if (tag != "9")
					throw IllegalMessage(to);

				const unsigned mlen(fast_atoi<unsigned>(len.c_str()));
				if (mlen == 0 || mlen > _max_msg_len - _bg_sz - _chksum_sz) // invalid msglen
					throw InvalidBodyLength(mlen);

				// read the body
				if ((result = sockRead(msg_buf, mlen) != static_cast<int>(mlen)))
					return false;

				// read the checksum
				if ((result = sockRead(msg_buf + mlen, _chksum_sz) != static_cast<int>(_chksum_sz)))
					return false;

				to.append(msg_buf, mlen + _chksum_sz);
				_session.update_received();
				//string ts;
				//cerr << GetTimeAsStringMS(ts, &_session.get_last_received(), 9) << endl;
				return true;
			}
		}

		throw IllegalMessage(to);
	}

	return false;
}
Example #20
0
	char get_key(const f8String& prompt=std::string(), bool echo=false) const
	{
		char ch(0);
		_is.clear();
		if (!prompt.empty())
			_os << prompt << std::flush;
		_is.get(ch);
		if (!_is.bad() && ch != 0x3 && ch != 0xa)
		{
			if (echo)
				_os << ch;
			return ch;
		}
		return 0;
	}
Example #21
0
//-------------------------------------------------------------------------------------------------
bool BDBPersister::get(const unsigned seqnum, f8String& to) const
{
	if (!_opened || !seqnum)
      return false;
   KeyDataBuffer buffer(seqnum);
   KeyDataPair keyPair(buffer);
   int retval(_db->get(0, &keyPair._key, &keyPair._data, 0));
   if (retval)
   {
		ostringstream ostr;
		ostr << "Could not get " << seqnum << '(' << db_strerror(retval) << ')';
		GlobalLogger::log(ostr.str());
      return false;
   }
   to.assign(buffer.dataBuf_);
   return true;
}
Example #22
0
 int send(const f8String& from)
 {
     _output.push_back(from);
     return static_cast<int>(from.length());
 }
Example #23
0
	/*! Write a string message to the underlying socket.
	    \param from Message (string) to write
	    \return number of bytes written */
	int send(const f8String& from) { return _writer.send(from.data(), from.size()); }
Example #24
0
//-------------------------------------------------------------------------------------------------
unsigned MessageBase::extract_trailer(const f8String& from, f8String& chksum)
{
	f8String tag;
	return extract_element(from.data() + from.size() - 7, 6, tag, chksum);
}
Example #25
0
	/*! Construct from string ctor.
	  \param from string to construct field from
	  \param rlm pointer to the realmbase for this field (if available) */
	Field (const f8String& from, const RealmBase *rlm=0) : BaseField(field, rlm), _value(fast_atoi<int>(from.c_str())) {}
Example #26
0
//-------------------------------------------------------------------------------------------------
bool Session::process(const f8String& from)
{
	unsigned seqnum(0);

	try
	{
		const f8String::size_type fpos(from.find("34="));
		if (fpos == f8String::npos)
		{
			//cerr << "Session::process throwing for " << from << endl;
			throw InvalidMessage(from);
		}

		seqnum = fast_atoi<unsigned>(from.data() + fpos + 3, default_field_separator);

		bool retry_plog(false);
		if (_plogger && _plogger->has_flag(Logger::inbound))
		{
			if (_state != States::st_wait_for_logon)
				plog(from, 1);
			else
				retry_plog = true;
		}

		const Message *msg(Message::factory(_ctx, from, _loginParameters._no_chksum_flag, _loginParameters._permissive_mode_flag));
		if (!msg)
		{
			GlobalLogger::log("Fatal: factory failed to generate a valid message");
			return false;
		}

		if ((_control & printnohb) && msg->get_msgtype() != Common_MsgType_HEARTBEAT)
			cout << *msg << endl;
		else if (_control & print)
			cout << *msg << endl;

		bool result(false), admin_result(msg->is_admin() ? handle_admin(seqnum, msg) : true);
		if (msg->get_msgtype().size() > 1)
			goto application_call;
		else switch(msg->get_msgtype()[0])
		{
		default:
application_call:
			if (activation_check(seqnum, msg))
				result = handle_application(seqnum, msg);
			break;
		case Common_MsgByte_HEARTBEAT:
			result = handle_heartbeat(seqnum, msg);
			break;
		case Common_MsgByte_TEST_REQUEST:
			result = handle_test_request(seqnum, msg);
			break;
		case Common_MsgByte_RESEND_REQUEST:
			result = handle_resend_request(seqnum, msg);
			break;
		case Common_MsgByte_REJECT:
			result = handle_reject(seqnum, msg);
			break;
		case Common_MsgByte_SEQUENCE_RESET:
			result = handle_sequence_reset(seqnum, msg);
			break;
		case Common_MsgByte_LOGOUT:
			result = handle_logout(seqnum, msg);
			break;
		case Common_MsgByte_LOGON:
			result = handle_logon(seqnum, msg);
			break;
		}

		++_next_receive_seq;
		if (retry_plog)
			plog(from, 1);
		if (_persist)
		{
			f8_scoped_spin_lock guard(_per_spl, _connection->get_pmodel() == pm_coro);
			_persist->put(_next_send_seq, _next_receive_seq);
			//cout << "Persisted:" << _next_send_seq << " and " << _next_receive_seq << endl;
		}
		delete msg;
		return result && admin_result;
	}
	catch (f8Exception& e)
	{
		//cerr << "process:: f8exception" << ' ' << seqnum << ' ' << e.what() << endl;

		log(e.what());
		if (!e.force_logoff())
		{
			send(generate_reject(seqnum, e.what()));
		}
		else
		{
			if (_state == States::st_logon_received && !_loginParameters._silent_disconnect)
			{
				send(generate_logout(e.what()), true, 0, true); // so it won't increment
				do_state_change(States::st_logoff_sent);
			}
			stop();
		}
	}
	catch (Poco::Net::NetException& e)
	{
		//cerr << "process:: Poco::Net::NetException" << endl;
		log(e.what());
	}
	catch (exception& e)
	{
		//cerr << "process:: std::exception" << endl;
		log(e.what());
	}

	return false;
}
Example #27
0
	/*! Print this field to the supplied buffer, update size written.
	  \param to buffer to print to
	  \param sz current size of buffer payload stream */
	void print(char *to, size_t& sz) const { sz += _value.copy(to, _value.size()); }
Example #28
0
	/*! Construct from string ctor.
	  \param from string to construct field from
	  \param rlm pointer to the realmbase for this field (if available) */
	Field (const f8String& from, const RealmBase *rlm=0) : BaseField(field, rlm), _value(fast_atof(from.c_str())), _precision(2) {}
Example #29
0
//-------------------------------------------------------------------------------------------------
unsigned MessageBase::decode(const f8String& from, unsigned s_offset, unsigned ignore, bool permissive_mode)
{
	const unsigned fsize(static_cast<unsigned>(from.size()) - ignore), npos(0xffffffff);
	unsigned pos(static_cast<unsigned>(_pos.size())), last_valid_pos(npos);
	const char *dptr(from.data());
	char tag[FIX8_MAX_FLD_LENGTH], val[FIX8_MAX_FLD_LENGTH];
	size_t last_valid_offset(0);

	for (unsigned result; s_offset <= fsize && (result = extract_element(dptr + s_offset, fsize - s_offset, tag, val));)
	{
		unsigned short tv(fast_atoi<unsigned short>(tag));
		Presence::const_iterator itr(_fp.get_presence().find(tv));
		if (itr == _fp.get_presence().end())
		{
unknown_field:
			if (permissive_mode)
			{
				if (last_valid_pos == npos)
				{
					last_valid_pos = pos;
					last_valid_offset = s_offset;
				}
				_unknown.append(dptr + s_offset, result);
				s_offset += result;
				continue;
			}
			break;
		}
		s_offset += result;
		if (itr->_field_traits.has(FieldTrait::present))
		{
			if (!itr->_field_traits.has(FieldTrait::automatic))
				throw DuplicateField(tv);
		}
		else for(unsigned ii(0); ii < 2; ++ii)
		{
			const BaseEntry *be(_ctx.find_be(tv));
			if (!be)
				throw UnknownField(tv);
			BaseField *bf(be->_create._do(val, be->_rlm, -1));
			add_field_decoder(tv, ++pos, bf);
			itr->_field_traits.set(FieldTrait::present);
			// check if repeating group and num elements > 0
			if (itr->_field_traits.has(FieldTrait::group) && has_group_count(bf))
				s_offset = decode_group(nullptr, tv, from, s_offset, ignore);

			if (itr->_ftype != FieldTrait::ft_Length || tv == Common_BodyLength) // this type expects next field to be data
				break;

			const unsigned val_sz(fast_atoi<unsigned>(val));
			if(val_sz > FIX8_MAX_FLD_LENGTH - 1)
				throw f8Exception("Value size too large");
			result = extract_element_fixed_width(dptr + s_offset, fsize - s_offset, val_sz, tag, val);
			if (!result)
				throw MissingMandatoryField("Unable to extract fixed width field");

			const unsigned short lasttv(tv);
			tv = fast_atoi<unsigned short>(tag);
			if ((itr = _fp.get_presence().find(tv)) == _fp.get_presence().end())
				goto unknown_field;
			if (itr->_ftype != FieldTrait::ft_data || lasttv + 1 != tv) // next field must be data, tag must be 1 greater than length tag
				break;
			s_offset += result;
		}
	}

	const unsigned short missing(_fp.find_missing());
	if (missing)
	{
		const BaseEntry *tbe(_ctx.find_be(missing));
		ostringstream ostr;
		ostr << tbe->_name << " (" << missing << ')';
		throw MissingMandatoryField(ostr.str());
	}

	return permissive_mode && last_valid_pos == pos ? static_cast<unsigned>(last_valid_offset) : s_offset;
}
Example #30
0
 /*!empty function
       \param msg message string to be sent
       \return return the message length*/
 int send(const f8String& msg)
 {
     return static_cast<int>(msg.length());
 }