1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- #pragma once
- #include "cescape.h"
- #include "fail.h"
- #include "stream_counter.h"
- #include <library/cpp/yson_pull/input.h>
- namespace NYsonPull {
- namespace NDetail {
- template <class StreamCounter>
- class byte_reader {
- NYsonPull::NInput::IStream& stream_;
- StreamCounter stream_counter_;
- public:
- byte_reader(NYsonPull::NInput::IStream& stream)
- : stream_(stream)
- {
- }
- // const-ness added to prevent direct stream mutation
- const NYsonPull::NInput::IStream& stream() {
- return stream_;
- }
- template <typename... Args>
- ATTRIBUTE(noinline, cold)
- void fail[[noreturn]](const char* msg, Args&&... args) {
- NYsonPull::NDetail::fail(
- stream_counter_.info(),
- msg,
- std::forward<Args>(args)...);
- }
- template <bool AllowFinish>
- void fill_buffer() {
- stream_.fill_buffer();
- if (!AllowFinish) {
- auto& buf = stream_.buffer();
- if (Y_UNLIKELY(buf.is_empty() && stream_.at_end())) {
- fail("Premature end of stream");
- }
- }
- }
- void fill_buffer() {
- return fill_buffer<true>();
- }
- template <bool AllowFinish>
- ui8 get_byte() {
- fill_buffer<AllowFinish>();
- auto& buf = stream_.buffer();
- return !buf.is_empty()
- ? *buf.pos()
- : ui8{'\0'};
- }
- ui8 get_byte() {
- return get_byte<true>();
- }
- void advance(size_t bytes) {
- auto& buf = stream_.buffer();
- stream_counter_.update(
- buf.pos(),
- buf.pos() + bytes);
- buf.advance(bytes);
- }
- };
- }
- }
|