Merge pull request #108 from Herringway/slicebuilder-fixes
make SliceBuilder safer to use. merged-on-behalf-of: BBasile <BBasile@users.noreply.github.com>
This commit is contained in:
commit
45cabaa1da
|
@ -531,15 +531,17 @@ public:
|
||||||
/// end of the slice being built, the slice is extended (trivial operation).
|
/// end of the slice being built, the slice is extended (trivial operation).
|
||||||
///
|
///
|
||||||
/// See_Also: begin
|
/// See_Also: begin
|
||||||
void write(char[] str) @trusted pure nothrow @nogc
|
void write(char[] str) @safe pure nothrow @nogc
|
||||||
{
|
{
|
||||||
assert(inProgress, "write called without begin");
|
assert(inProgress, "write called without begin");
|
||||||
assert(end_ <= reader_.bufferOffset_,
|
assert(end_ <= reader_.bufferOffset_,
|
||||||
"AT START: Slice ends after buffer position");
|
"AT START: Slice ends after buffer position");
|
||||||
|
|
||||||
|
// Nothing? Already done.
|
||||||
|
if (str.length == 0) { return; }
|
||||||
// If str starts at the end of the slice (is a string returned by a Reader
|
// If str starts at the end of the slice (is a string returned by a Reader
|
||||||
// method), just extend the slice to contain str.
|
// method), just extend the slice to contain str.
|
||||||
if(str.ptr == reader_.buffer_.ptr + end_)
|
if(&str[0] == &reader_.buffer_[end_])
|
||||||
{
|
{
|
||||||
end_ += str.length;
|
end_ += str.length;
|
||||||
}
|
}
|
||||||
|
@ -547,8 +549,7 @@ public:
|
||||||
// by a Reader method and point to buffer. So we need to memmove.
|
// by a Reader method and point to buffer. So we need to memmove.
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
core.stdc.string.memmove(reader_.buffer_.ptr + end_, cast(char*)str.ptr,
|
copy(str, reader_.buffer_[end_..end_ + str.length * char.sizeof]);
|
||||||
str.length * char.sizeof);
|
|
||||||
end_ += str.length;
|
end_ += str.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -585,7 +586,7 @@ public:
|
||||||
/// position = Position to insert the character at in code units, not code points.
|
/// position = Position to insert the character at in code units, not code points.
|
||||||
/// Must be less than slice length(); a previously returned length()
|
/// Must be less than slice length(); a previously returned length()
|
||||||
/// can be used.
|
/// can be used.
|
||||||
void insert(const dchar c, const size_t position) @system pure nothrow @nogc
|
void insert(const dchar c, const size_t position) @safe pure nothrow @nogc
|
||||||
{
|
{
|
||||||
assert(inProgress, "insert called without begin");
|
assert(inProgress, "insert called without begin");
|
||||||
assert(start_ + position <= end_, "Trying to insert after the end of the slice");
|
assert(start_ + position <= end_, "Trying to insert after the end of the slice");
|
||||||
|
@ -600,9 +601,8 @@ public:
|
||||||
|
|
||||||
if(movedLength > 0)
|
if(movedLength > 0)
|
||||||
{
|
{
|
||||||
core.stdc.string.memmove(reader_.buffer_.ptr + point + bytes,
|
copy(reader_.buffer_[point..point + movedLength * char.sizeof],
|
||||||
reader_.buffer_.ptr + point,
|
reader_.buffer_[point + bytes..point + bytes + movedLength * char.sizeof]);
|
||||||
movedLength * char.sizeof);
|
|
||||||
}
|
}
|
||||||
reader_.buffer_[point .. point + bytes] = encodeBuf[0 .. bytes];
|
reader_.buffer_[point .. point + bytes] = encodeBuf[0 .. bytes];
|
||||||
end_ += bytes;
|
end_ += bytes;
|
||||||
|
@ -635,9 +635,9 @@ public:
|
||||||
/// ended either by commit()-ing or reverting through the destructor.
|
/// ended either by commit()-ing or reverting through the destructor.
|
||||||
///
|
///
|
||||||
/// Saves the current state of a slice.
|
/// Saves the current state of a slice.
|
||||||
this(ref SliceBuilder builder) @system pure nothrow @nogc
|
this(SliceBuilder* builder) @safe pure nothrow @nogc
|
||||||
{
|
{
|
||||||
builder_ = &builder;
|
builder_ = builder;
|
||||||
stackLevel_ = builder_.endStackUsed_;
|
stackLevel_ = builder_.endStackUsed_;
|
||||||
builder_.push();
|
builder_.push();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1210,7 +1210,7 @@ final class Scanner
|
||||||
/// Scan a block scalar token with specified style.
|
/// Scan a block scalar token with specified style.
|
||||||
///
|
///
|
||||||
/// In case of an error, error_ is set. Use throwIfError() to handle this.
|
/// In case of an error, error_ is set. Use throwIfError() to handle this.
|
||||||
Token scanBlockScalar(const ScalarStyle style) @trusted
|
Token scanBlockScalar(const ScalarStyle style) @safe
|
||||||
{
|
{
|
||||||
const startMark = reader_.mark;
|
const startMark = reader_.mark;
|
||||||
|
|
||||||
|
@ -1233,7 +1233,7 @@ final class Scanner
|
||||||
alias Transaction = SliceBuilder.Transaction;
|
alias Transaction = SliceBuilder.Transaction;
|
||||||
// Used to strip the last line breaks written to the slice at the end of the
|
// Used to strip the last line breaks written to the slice at the end of the
|
||||||
// scalar, which may be needed based on chomping.
|
// scalar, which may be needed based on chomping.
|
||||||
Transaction breaksTransaction = Transaction(reader_.sliceBuilder);
|
Transaction breaksTransaction = Transaction(&reader_.sliceBuilder);
|
||||||
// Read the first indentation/line breaks before the scalar.
|
// Read the first indentation/line breaks before the scalar.
|
||||||
size_t startLen = reader_.sliceBuilder.length;
|
size_t startLen = reader_.sliceBuilder.length;
|
||||||
if(increment == int.min)
|
if(increment == int.min)
|
||||||
|
@ -1263,7 +1263,7 @@ final class Scanner
|
||||||
|
|
||||||
// This transaction serves to rollback data read in the
|
// This transaction serves to rollback data read in the
|
||||||
// scanBlockScalarBreaksToSlice() call.
|
// scanBlockScalarBreaksToSlice() call.
|
||||||
breaksTransaction = Transaction(reader_.sliceBuilder);
|
breaksTransaction = Transaction(&reader_.sliceBuilder);
|
||||||
startLen = reader_.sliceBuilder.length;
|
startLen = reader_.sliceBuilder.length;
|
||||||
// The line breaks should actually be written _after_ the if() block
|
// The line breaks should actually be written _after_ the if() block
|
||||||
// below. We work around that by inserting
|
// below. We work around that by inserting
|
||||||
|
@ -1712,7 +1712,7 @@ final class Scanner
|
||||||
/// Scan plain scalar token (no block, no quotes).
|
/// Scan plain scalar token (no block, no quotes).
|
||||||
///
|
///
|
||||||
/// In case of an error, error_ is set. Use throwIfError() to handle this.
|
/// In case of an error, error_ is set. Use throwIfError() to handle this.
|
||||||
Token scanPlain() @trusted
|
Token scanPlain() @safe
|
||||||
{
|
{
|
||||||
// We keep track of the allowSimpleKey_ flag here.
|
// We keep track of the allowSimpleKey_ flag here.
|
||||||
// Indentation rules are loosed for the flow context
|
// Indentation rules are loosed for the flow context
|
||||||
|
@ -1788,7 +1788,7 @@ final class Scanner
|
||||||
endMark = reader_.mark;
|
endMark = reader_.mark;
|
||||||
|
|
||||||
spacesTransaction.commit();
|
spacesTransaction.commit();
|
||||||
spacesTransaction = Transaction(reader_.sliceBuilder);
|
spacesTransaction = Transaction(&reader_.sliceBuilder);
|
||||||
|
|
||||||
const startLength = reader_.sliceBuilder.length;
|
const startLength = reader_.sliceBuilder.length;
|
||||||
scanPlainSpacesToSlice(startMark);
|
scanPlainSpacesToSlice(startMark);
|
||||||
|
@ -1809,7 +1809,7 @@ final class Scanner
|
||||||
///
|
///
|
||||||
/// Assumes that the caller is building a slice in Reader, and puts the spaces
|
/// Assumes that the caller is building a slice in Reader, and puts the spaces
|
||||||
/// into that slice.
|
/// into that slice.
|
||||||
void scanPlainSpacesToSlice(const Mark startMark) @system
|
void scanPlainSpacesToSlice(const Mark startMark) @safe
|
||||||
{
|
{
|
||||||
// The specification is really confusing about tabs in plain scalars.
|
// The specification is really confusing about tabs in plain scalars.
|
||||||
// We just forbid them completely. Do not use tabs in YAML!
|
// We just forbid them completely. Do not use tabs in YAML!
|
||||||
|
@ -1847,7 +1847,7 @@ final class Scanner
|
||||||
bool extraBreaks = false;
|
bool extraBreaks = false;
|
||||||
|
|
||||||
alias Transaction = SliceBuilder.Transaction;
|
alias Transaction = SliceBuilder.Transaction;
|
||||||
auto transaction = Transaction(reader_.sliceBuilder);
|
auto transaction = Transaction(&reader_.sliceBuilder);
|
||||||
if(lineBreak != '\n') { reader_.sliceBuilder.write(lineBreak); }
|
if(lineBreak != '\n') { reader_.sliceBuilder.write(lineBreak); }
|
||||||
while(search.canFind(reader_.peek()))
|
while(search.canFind(reader_.peek()))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue