// construct STOMP frame (command & header) from a streambuf // -------------------------------------------------- Frame::Frame(boost::asio::streambuf& stomp_response, const stomp_server_command_map_t& cmd_map) // -------------------------------------------------- { string _str; try { // STEP 1: find the next STOMP command line in stomp_response. // Chomp unknown lines till the buffer is empty, in which case an exception is raised //debug_print(boost::format("Frame parser phase 1, stomp_response.size()==%1%") % stomp_response.size()); //hexdump(boost::asio::buffer_cast<const char*>(stomp_response.data()), stomp_response.size()); while (stomp_response.size() > 0) { mygetline(stomp_response, _str); //hexdump(_str.c_str(), _str.length()); stomp_response.consume(_str.size() + 1); // plus one for the newline if (cmd_map.find(_str) != cmd_map.end()) { //debug_print(boost::format("phase 1: COMMAND==%1%, sb.size==%2%") % _str % stomp_response.size()); m_command = _str; break; } } // if after all this trouble m_command is not set, and there's no more data in stomp_response // (which shouldn't happen since we do async_read_until the double newline), then throw an exception if (m_command == "") throw(NoMoreFrames()); // STEP 2: parse all headers //debug_print("Frame parser phase 2"); vector< string > header_parts; while (stomp_response.size() > 0) { mygetline(stomp_response, _str); stomp_response.consume(_str.size()+1); boost::algorithm::split(header_parts, _str, is_any_of(":")); if (header_parts.size() > 1) { string& key = decode_header_token(header_parts[0]); string& val = decode_header_token(header_parts[1]); //debug_print(boost::format("phase 2: HEADER[%1%]==%2%") % key % val); m_headers[key] = val; // } else { // no valid header line detected, on to the body scanner break; } } // } catch(NoMoreFrames& e) { //debug_print("-- Frame parser ended (no more frames)"); throw(e); } };
// STEP 3: parse the body size_t Frame::parse_body(boost::asio::streambuf& _response) { std::size_t _content_length = 0, bytecount = 0; string _str; //debug_print("Frame parser phase 3"); // special case: content-length if (m_headers.find("content-length") != m_headers.end()) { string& val = m_headers["content-length"]; //debug_print(boost::format("phase 3: body content-length==%1%") % val); _content_length = lexical_cast<size_t>(val); } if (_content_length > 0) { bytecount += _content_length; // read back the body byte by byte const char* rawdata = boost::asio::buffer_cast<const char*>(_response.data()); for (size_t i = 0; i < _content_length; i++ ) { m_body << rawdata[i]; } } else { // read all bytes until the first NULL mygetline(_response, _str, '\0'); bytecount += _str.size(); m_body << _str; } bytecount += 1; // for the final frame-terminating NULL //debug_print(boost::format("phase 3: consumed %1% bytes, BODY(%2% bytes)==%3%") % bytecount % _str.size() % _str); _response.consume(bytecount); return(bytecount); }
bool EmptyData::Fill(boost::asio::streambuf& buf) { assert(Size() != UNDEFINED_SIZE); uint32_t pos = Pos(); const uint32_t copyBytes = std::min(buf.size(), Size() - pos); buf.consume(copyBytes); SetPos(pos + copyBytes); return true; }
void on_recv_(const boost::system::error_code& error, size_t bytes_transferred) { if(error && error != boost::asio::error::eof) { std::cout << "receive failed: " << error.message() << std::endl; } else { const char* data = asio::buffer_cast<const char*>(recv_.data()); std::cout << "response(" << bytes_transferred << "): "; std::cout << data << std::endl; recv_.consume(recv_.size()); read_trg_ = true; } }
void handle_line(const boost::system::error_code& error, size_t bytes_received) { if(!error) { boost::asio::streambuf::const_buffers_type bufs = m_buffer.data(); std::string line(boost::asio::buffers_begin(bufs), boost::asio::buffers_begin(bufs) + bytes_received); std::cerr << "Sentence: " << line << std::endl; m_buffer.consume(bytes_received); read_next(); } else { std::cerr << "Error: " << error << std::endl; } }
void run_event_loop_until_frame_received() { using boost::bind; have_frame = false; buffer.consume(buffer.size()); last_error = boost::system::error_code(); boost::asio::async_read_until(socket, buffer, "END\r\n", bind(&TimedSessionBase::handle_frame_reception, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); service.reset(); while (!last_error && !have_frame) { service.poll(); service.reset(); check_if_timed_out(); } }