mirror of
https://github.com/matrix-construct/construct
synced 2024-11-16 06:51:08 +01:00
ircd::spirit: Fix signedness and displacements in generator state; add assertions.
This commit is contained in:
parent
bf91bf9bcd
commit
6eb54341ef
1 changed files with 19 additions and 12 deletions
|
@ -250,16 +250,16 @@ struct ircd::spirit::generator_state
|
||||||
mutable_buffer &out;
|
mutable_buffer &out;
|
||||||
|
|
||||||
/// Current consumption count of the destination buffer.
|
/// Current consumption count of the destination buffer.
|
||||||
size_t consumed {0};
|
ssize_t consumed {0};
|
||||||
|
|
||||||
/// The number of attemtped generated characters to the destination. This
|
/// The number of attemtped generated characters to the destination. This
|
||||||
/// can be larger than the consumed counter to indicate the destination
|
/// can be larger than the consumed counter to indicate the destination
|
||||||
/// buffer is insufficient. Note that characters are otherwise quietly
|
/// buffer is insufficient. Note that characters are otherwise quietly
|
||||||
/// discarded when the destination (out) is full.
|
/// discarded when the destination (out) is full.
|
||||||
size_t generated {0};
|
ssize_t generated {0};
|
||||||
|
|
||||||
/// Internal state for buffer_sink::copy()
|
/// Internal state for buffer_sink::copy()
|
||||||
size_t last_generated {0}, last_width {0};
|
ssize_t last_generated {0}, last_width {0};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class gen,
|
template<class gen,
|
||||||
|
@ -298,7 +298,7 @@ ircd::generate(mutable_buffer &out,
|
||||||
karma::generate(sink, std::forward<gen>(g), std::forward<attr>(a)...)
|
karma::generate(sink, std::forward<gen>(g), std::forward<attr>(a)...)
|
||||||
};
|
};
|
||||||
|
|
||||||
if(unlikely(state.generated > max))
|
if(unlikely(size_t(state.generated) > max))
|
||||||
{
|
{
|
||||||
char pbuf[2][48];
|
char pbuf[2][48];
|
||||||
throw spirit::buffer_overrun
|
throw spirit::buffer_overrun
|
||||||
|
@ -416,31 +416,38 @@ const
|
||||||
*ircd::spirit::generator_state
|
*ircd::spirit::generator_state
|
||||||
};
|
};
|
||||||
|
|
||||||
|
assert(state.last_generated >= 0);
|
||||||
|
assert(state.generated >= state.last_generated);
|
||||||
const auto &width_diff
|
const auto &width_diff
|
||||||
{
|
{
|
||||||
this->width - state.last_width
|
state.last_generated == state.generated?
|
||||||
|
ssize_t(this->width) - state.last_width:
|
||||||
|
ssize_t(this->width)
|
||||||
};
|
};
|
||||||
|
|
||||||
state.consumed +=
|
assert(width_diff >= -state.consumed);
|
||||||
state.last_generated == state.generated?
|
assert(state.generated >= state.consumed);
|
||||||
width_diff:
|
state.consumed += width_diff;
|
||||||
this->width;
|
|
||||||
|
|
||||||
|
assert(state.consumed >= 0);
|
||||||
const auto &rewind_count
|
const auto &rewind_count
|
||||||
{
|
{
|
||||||
std::min(state.generated - state.consumed, state.consumed)
|
state.generated - state.consumed
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto &rewind
|
const auto &rewind
|
||||||
{
|
{
|
||||||
state.generated > state.consumed?
|
rewind_count >= 0L?
|
||||||
rewind_count:
|
std::min(rewind_count, state.generated):
|
||||||
0L
|
0L
|
||||||
};
|
};
|
||||||
|
|
||||||
|
assert(rewind >= 0L);
|
||||||
|
assert(rewind <= state.generated);
|
||||||
std::get<0>(state.out) -= rewind;
|
std::get<0>(state.out) -= rewind;
|
||||||
state.generated -= rewind;
|
state.generated -= rewind;
|
||||||
|
|
||||||
|
assert(state.generated >= 0);
|
||||||
state.last_generated = state.generated;
|
state.last_generated = state.generated;
|
||||||
state.last_width = this->width;
|
state.last_width = this->width;
|
||||||
return true; //sink.good();
|
return true; //sink.good();
|
||||||
|
|
Loading…
Reference in a new issue