I guess identifiers have changed since 2013. Is there an up-to-date example
of code that does this? 0mq + capnp seems like a worthwhile combination to
me.
On Monday, 9 September 2013 07:32:49 UTC+1, Michi Henning wrote:
>
>
> On 09/09/13 05:43, Kenton Varda wrote:
> > Great, so we can use 0mq's framing. I wonder if it makes sense to
> > define this as the canonical way to send Cap'n Proto messages over
> > 0mq, and maybe provide some reference code (which I imagine is not
> > very long).
>
> Here is something that does the job:
>
> ZmqSender::ZmqSender(zmqpp::socket& s) :
> s_(s)
> {
> }
>
> // Send a message provided as a capnp segment list. Each segment is sent
> as a separate zmq message part.
>
> void ZmqSender::send(kj::ArrayPtr<kj::ArrayPtr<capnp::word const> const>
> segments)
> {
> auto it = segments.begin();
> auto i = segments.size();
> assert(i != 0);
> while (--i != 0)
> {
> s_.send_raw(reinterpret_cast<char const*>(&(*it)[0]),
> it->size() * sizeof(capnp::word), zmqpp::socket::send_more);
> ++it;
> }
> s_.send_raw(reinterpret_cast<char const*>(&(*it)[0]), it->size() *
> sizeof(capnp::word), zmqpp::socket::normal);
> }
>
> The receiver is a bit messy, due to a bit of impedance mismatch with the
> zmq API (I have to unmarshal into a std::string). The check for a
> mis-aligned string buffer is there because the standard doesn't
> guarantee that a std::string buffer has any particular alignment, as far
> as I know. Obviously, the ZmqReceiver instance must remain in scope
> until after unmarshaling is complete.
>
> class ZmqReceiver final : private util::NonCopyable
> {
> public:
> ZmqReceiver(zmqpp::socket& s);
>
> kj::ArrayPtr<kj::ArrayPtr<capnp::word const> const> receive();
>
> private:
> zmqpp::socket& s_;
> std::vector<std::string> parts_;
> std::vector<std::unique_ptr<capnp::word[]>> copied_parts_;
> std::vector<kj::ArrayPtr<capnp::word const>> segments_;
> };
>
> ZmqReceiver::ZmqReceiver(zmqpp::socket& s) :
> s_(s)
> {
> }
>
> // Receive a message (as a single message or in parts) and convert to a
> capnp segment list.
>
> kj::ArrayPtr<kj::ArrayPtr<capnp::word const> const> ZmqReceiver::receive()
> {
> // Clear previously received content, if any.
> parts_.clear();
> copied_parts_.clear();
> segments_.clear();
>
> do
> {
> parts_.push_back(string());
> string& str = parts_.back();
> s_.receive(str);
>
> assert(str.size() % sizeof(capnp::word) == 0); //
> Received message must contain an integral number of words.
> auto num_words = str.size() / sizeof(capnp::word);
> char* buf = &str[0];
>
> if (reinterpret_cast<uintptr_t>(buf) % sizeof(capnp::word) == 0)
> {
> // String buffer is word-aligned, point directly at the
> start of the string.
> segments_.push_back(kj::ArrayPtr<capnp::word
> const>(reinterpret_cast<capnp::word const*>(buf), num_words));
> }
> else
> {
> // String buffer is not word-aligned, make a copy and point
> at that.
> unique_ptr<capnp::word[]> words(new capnp::word[num_words]);
> memcpy(words.get(), buf, str.size());
> segments_.push_back(kj::ArrayPtr<capnp::word
> const>(&words[0], num_words));
> copied_parts_.push_back(move(words));
> }
> }
> while (s_.has_more_parts());
>
> return kj::ArrayPtr<kj::ArrayPtr<capnp::word const>>(&segments_[0],
> segments_.size());
> }
>
> Cheers,
>
> Michi.
>
--
You received this message because you are subscribed to the Google Groups
"Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
Visit this group at https://groups.google.com/group/capnproto.