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;
|
2023-02-22 01:34:03 +00:00
|
|
|
extern const int CANNOT_READ_ALL_DATA;
|
2018-08-20 02:23:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-08-14 04:42:04 +00:00
|
|
|
bool LimitReadBuffer::nextImpl()
|
|
|
|
{
|
2024-03-03 13:22:40 +00:00
|
|
|
chassert(position() >= in->position());
|
2021-02-04 14:46:46 +00:00
|
|
|
|
2017-08-14 04:42:04 +00:00
|
|
|
/// Let underlying buffer calculate read bytes in `next()` call.
|
2021-02-19 12:51:26 +00:00
|
|
|
in->position() = position();
|
2017-08-14 04:42:04 +00:00
|
|
|
|
2018-08-20 02:23:35 +00:00
|
|
|
if (bytes >= limit)
|
|
|
|
{
|
2023-02-22 16:54:35 +00:00
|
|
|
if (exact_limit && bytes == *exact_limit)
|
2023-02-22 01:34:03 +00:00
|
|
|
return false;
|
|
|
|
|
2023-02-22 16:54:35 +00:00
|
|
|
if (exact_limit && bytes != *exact_limit)
|
|
|
|
throw Exception(ErrorCodes::CANNOT_READ_ALL_DATA, "Unexpected data, got {} bytes, expected {}", bytes, *exact_limit);
|
2023-02-22 01:34:03 +00:00
|
|
|
|
2018-08-20 02:23:35 +00:00
|
|
|
if (throw_exception)
|
2023-01-23 21:13:58 +00:00
|
|
|
throw Exception(ErrorCodes::LIMIT_EXCEEDED, "Limit for LimitReadBuffer exceeded: {}", exception_message);
|
2023-02-22 01:34:03 +00:00
|
|
|
|
|
|
|
return false;
|
2018-08-20 02:23:35 +00:00
|
|
|
}
|
|
|
|
|
2021-02-19 12:51:26 +00:00
|
|
|
if (!in->next())
|
2021-02-04 14:46:46 +00:00
|
|
|
{
|
2023-02-22 16:54:35 +00:00
|
|
|
if (exact_limit && bytes != *exact_limit)
|
|
|
|
throw Exception(ErrorCodes::CANNOT_READ_ALL_DATA, "Unexpected EOF, got {} of {} bytes", bytes, *exact_limit);
|
2021-12-19 20:37:12 +00:00
|
|
|
/// Clearing the buffer with existing data.
|
2024-03-03 13:22:40 +00:00
|
|
|
BufferBase::set(in->position(), 0, 0);
|
|
|
|
|
2017-08-14 04:42:04 +00:00
|
|
|
return false;
|
2021-02-04 14:46:46 +00:00
|
|
|
}
|
2017-08-14 04:42:04 +00:00
|
|
|
|
2024-03-03 13:22:40 +00:00
|
|
|
BufferBase::set(in->position(), std::min(in->available(), limit - bytes), 0);
|
2017-08-14 04:42:04 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-03-03 13:22:40 +00:00
|
|
|
LimitReadBuffer::LimitReadBuffer(ReadBuffer * in_, bool owns, size_t limit_, bool throw_exception_,
|
2023-02-22 16:54:35 +00:00
|
|
|
std::optional<size_t> exact_limit_, std::string exception_message_)
|
2021-02-19 12:51:26 +00:00
|
|
|
: ReadBuffer(in_ ? in_->position() : nullptr, 0)
|
|
|
|
, in(in_)
|
|
|
|
, owns_in(owns)
|
|
|
|
, limit(limit_)
|
|
|
|
, throw_exception(throw_exception_)
|
2023-02-22 01:34:03 +00:00
|
|
|
, exact_limit(exact_limit_)
|
2021-02-19 12:51:26 +00:00
|
|
|
, exception_message(std::move(exception_message_))
|
2017-08-15 20:14:15 +00:00
|
|
|
{
|
2024-03-03 13:22:40 +00:00
|
|
|
chassert(in);
|
2017-08-15 20:14:15 +00:00
|
|
|
|
2024-03-03 13:22:40 +00:00
|
|
|
BufferBase::set(in->position(), std::min(in->available(), limit), 0);
|
2021-02-19 12:51:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-03-03 13:22:40 +00:00
|
|
|
LimitReadBuffer::LimitReadBuffer(ReadBuffer & in_, size_t limit_, bool throw_exception_,
|
2023-02-22 16:54:35 +00:00
|
|
|
std::optional<size_t> exact_limit_, std::string exception_message_)
|
2023-02-22 01:34:03 +00:00
|
|
|
: LimitReadBuffer(&in_, false, limit_, throw_exception_, exact_limit_, exception_message_)
|
2021-02-19 12:51:26 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-03-03 13:22:40 +00:00
|
|
|
LimitReadBuffer::LimitReadBuffer(std::unique_ptr<ReadBuffer> in_, size_t limit_, bool throw_exception_,
|
2023-02-22 16:54:35 +00:00
|
|
|
std::optional<size_t> exact_limit_, std::string exception_message_)
|
2023-02-22 01:34:03 +00:00
|
|
|
: LimitReadBuffer(in_.release(), true, limit_, throw_exception_, exact_limit_, exception_message_)
|
2021-02-19 12:51:26 +00:00
|
|
|
{
|
2017-08-15 20:14:15 +00:00
|
|
|
}
|
2017-08-14 04:42:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
LimitReadBuffer::~LimitReadBuffer()
|
|
|
|
{
|
|
|
|
/// Update underlying buffer's position in case when limit wasn't reached.
|
2021-02-04 23:14:17 +00:00
|
|
|
if (!working_buffer.empty())
|
2021-02-19 12:51:26 +00:00
|
|
|
in->position() = position();
|
|
|
|
|
|
|
|
if (owns_in)
|
|
|
|
delete in;
|
2017-08-14 04:42:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|