summaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorHaavard <havardpe@yahoo-inc.com>2017-02-03 17:21:55 +0000
committerHaavard <havardpe@yahoo-inc.com>2017-02-03 18:16:47 +0000
commit777726e51445f567809c1379d53e7da2bb6fa6db (patch)
treecff9852b3075a16a1b7c77cde796ae154eced8b9 /vespalib
parent57c297bcc6d3b8ef70ef71d7664c6ad51d104e73 (diff)
let obtain set eof flag and read set failed state
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/tests/data/input_reader/input_reader_test.cpp28
-rw-r--r--vespalib/src/vespa/vespalib/data/input_reader.cpp25
-rw-r--r--vespalib/src/vespa/vespalib/data/input_reader.h11
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();
}
/**