diff options
author | Haavard <havardpe@yahoo-inc.com> | 2017-02-03 17:21:55 +0000 |
---|---|---|
committer | Haavard <havardpe@yahoo-inc.com> | 2017-02-03 18:16:47 +0000 |
commit | 777726e51445f567809c1379d53e7da2bb6fa6db (patch) | |
tree | cff9852b3075a16a1b7c77cde796ae154eced8b9 | |
parent | 57c297bcc6d3b8ef70ef71d7664c6ad51d104e73 (diff) |
let obtain set eof flag and read set failed state
-rw-r--r-- | vespalib/src/tests/data/input_reader/input_reader_test.cpp | 28 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/data/input_reader.cpp | 25 | ||||
-rw-r--r-- | vespalib/src/vespa/vespalib/data/input_reader.h | 11 |
3 files changed, 52 insertions, 12 deletions
diff --git a/vespalib/src/tests/data/input_reader/input_reader_test.cpp b/vespalib/src/tests/data/input_reader/input_reader_test.cpp index 345baf12293..31b440f9800 100644 --- a/vespalib/src/tests/data/input_reader/input_reader_test.cpp +++ b/vespalib/src/tests/data/input_reader/input_reader_test.cpp @@ -48,8 +48,9 @@ TEST("input reader smoke test") { EXPECT_TRUE(!src.failed()); EXPECT_EQUAL(src.get_offset(), strlen(data)); EXPECT_EQUAL(src.obtain(), 0u); - EXPECT_TRUE(src.failed()); + EXPECT_TRUE(!src.failed()); EXPECT_EQUAL(src.read(5), Memory()); + EXPECT_TRUE(src.failed()); EXPECT_EQUAL(src.read(), '\0'); EXPECT_EQUAL(src.obtain(), 0u); EXPECT_EQUAL(src.get_offset(), strlen(data)); @@ -100,4 +101,29 @@ TEST("require that reading a byte sequence crossing the end of input fails") { } } +TEST("expect that obtain sets eof but not failure state on input reader") { + const char *data = "12345"; + for (bool byte_first: {true, false}) { + MemoryInput input(data); + InputReader src(input); + EXPECT_EQUAL(src.obtain(), 5); + EXPECT_EQUAL(src.read(5), Memory("12345")); + EXPECT_TRUE(!src.failed()); + EXPECT_TRUE(!src.eof()); + EXPECT_EQUAL(src.obtain(), 0); + EXPECT_TRUE(src.eof()); + EXPECT_TRUE(!src.failed()); + if (byte_first) { + EXPECT_EQUAL(src.read(), 0); + EXPECT_EQUAL(src.read(5), Memory()); + } else { + EXPECT_EQUAL(src.read(5), Memory()); + EXPECT_EQUAL(src.read(), 0); + } + EXPECT_TRUE(src.failed()); + EXPECT_EQUAL(src.get_error_message(), vespalib::string("input underflow")); + EXPECT_EQUAL(src.obtain(), 0); + } +} + TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/vespalib/src/vespa/vespalib/data/input_reader.cpp b/vespalib/src/vespa/vespalib/data/input_reader.cpp index 031cb9b1624..b71935c795b 100644 --- a/vespalib/src/vespa/vespalib/data/input_reader.cpp +++ b/vespalib/src/vespa/vespalib/data/input_reader.cpp @@ -9,17 +9,24 @@ namespace vespalib { size_t InputReader::obtain_slow() { - if (!failed()) { - _data = _input.evict(_pos).obtain(); - _bytes_evicted += _pos; - _pos = 0; - if (_data.size == 0) { - fail("input underflow"); - } + _data = _input.evict(_pos).obtain(); + _bytes_evicted += _pos; + _pos = 0; + if (_data.size == 0) { + _eof = true; } return size(); } +char +InputReader::read_slow() +{ + if (!failed()) { + fail("input underflow"); + } + return 0; +} + Memory InputReader::read_slow(size_t bytes) { @@ -32,6 +39,9 @@ InputReader::read_slow(size_t bytes) if (_space.size() == bytes) { return Memory(&_space[0], _space.size()); } + if (!failed()) { + fail("input underflow"); + } return Memory(); } @@ -48,6 +58,7 @@ InputReader::fail(const vespalib::string &msg) { _data = Memory(); _bytes_evicted += _pos; _pos = 0; + _eof = true; } } diff --git a/vespalib/src/vespa/vespalib/data/input_reader.h b/vespalib/src/vespa/vespalib/data/input_reader.h index 3d01eaffca0..38824f29139 100644 --- a/vespalib/src/vespa/vespalib/data/input_reader.h +++ b/vespalib/src/vespa/vespalib/data/input_reader.h @@ -23,6 +23,7 @@ private: Memory _data; size_t _pos; size_t _bytes_evicted; + bool _eof; vespalib::string _error; std::vector<char> _space; @@ -30,13 +31,15 @@ private: size_t size() const { return (_data.size - _pos); } size_t obtain_slow(); + char read_slow(); Memory read_slow(size_t bytes); public: explicit InputReader(Input &input) - : _input(input), _data(), _pos(0), _bytes_evicted(0), _error(), _space() {} + : _input(input), _data(), _pos(0), _bytes_evicted(0), _eof(false), _error(), _space() {} ~InputReader(); + bool eof() const { return _eof; } bool failed() const { return !_error.empty(); } const vespalib::string &get_error_message() const { return _error; } size_t get_offset() const { return (_bytes_evicted + _pos); } @@ -47,11 +50,11 @@ public: * Make sure we have more input data available. * * @return number of bytes available without requesting more from - * the underlying Input. Returns 0 if and only is there is + * the underlying Input. Returns 0 if and only if there is * no more input data available. **/ size_t obtain() { - if (__builtin_expect(_pos < _data.size, true)) { + if (__builtin_expect((_pos < _data.size) || _eof, true)) { return size(); } return obtain_slow(); @@ -68,7 +71,7 @@ public: if (__builtin_expect(obtain() > 0, true)) { return _data.data[_pos++]; } - return 0; + return read_slow(); } /** |