]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/parser/BinaryTokenizer.cc
2 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section 24 SBuf */
12 #include "parser/BinaryTokenizer.h"
14 Parser::BinaryTokenizer::BinaryTokenizer(): BinaryTokenizer(SBuf())
18 Parser::BinaryTokenizer::BinaryTokenizer(const SBuf
&data
, const bool expectMore
):
23 expectMore_(expectMore
)
29 operator <<(std::ostream
&os
, const Parser::BinaryTokenizerContext
*context
)
32 os
<< context
->parent
<< context
->name
;
36 /// debugging helper that prints a "standard" debugs() trailer
37 #define BinaryTokenizer_tail(size, start) \
38 " occupying " << (size) << " bytes @" << (start) << " in " << this << \
39 (expectMore_ ? ';' : '.');
41 /// logs and throws if fewer than size octets remain; no other side effects
43 Parser::BinaryTokenizer::want(uint64_t size
, const char *description
) const
45 if (parsed_
+ size
> data_
.length()) {
46 debugs(24, 5, (parsed_
+ size
- data_
.length()) << " more bytes for " <<
47 context
<< description
<< BinaryTokenizer_tail(size
, parsed_
));
48 Must(expectMore_
); // throw an error on premature input termination
49 throw InsufficientInput();
54 Parser::BinaryTokenizer::got(uint64_t size
, const char *description
) const
56 debugs(24, 7, context
<< description
<<
57 BinaryTokenizer_tail(size
, parsed_
- size
));
60 /// debugging helper for parsed number fields
62 Parser::BinaryTokenizer::got(uint32_t value
, uint64_t size
, const char *description
) const
64 debugs(24, 7, context
<< description
<< '=' << value
<<
65 BinaryTokenizer_tail(size
, parsed_
- size
));
68 /// debugging helper for parsed areas/blobs
70 Parser::BinaryTokenizer::got(const SBuf
&value
, uint64_t size
, const char *description
) const
72 debugs(24, 7, context
<< description
<< '=' <<
73 Raw(nullptr, value
.rawContent(), value
.length()).hex() <<
74 BinaryTokenizer_tail(size
, parsed_
- size
));
78 /// debugging helper for skipped fields
80 Parser::BinaryTokenizer::skipped(uint64_t size
, const char *description
) const
82 debugs(24, 7, context
<< description
<< BinaryTokenizer_tail(size
, parsed_
- size
));
86 /// Returns the next ready-for-shift byte, adjusting the number of parsed bytes.
87 /// The larger 32-bit return type helps callers shift/merge octets into numbers.
88 /// This internal method does not perform out-of-bounds checks.
90 Parser::BinaryTokenizer::octet()
92 // While char may be signed, we view data characters as unsigned,
93 // which helps to arrive at the right 32-bit return value.
94 return static_cast<uint8_t>(data_
[parsed_
++]);
98 Parser::BinaryTokenizer::reset(const SBuf
&data
, const bool expectMore
)
100 *this = BinaryTokenizer(data
, expectMore
);
104 Parser::BinaryTokenizer::rollback()
106 parsed_
= syncPoint_
;
110 Parser::BinaryTokenizer::commit()
112 syncPoint_
= parsed_
;
116 Parser::BinaryTokenizer::atEnd() const
118 return parsed_
>= data_
.length();
122 Parser::BinaryTokenizer::uint8(const char *description
)
124 want(1, description
);
125 const uint8_t result
= octet();
126 got(result
, 1, description
);
131 Parser::BinaryTokenizer::uint16(const char *description
)
133 want(2, description
);
134 const uint16_t result
= (octet() << 8) | octet();
135 got(result
, 2, description
);
140 Parser::BinaryTokenizer::uint24(const char *description
)
142 want(3, description
);
143 const uint32_t result
= (octet() << 16) | (octet() << 8) | octet();
144 got(result
, 3, description
);
149 Parser::BinaryTokenizer::uint32(const char *description
)
151 want(4, description
);
152 const uint32_t result
= (octet() << 24) | (octet() << 16) | (octet() << 8) | octet();
153 got(result
, 4, description
);
158 Parser::BinaryTokenizer::area(uint64_t size
, const char *description
)
160 want(size
, description
);
161 const SBuf result
= data_
.substr(parsed_
, size
);
163 got(result
, size
, description
);
168 Parser::BinaryTokenizer::skip(uint64_t size
, const char *description
)
170 want(size
, description
);
172 skipped(size
, description
);
176 * BinaryTokenizer::pstringN() implementations below reduce debugging noise by
177 * not parsing empty areas and not summarizing parsing context.success().
181 Parser::BinaryTokenizer::pstring8(const char *description
)
183 BinaryTokenizerContext
pstring(*this, description
);
184 if (const uint8_t length
= uint8(".length"))
185 return area(length
, ".octets");
190 Parser::BinaryTokenizer::pstring16(const char *description
)
192 BinaryTokenizerContext
pstring(*this, description
);
193 if (const uint16_t length
= uint16(".length"))
194 return area(length
, ".octets");
199 Parser::BinaryTokenizer::pstring24(const char *description
)
201 BinaryTokenizerContext
pstring(*this, description
);
202 if (const uint32_t length
= uint24(".length"))
203 return area(length
, ".octets");