void HttpMessage::setString( const std::string& string ) throw( InvalidMessage ) { QF_STACK_PUSH(HttpMessage::setString) clear(); std::string::size_type eolPos = string.find( "\r\n" ); if( eolPos == std::string::npos ) throw InvalidMessage(); std::string line = string.substr( 0, eolPos ); std::string::size_type getPos = line.find( "GET " ); if( getPos != 0 ) throw InvalidMessage(); std::string::size_type httpPos = line.rfind( "HTTP", std::string::npos ); if( httpPos == std::string::npos ) throw InvalidMessage(); m_root = line.substr( getPos + 4, httpPos - 5 ); std::string::size_type paramPos = m_root.find_first_of( '?' ); if( paramPos == std::string::npos ) return; std::string parameters = m_root.substr( paramPos, m_root.size() - paramPos ); m_root = m_root.substr( 0, paramPos ); paramPos = 0; while( paramPos != std::string::npos ) { std::string::size_type sepPos = parameters.find_first_of( "=", paramPos ); if( sepPos == std::string::npos ) break; std::string::size_type tempPos = paramPos; paramPos = parameters.find_first_of( "&", paramPos + 1 ); std::string key = parameters.substr(tempPos + 1, sepPos - tempPos - 1); std::string value = parameters.substr(sepPos + 1, paramPos - sepPos - 1); m_parameters[key] = value; } QF_STACK_POP }
//------------------------------------------------------------------------------------------------- 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; }
//------------------------------------------------------------------------------------------------- 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; }
void Message::validate( const ValidationRules* vrptr ) { /* try { */ if ( !ValidationRules::shouldValidate( vrptr ) ) return; if ( ValidationRules::shouldValidateLength( vrptr ) ) { const BodyLength& aBodyLength = FIELD_GET_REF( m_header, BodyLength ); const int expectedLength = (int)aBodyLength; const int actualLength = bodyLength(); if ( expectedLength != actualLength ) { std::stringstream text; text << "Expected BodyLength=" << expectedLength << ", Received BodyLength=" << actualLength; throw InvalidMessage(text.str()); } } if ( ValidationRules::shouldValidateChecksum( vrptr ) ) { const CheckSum& aCheckSum = FIELD_GET_REF( m_trailer, CheckSum ); const int expectedChecksum = (int)aCheckSum; const int actualChecksum = checkSum(); if ( expectedChecksum != actualChecksum ) { std::stringstream text; text << "Expected CheckSum=" << expectedChecksum << ", Received CheckSum=" << actualChecksum; throw InvalidMessage(text.str()); } } /* } catch ( FieldNotFound& e ) { const std::string fieldName = ( e.field == FIX::FIELD::BodyLength ) ? "BodyLength" : "CheckSum"; throw InvalidMessage( fieldName + std::string(" is missing") ); } catch ( IncorrectDataFormat& e ) { const std::string fieldName = ( e.field == FIX::FIELD::BodyLength ) ? "BodyLength" : "CheckSum"; throw InvalidMessage( fieldName + std::string(" has wrong format: ") + e.detail ); } */ }
//------------------------------------------------------------------------------------------------- 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; }
FIX::FieldBase Message::extractField( const std::string& string, std::string::size_type& pos, const DataDictionary* pSessionDD /*= 0*/, const DataDictionary* pAppDD /*= 0*/, const Group* pGroup /*= 0*/ ) { std::string::const_iterator const tagStart = string.begin() + pos; std::string::const_iterator const strEnd = string.end(); std::string::const_iterator const equalSign = std::find( tagStart, strEnd, '=' ); if( equalSign == strEnd ) throw InvalidMessage("Equal sign not found in field"); int field = 0; IntConvertor::convert( tagStart, equalSign, field ); std::string::const_iterator const valueStart = equalSign + 1; std::string::const_iterator soh = std::find( valueStart, strEnd, '\001' ); if ( soh == strEnd ) throw InvalidMessage("SOH not found at end of field"); if ( IsDataField( field, pSessionDD, pAppDD ) ) { // Assume length field is 1 less. int lenField = field - 1; // Special case for Signature which violates above assumption. if ( field == FIELD::Signature ) lenField = FIELD::SignatureLength; if ( pGroup && pGroup->isSetField( lenField ) ) { const std::string& fieldLength = pGroup->getField( lenField ); soh = valueStart + atol( fieldLength.c_str() ); } else { FIX::FieldMap *lenMap; if ( isHeaderField( lenField ) ) { lenMap = &m_header; } else { lenMap = this; } if ( lenMap->isSetField( lenField ) ) { const std::string& fieldLength = lenMap->getField( lenField ); soh = valueStart + atol( fieldLength.c_str() ); } } } std::string::const_iterator const tagEnd = soh + 1; pos = std::distance( string.begin(), tagEnd ); return FieldBase ( field, valueStart, soh, tagStart, tagEnd ); }