MCPcopy Create free account
hub / github.com/Icinga/icinga2 / ReadStringFromStream

Method ReadStringFromStream

lib/base/netstring.cpp:27–102  ·  view source on GitHub ↗

* Reads data from a stream in netstring format. * * @param stream The stream to read from. * @param[out] str The String that has been read from the IOQueue. * @returns true if a complete String was read from the IOQueue, false otherwise. * @exception invalid_argument The input stream is invalid. * @see https://github.com/PeterScott/netstring-c/blob/master/netstring.c */

Source from the content-addressed store, hash-verified

25 * @see https://github.com/PeterScott/netstring-c/blob/master/netstring.c
26 */
27StreamReadStatus NetString::ReadStringFromStream(const Stream::Ptr& stream, String *str, StreamReadContext& context,
28 bool may_wait, ssize_t maxMessageLength)
29{
30 if (context.Eof)
31 return StatusEof;
32
33 if (context.MustRead) {
34 if (!context.FillFromStream(stream, may_wait)) {
35 context.Eof = true;
36 return StatusEof;
37 }
38
39 context.MustRead = false;
40 }
41
42 size_t header_length = 0;
43
44 for (size_t i = 0; i < context.Size; i++) {
45 if (context.Buffer[i] == ':') {
46 header_length = i;
47
48 /* make sure there's a header */
49 if (header_length == 0)
50 BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid NetString (no length specifier)"));
51
52 break;
53 } else if (i > 16)
54 BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid NetString (missing :)"));
55 }
56
57 if (header_length == 0) {
58 context.MustRead = true;
59 return StatusNeedData;
60 }
61
62 /* no leading zeros allowed */
63 if (context.Buffer[0] == '0' && isdigit(context.Buffer[1]))
64 BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid NetString (leading zero)"));
65
66 size_t len, i;
67
68 len = 0;
69 for (i = 0; i < header_length && isdigit(context.Buffer[i]); i++) {
70 /* length specifier must have at most 9 characters */
71 if (i >= 9)
72 BOOST_THROW_EXCEPTION(std::invalid_argument("Length specifier must not exceed 9 characters"));
73
74 len = len * 10 + (context.Buffer[i] - '0');
75 }
76
77 /* read the whole message */
78 size_t data_length = len + 1;
79
80 if (maxMessageLength >= 0 && data_length > (size_t)maxMessageLength) {
81 std::stringstream errorMessage;
82 errorMessage << "Max data length exceeded: " << (maxMessageLength / 1024) << " KB";
83
84 BOOST_THROW_EXCEPTION(std::invalid_argument(errorMessage.str()));

Callers

nothing calls this directly

Calls 6

FillFromStreamMethod · 0.80
DropDataMethod · 0.80
AppendMethod · 0.80
StringClass · 0.70
BeginMethod · 0.45
GetLengthMethod · 0.45

Tested by

no test coverage detected