/src/libzmq/src/v2_encoder.cpp
Line | Count | Source |
1 | | /* SPDX-License-Identifier: MPL-2.0 */ |
2 | | |
3 | | #include "precompiled.hpp" |
4 | | #include "v2_protocol.hpp" |
5 | | #include "v2_encoder.hpp" |
6 | | #include "msg.hpp" |
7 | | #include "likely.hpp" |
8 | | #include "wire.hpp" |
9 | | |
10 | | #include <limits.h> |
11 | | |
12 | | zmq::v2_encoder_t::v2_encoder_t (size_t bufsize_) : |
13 | 0 | encoder_base_t<v2_encoder_t> (bufsize_) |
14 | 0 | { |
15 | | // Write 0 bytes to the batch and go to message_ready state. |
16 | 0 | next_step (NULL, 0, &v2_encoder_t::message_ready, true); |
17 | 0 | } |
18 | | |
19 | | zmq::v2_encoder_t::~v2_encoder_t () |
20 | 0 | { |
21 | 0 | } |
22 | | |
23 | | void zmq::v2_encoder_t::message_ready () |
24 | 0 | { |
25 | | // Encode flags. |
26 | 0 | size_t size = in_progress ()->size (); |
27 | 0 | size_t header_size = 2; // flags byte + size byte |
28 | 0 | unsigned char &protocol_flags = _tmp_buf[0]; |
29 | 0 | protocol_flags = 0; |
30 | 0 | if (in_progress ()->flags () & msg_t::more) |
31 | 0 | protocol_flags |= v2_protocol_t::more_flag; |
32 | 0 | if (in_progress ()->size () > UCHAR_MAX) |
33 | 0 | protocol_flags |= v2_protocol_t::large_flag; |
34 | 0 | if (in_progress ()->flags () & msg_t::command) |
35 | 0 | protocol_flags |= v2_protocol_t::command_flag; |
36 | 0 | if (in_progress ()->is_subscribe () || in_progress ()->is_cancel ()) |
37 | 0 | ++size; |
38 | | |
39 | | // Encode the message length. For messages less then 256 bytes, |
40 | | // the length is encoded as 8-bit unsigned integer. For larger |
41 | | // messages, 64-bit unsigned integer in network byte order is used. |
42 | 0 | if (unlikely (size > UCHAR_MAX)) { |
43 | 0 | put_uint64 (_tmp_buf + 1, size); |
44 | 0 | header_size = 9; // flags byte + size 8 bytes |
45 | 0 | } else { |
46 | 0 | _tmp_buf[1] = static_cast<uint8_t> (size); |
47 | 0 | } |
48 | | |
49 | | // Encode the subscribe/cancel byte. This is done in the encoder as |
50 | | // opposed to when the subscribe message is created to allow different |
51 | | // protocol behaviour on the wire in the v3.1 and legacy encoders. |
52 | | // It results in the work being done multiple times in case the sub |
53 | | // is sending the subscription/cancel to multiple pubs, but it cannot |
54 | | // be avoided. This processing can be moved to xsub once support for |
55 | | // ZMTP < 3.1 is dropped. |
56 | 0 | if (in_progress ()->is_subscribe ()) |
57 | 0 | _tmp_buf[header_size++] = 1; |
58 | 0 | else if (in_progress ()->is_cancel ()) |
59 | 0 | _tmp_buf[header_size++] = 0; |
60 | |
|
61 | 0 | next_step (_tmp_buf, header_size, &v2_encoder_t::size_ready, false); |
62 | 0 | } |
63 | | |
64 | | void zmq::v2_encoder_t::size_ready () |
65 | 0 | { |
66 | | // Write message body into the buffer. |
67 | 0 | next_step (in_progress ()->data (), in_progress ()->size (), |
68 | 0 | &v2_encoder_t::message_ready, true); |
69 | 0 | } |