dchar[], not dstring in Reader/Scanner. Will be changed back where possible.
This commit is contained in:
parent
7ae6098bd9
commit
02494914e4
|
@ -157,7 +157,7 @@ final class Reader
|
||||||
/// buffer; in that case the returned slice will be shorter.
|
/// buffer; in that case the returned slice will be shorter.
|
||||||
///
|
///
|
||||||
/// Returns: Characters starting at current position or an empty slice if out of bounds.
|
/// Returns: Characters starting at current position or an empty slice if out of bounds.
|
||||||
dstring prefix(size_t length) @safe pure nothrow const @nogc
|
dchar[] prefix(size_t length) @safe pure nothrow @nogc
|
||||||
{
|
{
|
||||||
return slice(0, length);
|
return slice(0, length);
|
||||||
}
|
}
|
||||||
|
@ -173,12 +173,13 @@ final class Reader
|
||||||
/// slice will be shorter.
|
/// slice will be shorter.
|
||||||
///
|
///
|
||||||
/// Returns: Slice into the internal buffer or an empty slice if out of bounds.
|
/// Returns: Slice into the internal buffer or an empty slice if out of bounds.
|
||||||
dstring slice(size_t start, size_t end) @trusted pure nothrow const @nogc
|
dchar[] slice(size_t start, size_t end) @trusted pure nothrow @nogc
|
||||||
{
|
{
|
||||||
start += bufferOffset_;
|
start += bufferOffset_;
|
||||||
end = min(buffer_.length, end + bufferOffset_);
|
end = min(buffer_.length, end + bufferOffset_);
|
||||||
|
assert(end >= start, "Trying to read a slice that starts after its end");
|
||||||
|
|
||||||
return end > start ? cast(dstring)buffer_[start .. end] : "";
|
return buffer_[start .. end];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the next character, moving buffer position beyond it.
|
/// Get the next character, moving buffer position beyond it.
|
||||||
|
@ -199,7 +200,7 @@ final class Reader
|
||||||
/// Params: length = Number or characters to get.
|
/// Params: length = Number or characters to get.
|
||||||
///
|
///
|
||||||
/// Returns: Characters starting at current position.
|
/// Returns: Characters starting at current position.
|
||||||
dstring get(size_t length) @safe pure nothrow @nogc
|
dchar[] get(size_t length) @safe pure nothrow @nogc
|
||||||
{
|
{
|
||||||
auto result = prefix(length);
|
auto result = prefix(length);
|
||||||
forward(length);
|
forward(length);
|
||||||
|
@ -315,14 +316,17 @@ public:
|
||||||
///
|
///
|
||||||
/// Any Transactions on the slice must be committed or destroyed before the slice
|
/// Any Transactions on the slice must be committed or destroyed before the slice
|
||||||
/// is finished.
|
/// is finished.
|
||||||
|
///
|
||||||
|
/// Returns a string; once a slice is finished it is definitive that its contents
|
||||||
|
/// will not be changed.
|
||||||
dstring finish() @system pure nothrow @nogc
|
dstring finish() @system pure nothrow @nogc
|
||||||
{
|
{
|
||||||
assert(inProgress, "sliceFinish called without sliceBegin");
|
assert(inProgress, "sliceFinish called without sliceBegin");
|
||||||
assert(endStackUsed_ == 0, "Finishing a slice with running transactions.");
|
assert(endStackUsed_ == 0, "Finishing a slice with running transactions.");
|
||||||
|
|
||||||
const result = cast(dstring)reader_.buffer_[start_ .. end_];
|
const result = reader_.buffer_[start_ .. end_];
|
||||||
start_ = end_ = size_t.max;
|
start_ = end_ = size_t.max;
|
||||||
return result;
|
return cast(dstring)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write a string to the slice being built.
|
/// Write a string to the slice being built.
|
||||||
|
@ -333,7 +337,7 @@ 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(dstring str) @system pure nothrow @nogc
|
void write(dchar[] str) @system pure nothrow @nogc
|
||||||
{
|
{
|
||||||
assert(inProgress, "sliceWrite called without sliceBegin");
|
assert(inProgress, "sliceWrite called without sliceBegin");
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import std.ascii : isAlphaNum, isDigit, isHexDigit;
|
||||||
import std.exception;
|
import std.exception;
|
||||||
import std.string;
|
import std.string;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
|
import std.traits : Unqual;
|
||||||
import std.utf;
|
import std.utf;
|
||||||
|
|
||||||
import dyaml.fastcharsearch;
|
import dyaml.fastcharsearch;
|
||||||
|
@ -800,7 +801,7 @@ final class Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scan a string of alphanumeric or "-_" characters.
|
/// Scan a string of alphanumeric or "-_" characters.
|
||||||
dstring scanAlphaNumeric(string name)(const Mark startMark) @safe pure
|
dchar[] scanAlphaNumeric(string name)(const Mark startMark) @safe pure
|
||||||
{
|
{
|
||||||
uint length = 0;
|
uint length = 0;
|
||||||
dchar c = reader_.peek();
|
dchar c = reader_.peek();
|
||||||
|
@ -819,7 +820,7 @@ final class Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scan all characters until next line break.
|
/// Scan all characters until next line break.
|
||||||
dstring scanToNextBreak() @safe pure nothrow @nogc
|
dchar[] scanToNextBreak() @safe pure nothrow @nogc
|
||||||
{
|
{
|
||||||
uint length = 0;
|
uint length = 0;
|
||||||
while(!"\0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek(length)))
|
while(!"\0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek(length)))
|
||||||
|
@ -873,9 +874,9 @@ final class Scanner
|
||||||
//Skip the '%'.
|
//Skip the '%'.
|
||||||
reader_.forward();
|
reader_.forward();
|
||||||
|
|
||||||
const name = scanDirectiveName(startMark);
|
auto name = scanDirectiveName(startMark);
|
||||||
const value = name == "YAML" ? scanYAMLDirectiveValue(startMark):
|
auto value = name == "YAML" ? scanYAMLDirectiveValue(startMark):
|
||||||
name == "TAG" ? scanTagDirectiveValue(startMark) : "";
|
name == "TAG" ? scanTagDirectiveValue(startMark) : "";
|
||||||
|
|
||||||
Mark endMark = reader_.mark;
|
Mark endMark = reader_.mark;
|
||||||
|
|
||||||
|
@ -887,10 +888,10 @@ final class Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
///Scan name of a directive token.
|
///Scan name of a directive token.
|
||||||
dstring scanDirectiveName(const Mark startMark) @trusted
|
dchar[] scanDirectiveName(const Mark startMark) @trusted
|
||||||
{
|
{
|
||||||
//Scan directive name.
|
//Scan directive name.
|
||||||
const name = scanAlphaNumeric!"a directive"(startMark);
|
auto name = scanAlphaNumeric!"a directive"(startMark);
|
||||||
|
|
||||||
enforce(" \0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek()),
|
enforce(" \0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek()),
|
||||||
new Error("While scanning a directive", startMark,
|
new Error("While scanning a directive", startMark,
|
||||||
|
@ -900,11 +901,11 @@ final class Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
///Scan value of a YAML directive token. Returns major, minor version separated by '.'.
|
///Scan value of a YAML directive token. Returns major, minor version separated by '.'.
|
||||||
dstring scanYAMLDirectiveValue(const Mark startMark) @trusted
|
dchar[] scanYAMLDirectiveValue(const Mark startMark) @trusted
|
||||||
{
|
{
|
||||||
findNextNonSpace();
|
findNextNonSpace();
|
||||||
|
|
||||||
dstring result = scanYAMLDirectiveNumber(startMark);
|
dchar[] result = scanYAMLDirectiveNumber(startMark);
|
||||||
enforce(reader_.peek() == '.',
|
enforce(reader_.peek() == '.',
|
||||||
new Error("While scanning a directive", startMark,
|
new Error("While scanning a directive", startMark,
|
||||||
"expected a digit or '.', but found: "
|
"expected a digit or '.', but found: "
|
||||||
|
@ -921,7 +922,7 @@ final class Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scan a number from a YAML directive.
|
/// Scan a number from a YAML directive.
|
||||||
dstring scanYAMLDirectiveNumber(const Mark startMark) @safe pure
|
dchar[] scanYAMLDirectiveNumber(const Mark startMark) @safe pure
|
||||||
{
|
{
|
||||||
enforce(isDigit(reader_.peek()),
|
enforce(isDigit(reader_.peek()),
|
||||||
new Error("While scanning a directive", startMark,
|
new Error("While scanning a directive", startMark,
|
||||||
|
@ -936,7 +937,7 @@ final class Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
///Scan value of a tag directive.
|
///Scan value of a tag directive.
|
||||||
dstring scanTagDirectiveValue(const Mark startMark) @safe
|
dchar[] scanTagDirectiveValue(const Mark startMark) @safe
|
||||||
{
|
{
|
||||||
findNextNonSpace();
|
findNextNonSpace();
|
||||||
const handle = scanTagDirectiveHandle(startMark);
|
const handle = scanTagDirectiveHandle(startMark);
|
||||||
|
@ -945,9 +946,9 @@ final class Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
///Scan handle of a tag directive.
|
///Scan handle of a tag directive.
|
||||||
dstring scanTagDirectiveHandle(const Mark startMark) @trusted
|
dchar[] scanTagDirectiveHandle(const Mark startMark) @trusted
|
||||||
{
|
{
|
||||||
const value = scanTagHandle("directive", startMark);
|
auto value = scanTagHandle("directive", startMark);
|
||||||
enforce(reader_.peek() == ' ',
|
enforce(reader_.peek() == ' ',
|
||||||
new Error("While scanning a directive handle", startMark,
|
new Error("While scanning a directive handle", startMark,
|
||||||
"expected ' ', but found: " ~ to!string(reader_.peek()),
|
"expected ' ', but found: " ~ to!string(reader_.peek()),
|
||||||
|
@ -956,9 +957,9 @@ final class Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
///Scan prefix of a tag directive.
|
///Scan prefix of a tag directive.
|
||||||
dstring scanTagDirectivePrefix(const Mark startMark) @trusted
|
dchar[] scanTagDirectivePrefix(const Mark startMark) @trusted
|
||||||
{
|
{
|
||||||
const value = scanTagURI("directive", startMark);
|
auto value = scanTagURI("directive", startMark);
|
||||||
enforce(" \0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek()),
|
enforce(" \0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek()),
|
||||||
new Error("While scanning a directive prefix", startMark,
|
new Error("While scanning a directive prefix", startMark,
|
||||||
"expected ' ', but found" ~ to!string(reader_.peek()),
|
"expected ' ', but found" ~ to!string(reader_.peek()),
|
||||||
|
@ -998,7 +999,7 @@ final class Scanner
|
||||||
|
|
||||||
const dchar i = reader_.get();
|
const dchar i = reader_.get();
|
||||||
|
|
||||||
dstring value = i == '*' ? scanAlphaNumeric!("an alias")(startMark)
|
dchar[] value = i == '*' ? scanAlphaNumeric!("an alias")(startMark)
|
||||||
: scanAlphaNumeric!("an anchor")(startMark);
|
: scanAlphaNumeric!("an anchor")(startMark);
|
||||||
|
|
||||||
enforce((" \t\0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek()) ||
|
enforce((" \t\0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek()) ||
|
||||||
|
@ -1023,8 +1024,8 @@ final class Scanner
|
||||||
{
|
{
|
||||||
const startMark = reader_.mark;
|
const startMark = reader_.mark;
|
||||||
dchar c = reader_.peek(1);
|
dchar c = reader_.peek(1);
|
||||||
dstring handle = "";
|
dchar[] handle;
|
||||||
dstring suffix;
|
dchar[] suffix;
|
||||||
|
|
||||||
if(c == '<')
|
if(c == '<')
|
||||||
{
|
{
|
||||||
|
@ -1038,7 +1039,7 @@ final class Scanner
|
||||||
}
|
}
|
||||||
else if(" \t\0\n\r\u0085\u2028\u2029"d.canFind(c))
|
else if(" \t\0\n\r\u0085\u2028\u2029"d.canFind(c))
|
||||||
{
|
{
|
||||||
suffix = "!";
|
suffix = "!"d.dup;
|
||||||
reader_.forward();
|
reader_.forward();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1060,7 +1061,7 @@ final class Scanner
|
||||||
if(useHandle) { handle = scanTagHandle("tag", startMark); }
|
if(useHandle) { handle = scanTagHandle("tag", startMark); }
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
handle = "!";
|
handle = "!"d.dup;
|
||||||
reader_.forward();
|
reader_.forward();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1106,7 +1107,7 @@ final class Scanner
|
||||||
endMark = scalarBreaks[1];
|
endMark = scalarBreaks[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
dstring lineBreak = "";
|
dchar[] lineBreak = ""d.dup;
|
||||||
|
|
||||||
//Using appender_, so clear it when we're done.
|
//Using appender_, so clear it when we're done.
|
||||||
scope(exit){appender_.clear();}
|
scope(exit){appender_.clear();}
|
||||||
|
@ -1117,7 +1118,7 @@ final class Scanner
|
||||||
appender_.put(breaks);
|
appender_.put(breaks);
|
||||||
const bool leadingNonSpace = !" \t"d.canFind(reader_.peek());
|
const bool leadingNonSpace = !" \t"d.canFind(reader_.peek());
|
||||||
appender_.put(scanToNextBreak());
|
appender_.put(scanToNextBreak());
|
||||||
lineBreak = ""d ~ scanLineBreak();
|
lineBreak = [scanLineBreak()];
|
||||||
|
|
||||||
auto scalarBreaks = scanBlockScalarBreaks(indent);
|
auto scalarBreaks = scanBlockScalarBreaks(indent);
|
||||||
breaks = scalarBreaks[0];
|
breaks = scalarBreaks[0];
|
||||||
|
@ -1152,7 +1153,7 @@ final class Scanner
|
||||||
if(chomping != Chomping.Strip){appender_.put(lineBreak);}
|
if(chomping != Chomping.Strip){appender_.put(lineBreak);}
|
||||||
if(chomping == Chomping.Keep){appender_.put(breaks);}
|
if(chomping == Chomping.Keep){appender_.put(breaks);}
|
||||||
|
|
||||||
return scalarToken(startMark, endMark, utf32To8(cast(dstring)appender_.data), style);
|
return scalarToken(startMark, endMark, utf32To8(appender_.data), style);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Scan chomping and indentation indicators of a scalar token.
|
///Scan chomping and indentation indicators of a scalar token.
|
||||||
|
@ -1269,7 +1270,7 @@ final class Scanner
|
||||||
}
|
}
|
||||||
reader_.forward();
|
reader_.forward();
|
||||||
|
|
||||||
return scalarToken(startMark, reader_.mark, utf32To8(cast(dstring)appender_.data), quotes);
|
return scalarToken(startMark, reader_.mark, utf32To8(appender_.data), quotes);
|
||||||
}
|
}
|
||||||
|
|
||||||
///Scan nonspace characters in a flow scalar.
|
///Scan nonspace characters in a flow scalar.
|
||||||
|
@ -1338,7 +1339,7 @@ final class Scanner
|
||||||
to!string(reader_.peek(i)), reader_.mark));
|
to!string(reader_.peek(i)), reader_.mark));
|
||||||
}
|
}
|
||||||
|
|
||||||
dstring hex = reader_.get(length);
|
dchar[] hex = reader_.get(length);
|
||||||
appender_.put(cast(dchar)parse!int(hex, 16));
|
appender_.put(cast(dchar)parse!int(hex, 16));
|
||||||
}
|
}
|
||||||
else if("\n\r\u0085\u2028\u2029"d.canFind(c))
|
else if("\n\r\u0085\u2028\u2029"d.canFind(c))
|
||||||
|
@ -1390,9 +1391,9 @@ final class Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scan line breaks in a flow scalar.
|
/// Scan line breaks in a flow scalar.
|
||||||
dstring scanFlowScalarBreaks(const Mark startMark) @safe pure
|
dchar[] scanFlowScalarBreaks(const Mark startMark) @safe pure
|
||||||
{
|
{
|
||||||
auto appender = appender!dstring();
|
auto appender = appender!(dchar[])();
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
// Instead of checking indentation, we check for document separators.
|
// Instead of checking indentation, we check for document separators.
|
||||||
|
@ -1426,7 +1427,6 @@ final class Scanner
|
||||||
// We allow zero indentation for scalars, but then we need to check for
|
// We allow zero indentation for scalars, but then we need to check for
|
||||||
// document separators at the beginning of the line.
|
// document separators at the beginning of the line.
|
||||||
// if(indent == 0) { indent = 1; }
|
// if(indent == 0) { indent = 1; }
|
||||||
dstring spaces;
|
|
||||||
|
|
||||||
mixin FastCharSearch!" \t\0\n\r\u0085\u2028\u2029"d search;
|
mixin FastCharSearch!" \t\0\n\r\u0085\u2028\u2029"d search;
|
||||||
|
|
||||||
|
@ -1486,7 +1486,7 @@ final class Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
spacesTransaction.__dtor();
|
spacesTransaction.__dtor();
|
||||||
const dstring slice = reader_.sliceBuilder.finish();
|
dstring slice = reader_.sliceBuilder.finish();
|
||||||
|
|
||||||
return scalarToken(startMark, endMark, slice.utf32To8, ScalarStyle.Plain);
|
return scalarToken(startMark, endMark, slice.utf32To8, ScalarStyle.Plain);
|
||||||
}
|
}
|
||||||
|
@ -1503,7 +1503,7 @@ final class Scanner
|
||||||
// Get as many plain spaces as there are.
|
// Get as many plain spaces as there are.
|
||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
while(reader_.peek(length) == ' ') { ++length; }
|
while(reader_.peek(length) == ' ') { ++length; }
|
||||||
const dstring whitespaces = reader_.get(length);
|
dchar[] whitespaces = reader_.get(length);
|
||||||
|
|
||||||
dchar c = reader_.peek();
|
dchar c = reader_.peek();
|
||||||
// No newline after the spaces (if any)
|
// No newline after the spaces (if any)
|
||||||
|
@ -1564,7 +1564,7 @@ final class Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scan handle of a tag token.
|
/// Scan handle of a tag token.
|
||||||
dstring scanTagHandle(const string name, const Mark startMark) @safe pure
|
dchar[] scanTagHandle(const string name, const Mark startMark) @safe pure
|
||||||
{
|
{
|
||||||
dchar c = reader_.peek();
|
dchar c = reader_.peek();
|
||||||
enforce(c == '!',
|
enforce(c == '!',
|
||||||
|
@ -1593,7 +1593,7 @@ final class Scanner
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scan URI in a tag token.
|
/// Scan URI in a tag token.
|
||||||
dstring scanTagURI(const string name, const Mark startMark) @system pure
|
dchar[] scanTagURI(const string name, const Mark startMark) @system pure
|
||||||
{
|
{
|
||||||
// Note: we do not check if URI is well-formed.
|
// Note: we do not check if URI is well-formed.
|
||||||
// Using appender_, so clear it when we're done.
|
// Using appender_, so clear it when we're done.
|
||||||
|
@ -1621,11 +1621,11 @@ final class Scanner
|
||||||
new Error("While parsing a " ~ name, startMark,
|
new Error("While parsing a " ~ name, startMark,
|
||||||
"expected URI, but found: " ~ c.to!string, reader_.mark));
|
"expected URI, but found: " ~ c.to!string, reader_.mark));
|
||||||
|
|
||||||
return cast(dstring)appender_.data;
|
return appender_.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scan URI escape sequences.
|
/// Scan URI escape sequences.
|
||||||
dstring scanURIEscapes(const string name, const Mark startMark) @system pure
|
dchar[] scanURIEscapes(const string name, const Mark startMark) @system pure
|
||||||
{
|
{
|
||||||
ubyte[] bytes;
|
ubyte[] bytes;
|
||||||
Mark mark = reader_.mark;
|
Mark mark = reader_.mark;
|
||||||
|
@ -1659,7 +1659,7 @@ final class Scanner
|
||||||
reader_.forward(2);
|
reader_.forward(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
try { return to!dstring(cast(string)bytes); }
|
try { return to!(dchar[])(cast(string)bytes); }
|
||||||
catch(ConvException e)
|
catch(ConvException e)
|
||||||
{
|
{
|
||||||
throw new Error("While scanning a " ~ name, startMark, e.msg, mark);
|
throw new Error("While scanning a " ~ name, startMark, e.msg, mark);
|
||||||
|
@ -1702,8 +1702,9 @@ final class Scanner
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// A nothrow function that converts a dstring to a string.
|
/// A nothrow function that converts a dchar[] to a string.
|
||||||
string utf32To8(dstring str) @safe pure nothrow
|
string utf32To8(C)(C[] str) @safe pure nothrow
|
||||||
|
if(is(Unqual!C == dchar))
|
||||||
{
|
{
|
||||||
try { return str.to!string; }
|
try { return str.to!string; }
|
||||||
catch(ConvException e) { assert(false, "Unexpected invalid UTF-32 string"); }
|
catch(ConvException e) { assert(false, "Unexpected invalid UTF-32 string"); }
|
||||||
|
|
Loading…
Reference in a new issue