32 #ifndef __ZMSG_H_INCLUDED__
33 #define __ZMSG_H_INCLUDED__
43 typedef std::basic_string<unsigned char>
ustring;
70 m_part_data.resize(msg.m_part_data.size());
71 std::copy(msg.m_part_data.begin(), msg.m_part_data.end(), m_part_data.begin());
85 if (part_nbr < m_part_data.size()) {
86 m_part_data[part_nbr] =
data;
95 if (!socket.
recv(&message, 0)) {
106 if (message.
size() == 17 && ((
unsigned char *) message.
data())[0] == 0) {
119 size_t more_size =
sizeof(more);
121 socket.
getsockopt(ZMQ_RCVMORE, &more, &more_size);
134 for (
size_t part_nbr = 0; part_nbr < m_part_data.size(); part_nbr++) {
137 if (data.size() == 33 && data[0] ==
'@') {
138 unsigned char * uuidbin =
decode_uuid((
char *) data.c_str());
140 memcpy(message.
data(), uuidbin, 17);
144 memcpy(message.
data(), data.c_str(), data.size());
147 socket.
send(message, part_nbr < m_part_data.size() - 1 ? ZMQ_SNDMORE : 0);
150 assert(error.
num() != 0);
157 return m_part_data.size();
161 if (!m_part_data.empty()) {
162 m_part_data.erase(m_part_data.end() - 1);
171 va_start(args, format);
172 vsnprintf(value, 255, format, args);
179 if (!m_part_data.empty())
180 return ((
char *) m_part_data[m_part_data.size() - 1].c_str());
187 m_part_data.insert(m_part_data.begin(), (
unsigned char*) part);
192 m_part_data.push_back((
unsigned char*) part);
201 static char hex_char[] =
"0123456789ABCDEF";
203 assert(data[0] == 0);
204 char *uuidstr =
new char[34];
207 for (byte_nbr = 0; byte_nbr < 16; byte_nbr++) {
208 uuidstr[byte_nbr * 2 + 1] = hex_char[data[byte_nbr + 1] >> 4];
209 uuidstr[byte_nbr * 2 + 2] = hex_char[data[byte_nbr + 1] & 15];
219 static unsigned char *
221 static char hex_to_bin[128] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
222 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
223 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
224 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
225 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
226 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
227 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
228 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
230 assert(strlen(uuidstr) == 33);
231 assert(uuidstr[0] ==
'@');
232 unsigned char *
data =
new unsigned char[17];
235 for (byte_nbr = 0; byte_nbr < 16; byte_nbr++)
236 data[byte_nbr + 1] = (hex_to_bin[uuidstr[byte_nbr * 2 + 1] & 127] << 4) + (hex_to_bin[uuidstr[byte_nbr * 2 + 2] & 127]);
243 if (m_part_data.empty()) {
246 ustring part = m_part_data.front();
247 m_part_data.erase(m_part_data.begin());
257 if (!m_part_data.empty()) {
258 return (
char*) m_part_data[0].c_str();
272 if (m_part_data.empty()) {
275 char *addr = (
char*)
pop_front().c_str();
285 for (
unsigned int part_nbr = 0; part_nbr < m_part_data.size(); part_nbr++) {
286 size+=m_part_data[part_nbr].size();
291 std::string
dump(
bool outToCErr=
false)
const {
292 std::stringstream ress;
294 ress <<
"--------------------------------------" <<
std::endl;
295 for (
unsigned int part_nbr = 0; part_nbr < m_part_data.size(); part_nbr++) {
299 for (
unsigned int char_nbr = 0; char_nbr < data.size(); char_nbr++)
300 if (data[char_nbr] < 32 || data[char_nbr] > 127)
303 ress <<
"[" << std::setw(3) << std::setfill(
'0') << (int) data.size() <<
"] ";
304 for (
unsigned int char_nbr = 0; char_nbr < data.size(); char_nbr++) {
306 ress << (char) data[char_nbr];
308 ress << std::hex << std::setw(2) << std::setfill(
'0') << (
short int) data[char_nbr];
313 ress <<
"--------------------------------------" << std::endl <<
std::endl;
316 std::cerr << ress.str();
326 output.
bind(
"ipc://zmsg_selftest.ipc");
329 assert(error.
num() != 0);
333 input.
connect(
"ipc://zmsg_selftest.ipc");
336 assert(error.
num() != 0);
341 assert(strcmp(zm.
body(),
"Hello") == 0);
344 assert(zm.
parts() == 0);
347 assert(zm.
parts() == 2);
352 assert(strcmp(zm.
body(),
"Hello") == 0);
356 zm.
wrap(
"address1",
"");
357 zm.
wrap(
"address2", 0);
358 assert(zm.
parts() == 4);
365 assert(zm.
parts() == 5);
366 assert(strlen(zm.
address()) == 33);
368 assert(strcmp(zm.
address(),
"address2") == 0);
374 assert(zm.
parts() == 4);
375 assert(strcmp(zm.
body(),
"World") == 0);
376 std::string part = zm.
unwrap();
377 assert(part.compare(
"address2") == 0);
381 assert(part.compare(
"address1") == 0);
382 assert(zm.
parts() == 1);
386 assert(part.compare(
"World") == 0);
387 assert(zm.
parts() == 0);
392 assert(zm.
parts() == 2);
393 assert(strcmp(zm.
body(),
"World!") == 0);
396 assert(zm.
parts() == 0);
403 std::vector<ustring> m_part_data;