Ejemplo n.º 1
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();
}
Ejemplo n.º 2
0
//-------------------------------------------------------------------------------------------------
/// Encode message with minimal copying
size_t Message::encode(char **hmsg_store) const
{
	char *moffs(*hmsg_store + HEADER_CALC_OFFSET), *msg(moffs);

#if defined CODECTIMING
	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);
	msg += _header->encode(msg); // start
	msg += MessageBase::encode(msg);
	if (!_trailer)
		throw MissingMessageComponent("trailer");
	msg += _trailer->encode(msg);
	const size_t msgLen(msg - moffs); // checksummable msglength
	const size_t hlen(_ctx._preamble_sz + (msgLen < 10 ? 1 : msgLen < 100 ? 2 : msgLen < 1000 ? 3 : 4));
	char *hmsg(moffs - hlen);
	*hmsg_store = hmsg;

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

	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(moffs - hlen, msgLen + hlen)));
	_trailer->_fp.clear(Common_CheckSum, FieldTrait::suppress);
	msg += fitr->second->encode(msg);
#if defined MSGRECYCLING
	_trailer->_fp.set(Common_CheckSum, FieldTrait::suppress); // in case we want to reuse
#endif

#if defined CODECTIMING
	_encode_timings._cpu_used += itm.Calculate().AsDouble();
	++_encode_timings._msg_count;
#endif

	*msg = 0;
	return msg - *hmsg_store;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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

		Fields::const_iterator fitr(msg->_header->_fields.find(Common_BodyLength));
		static_cast<body_length *>(fitr->second)->set(mlen);
		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

		f8String chksum;
		if (extract_trailer(from, chksum))
		{
			Fields::const_iterator fitr(msg->_trailer->_fields.find(Common_CheckSum));
			static_cast<check_sum *>(fitr->second)->set(chksum);
			const unsigned chkval(fast_atoi<unsigned>(chksum.c_str())), // chksum value
				mchkval(calc_chksum(from, 0)); // chksum pos
			if (chkval != mchkval)
				throw BadCheckSum(mchkval);
		}
	}
	else
	{
		//cerr << "Message::factory throwing" << endl;
		throw InvalidMessage(from);
	}

	return msg;
}
Ejemplo n.º 5
0
//-------------------------------------------------------------------------------------------------
/// Encode message with minimal copying
size_t Message::encode(char **hmsg_store) const
{
	char *moffs(*hmsg_store + HEADER_CALC_OFFSET), *msg(moffs);

#if defined CODECTIMING
	IntervalTimer itm;
#endif

	if (!_header)
		throw MissingMessageComponent("header");
	_header->get_msg_type()->set(_msgType);
	msg += _header->encode(msg); // start
	msg += MessageBase::encode(msg);
	if (!_trailer)
		throw MissingMessageComponent("trailer");
	msg += _trailer->encode(msg);
	const size_t msgLen(msg - moffs); // checksummable msglength
	const size_t hlen(_ctx._preamble_sz +
		(msgLen < 10 ? 1 : msgLen < 100 ? 2 : msgLen < 1000 ? 3 : msgLen < 10000 ? 4 :
		 msgLen < 100000 ? 5 : msgLen < 1000000 ? 6 : 7));
	char *hmsg(moffs - hlen);
	*hmsg_store = hmsg;

	if (!_header->get_begin_string())
		throw MissingMandatoryField(Common_BeginString);
	_header->_fp.clear(Common_BeginString, FieldTrait::suppress);
	hmsg += _header->get_begin_string()->encode(hmsg);

	if (!_header->get_body_length())
		throw MissingMandatoryField(Common_BodyLength);
	_header->_fp.clear(Common_BodyLength, FieldTrait::suppress);

	_header->get_body_length()->set(msgLen);
	hmsg += _header->get_body_length()->encode(hmsg);

	if (!_trailer->get_check_sum())
		throw MissingMandatoryField(Common_CheckSum);
	_trailer->get_check_sum()->set(fmt_chksum(calc_chksum(moffs - hlen, msgLen + hlen)));
	_trailer->_fp.clear(Common_CheckSum, FieldTrait::suppress);
	msg += _trailer->get_check_sum()->encode(msg);

#if defined CODECTIMING
	_encode_timings._cpu_used += itm.Calculate().AsDouble();
	++_encode_timings._msg_count;
#endif

	*msg = 0;
	return msg - *hmsg_store;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
//-------------------------------------------------------------------------------------------------
/// Encode message with minimal copying
size_t Message::encode(char **hmsg_store) const
{
	char *moffs(*hmsg_store + HEADER_CALC_OFFSET), *msg(moffs);

#if defined FIX8_CODECTIMING
	IntervalTimer itm;
#endif

	if (!_header)
		throw MissingMessageComponent("header");
	_header->get_msg_type()->set(_msgType);

#if defined FIX8_RAW_MSG_SUPPORT
	msg += (_begin_payload = _header->encode(msg)); // start
#if defined FIX8_PREENCODE_MSG_SUPPORT
	if (_preencode_len)
	{
		::memcpy(msg, _preencode.data(), _payload_len =_preencode_len);
		msg += _preencode_len;
	}
	else
#endif
		msg += (_payload_len = MessageBase::encode(msg));
#else
	msg += _header->encode(msg); // start
#if defined FIX8_PREENCODE_MSG_SUPPORT
	if (_preencode_len)
	{
		::memcpy(msg, _preencode.data(), _preencode_len);
		msg += _preencode_len;
	}
	else
#endif
		msg += MessageBase::encode(msg);
#endif

	if (!_trailer)
		throw MissingMessageComponent("trailer");
	msg += _trailer->encode(msg);
	const size_t msgLen(msg - moffs); // checksummable msglength
	const size_t hlen(_ctx._preamble_sz +
		(msgLen < 10 ? 1 : msgLen < 100 ? 2 : msgLen < 1000 ? 3 : msgLen < 10000 ? 4 :
		 msgLen < 100000 ? 5 : msgLen < 1000000 ? 6 : 7));
	char *hmsg(moffs - hlen);
	*hmsg_store = hmsg;

	if (!_header->get_begin_string())
		throw MissingMandatoryField(Common_BeginString);
	_header->_fp.clear(Common_BeginString, FieldTrait::suppress);
	hmsg += _header->get_begin_string()->encode(hmsg);

	if (!_header->get_body_length())
		throw MissingMandatoryField(Common_BodyLength);
	_header->_fp.clear(Common_BodyLength, FieldTrait::suppress);

	_header->get_body_length()->set(static_cast<int>(msgLen));
	hmsg += _header->get_body_length()->encode(hmsg);

	if (!_trailer->get_check_sum())
		throw MissingMandatoryField(Common_CheckSum);
	_trailer->get_check_sum()->set(fmt_chksum(calc_chksum(moffs - hlen, msgLen + hlen)));
	_trailer->_fp.clear(Common_CheckSum, FieldTrait::suppress);
	msg += _trailer->get_check_sum()->encode(msg);

#if defined FIX8_CODECTIMING
	_encode_timings._cpu_used += itm.Calculate().AsDouble();
	++_encode_timings._msg_count;
#endif

	*msg = 0;
	const size_t rlen(msg - *hmsg_store);
#if defined FIX8_RAW_MSG_SUPPORT
	_rawmsg.assign(*hmsg_store, rlen);
#endif
	return rlen;
}