Permalink
Browse files

yay! binary bodies in frames!

  • Loading branch information...
1 parent 0389cbd commit 965308b2428e3afb3df29acf2a072849252fe04a @ekarak committed Apr 25, 2012
Showing with 69 additions and 42 deletions.
  1. +6 −24 BoostStomp.cpp
  2. +10 −2 BoostStomp.hpp
  3. +10 −7 Main.cpp
  4. +4 −4 StompFrame.cpp
  5. +39 −5 StompFrame.hpp
View
@@ -277,6 +277,7 @@ namespace STOMP {
// special case: content-length
if (*key == "content-length") {
content_length = lexical_cast<int>(*val);
+ debug_print(boost::format("content-length read back value==%1%") % content_length);
}
delete key;
delete val;
@@ -292,21 +293,19 @@ namespace STOMP {
// read until the specified content length
_input.read(buffer, content_length);
bytes_to_consume += content_length;
- /*
- for (int i=0; i<content_length; i++) {
+ // read back the body byte by byte
+ for (size_t i=0; i<content_length; i++) {
frame->m_body << buffer[i];
- } */
- _str = string(buffer); // TODO: check if NULLs inside the body
+ }
//debug_print(boost::format("parse_next phase 3: BODY(%1% bytes)==%2%") % _str.size() % _str);
- frame->m_body.assign(_str.begin(), _str.end());
delete buffer;
} else {
// read all bytes until the first NULL
std::getline(_input, _str, '\0');
//debug_print(boost::format("parse_next phase 3: BODY(%1% bytes)==%2%") % _str.size() % _str);
if (_str.length() > 0) {
bytes_to_consume += _str.size() + 1;
- frame->m_body.assign(_str.begin(), _str.end());
+ frame->m_body << _str;
};
}
} else {
@@ -517,7 +516,7 @@ namespace STOMP {
string errormessage = (_rcvd_frame.headers().find("message") != _rcvd_frame.headers().end()) ?
_rcvd_frame.headers()["message"] :
"(unknown error!)";
- errormessage += _rcvd_frame.body().data();
+ errormessage += _rcvd_frame.body().c_str();
throw(errormessage);
}
@@ -541,23 +540,6 @@ namespace STOMP {
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
- // ------------------------------------------
- bool BoostStomp::send( string& topic, hdrmap _headers, std::string& body )
- // ------------------------------------------
- {
- _headers["destination"] = topic;
- Frame frame( "SEND", _headers, body );
- return(send_frame(frame));
- }
-
- // ------------------------------------------
- bool BoostStomp::send( string& topic, hdrmap _headers, std::string& body, pfnOnStompMessage_t callback )
- // ------------------------------------------
- {
- _headers["destination"] = topic;
- Frame frame( "SEND", _headers, body );
- return(send_frame(frame));
- }
// ------------------------------------------
bool BoostStomp::subscribe( string& topic, pfnOnStompMessage_t callback )
View
@@ -165,8 +165,16 @@ namespace STOMP {
void stop();
// thread-safe methods called from outside the thread loop
- bool send ( std::string& topic, hdrmap _headers, std::string& body );
- bool send ( std::string& topic, hdrmap _headers, std::string& body, pfnOnStompMessage_t callback );
+ template <typename BodyType>
+ bool send ( std::string& _topic, hdrmap _headers, BodyType& _body, pfnOnStompMessage_t callback = NULL) {
+ _headers["destination"] = _topic;
+ Frame frame( "SEND", _headers, _body );
+ return(send_frame(frame));
+ }
+
+
+ //bool send ( std::string& topic, hdrmap _headers, std::string& body );
+ //
bool subscribe ( std::string& topic, pfnOnStompMessage_t callback );
bool unsubscribe ( std::string& topic );
bool acknowledge ( Frame& _frame, bool acked );
View
@@ -50,8 +50,8 @@ bool subscription_callback(STOMP::Frame& _frame) {
for ( it = _frame.headers().begin() ; it != _frame.headers().end(); it++ )
cout << "\t" << (*it).first << "\t=>\t" << (*it).second << endl;
//
- cout << " Body: (size: " << _frame.body().size() << " chars):" << endl;
- cout << _frame.body().data() << endl;
+ cout << " Body: (size: " << _frame.body().v.size() << " chars):" << endl;
+ hexdump(_frame.body().c_str(), _frame.body().v.size() );
return(true); // return false if we want to disacknowledge the frame (send NACK instead of ACK)
}
@@ -81,13 +81,16 @@ int main(int argc, char *argv[]) {
// add an outgoing message to the queue
stomp_client->send(notifications_topic, headers, body);
sleep(1);
- string body2 = string("this is the SECOND message.\0with a NULL in it");
+ // send another one
+ string body2 = string("this is the SECOND message.");
stomp_client->send(notifications_topic, headers, body2);
sleep(1);
- string body3 = string("this is the THIRD message.\0\0with two NULLs in it");
- vector<char> binbody;
- binbody.push_back(body3.c_str());
- stomp_client->send(notifications_topic, headers, body3);
+ // add some binary content in the body
+ binbody bb;
+ bb << "this is the THIRD message.";
+ bb << '\0';
+ bb << "with a NULL in it.";
+ stomp_client->send(notifications_topic, headers, bb);
sleep(1);
stomp_client->stop();
}
View
@@ -82,14 +82,14 @@ namespace STOMP {
}
}
// special header: content-length
- if( m_body.size() > 0 ) {
- os << "content-length:" << m_body.size() << "\n";
+ if( m_body.v.size() > 0 ) {
+ os << "content-length:" << m_body.v.size() << "\n";
}
// write newline signifying end of headers
os << "\n";
// step 3. Write the body
- if( m_body.size() > 0 ) {
- request.sputn(m_body.data(), m_body.size());
+ if( m_body.v.size() > 0 ) {
+ request.sputn(m_body.v.data(), m_body.v.size());
//os << m_body.data();
// TODO: check bodies with NULL in them (data() returns char*)
}
View
@@ -24,7 +24,40 @@ namespace STOMP {
/* STOMP Frame header map */
typedef map<string, string> hdrmap;
- struct BoostStomp;
+ class BoostStomp;
+
+ // an std::vector encapsulation in order to store binary strings
+ // (STOMP doesn't prohibit NULLs inside the frame body)
+ class binbody {
+
+ public:
+ // one vector to hold them all
+ vector<char> v;
+ // constructors:
+ binbody() {};
+ binbody(string b) {
+ v.assign(b.begin(), b.end());
+ }
+ binbody(string::iterator begin, string::iterator end) {
+ v.assign(begin, end);
+ };
+ // append a string at the end of the body vector
+ binbody& operator << (std::string s) {
+ v.insert(v.end(), s.begin(), s.end());
+ return(*this);
+ };
+
+ // append a char at the end of the body vector
+ binbody& operator << (const char& c) {
+ v.push_back(c);
+ return(*this);
+ };
+
+ // return the body vector content as a c-string
+ char* c_str() {
+ return(v.data());
+ };
+ };
class Frame {
friend class BoostStomp;
@@ -33,7 +66,7 @@ namespace STOMP {
protected:
string m_command;
hdrmap m_headers;
- vector<char> m_body;
+ binbody m_body;
boost::asio::streambuf request;
@@ -49,10 +82,11 @@ namespace STOMP {
m_headers(h)
{};
- Frame(string cmd, hdrmap h, string b):
+ template <typename BodyType>
+ Frame(string cmd, hdrmap h, BodyType b):
m_command(cmd),
m_headers(h),
- m_body(b.begin(), b.end())
+ m_body(b)
{};
// copy constructor
@@ -66,7 +100,7 @@ namespace STOMP {
//
string command() { return m_command; };
hdrmap headers() { return m_headers; };
- vector<char>& body() { return m_body; };
+ binbody& body() { return m_body; };
// encode a STOMP Frame into a streambuf
void encode();

0 comments on commit 965308b

Please sign in to comment.