2017-08-14 04:42:04 +00:00
|
|
|
#include <IO/LimitReadBuffer.h>
|
2018-08-20 02:23:35 +00:00
|
|
|
#include <Common/Exception.h>
|
2017-08-14 04:42:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2018-08-20 02:23:35 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int LIMIT_EXCEEDED;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-08-14 04:42:04 +00:00
|
|
|
bool LimitReadBuffer::nextImpl()
|
|
|
|
{
|
|
|
|
/// Let underlying buffer calculate read bytes in `next()` call.
|
|
|
|
in.position() = position();
|
|
|
|
|
2018-08-20 02:23:35 +00:00
|
|
|
if (bytes >= limit)
|
|
|
|
{
|
|
|
|
if (throw_exception)
|
|
|
|
throw Exception("Limit for LimitReadBuffer exceeded: " + exception_message, ErrorCodes::LIMIT_EXCEEDED);
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!in.next())
|
2017-08-14 04:42:04 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
working_buffer = in.buffer();
|
|
|
|
|
|
|
|
if (limit - bytes < working_buffer.size())
|
|
|
|
working_buffer.resize(limit - bytes);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-02-10 15:17:45 +00:00
|
|
|
LimitReadBuffer::LimitReadBuffer(ReadBuffer & in, UInt64 limit, bool throw_exception, std::string exception_message)
|
2018-08-20 02:23:35 +00:00
|
|
|
: ReadBuffer(in.position(), 0), in(in), limit(limit), throw_exception(throw_exception), exception_message(std::move(exception_message))
|
2017-08-15 20:14:15 +00:00
|
|
|
{
|
|
|
|
size_t remaining_bytes_in_buffer = in.buffer().end() - in.position();
|
|
|
|
if (remaining_bytes_in_buffer > limit)
|
|
|
|
remaining_bytes_in_buffer = limit;
|
|
|
|
|
|
|
|
working_buffer = Buffer(in.position(), in.position() + remaining_bytes_in_buffer);
|
|
|
|
}
|
2017-08-14 04:42:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
LimitReadBuffer::~LimitReadBuffer()
|
|
|
|
{
|
|
|
|
/// Update underlying buffer's position in case when limit wasn't reached.
|
|
|
|
if (working_buffer.size() != 0)
|
|
|
|
in.position() = position();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|