コード例 #1
0
ファイル: zmailer_msg.c プロジェクト: oikosdev/zmailer
int
zmailer_msg_send (zmailer_msg_t *self, zsock_t *output)
{
    assert (self);
    assert (output);

    if (zsock_type (output) == ZMQ_ROUTER)
        zframe_send (&self->routing_id, output, ZFRAME_MORE + ZFRAME_REUSE);

    size_t frame_size = 2 + 1;          //  Signature and message ID
    switch (self->id) {
        case ZMAILER_MSG_MAIL:
            frame_size += 2;            //  version
            frame_size += 1 + strlen (self->from);
            frame_size += 4;
            if (self->to)
                frame_size += strlen (self->to);
            frame_size += 4;
            if (self->subject)
                frame_size += strlen (self->subject);
            frame_size += 4;
            if (self->request)
                frame_size += strlen (self->request);
            break;
    }
    //  Now serialize message into the frame
    zmq_msg_t frame;
    zmq_msg_init_size (&frame, frame_size);
    self->needle = (byte *) zmq_msg_data (&frame);
    PUT_NUMBER2 (0xAAA0 | 0);
    PUT_NUMBER1 (self->id);
    size_t nbr_frames = 1;              //  Total number of frames to send

    switch (self->id) {
        case ZMAILER_MSG_MAIL:
            PUT_NUMBER2 (1);
            PUT_STRING (self->from);
            if (self->to) {
                PUT_LONGSTR (self->to);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            if (self->subject) {
                PUT_LONGSTR (self->subject);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            if (self->request) {
                PUT_LONGSTR (self->request);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            break;

    }
    //  Now send the data frame
    zmq_msg_send (&frame, zsock_resolve (output), --nbr_frames? ZMQ_SNDMORE: 0);

    return 0;
}
コード例 #2
0
ファイル: zre_msg.c プロジェクト: karinies/coast
//  Serialize headers key=value pair
static int
s_headers_write (const char *key, void *item, void *argument)
{
    zre_msg_t *self = (zre_msg_t *) argument;
    PUT_STRING (key);
    PUT_LONGSTR ((char *) item);
    return 0;
}
コード例 #3
0
ファイル: zgossip_msg.c プロジェクト: wangxx2026/czmq
zmsg_t *
zgossip_msg_encode (zgossip_msg_t **self_p)
{
    assert (self_p);
    assert (*self_p);
    
    zgossip_msg_t *self = *self_p;
    zmsg_t *msg = zmsg_new ();

    size_t frame_size = 2 + 1;          //  Signature and message ID
    switch (self->id) {
        case ZGOSSIP_MSG_HELLO:
            //  version is a 1-byte integer
            frame_size += 1;
            break;
            
        case ZGOSSIP_MSG_PUBLISH:
            //  version is a 1-byte integer
            frame_size += 1;
            //  key is a string with 1-byte length
            frame_size++;       //  Size is one octet
            if (self->key)
                frame_size += strlen (self->key);
            //  value is a string with 4-byte length
            frame_size += 4;
            if (self->value)
                frame_size += strlen (self->value);
            //  ttl is a 4-byte integer
            frame_size += 4;
            break;
            
        case ZGOSSIP_MSG_PING:
            //  version is a 1-byte integer
            frame_size += 1;
            break;
            
        case ZGOSSIP_MSG_PONG:
            //  version is a 1-byte integer
            frame_size += 1;
            break;
            
        case ZGOSSIP_MSG_INVALID:
            //  version is a 1-byte integer
            frame_size += 1;
            break;
            
        default:
            zsys_error ("bad message type '%d', not sent\n", self->id);
            //  No recovery, this is a fatal application error
            assert (false);
    }
    //  Now serialize message into the frame
    zframe_t *frame = zframe_new (NULL, frame_size);
    self->needle = zframe_data (frame);
    PUT_NUMBER2 (0xAAA0 | 0);
    PUT_NUMBER1 (self->id);

    switch (self->id) {
        case ZGOSSIP_MSG_HELLO:
            PUT_NUMBER1 (1);
            break;

        case ZGOSSIP_MSG_PUBLISH:
            PUT_NUMBER1 (1);
            if (self->key) {
                PUT_STRING (self->key);
            }
            else
                PUT_NUMBER1 (0);    //  Empty string
            if (self->value) {
                PUT_LONGSTR (self->value);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            PUT_NUMBER4 (self->ttl);
            break;

        case ZGOSSIP_MSG_PING:
            PUT_NUMBER1 (1);
            break;

        case ZGOSSIP_MSG_PONG:
            PUT_NUMBER1 (1);
            break;

        case ZGOSSIP_MSG_INVALID:
            PUT_NUMBER1 (1);
            break;

    }
    //  Now send the data frame
    if (zmsg_append (msg, &frame)) {
        zmsg_destroy (&msg);
        zgossip_msg_destroy (self_p);
        return NULL;
    }
    //  Destroy zgossip_msg object
    zgossip_msg_destroy (self_p);
    return msg;
}
コード例 #4
0
ファイル: zgossip_msg.c プロジェクト: AxelVoitier/czmq
int
zgossip_msg_send (zgossip_msg_t *self, zsock_t *output)
{
    assert (self);
    assert (output);

    if (zsock_type (output) == ZMQ_ROUTER)
        zframe_send (&self->routing_id, output, ZFRAME_MORE + ZFRAME_REUSE);

    size_t frame_size = 2 + 1;          //  Signature and message ID
    switch (self->id) {
        case ZGOSSIP_MSG_HELLO:
            frame_size += 1;            //  version
            break;
        case ZGOSSIP_MSG_PUBLISH:
            frame_size += 1;            //  version
            frame_size += 1 + strlen (self->key);
            frame_size += 4;
            if (self->value)
                frame_size += strlen (self->value);
            frame_size += 4;            //  ttl
            break;
        case ZGOSSIP_MSG_PING:
            frame_size += 1;            //  version
            break;
        case ZGOSSIP_MSG_PONG:
            frame_size += 1;            //  version
            break;
        case ZGOSSIP_MSG_INVALID:
            frame_size += 1;            //  version
            break;
    }
    //  Now serialize message into the frame
    zmq_msg_t frame;
    zmq_msg_init_size (&frame, frame_size);
    self->needle = (byte *) zmq_msg_data (&frame);
    PUT_NUMBER2 (0xAAA0 | 0);
    PUT_NUMBER1 (self->id);
    size_t nbr_frames = 1;              //  Total number of frames to send

    switch (self->id) {
        case ZGOSSIP_MSG_HELLO:
            PUT_NUMBER1 (1);
            break;

        case ZGOSSIP_MSG_PUBLISH:
            PUT_NUMBER1 (1);
            PUT_STRING (self->key);
            if (self->value) {
                PUT_LONGSTR (self->value);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            PUT_NUMBER4 (self->ttl);
            break;

        case ZGOSSIP_MSG_PING:
            PUT_NUMBER1 (1);
            break;

        case ZGOSSIP_MSG_PONG:
            PUT_NUMBER1 (1);
            break;

        case ZGOSSIP_MSG_INVALID:
            PUT_NUMBER1 (1);
            break;

    }
    //  Now send the data frame
    zmq_msg_send (&frame, zsock_resolve (output), --nbr_frames? ZMQ_SNDMORE: 0);

    return 0;
}
コード例 #5
0
ファイル: zre_msg.c プロジェクト: karinies/coast
zmsg_t *
zre_msg_encode (zre_msg_t *self, int socket_type)
{
    assert (self);
    zmsg_t *msg = zmsg_new ();

    //  If we're sending to a ROUTER, send the routing_id first
    if (socket_type == ZMQ_ROUTER)
        zmsg_prepend (msg, &self->routing_id);
        
    size_t frame_size = 2 + 1;          //  Signature and message ID
    switch (self->id) {
        case ZRE_MSG_HELLO:
            //  sequence is a 2-byte integer
            frame_size += 2;
            //  ipaddress is a string with 1-byte length
            frame_size++;       //  Size is one octet
            if (self->ipaddress)
                frame_size += strlen (self->ipaddress);
            //  mailbox is a 2-byte integer
            frame_size += 2;
            //  groups is an array of strings
            frame_size += 4;    //  Size is 4 octets
            if (self->groups) {
                //  Add up size of list contents
                char *groups = (char *) zlist_first (self->groups);
                while (groups) {
                    frame_size += 4 + strlen (groups);
                    groups = (char *) zlist_next (self->groups);
                }
            }
            //  status is a 1-byte integer
            frame_size += 1;
            //  headers is an array of key=value strings
            frame_size += 4;    //  Size is 4 octets
            if (self->headers) {
                self->headers_bytes = 0;
                //  Add up size of dictionary contents
                zhash_foreach (self->headers, s_headers_count, self);
            }
            frame_size += self->headers_bytes;
            break;
            
        case ZRE_MSG_WHISPER:
            //  sequence is a 2-byte integer
            frame_size += 2;
            break;
            
        case ZRE_MSG_SHOUT:
            //  sequence is a 2-byte integer
            frame_size += 2;
            //  group is a string with 1-byte length
            frame_size++;       //  Size is one octet
            if (self->group)
                frame_size += strlen (self->group);
            break;
            
        case ZRE_MSG_JOIN:
            //  sequence is a 2-byte integer
            frame_size += 2;
            //  group is a string with 1-byte length
            frame_size++;       //  Size is one octet
            if (self->group)
                frame_size += strlen (self->group);
            //  status is a 1-byte integer
            frame_size += 1;
            break;
            
        case ZRE_MSG_LEAVE:
            //  sequence is a 2-byte integer
            frame_size += 2;
            //  group is a string with 1-byte length
            frame_size++;       //  Size is one octet
            if (self->group)
                frame_size += strlen (self->group);
            //  status is a 1-byte integer
            frame_size += 1;
            break;
            
        case ZRE_MSG_PING:
            //  sequence is a 2-byte integer
            frame_size += 2;
            break;
            
        case ZRE_MSG_PING_OK:
            //  sequence is a 2-byte integer
            frame_size += 2;
            break;
            
        default:
            printf ("E: bad message type '%d', not sent\n", self->id);
            //  No recovery, this is a fatal application error
            assert (false);
    }
    //  Now serialize message into the frame
    zframe_t *frame = zframe_new (NULL, frame_size);
    self->needle = zframe_data (frame);
    PUT_NUMBER2 (0xAAA0 | 1);
    PUT_NUMBER1 (self->id);

    switch (self->id) {
        case ZRE_MSG_HELLO:
            PUT_NUMBER2 (self->sequence);
            if (self->ipaddress) {
                PUT_STRING (self->ipaddress);
            }
            else
                PUT_NUMBER1 (0);    //  Empty string
            PUT_NUMBER2 (self->mailbox);
            if (self->groups) {
                PUT_NUMBER4 (zlist_size (self->groups));
                char *groups = (char *) zlist_first (self->groups);
                while (groups) {
                    PUT_LONGSTR (groups);
                    groups = (char *) zlist_next (self->groups);
                }
            }
            else
                PUT_NUMBER4 (0);    //  Empty string array
            PUT_NUMBER1 (self->status);
            if (self->headers) {
                PUT_NUMBER4 (zhash_size (self->headers));
                zhash_foreach (self->headers, s_headers_write, self);
            }
            else
                PUT_NUMBER4 (0);    //  Empty dictionary
            break;

        case ZRE_MSG_WHISPER:
            PUT_NUMBER2 (self->sequence);
            break;

        case ZRE_MSG_SHOUT:
            PUT_NUMBER2 (self->sequence);
            if (self->group) {
                PUT_STRING (self->group);
            }
            else
                PUT_NUMBER1 (0);    //  Empty string
            break;

        case ZRE_MSG_JOIN:
            PUT_NUMBER2 (self->sequence);
            if (self->group) {
                PUT_STRING (self->group);
            }
            else
                PUT_NUMBER1 (0);    //  Empty string
            PUT_NUMBER1 (self->status);
            break;

        case ZRE_MSG_LEAVE:
            PUT_NUMBER2 (self->sequence);
            if (self->group) {
                PUT_STRING (self->group);
            }
            else
                PUT_NUMBER1 (0);    //  Empty string
            PUT_NUMBER1 (self->status);
            break;

        case ZRE_MSG_PING:
            PUT_NUMBER2 (self->sequence);
            break;

        case ZRE_MSG_PING_OK:
            PUT_NUMBER2 (self->sequence);
            break;

    }
    //  Now send the data frame
    if (zmsg_append (msg, &frame)) {
        zmsg_destroy (&msg);
        zre_msg_destroy (&self);
        return NULL;
    }
    //  Now send the content field if set
    if (self->id == ZRE_MSG_WHISPER) {
        zframe_t *content_part = zmsg_pop (self->content);
        while (content_part) {
            zmsg_append (msg, &content_part);
            content_part = zmsg_pop (self->content);
        }
    }
    //  Now send the content field if set
    if (self->id == ZRE_MSG_SHOUT) {
        zframe_t *content_part = zmsg_pop (self->content);
        while (content_part) {
            zmsg_append (msg, &content_part);
            content_part = zmsg_pop (self->content);
        }
    }
    //  Destroy zre_msg object
    zre_msg_destroy (&self);
    return msg;

}
コード例 #6
0
ファイル: fmq_msg.c プロジェクト: hintjens/filemq
int
fmq_msg_send (fmq_msg_t *self, zsock_t *output)
{
    assert (self);
    assert (output);

    if (zsock_type (output) == ZMQ_ROUTER)
        zframe_send (&self->routing_id, output, ZFRAME_MORE + ZFRAME_REUSE);

    size_t frame_size = 2 + 1;          //  Signature and message ID
    switch (self->id) {
        case FMQ_MSG_OHAI:
            frame_size += 1 + strlen ("FILEMQ");
            frame_size += 2;            //  version
            break;
        case FMQ_MSG_ICANHAZ:
            frame_size += 4;
            if (self->path)
                frame_size += strlen (self->path);
            frame_size += 4;            //  Size is 4 octets
            if (self->options) {
                self->options_bytes = 0;
                char *item = (char *) zhash_first (self->options);
                while (item) {
                    self->options_bytes += 1 + strlen (zhash_cursor (self->options));
                    self->options_bytes += 4 + strlen (item);
                    item = (char *) zhash_next (self->options);
                }
            }
            frame_size += self->options_bytes;
            frame_size += 4;            //  Size is 4 octets
            if (self->cache) {
                self->cache_bytes = 0;
                char *item = (char *) zhash_first (self->cache);
                while (item) {
                    self->cache_bytes += 1 + strlen (zhash_cursor (self->cache));
                    self->cache_bytes += 4 + strlen (item);
                    item = (char *) zhash_next (self->cache);
                }
            }
            frame_size += self->cache_bytes;
            break;
        case FMQ_MSG_NOM:
            frame_size += 8;            //  credit
            frame_size += 8;            //  sequence
            break;
        case FMQ_MSG_CHEEZBURGER:
            frame_size += 8;            //  sequence
            frame_size += 1;            //  operation
            frame_size += 4;
            if (self->filename)
                frame_size += strlen (self->filename);
            frame_size += 8;            //  offset
            frame_size += 1;            //  eof
            frame_size += 4;            //  Size is 4 octets
            if (self->headers) {
                self->headers_bytes = 0;
                char *item = (char *) zhash_first (self->headers);
                while (item) {
                    self->headers_bytes += 1 + strlen (zhash_cursor (self->headers));
                    self->headers_bytes += 4 + strlen (item);
                    item = (char *) zhash_next (self->headers);
                }
            }
            frame_size += self->headers_bytes;
            frame_size += 4;            //  Size is 4 octets
            if (self->chunk)
                frame_size += zchunk_size (self->chunk);
            break;
        case FMQ_MSG_SRSLY:
            frame_size += 1 + strlen (self->reason);
            break;
        case FMQ_MSG_RTFM:
            frame_size += 1 + strlen (self->reason);
            break;
    }
    //  Now serialize message into the frame
    zmq_msg_t frame;
    zmq_msg_init_size (&frame, frame_size);
    self->needle = (byte *) zmq_msg_data (&frame);
    PUT_NUMBER2 (0xAAA0 | 3);
    PUT_NUMBER1 (self->id);
    size_t nbr_frames = 1;              //  Total number of frames to send

    switch (self->id) {
        case FMQ_MSG_OHAI:
            PUT_STRING ("FILEMQ");
            PUT_NUMBER2 (FMQ_MSG_VERSION);
            break;

        case FMQ_MSG_ICANHAZ:
            if (self->path) {
                PUT_LONGSTR (self->path);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            if (self->options) {
                PUT_NUMBER4 (zhash_size (self->options));
                char *item = (char *) zhash_first (self->options);
                while (item) {
                    PUT_STRING (zhash_cursor (self->options));
                    PUT_LONGSTR (item);
                    item = (char *) zhash_next (self->options);
                }
            }
            else
                PUT_NUMBER4 (0);    //  Empty hash
            if (self->cache) {
                PUT_NUMBER4 (zhash_size (self->cache));
                char *item = (char *) zhash_first (self->cache);
                while (item) {
                    PUT_STRING (zhash_cursor (self->cache));
                    PUT_LONGSTR (item);
                    item = (char *) zhash_next (self->cache);
                }
            }
            else
                PUT_NUMBER4 (0);    //  Empty hash
            break;

        case FMQ_MSG_NOM:
            PUT_NUMBER8 (self->credit);
            PUT_NUMBER8 (self->sequence);
            break;

        case FMQ_MSG_CHEEZBURGER:
            PUT_NUMBER8 (self->sequence);
            PUT_NUMBER1 (self->operation);
            if (self->filename) {
                PUT_LONGSTR (self->filename);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            PUT_NUMBER8 (self->offset);
            PUT_NUMBER1 (self->eof);
            if (self->headers) {
                PUT_NUMBER4 (zhash_size (self->headers));
                char *item = (char *) zhash_first (self->headers);
                while (item) {
                    PUT_STRING (zhash_cursor (self->headers));
                    PUT_LONGSTR (item);
                    item = (char *) zhash_next (self->headers);
                }
            }
            else
                PUT_NUMBER4 (0);    //  Empty hash
            if (self->chunk) {
                PUT_NUMBER4 (zchunk_size (self->chunk));
                memcpy (self->needle,
                        zchunk_data (self->chunk),
                        zchunk_size (self->chunk));
                self->needle += zchunk_size (self->chunk);
            }
            else
                PUT_NUMBER4 (0);    //  Empty chunk
            break;

        case FMQ_MSG_SRSLY:
            PUT_STRING (self->reason);
            break;

        case FMQ_MSG_RTFM:
            PUT_STRING (self->reason);
            break;

    }
    //  Now send the data frame
    zmq_msg_send (&frame, zsock_resolve (output), --nbr_frames? ZMQ_SNDMORE: 0);

    return 0;
}
コード例 #7
0
ファイル: zproto_example.c プロジェクト: asokoloski/zproto
int
zproto_example_send (zproto_example_t *self, zsock_t *output)
{
    assert (self);
    assert (output);

    if (zsock_type (output) == ZMQ_ROUTER)
        zframe_send (&self->routing_id, output, ZFRAME_MORE + ZFRAME_REUSE);

    size_t frame_size = 2 + 1;          //  Signature and message ID
    switch (self->id) {
        case ZPROTO_EXAMPLE_LOG:
            frame_size += 2;            //  sequence
            frame_size += 2;            //  version
            frame_size += 1;            //  level
            frame_size += 1;            //  event
            frame_size += 2;            //  node
            frame_size += 2;            //  peer
            frame_size += 8;            //  time
            frame_size += 1 + strlen (self->host);
            frame_size += 4;
            if (self->data)
                frame_size += strlen (self->data);
            break;
        case ZPROTO_EXAMPLE_STRUCTURES:
            frame_size += 2;            //  sequence
            frame_size += 4;            //  Size is 4 octets
            if (self->aliases) {
                char *aliases = (char *) zlist_first (self->aliases);
                while (aliases) {
                    frame_size += 4 + strlen (aliases);
                    aliases = (char *) zlist_next (self->aliases);
                }
            }
            frame_size += 4;            //  Size is 4 octets
            if (self->headers) {
                self->headers_bytes = 0;
                char *item = (char *) zhash_first (self->headers);
                while (item) {
                    self->headers_bytes += 1 + strlen (zhash_cursor (self->headers));
                    self->headers_bytes += 4 + strlen (item);
                    item = (char *) zhash_next (self->headers);
                }
            }
            frame_size += self->headers_bytes;
            break;
        case ZPROTO_EXAMPLE_BINARY:
            frame_size += 2;            //  sequence
            frame_size += 4;            //  flags
            frame_size += 4;            //  Size is 4 octets
            if (self->public_key)
                frame_size += zchunk_size (self->public_key);
            frame_size += ZUUID_LEN;    //  identifier
            break;
        case ZPROTO_EXAMPLE_TYPES:
            frame_size += 2;            //  sequence
            frame_size += 1 + strlen (self->client_forename);
            frame_size += 1 + strlen (self->client_surname);
            frame_size += 1 + strlen (self->client_mobile);
            frame_size += 1 + strlen (self->client_email);
            frame_size += 1 + strlen (self->supplier_forename);
            frame_size += 1 + strlen (self->supplier_surname);
            frame_size += 1 + strlen (self->supplier_mobile);
            frame_size += 1 + strlen (self->supplier_email);
            break;
    }
    //  Now serialize message into the frame
    zmq_msg_t frame;
    zmq_msg_init_size (&frame, frame_size);
    self->needle = (byte *) zmq_msg_data (&frame);
    PUT_NUMBER2 (0xAAA0 | 0);
    PUT_NUMBER1 (self->id);
    bool have_content = false;
    size_t nbr_frames = 1;              //  Total number of frames to send

    switch (self->id) {
        case ZPROTO_EXAMPLE_LOG:
            PUT_NUMBER2 (self->sequence);
            PUT_NUMBER2 (3);
            PUT_NUMBER1 (self->level);
            PUT_NUMBER1 (self->event);
            PUT_NUMBER2 (self->node);
            PUT_NUMBER2 (self->peer);
            PUT_NUMBER8 (self->time);
            PUT_STRING (self->host);
            if (self->data) {
                PUT_LONGSTR (self->data);
            }
            else
                PUT_NUMBER4 (0);    //  Empty string
            break;

        case ZPROTO_EXAMPLE_STRUCTURES:
            PUT_NUMBER2 (self->sequence);
            if (self->aliases) {
                PUT_NUMBER4 (zlist_size (self->aliases));
                char *aliases = (char *) zlist_first (self->aliases);
                while (aliases) {
                    PUT_LONGSTR (aliases);
                    aliases = (char *) zlist_next (self->aliases);
                }
            }
            else
                PUT_NUMBER4 (0);    //  Empty string array
            if (self->headers) {
                PUT_NUMBER4 (zhash_size (self->headers));
                char *item = (char *) zhash_first (self->headers);
                while (item) {
                    PUT_STRING (zhash_cursor (self->headers));
                    PUT_LONGSTR (item);
                    item = (char *) zhash_next (self->headers);
                }
            }
            else
                PUT_NUMBER4 (0);    //  Empty hash
            break;

        case ZPROTO_EXAMPLE_BINARY:
            PUT_NUMBER2 (self->sequence);
            PUT_OCTETS (self->flags, 4);
            if (self->public_key) {
                PUT_NUMBER4 (zchunk_size (self->public_key));
                memcpy (self->needle,
                        zchunk_data (self->public_key),
                        zchunk_size (self->public_key));
                self->needle += zchunk_size (self->public_key);
            }
            else
                PUT_NUMBER4 (0);    //  Empty chunk
            if (self->identifier)
                zuuid_export (self->identifier, self->needle);
            else
                memset (self->needle, 0, ZUUID_LEN);
            self->needle += ZUUID_LEN;
            nbr_frames++;
            nbr_frames += self->content? zmsg_size (self->content): 1;
            have_content = true;
            break;

        case ZPROTO_EXAMPLE_TYPES:
            PUT_NUMBER2 (self->sequence);
            PUT_STRING (self->client_forename);
            PUT_STRING (self->client_surname);
            PUT_STRING (self->client_mobile);
            PUT_STRING (self->client_email);
            PUT_STRING (self->supplier_forename);
            PUT_STRING (self->supplier_surname);
            PUT_STRING (self->supplier_mobile);
            PUT_STRING (self->supplier_email);
            break;

    }
    //  Now send the data frame
    zmq_msg_send (&frame, zsock_resolve (output), --nbr_frames? ZMQ_SNDMORE: 0);

    //  Now send any frame fields, in order
    if (self->id == ZPROTO_EXAMPLE_BINARY) {
        //  If address isn't set, send an empty frame
        if (self->address)
            zframe_send (&self->address, output, ZFRAME_REUSE + (--nbr_frames? ZFRAME_MORE: 0));
        else
            zmq_send (zsock_resolve (output), NULL, 0, (--nbr_frames? ZMQ_SNDMORE: 0));
    }
    //  Now send the content if necessary
    if (have_content) {
        if (self->content) {
            zframe_t *frame = zmsg_first (self->content);
            while (frame) {
                zframe_send (&frame, output, ZFRAME_REUSE + (--nbr_frames? ZFRAME_MORE: 0));
                frame = zmsg_next (self->content);
            }
        }
        else
            zmq_send (zsock_resolve (output), NULL, 0, 0);
    }
    return 0;
}