@@ -45,60 +45,72 @@ class multipart_t
45
45
std::deque<message_t > m_parts;
46
46
47
47
public:
48
+ // Default constructor
48
49
multipart_t ()
49
50
{}
50
51
52
+ // Construct from socket receive
51
53
multipart_t (socket_t & socket)
52
54
{
53
55
recv (socket);
54
56
}
55
57
58
+ // Construct from memory block
56
59
multipart_t (const void *src, size_t size)
57
60
{
58
61
addmem (src, size);
59
62
}
60
63
64
+ // Construct from string
61
65
multipart_t (const std::string& string)
62
66
{
63
67
addstr (string);
64
68
}
65
69
70
+ // Construct from message part
66
71
multipart_t (message_t && message)
67
72
{
68
73
add (std::move (message));
69
74
}
70
75
76
+ // Move constructor
71
77
multipart_t (multipart_t && other)
72
78
{
73
- std::swap (m_parts, other.m_parts );
79
+ m_parts = std::move ( other.m_parts );
74
80
}
75
81
82
+ // Move assignment operator
76
83
multipart_t & operator =(multipart_t && other)
77
84
{
78
- std::swap (m_parts, other.m_parts );
85
+ m_parts = std::move ( other.m_parts );
79
86
return *this ;
80
87
}
81
88
89
+ // Destructor
82
90
virtual ~multipart_t ()
83
91
{
84
92
clear ();
85
93
}
86
94
95
+ // Delete all parts
87
96
void clear ()
88
97
{
89
98
m_parts.clear ();
90
99
}
91
100
101
+ // Get number of parts
92
102
size_t size () const
93
103
{
94
104
return m_parts.size ();
95
105
}
96
106
107
+ // Check if number of parts is zero
97
108
bool empty () const
98
109
{
99
110
return m_parts.empty ();
100
111
}
101
112
113
+ // Receive multipart message from socket
102
114
bool recv (socket_t & socket, int flags = 0 )
103
115
{
104
116
clear ();
@@ -114,6 +126,7 @@ class multipart_t
114
126
return true ;
115
127
}
116
128
129
+ // Send multipart message to socket
117
130
bool send (socket_t & socket, int flags = 0 )
118
131
{
119
132
flags &= ~(ZMQ_SNDMORE);
@@ -129,104 +142,115 @@ class multipart_t
129
142
return true ;
130
143
}
131
144
145
+ // Concatenate other multipart to front
132
146
void prepend (multipart_t && other)
133
147
{
134
148
while (!other.empty ())
135
149
push (other.remove ());
136
150
}
137
151
152
+ // Concatenate other multipart to back
138
153
void append (multipart_t && other)
139
154
{
140
155
while (!other.empty ())
141
156
add (other.pop ());
142
157
}
143
158
159
+ // Push memory block to front
144
160
void pushmem (const void *src, size_t size)
145
161
{
146
162
m_parts.push_front (message_t (src, size));
147
163
}
148
164
165
+ // Push memory block to back
149
166
void addmem (const void *src, size_t size)
150
167
{
151
168
m_parts.push_back (message_t (src, size));
152
169
}
153
170
171
+ // Push string to front
154
172
void pushstr (const std::string& string)
155
173
{
156
174
m_parts.push_front (message_t (string.data (), string.size ()));
157
175
}
158
176
177
+ // Push string to back
159
178
void addstr (const std::string& string)
160
179
{
161
180
m_parts.push_back (message_t (string.data (), string.size ()));
162
181
}
163
182
183
+ // Push type (fixed-size) to front
164
184
template <typename T>
165
185
void pushtyp (const T& type)
166
186
{
187
+ static_assert (!std::is_same<T, std::string>::value, " Use pushstr() instead of pushtyp<std::string>()" );
167
188
m_parts.push_front (message_t (&type, sizeof (type)));
168
189
}
169
190
191
+ // Push type (fixed-size) to back
170
192
template <typename T>
171
193
void addtyp (const T& type)
172
194
{
195
+ static_assert (!std::is_same<T, std::string>::value, " Use addstr() instead of addtyp<std::string>()" );
173
196
m_parts.push_back (message_t (&type, sizeof (type)));
174
197
}
175
198
199
+ // Push message part to front
176
200
void push (message_t && message)
177
201
{
178
202
m_parts.push_front (std::move (message));
179
203
}
180
204
205
+ // Push message part to back
181
206
void add (message_t && message)
182
207
{
183
208
m_parts.push_back (std::move (message));
184
209
}
185
210
211
+ // Pop string from front
186
212
std::string popstr ()
187
213
{
188
- if (m_parts.empty ())
189
- return " " ;
190
214
std::string string (m_parts.front ().data <char >(), m_parts.front ().size ());
191
215
m_parts.pop_front ();
192
216
return string;
193
217
}
194
218
219
+ // Pop type (fixed-size) from front
195
220
template <typename T>
196
221
T poptyp ()
197
222
{
198
- if (m_parts.empty ())
199
- return T ();
223
+ static_assert (!std::is_same<T, std::string>::value, " Use popstr() instead of poptyp<std::string>()" );
224
+ if (sizeof (T) != m_parts.front ().size ())
225
+ throw std::exception (" Invalid type, size does not match the message size" );
200
226
T type = *m_parts.front ().data <T>();
201
227
m_parts.pop_front ();
202
228
return type;
203
229
}
204
230
231
+ // Pop message part from front
205
232
message_t pop ()
206
233
{
207
- if (m_parts.empty ())
208
- return message_t (0 );
209
234
message_t message = std::move (m_parts.front ());
210
235
m_parts.pop_front ();
211
236
return message;
212
237
}
213
238
239
+ // Pop message part from back
214
240
message_t remove ()
215
241
{
216
- if (m_parts.empty ())
217
- return message_t (0 );
218
242
message_t message = std::move (m_parts.back ());
219
243
m_parts.pop_back ();
220
244
return message;
221
245
}
222
246
247
+ // Get pointer to a specific message part
223
248
const message_t * peek (size_t index) const
224
249
{
225
- if (index >= size ())
226
- return nullptr ;
227
250
return &m_parts[index];
228
251
}
229
252
253
+ // Create multipart from type (fixed-size)
230
254
template <typename T>
231
255
static multipart_t create (const T& type)
232
256
{
@@ -235,6 +259,7 @@ class multipart_t
235
259
return multipart;
236
260
}
237
261
262
+ // Copy multipart
238
263
multipart_t clone () const
239
264
{
240
265
multipart_t multipart;
@@ -243,6 +268,7 @@ class multipart_t
243
268
return multipart;
244
269
}
245
270
271
+ // Dump content to string
246
272
std::string str () const
247
273
{
248
274
std::stringstream ss;
@@ -278,6 +304,7 @@ class multipart_t
278
304
return ss.str ();
279
305
}
280
306
307
+ // Check if equal to other multipart
281
308
bool equal (const multipart_t * other) const
282
309
{
283
310
if (size () != other->size ())
@@ -288,6 +315,7 @@ class multipart_t
288
315
return true ;
289
316
}
290
317
318
+ // Self test
291
319
static int test ()
292
320
{
293
321
bool ok = true ;
0 commit comments