[zeromq-dev] more on c++ api

Burak Arslan burak.arslan at arskom.com.tr
Wed Oct 27 18:57:35 CEST 2010


 On 10/27/10 19:26, Martin Sustrik wrote:
> Hi Burak,
>> i got a few ideas that would be nice to have in the c++ api:
>>
>> 1) zmq.hpp has
>>
>> #include<assert.h>
>> #include<string.h>
>>
>> in the beginning. converting them to
>>
>> #include<cassert>
>> #include<cstring>
>>
>> would be better in line with c++ conventions, and in case of cstring
>> header, would help keep the default namespace clean.
>>    
> Yes.
>




>From 1757294e122a5563133812dc0711af94b9f5fa54 Mon Sep 17 00:00:00 2001
From: Burak Arslan <burak-github at arskom.com.tr>
Date: Wed, 27 Oct 2010 19:34:23 +0300
Subject: [PATCH 1/3] switch to c++-specific headers

Signed-off-by: Burak Arslan <burak-github at arskom.com.tr>
---
 include/zmq.hpp |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/zmq.hpp b/include/zmq.hpp
index 86ffff6..01e539e 100644
--- a/include/zmq.hpp
+++ b/include/zmq.hpp
@@ -22,8 +22,8 @@
 
 #include "zmq.h"
 
-#include <assert.h>
-#include <string.h>
+#include <cassert>
+#include <cstring>
 #include <exception>
 
 namespace zmq
-- 
1.7.2.2




>> 2) providing message_t (copy) constructors as such;
>>
>> message_t(const std::vector<uint8_t>  &) // for binary data
>> message_t(const std::string&) // for strings
>>
>> will let us call socket.send("blah") or
>> socket.send(vector_with_binary_data);
>>    
> The string constructor looks useful.
>



>From 25fa97749c60f464f979bae264a8e40a0d53ea84 Mon Sep 17 00:00:00 2001
From: Burak Arslan <burak-github at arskom.com.tr>
Date: Wed, 27 Oct 2010 19:35:36 +0300
Subject: [PATCH 2/3] add std::string ctor for message_t

Signed-off-by: Burak Arslan <burak-github at arskom.com.tr>
---
 include/zmq.hpp |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/include/zmq.hpp b/include/zmq.hpp
index 01e539e..cd5f909 100644
--- a/include/zmq.hpp
+++ b/include/zmq.hpp
@@ -25,6 +25,7 @@
 #include <cassert>
 #include <cstring>
 #include <exception>
+#include <string>
 
 namespace zmq
 {
@@ -91,6 +92,14 @@ namespace zmq
                 throw error_t ();
         }
 
+        inline message_t (const std::string &str_)
+        {
+            int rc = zmq_msg_init_size (this, str_.size());
+            if (rc != 0)
+                throw error_t ();
+            std::memcpy(this->data(), str_.data(), str_.size());
+        }
+
         inline ~message_t ()
         {
             int rc = zmq_msg_close (this);
-- 
1.7.2.2




> About vector<uint8_t> one I am not sure. I don't recall I've ever seen
> binary data stored in vector<uint8_t>. People tend to use raw malloc
> instead.
>


http://stackoverflow.com/questions/837521/c-stls-string-eqivalent-for-binary-data

i think std::vector<uint8_t> is the nicest way to store binary data, as
it provides a flexible contiguous block.

here is the patch if you want it.

>From 8a4f3f3a3704b554fc42e6bff3c99e4427c81630 Mon Sep 17 00:00:00 2001
From: Burak Arslan <burak-github at arskom.com.tr>
Date: Wed, 27 Oct 2010 19:36:21 +0300
Subject: [PATCH 3/3] add std::vector<uint8_t> ctor for message_t

Signed-off-by: Burak Arslan <burak-github at arskom.com.tr>
---
 include/zmq.hpp |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/include/zmq.hpp b/include/zmq.hpp
index cd5f909..51d64a3 100644
--- a/include/zmq.hpp
+++ b/include/zmq.hpp
@@ -25,6 +25,7 @@
 #include <cassert>
 #include <cstring>
 #include <exception>
+#include <vector>
 #include <string>
 
 namespace zmq
@@ -92,6 +93,14 @@ namespace zmq
                 throw error_t ();
         }
 
+        inline message_t (const std::string<uint8_t> &vect_)
+        {
+            int rc = zmq_msg_init_size (this, vect_.size());
+            if (rc != 0)
+                throw error_t ();
+            std::memcpy(this->data(), &vect_[0], vect_.size());
+        }
+
         inline message_t (const std::string &str_)
         {
             int rc = zmq_msg_init_size (this, str_.size());
-- 
1.7.2.2





>> 3) providing stream operators
>>
>> zmq::socket_t&operator<<(zmq::socket_t&, zmq::message_t&);
>> zmq::socket_t&operator>>(zmq::socket_t&, zmq::message_t&);
>>    
> operator << normally has copy semantics, i.e. writing an object to a
> stream doesn't empty the object. zmq_send on the other hand has move
> semantics, ie. the message is emptied when sent. The move semantics
> could be in theory simulated using zmq_msg_copy, however, that would
> have performance impact.
>
> My advise would be to wait till 0MQ/3.0 where standard POSIX-like
> zmq_send(void*,size_t) withe copy semantics will be available.
> Operator << then can use that API.

okay.


>> or even:
>>
>> std::ostream&operator<<(std::ostream&, zmq::message_t&);
>>

what about this? it can be o(n) as it requires detection of binary/text
encoding the way you do in s_dump in zmqhelpers. but it's mostly for
debugging anyway.

>> would be nice.
>>
>> 4) providing a multipart_message_t class and adding support for it to
>> socket's relevant functions would make the api more elegant.
>>    
> Pretty hard to do that without introducing performance overhead
> (managing list of message parts within the multipart_message_t object
> and thus doing additional allocations). You can try though.

i was thinking about having a std::list<zmq::message_t *>. yes, this
doesn't come for free, but one needs to do this for complex multipart
messages anyway.

here's how i'd like to see it used:

mp_message_t mp_msg;
socket >> mp_msg;
cout << mp_msg[0];
cout << mp_msg[1];

one could even replace field numbers by subclassing it and adding proper
accessors or by defining constants.

best regards,
burak





More information about the zeromq-dev mailing list