v1_decoder.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MPL-2.0 */
2 
3 #include "precompiled.hpp"
4 #include <stdlib.h>
5 #include <string.h>
6 #include <limits>
7 #include <limits.h>
8 
9 #include "decoder.hpp"
10 #include "v1_decoder.hpp"
11 #include "likely.hpp"
12 #include "wire.hpp"
13 #include "err.hpp"
14 
15 zmq::v1_decoder_t::v1_decoder_t (size_t bufsize_, int64_t maxmsgsize_) :
16  decoder_base_t<v1_decoder_t> (bufsize_), _max_msg_size (maxmsgsize_)
17 {
18  int rc = _in_progress.init ();
19  errno_assert (rc == 0);
20 
21  // At the beginning, read one byte and go to one_byte_size_ready state.
22  next_step (_tmpbuf, 1, &v1_decoder_t::one_byte_size_ready);
23 }
24 
25 zmq::v1_decoder_t::~v1_decoder_t ()
26 {
27  const int rc = _in_progress.close ();
28  errno_assert (rc == 0);
29 }
30 
31 int zmq::v1_decoder_t::one_byte_size_ready (unsigned char const *)
32 {
33  // First byte of size is read. If it is UCHAR_MAX (0xff) read 8-byte size.
34  // Otherwise allocate the buffer for message data and read the
35  // message data into it.
36  if (*_tmpbuf == UCHAR_MAX)
37  next_step (_tmpbuf, 8, &v1_decoder_t::eight_byte_size_ready);
38  else {
39  // There has to be at least one byte (the flags) in the message).
40  if (!*_tmpbuf) {
41  errno = EPROTO;
42  return -1;
43  }
44 
45  if (_max_msg_size >= 0
46  && static_cast<int64_t> (*_tmpbuf - 1) > _max_msg_size) {
47  errno = EMSGSIZE;
48  return -1;
49  }
50 
51  int rc = _in_progress.close ();
52  assert (rc == 0);
53  rc = _in_progress.init_size (*_tmpbuf - 1);
54  if (rc != 0) {
55  errno_assert (errno == ENOMEM);
56  rc = _in_progress.init ();
57  errno_assert (rc == 0);
58  errno = ENOMEM;
59  return -1;
60  }
61 
62  next_step (_tmpbuf, 1, &v1_decoder_t::flags_ready);
63  }
64  return 0;
65 }
66 
67 int zmq::v1_decoder_t::eight_byte_size_ready (unsigned char const *)
68 {
69  // 8-byte payload length is read. Allocate the buffer
70  // for message body and read the message data into it.
71  const uint64_t payload_length = get_uint64 (_tmpbuf);
72 
73  // There has to be at least one byte (the flags) in the message).
74  if (payload_length == 0) {
75  errno = EPROTO;
76  return -1;
77  }
78 
79  // Message size must not exceed the maximum allowed size.
80  if (_max_msg_size >= 0
81  && payload_length - 1 > static_cast<uint64_t> (_max_msg_size)) {
82  errno = EMSGSIZE;
83  return -1;
84  }
85 
86 #ifndef __aarch64__
87  // Message size must fit within range of size_t data type.
88  if (payload_length - 1 > std::numeric_limits<size_t>::max ()) {
89  errno = EMSGSIZE;
90  return -1;
91  }
92 #endif
93 
94  const size_t msg_size = static_cast<size_t> (payload_length - 1);
95 
96  int rc = _in_progress.close ();
97  assert (rc == 0);
98  rc = _in_progress.init_size (msg_size);
99  if (rc != 0) {
100  errno_assert (errno == ENOMEM);
101  rc = _in_progress.init ();
102  errno_assert (rc == 0);
103  errno = ENOMEM;
104  return -1;
105  }
106 
107  next_step (_tmpbuf, 1, &v1_decoder_t::flags_ready);
108  return 0;
109 }
110 
111 int zmq::v1_decoder_t::flags_ready (unsigned char const *)
112 {
113  // Store the flags from the wire into the message structure.
114  _in_progress.set_flags (_tmpbuf[0] & msg_t::more);
115 
116  next_step (_in_progress.data (), _in_progress.size (),
117  &v1_decoder_t::message_ready);
118 
119  return 0;
120 }
121 
122 int zmq::v1_decoder_t::message_ready (unsigned char const *)
123 {
124  // Message is completely read. Push it further and start reading
125  // new message. (in_progress is a 0-byte message after this point.)
126  next_step (_tmpbuf, 1, &v1_decoder_t::one_byte_size_ready);
127  return 1;
128 }
precompiled.hpp
errno
int errno
wire.hpp
EPROTO
#define EPROTO
Definition: err.hpp:26
errno_assert
#define errno_assert(x)
Definition: err.hpp:113
v1_decoder.hpp
EMSGSIZE
#define EMSGSIZE
Definition: zmq.h:131
decoder.hpp
zmq::get_uint64
uint64_t get_uint64(const unsigned char *buffer_)
Definition: wire.hpp:63
err.hpp
likely.hpp


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:07:01