A risky Reader change to avoid allocations/exceptions.

This commit is contained in:
Ferdinand Majerech 2014-07-23 00:42:49 +02:00
parent 3ce23f2892
commit 949a396248

View file

@ -128,13 +128,17 @@ final class Reader
/// ///
/// Returns: Character at specified position. /// Returns: Character at specified position.
/// ///
/// Throws: ReaderException if trying to read past the end of the buffer // XXX removed; search for 'risky' to find why.
/// or if invalid data is read. // Throws: ReaderException if trying to read past the end of the buffer.
dchar peek(size_t index = 0) @safe pure const dchar peek(size_t index = 0) @safe pure const
{ {
if(buffer_.length <= bufferOffset_ + index) if(buffer_.length <= bufferOffset_ + index)
{ {
throw new ReaderException("Trying to read past the end of the buffer"); // XXX This is risky; revert this and the 'risky' change in UTF decoder
// if any bugs are introduced. We rely on the assumption that Reader
// only uses peek() to detect the of buffer. The test suite passes.
// throw new ReaderException("Trying to read past the end of the buffer");
return '\0';
} }
return buffer_[bufferOffset_ + index]; return buffer_[bufferOffset_ + index];
@ -317,11 +321,15 @@ struct UTFDecoder
decoded_ = cast(dchar[])input_; decoded_ = cast(dchar[])input_;
break; break;
} }
// XXX This is risky. We rely on the assumption that the scanner only uses
// peek() to detect the end of the buffer. Should this cause any bugs,
// revert.
//
// The buffer must be zero terminated for scanner to detect its end. // The buffer must be zero terminated for scanner to detect its end.
if(decoded_.empty || decoded_.back() != '\0') // if(decoded_.empty || decoded_.back() != '\0')
{ // {
decoded_ ~= cast(dchar)'\0'; // decoded_ ~= cast(dchar)'\0';
} // }
} }
/// Get encoding we're decoding from. /// Get encoding we're decoding from.
@ -464,10 +472,10 @@ void testPeekPrefixForward(R)()
assert(reader.peek(3) == 'a'); assert(reader.peek(3) == 'a');
assert(reader.peek(4) == '\0'); assert(reader.peek(4) == '\0');
assert(reader.prefix(4) == "data"); assert(reader.prefix(4) == "data");
assert(reader.prefix(6) == "data\0"); // assert(reader.prefix(6) == "data\0");
reader.forward(2); reader.forward(2);
assert(reader.peek(1) == 'a'); assert(reader.peek(1) == 'a');
assert(collectException(reader.peek(3))); // assert(collectException(reader.peek(3)));
} }
void testUTF(R)() void testUTF(R)()
@ -497,7 +505,7 @@ void test1Byte(R)()
auto reader = new R(new MemoryStream(data)); auto reader = new R(new MemoryStream(data));
assert(reader.peek() == 'a'); assert(reader.peek() == 'a');
assert(reader.peek(1) == '\0'); assert(reader.peek(1) == '\0');
assert(collectException(reader.peek(2))); // assert(collectException(reader.peek(2)));
} }
unittest unittest