directiveToken no longer stores multiple values by zero-separating.

This commit is contained in:
Ferdinand Majerech 2014-07-26 16:41:04 +02:00
parent b5259e6ada
commit db7fecf960
3 changed files with 38 additions and 23 deletions

View file

@ -346,23 +346,20 @@ final class Parser
while(scanner_.checkToken(TokenID.Directive)) while(scanner_.checkToken(TokenID.Directive))
{ {
immutable token = scanner_.getToken(); immutable token = scanner_.getToken();
//Name and value are separated by '\0'. const value = token.value;
const parts = token.value.split("\0"); if(token.directive == DirectiveType.YAML)
const name = parts[0];
if(name == "YAML")
{ {
enforce(YAMLVersion_ is null, enforce(YAMLVersion_ is null,
new Error("Duplicate YAML directive", token.startMark)); new Error("Duplicate YAML directive", token.startMark));
const minor = parts[1].split(".")[0]; const minor = value.split(".")[0];
enforce(minor == "1", enforce(minor == "1",
new Error("Incompatible document (version 1.x is required)", new Error("Incompatible document (version 1.x is required)",
token.startMark)); token.startMark));
YAMLVersion_ = parts[1]; YAMLVersion_ = value;
} }
else if(name == "TAG") else if(token.directive == DirectiveType.TAG)
{ {
assert(parts.length == 3, "Tag directive stored incorrectly in a token"); auto handle = value[0 .. token.valueDivider];
auto handle = parts[1];
foreach(ref pair; tagDirectives_) foreach(ref pair; tagDirectives_)
{ {
@ -371,8 +368,10 @@ final class Parser
enforce(h != handle, new Error("Duplicate tag handle: " ~ handle, enforce(h != handle, new Error("Duplicate tag handle: " ~ handle,
token.startMark)); token.startMark));
} }
tagDirectives_ ~= TagDirective(handle, parts[2]); tagDirectives_ ~= TagDirective(handle, value[token.valueDivider .. $]);
} }
// Any other directive type is ignored (only YAML and TAG are in YAML
// 1.1/1.2, any other directives are "reserved")
} }
TagDirective[] value = tagDirectives_; TagDirective[] value = tagDirectives_;

View file

@ -943,17 +943,28 @@ final class Scanner
throwIfError(); throwIfError();
} }
const name = reader_.sliceBuilder.finish(); const name = reader_.sliceBuilder.finish();
const value = name == "YAML" ? scanYAMLDirectiveValue(startMark): // Index where tag handle ends and suffix starts in a tag directive value.
name == "TAG" ? scanTagDirectiveValue(startMark) : ""; uint tagHandleEnd = uint.max;
const value = name == "YAML"d ? scanYAMLDirectiveValue(startMark):
name == "TAG"d ? scanTagDirectiveValue(startMark, tagHandleEnd) : "";
Mark endMark = reader_.mark; Mark endMark = reader_.mark;
if(!["YAML"d, "TAG"d].canFind(name)) { scanToNextBreak(); } DirectiveType directive;
if(name == "YAML"d) { directive = DirectiveType.YAML; }
else if(name == "TAG"d) { directive = DirectiveType.TAG; }
else
{
directive = DirectiveType.Reserved;
scanToNextBreak();
}
scanDirectiveIgnoredLine(startMark); scanDirectiveIgnoredLine(startMark);
throwIfError(); throwIfError();
//Storing directive name and value in a single string, separated by zero. //Storing directive name and value in a single string, separated by zero.
return directiveToken(startMark, endMark, utf32To8(name ~ '\0' ~ value)); return directiveToken(startMark, endMark, utf32To8(value),
directive, tagHandleEnd);
} }
/// Scan name of a directive token. /// Scan name of a directive token.
@ -1010,12 +1021,14 @@ final class Scanner
} }
/// Scan value of a tag directive. /// Scan value of a tag directive.
dstring scanTagDirectiveValue(const Mark startMark) @safe pure dstring scanTagDirectiveValue(const Mark startMark, ref uint handleLength)
@safe pure
{ {
findNextNonSpace(); findNextNonSpace();
const handle = scanTagDirectiveHandle(startMark); const handle = scanTagDirectiveHandle(startMark);
findNextNonSpace(); findNextNonSpace();
return handle ~ '\0' ~ scanTagDirectivePrefix(startMark); handleLength = cast(uint)handle.length;
return handle ~ scanTagDirectivePrefix(startMark);
} }
///Scan handle of a tag directive. ///Scan handle of a tag directive.

View file

@ -98,12 +98,15 @@ static assert(Token.sizeof <= 32, "Token has unexpected size");
/// Construct a directive token. /// Construct a directive token.
/// ///
/// Params: start = Start position of the token. /// Params: start = Start position of the token.
/// end = End position of the token. /// end = End position of the token.
/// value = Value of the token. /// value = Value of the token.
Token directiveToken(const Mark start, const Mark end, const string value) /// directive = Directive type (YAML or TAG in YAML 1.1).
Token directiveToken(const Mark start, const Mark end, const string value,
DirectiveType directive, const uint nameEnd)
{ {
return Token(value, start, end, TokenID.Directive); return Token(value, start, end, TokenID.Directive, ScalarStyle.init, Encoding.init,
directive, nameEnd);
} }
/// Construct a simple (no value) token with specified type. /// Construct a simple (no value) token with specified type.