remove zerostring (#94)

remove zerostring
merged-on-behalf-of: BBasile <BBasile@users.noreply.github.com>
This commit is contained in:
Cameron Ross 2018-02-28 23:20:43 -04:00 committed by The Dlang Bot
parent 72995df864
commit 683335aa3e
15 changed files with 105 additions and 231 deletions

View file

@ -10,7 +10,6 @@ src_dir = include_directories('source/')
pkgc = import('pkgconfig')
dyaml_src = [
'source/dyaml/anchor.d',
'source/dyaml/composer.d',
'source/dyaml/constructor.d',
'source/dyaml/dumper.d',
@ -36,7 +35,6 @@ dyaml_src = [
'source/dyaml/serializer.d',
'source/dyaml/stream.d',
'source/dyaml/style.d',
'source/dyaml/tag.d',
'source/dyaml/tagdirective.d',
'source/dyaml/test/common.d',
'source/dyaml/test/compare.d',
@ -49,8 +47,7 @@ dyaml_src = [
'source/dyaml/test/resolver.d',
'source/dyaml/test/tokens.d',
'source/dyaml/token.d',
'source/dyaml/unused.d',
'source/dyaml/zerostring.d'
'source/dyaml/unused.d'
]
install_subdir('source/dyaml', install_dir: 'include/d/yaml/')

View file

@ -1,13 +0,0 @@
// Copyright Ferdinand Majerech 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
///YAML anchor.
module dyaml.anchor;
import dyaml.zerostring;
///YAML anchor (reference) struct. Encapsulates an anchor to save memory.
alias ZeroString!"Anchor" Anchor;

View file

@ -17,7 +17,6 @@ import std.conv;
import std.exception;
import std.typecons;
import dyaml.anchor;
import dyaml.constructor;
import dyaml.event;
import dyaml.exception;
@ -48,7 +47,7 @@ final class Composer
///Constructor constructing YAML values.
Constructor constructor_;
///Nodes associated with anchors. Used by YAML aliases.
Node[Anchor] anchors_;
Node[string] anchors_;
///Used to reduce allocations when creating pair arrays.
///
@ -182,14 +181,14 @@ final class Composer
immutable event = parser_.getEvent();
const anchor = event.anchor;
enforce((anchor in anchors_) !is null,
new ComposerException("Found undefined alias: " ~ anchor.get,
new ComposerException("Found undefined alias: " ~ anchor,
event.startMark));
//If the node referenced by the anchor is uninitialized,
//it's not finished, i.e. we're currently composing it
//and trying to use it recursively here.
enforce(anchors_[anchor] != Node(),
new ComposerException("Found recursive alias: " ~ anchor.get,
new ComposerException("Found recursive alias: " ~ anchor,
event.startMark));
return anchors_[anchor];
@ -197,16 +196,16 @@ final class Composer
immutable event = parser_.peekEvent();
const anchor = event.anchor;
if(!anchor.isNull() && (anchor in anchors_) !is null)
if((anchor !is null) && (anchor in anchors_) !is null)
{
throw new ComposerException("Found duplicate anchor: " ~ anchor.get,
throw new ComposerException("Found duplicate anchor: " ~ anchor,
event.startMark);
}
Node result;
//Associate the anchor, if any, with an uninitialized node.
//used to detect duplicate and recursive anchors.
if(!anchor.isNull())
if(anchor !is null)
{
anchors_[anchor] = Node();
}
@ -225,7 +224,7 @@ final class Composer
}
else{assert(false, "This code should never be reached");}
if(!anchor.isNull())
if(anchor !is null)
{
anchors_[anchor] = result;
}

View file

@ -27,7 +27,6 @@ import std.utf;
import dyaml.node;
import dyaml.exception;
import dyaml.tag;
import dyaml.style;
@ -67,11 +66,11 @@ final class Constructor
{
private:
// Constructor functions from scalars.
Node.Value delegate(ref Node)[Tag] fromScalar_;
Node.Value delegate(ref Node)[string] fromScalar_;
// Constructor functions from sequences.
Node.Value delegate(ref Node)[Tag] fromSequence_;
Node.Value delegate(ref Node)[string] fromSequence_;
// Constructor functions from mappings.
Node.Value delegate(ref Node)[Tag] fromMapping_;
Node.Value delegate(ref Node)[string] fromMapping_;
public:
/// Construct a Constructor.
@ -185,7 +184,7 @@ final class Constructor
void addConstructorScalar(T)(const string tag, T function(ref Node) ctor)
@safe nothrow
{
const t = Tag(tag);
const t = tag;
auto deleg = addConstructor!T(t, ctor);
(*delegates!string)[t] = deleg;
}
@ -236,7 +235,7 @@ final class Constructor
void addConstructorSequence(T)(const string tag, T function(ref Node) ctor)
@safe nothrow
{
const t = Tag(tag);
const t = tag;
auto deleg = addConstructor!T(t, ctor);
(*delegates!(Node[]))[t] = deleg;
}
@ -287,7 +286,7 @@ final class Constructor
void addConstructorMapping(T)(const string tag, T function(ref Node) ctor)
@safe nothrow
{
const t = Tag(tag);
const t = tag;
auto deleg = addConstructor!T(t, ctor);
(*delegates!(Node.Pair[]))[t] = deleg;
}
@ -304,7 +303,7 @@ final class Constructor
*
* Returns: Constructed node.
*/
Node node(T, U)(const Mark start, const Mark end, const Tag tag,
Node node(T, U)(const Mark start, const Mark end, const string tag,
T value, U style) @trusted
if((is(T : string) || is(T == Node[]) || is(T == Node.Pair[])) &&
(is(U : CollectionStyle) || is(U : ScalarStyle)))
@ -315,7 +314,7 @@ final class Constructor
"ERROR";
enforce((tag in *delegates!T) !is null,
new Error("No constructor function from " ~ type ~
" for tag " ~ tag.get(), start, end));
" for tag " ~ tag, start, end));
Node node = Node(value);
try
@ -346,13 +345,13 @@ final class Constructor
* Params: tag = Tag for the function to handle.
* ctor = Constructor function.
*/
auto addConstructor(T)(const Tag tag, T function(ref Node) ctor)
auto addConstructor(T)(const string tag, T function(ref Node) ctor)
@safe nothrow
{
assert((tag in fromScalar_) is null &&
(tag in fromSequence_) is null &&
(tag in fromMapping_) is null,
"Constructor function for tag " ~ tag.get ~ " is already " ~
"Constructor function for tag " ~ tag ~ " is already " ~
"specified. Can't specify another one.");

View file

@ -16,7 +16,6 @@ module dyaml.dumper;
import std.typecons;
import dyaml.stream;
import dyaml.anchor;
import dyaml.emitter;
import dyaml.encoding;
import dyaml.event;

View file

@ -24,7 +24,6 @@ import std.typecons;
import std.utf;
import dyaml.stream;
import dyaml.anchor;
import dyaml.encoding;
import dyaml.escapes;
import dyaml.event;
@ -34,7 +33,6 @@ import dyaml.flags;
import dyaml.linebreak;
import dyaml.queue;
import dyaml.style;
import dyaml.tag;
import dyaml.tagdirective;
@ -500,7 +498,7 @@ struct Emitter
///Handle an alias.
void expectAlias() @trusted
{
enforce(!event_.anchor.isNull(), new Error("Anchor is not specified for alias"));
enforce(event_.anchor !is null, new Error("Anchor is not specified for alias"));
processAnchor("*");
state_ = popState();
}
@ -707,8 +705,8 @@ struct Emitter
}
const event = events_.peek();
const emptyScalar = event.id == EventID.Scalar && event.anchor.isNull() &&
event.tag.isNull() && event.implicit && event.value == "";
const emptyScalar = event.id == EventID.Scalar && (event.anchor is null) &&
(event.tag is null) && event.implicit && event.value == "";
return emptyScalar;
}
@ -722,7 +720,7 @@ struct Emitter
id == EventID.SequenceStart;
if((id == EventID.Alias || scalar || collectionStart)
&& !event_.anchor.isNull())
&& (event_.anchor !is null))
{
if(preparedAnchor_ is null)
{
@ -731,7 +729,7 @@ struct Emitter
length += preparedAnchor_.length;
}
if((scalar || collectionStart) && !event_.tag.isNull())
if((scalar || collectionStart) && (event_.tag !is null))
{
if(preparedTag_ is null){preparedTag_ = prepareTag(event_.tag);}
length += preparedTag_.length;
@ -784,7 +782,7 @@ struct Emitter
///Process and write an anchor/alias.
void processAnchor(const string indicator) @trusted
{
if(event_.anchor.isNull())
if(event_.anchor is null)
{
preparedAnchor_ = null;
return;
@ -804,30 +802,30 @@ struct Emitter
///Process and write a tag.
void processTag() @trusted
{
Tag tag = event_.tag;
string tag = event_.tag;
if(event_.id == EventID.Scalar)
{
if(style_ == ScalarStyle.Invalid){style_ = chooseScalarStyle();}
if((!canonical_ || tag.isNull()) &&
if((!canonical_ || (tag is null)) &&
(style_ == ScalarStyle.Plain ? event_.implicit : event_.implicit_2))
{
preparedTag_ = null;
return;
}
if(event_.implicit && tag.isNull())
if(event_.implicit && (tag is null))
{
tag = Tag("!");
tag = "!";
preparedTag_ = null;
}
}
else if((!canonical_ || tag.isNull()) && event_.implicit)
else if((!canonical_ || (tag is null)) && event_.implicit)
{
preparedTag_ = null;
return;
}
enforce(!tag.isNull(), new Error("Tag is not specified"));
enforce(tag !is null, new Error("Tag is not specified"));
if(preparedTag_ is null){preparedTag_ = prepareTag(tag);}
if(preparedTag_ !is null && preparedTag_ != "")
{
@ -946,11 +944,11 @@ struct Emitter
}
///Prepare tag for output.
string prepareTag(in Tag tag) @trusted
string prepareTag(in string tag) @trusted
{
enforce(!tag.isNull(), new Error("Tag must not be empty"));
enforce(tag !is null, new Error("Tag must not be empty"));
string tagString = tag.get;
string tagString = tag;
if(tagString == "!"){return tagString;}
string handle = null;
string suffix = tagString;
@ -993,11 +991,11 @@ struct Emitter
}
///Prepare anchor for output.
static string prepareAnchor(const Anchor anchor) @trusted
static string prepareAnchor(const string anchor) @trusted
{
enforce(!anchor.isNull() && anchor.get != "",
enforce(anchor != "",
new Error("Anchor must not be empty"));
const str = anchor.get;
const str = anchor;
foreach(const dchar c; str)
{
enforce(isAlphaNum(c) || "-_"d.canFind(c),

View file

@ -14,11 +14,9 @@ import std.array;
import std.conv;
import std.typecons;
import dyaml.anchor;
import dyaml.encoding;
import dyaml.exception;
import dyaml.reader;
import dyaml.tag;
import dyaml.tagdirective;
import dyaml.style;
@ -60,9 +58,9 @@ struct Event
struct
{
///Anchor of the event, if any.
Anchor anchor;
string anchor;
///Tag of the event, if any.
Tag tag;
string tag;
}
///Tag directives, if this is a DocumentStart.
//TagDirectives tagDirectives;
@ -96,7 +94,7 @@ struct Event
///Get string representation of the token ID.
@property string idString() const @system {return to!string(id);}
static assert(Event.sizeof <= 48, "Event struct larger than expected");
static assert(Event.sizeof <= 64, "Event struct larger than expected");
}
/**
@ -106,7 +104,7 @@ struct Event
* end = End position of the event in the file/stream.
* anchor = Anchor, if this is an alias event.
*/
Event event(EventID id)(const Mark start, const Mark end, const Anchor anchor = Anchor())
Event event(EventID id)(const Mark start, const Mark end, const string anchor = null)
pure @trusted nothrow
{
Event result;
@ -127,7 +125,7 @@ Event event(EventID id)(const Mark start, const Mark end, const Anchor anchor =
* implicit = Should the tag be implicitly resolved?
*/
Event collectionStartEvent(EventID id)
(const Mark start, const Mark end, const Anchor anchor, const Tag tag,
(const Mark start, const Mark end, const string anchor, const string tag,
const bool implicit, const CollectionStyle style) pure @trusted nothrow
{
static assert(id == EventID.SequenceStart || id == EventID.SequenceEnd ||
@ -219,7 +217,7 @@ Event documentEndEvent(const Mark start, const Mark end, const bool explicit) pu
/// implicit = Should the tag be implicitly resolved?
/// value = String value of the scalar.
/// style = Scalar style.
Event scalarEvent(const Mark start, const Mark end, const Anchor anchor, const Tag tag,
Event scalarEvent(const Mark start, const Mark end, const string anchor, const string tag,
const Tuple!(bool, bool) implicit, const string value,
const ScalarStyle style = ScalarStyle.Invalid) @safe pure nothrow @nogc
{

View file

@ -25,8 +25,6 @@ import std.variant;
import dyaml.event;
import dyaml.exception;
import dyaml.style;
import dyaml.tag;
/// Exception thrown at node related errors.
class NodeException : YAMLException
@ -212,14 +210,14 @@ struct Node
package:
// Tag of the node.
Tag tag_;
string tag_;
// Node scalar style. Used to remember style this node was loaded with.
ScalarStyle scalarStyle = ScalarStyle.Invalid;
// Node collection style. Used to remember style this node was loaded with.
CollectionStyle collectionStyle = CollectionStyle.Invalid;
static assert(Value.sizeof <= 24, "Unexpected YAML value size");
static assert(Node.sizeof <= 48, "Unexpected YAML node size");
static assert(Node.sizeof <= 56, "Unexpected YAML node size");
// If scalarCtorNothrow!T is true, scalar node ctor from T can be nothrow.
//
@ -253,7 +251,7 @@ struct Node
this(T)(T value, const string tag = null) @trusted
if(!scalarCtorNothrow!T && (!isArray!T && !isAssociativeArray!T))
{
tag_ = Tag(tag);
tag_ = tag;
// No copyconstruction.
static assert(!is(Unqual!T == Node));
@ -270,7 +268,7 @@ struct Node
this(T)(T value, const string tag = null) @trusted pure nothrow
if(scalarCtorNothrow!T)
{
tag_ = Tag(tag);
tag_ = tag;
// We can easily store ints, floats, strings.
static if(isIntegral!T) { value_ = Value(cast(long)value); }
else static if(is(Unqual!T==bool)){ value_ = Value(cast(bool)value); }
@ -326,7 +324,7 @@ struct Node
this(T)(T[] array, const string tag = null) @trusted
if (!isSomeString!(T[]))
{
tag_ = Tag(tag);
tag_ = tag;
// Construction from raw node or pair array.
static if(is(Unqual!T == Node) || is(Unqual!T == Node.Pair))
@ -389,7 +387,7 @@ struct Node
*/
this(K, V)(V[K] array, const string tag = null) @trusted
{
tag_ = Tag(tag);
tag_ = tag;
Node.Pair[] pairs;
foreach(key, ref value; array){pairs ~= Pair(key, value);}
@ -461,7 +459,7 @@ struct Node
}
body
{
tag_ = Tag(tag);
tag_ = tag;
Node.Pair[] pairs;
foreach(i; 0 .. keys.length){pairs ~= Pair(keys[i], values[i]);}
@ -521,7 +519,7 @@ struct Node
}
/// Return tag of the node.
@property string tag() const @safe nothrow {return tag_.get;}
@property string tag() const @safe nothrow {return tag_;}
/** Equality test.
*
@ -1634,9 +1632,9 @@ struct Node
}
// Compute hash of the node.
hash_t toHash() @safe nothrow const
hash_t toHash() nothrow const
{
const tagHash = tag_.isNull ? 0 : tag_.toHash();
const tagHash = (tag_ is null) ? 0 : tag_.hashOf();
// Variant toHash is not const at the moment, so we need to const-cast.
return tagHash + value_.toHash();
}
@ -1655,7 +1653,7 @@ struct Node
// collectionStyle = Collection style of the node.
//
// Returns: Constructed node.
static Node rawNode(Value value, const Mark startMark, const Tag tag,
static Node rawNode(Value value, const Mark startMark, const string tag,
const ScalarStyle scalarStyle,
const CollectionStyle collectionStyle) @trusted
{
@ -1739,8 +1737,8 @@ struct Node
// Compare tags - if equal or both null, we need to compare further.
static if(useTag)
{
const tagCmp = tag_.isNull ? rhs.tag_.isNull ? 0 : -1
: rhs.tag_.isNull ? 1 : tag_.opCmp(rhs.tag_);
const tagCmp = (tag_ is null) ? (rhs.tag_ is null) ? 0 : -1
: (rhs.tag_ is null) ? 1 : std.algorithm.comparison.cmp(tag_, rhs.tag_);
if(tagCmp != 0){return tagCmp;}
}

View file

@ -18,13 +18,11 @@ import std.conv;
import std.exception;
import std.typecons;
import dyaml.anchor;
import dyaml.event;
import dyaml.exception;
import dyaml.scanner;
import dyaml.style;
import dyaml.token;
import dyaml.tag;
import dyaml.tagdirective;
@ -423,7 +421,7 @@ final class Parser
const token = scanner_.getToken();
state_ = popState();
return aliasEvent(token.startMark, token.endMark,
Anchor(cast(string)token.value));
cast(string)token.value);
}
string anchor = null;
@ -467,8 +465,8 @@ final class Parser
{
state_ = &parseIndentlessSequenceEntry;
return sequenceStartEvent
(startMark, scanner_.peekToken().endMark, Anchor(anchor),
Tag(tag), implicit, CollectionStyle.Block);
(startMark, scanner_.peekToken().endMark, anchor,
tag, implicit, CollectionStyle.Block);
}
if(scanner_.checkToken(TokenID.Scalar))
@ -481,7 +479,7 @@ final class Parser
implicit = (token.style == ScalarStyle.Plain && tag is null) || tag == "!";
bool implicit_2 = (!implicit) && tag is null;
state_ = popState();
return scalarEvent(startMark, token.endMark, Anchor(anchor), Tag(tag),
return scalarEvent(startMark, token.endMark, anchor, tag,
tuple(implicit, implicit_2), value, token.style);
}
@ -489,7 +487,7 @@ final class Parser
{
endMark = scanner_.peekToken().endMark;
state_ = &parseFlowSequenceEntry!(Yes.first);
return sequenceStartEvent(startMark, endMark, Anchor(anchor), Tag(tag),
return sequenceStartEvent(startMark, endMark, anchor, tag,
implicit, CollectionStyle.Flow);
}
@ -497,7 +495,7 @@ final class Parser
{
endMark = scanner_.peekToken().endMark;
state_ = &parseFlowMappingKey!(Yes.first);
return mappingStartEvent(startMark, endMark, Anchor(anchor), Tag(tag),
return mappingStartEvent(startMark, endMark, anchor, tag,
implicit, CollectionStyle.Flow);
}
@ -505,7 +503,7 @@ final class Parser
{
endMark = scanner_.peekToken().endMark;
state_ = &parseBlockSequenceEntry!(Yes.first);
return sequenceStartEvent(startMark, endMark, Anchor(anchor), Tag(tag),
return sequenceStartEvent(startMark, endMark, anchor, tag,
implicit, CollectionStyle.Block);
}
@ -513,11 +511,11 @@ final class Parser
{
endMark = scanner_.peekToken().endMark;
state_ = &parseBlockMappingKey!(Yes.first);
return mappingStartEvent(startMark, endMark, Anchor(anchor), Tag(tag),
return mappingStartEvent(startMark, endMark, anchor, tag,
implicit, CollectionStyle.Block);
}
if(anchor != null || tag !is null)
if(anchor !is null || tag !is null)
{
state_ = popState();
@ -525,7 +523,7 @@ final class Parser
//but the second bool is never used after that - so we don't use it.
//Empty scalars are allowed even if a tag or an anchor is specified.
return scalarEvent(startMark, endMark, Anchor(anchor), Tag(tag),
return scalarEvent(startMark, endMark, anchor, tag,
tuple(implicit, false) , "");
}
@ -815,7 +813,7 @@ final class Parser
const token = scanner_.peekToken();
state_ = &parseFlowSequenceEntryMappingKey;
return mappingStartEvent(token.startMark, token.endMark,
Anchor(), Tag(), true, CollectionStyle.Flow);
null, null, true, CollectionStyle.Flow);
}
else if(!scanner_.checkToken(TokenID.FlowSequenceEnd))
{
@ -952,6 +950,6 @@ final class Parser
///Return an empty scalar.
Event processEmptyScalar(const Mark mark) @safe pure nothrow const @nogc
{
return scalarEvent(mark, mark, Anchor(), Tag(), tuple(true, false), "");
return scalarEvent(mark, mark, null, null, tuple(true, false), "");
}
}

View file

@ -29,7 +29,6 @@ import dyaml.exception;
import dyaml.node;
import dyaml.serializer;
import dyaml.style;
import dyaml.tag;
///Exception thrown on Representer errors.
@ -277,7 +276,7 @@ final class Representer
ScalarStyle style = ScalarStyle.Invalid) @trusted
{
if(style == ScalarStyle.Invalid){style = defaultScalarStyle_;}
return Node.rawNode(Node.Value(scalar), Mark(), Tag(tag), style,
return Node.rawNode(Node.Value(scalar), Mark(), tag, style,
CollectionStyle.Invalid);
}
@ -346,7 +345,7 @@ final class Representer
? defaultCollectionStyle_
: bestStyle;
}
return Node.rawNode(Node.Value(value), Mark(), Tag(tag),
return Node.rawNode(Node.Value(value), Mark(), tag,
ScalarStyle.Invalid, style);
}
@ -423,7 +422,7 @@ final class Representer
? defaultCollectionStyle_
: bestStyle;
}
return Node.rawNode(Node.Value(value), Mark(), Tag(tag),
return Node.rawNode(Node.Value(value), Mark(), tag,
ScalarStyle.Invalid, style);
}
@ -440,7 +439,7 @@ final class Representer
Node result = representers_[type](data, this);
//Override tag if specified.
if(!data.tag_.isNull()){result.tag_ = data.tag_;}
if(data.tag_ !is null){result.tag_ = data.tag_;}
//Remember style if this was loaded before.
if(data.scalarStyle != ScalarStyle.Invalid)
@ -527,7 +526,7 @@ Node representSysTime(ref Node node, Representer representer) @system
Node representNodes(ref Node node, Representer representer) @safe
{
auto nodes = node.as!(Node[]);
if(node.tag_ == Tag("tag:yaml.org,2002:set"))
if(node.tag_ == "tag:yaml.org,2002:set")
{
///YAML sets are mapping with null values.
Node.Pair[] pairs;
@ -537,7 +536,7 @@ Node representNodes(ref Node node, Representer representer) @safe
{
pairs[idx] = Node.Pair(key, representNull(dummy, representer));
}
return representer.representMapping(node.tag_.get, pairs);
return representer.representMapping(node.tag_, pairs);
}
else
{
@ -574,15 +573,15 @@ Node representPairs(ref Node node, Representer representer) @system
return nodes;
}
if(node.tag_ == Tag("tag:yaml.org,2002:omap"))
if(node.tag_ == "tag:yaml.org,2002:omap")
{
enforce(!hasDuplicates(pairs),
new RepresenterException("Duplicate entry in an ordered map"));
return representer.representSequence(node.tag_.get, mapToSequence(pairs));
return representer.representSequence(node.tag_, mapToSequence(pairs));
}
else if(node.tag_ == Tag("tag:yaml.org,2002:pairs"))
else if(node.tag_ == "tag:yaml.org,2002:pairs")
{
return representer.representSequence(node.tag_.get, mapToSequence(pairs));
return representer.representSequence(node.tag_, mapToSequence(pairs));
}
else
{

View file

@ -23,7 +23,6 @@ import std.utf;
import dyaml.node;
import dyaml.exception;
import dyaml.tag;
/**
@ -35,11 +34,11 @@ final class Resolver
{
private:
// Default tag to use for scalars.
Tag defaultScalarTag_;
string defaultScalarTag_;
// Default tag to use for sequences.
Tag defaultSequenceTag_;
string defaultSequenceTag_;
// Default tag to use for mappings.
Tag defaultMappingTag_;
string defaultMappingTag_;
/*
* Arrays of scalar resolver tuples indexed by starting character of a scalar.
@ -47,7 +46,7 @@ final class Resolver
* Each tuple stores regular expression the scalar must match,
* and tag to assign to it if it matches.
*/
Tuple!(Tag, Regex!char)[][dchar] yamlImplicitResolvers_;
Tuple!(string, Regex!char)[][dchar] yamlImplicitResolvers_;
public:
@disable bool opEquals(ref Resolver);
@ -64,9 +63,9 @@ final class Resolver
this(Flag!"useDefaultImplicitResolvers" defaultImplicitResolvers = Yes.useDefaultImplicitResolvers)
@safe
{
defaultScalarTag_ = Tag("tag:yaml.org,2002:str");
defaultSequenceTag_ = Tag("tag:yaml.org,2002:seq");
defaultMappingTag_ = Tag("tag:yaml.org,2002:map");
defaultScalarTag_ = "tag:yaml.org,2002:str";
defaultSequenceTag_ = "tag:yaml.org,2002:seq";
defaultMappingTag_ = "tag:yaml.org,2002:map";
if(defaultImplicitResolvers){addImplicitResolvers();}
}
@ -125,7 +124,7 @@ final class Resolver
{
yamlImplicitResolvers_[c] = [];
}
yamlImplicitResolvers_[c] ~= tuple(Tag(tag), regexp);
yamlImplicitResolvers_[c] ~= tuple(tag, regexp);
}
}
@ -143,10 +142,10 @@ final class Resolver
*
* Returns: Resolved tag.
*/
Tag resolve(const NodeID kind, const Tag tag, const string value,
string resolve(const NodeID kind, const string tag, const string value,
const bool implicit) @safe
{
if(!tag.isNull() && tag.get() != "!"){return tag;}
if((tag !is null) && tag != "!"){return tag;}
if(kind == NodeID.Scalar)
{
@ -178,10 +177,10 @@ final class Resolver
bool tagMatch(string tag, string[] values)
{
Tag expected = Tag(tag);
string expected = tag;
foreach(value; values)
{
Tag resolved = resolver.resolve(NodeID.Scalar, Tag(), value, true);
string resolved = resolver.resolve(NodeID.Scalar, null, value, true);
if(expected != resolved)
{
return false;
@ -213,13 +212,13 @@ final class Resolver
}
///Return default scalar tag.
@property Tag defaultScalarTag() const pure @safe nothrow {return defaultScalarTag_;}
@property string defaultScalarTag() const pure @safe nothrow {return defaultScalarTag_;}
///Return default sequence tag.
@property Tag defaultSequenceTag() const pure @safe nothrow {return defaultSequenceTag_;}
@property string defaultSequenceTag() const pure @safe nothrow {return defaultSequenceTag_;}
///Return default mapping tag.
@property Tag defaultMappingTag() const pure @safe nothrow {return defaultMappingTag_;}
@property string defaultMappingTag() const pure @safe nothrow {return defaultMappingTag_;}
private:
// Add default implicit resolvers.

View file

@ -15,14 +15,12 @@ import std.array;
import std.format;
import std.typecons;
import dyaml.anchor;
import dyaml.emitter;
import dyaml.encoding;
import dyaml.event;
import dyaml.exception;
import dyaml.node;
import dyaml.resolver;
import dyaml.tag;
import dyaml.tagdirective;
import dyaml.token;
@ -50,7 +48,7 @@ struct Serializer
//TODO Use something with more deterministic memory usage.
///Nodes with assigned anchors.
Anchor[Node] anchors_;
string[Node] anchors_;
///Nodes with assigned anchors that are already serialized.
bool[Node] serializedNodes_;
///ID of the last anchor generated.
@ -105,7 +103,7 @@ struct Serializer
emitter_.emit(documentEndEvent(Mark(), Mark(), explicitEnd_));
serializedNodes_.destroy();
anchors_.destroy();
Anchor[Node] emptyAnchors;
string[Node] emptyAnchors;
anchors_ = emptyAnchors;
lastAnchorID_ = 0;
}
@ -139,14 +137,14 @@ struct Serializer
if((node in anchors_) !is null)
{
if(anchors_[node].isNull())
if(anchors_[node] is null)
{
anchors_[node] = generateAnchor();
}
return;
}
anchors_[node] = Anchor(null);
anchors_[node] = null;
if(node.isSequence) foreach(ref Node item; node)
{
anchorNode(item);
@ -159,12 +157,12 @@ struct Serializer
}
///Generate and return a new anchor.
Anchor generateAnchor() @trusted
string generateAnchor() @trusted
{
++lastAnchorID_;
auto appender = appender!string();
formattedWrite(appender, "id%03d", lastAnchorID_);
return Anchor(appender.data);
return appender.data;
}
///Serialize a node and all its subnodes.
@ -173,7 +171,7 @@ struct Serializer
//If the node has an anchor, emit an anchor (as aliasEvent) on the
//first occurrence, save it in serializedNodes_, and emit an alias
//if it reappears.
Anchor aliased = Anchor(null);
string aliased = null;
if(anchorable(node) && (node in anchors_) !is null)
{
aliased = anchors_[node];
@ -189,8 +187,8 @@ struct Serializer
{
assert(node.isType!string, "Scalar node type must be string before serialized");
auto value = node.as!string;
const detectedTag = resolver_.resolve(NodeID.Scalar, Tag(null), value, true);
const defaultTag = resolver_.resolve(NodeID.Scalar, Tag(null), value, false);
const detectedTag = resolver_.resolve(NodeID.Scalar, null, value, true);
const defaultTag = resolver_.resolve(NodeID.Scalar, null, value, false);
bool isDetected = node.tag_ == detectedTag;
bool isDefault = node.tag_ == defaultTag;

View file

@ -1,13 +0,0 @@
// Copyright Ferdinand Majerech 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
///YAML tag.
module dyaml.tag;
import dyaml.zerostring;
///YAML tag (data type) struct. Encapsulates a tag to save memory and speed up comparison.
alias ZeroString!"Tag" Tag;

View file

@ -16,7 +16,6 @@ import std.path;
import std.string;
import std.typecons;
import dyaml.tag;
import dyaml.test.common;

View file

@ -1,81 +0,0 @@
// Copyright Ferdinand Majerech 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
///Zero terminated string.
module dyaml.zerostring;
import core.stdc.string;
/**
* Zero terminated string used to decrease data structure size.
*
* TypeName is used to differentiate types (better than simple alias).
*/
struct ZeroString(string TypeName)
{
private:
///Zero terminated string.
immutable(char)* str_ = null;
public:
@disable int opCmp(ref ZeroString);
///Construct a string.
this(const string str) pure nothrow @trusted
{
if(str is null || str == "")
{
str_ = null;
return;
}
str_ = &(str ~ '\0')[0];
}
///Get the string.
@property string get() const nothrow @trusted
in{assert(!isNull());}
body
{
return cast(string)str_[0 .. strlen(str_)];
}
///Test for equality with another string.
bool opEquals(const ZeroString str) const nothrow @trusted
{
return isNull ? str.isNull :
str.isNull ? false : (0 == strcmp(str_, str.str_));
}
///Compute a hash.
hash_t toHash() const nothrow @safe
in{assert(!isNull);}
body
{
auto str = get();
return getHash(str);
}
///Compare with another string.
int opCmp(const ref ZeroString str) const nothrow @trusted
in{assert(!isNull && !str.isNull);}
body
{
return strcmp(str_, str.str_);
}
///Is this string null (invalid)?
@property bool isNull() pure const nothrow @safe {return str_ is null;}
private:
///Hack to allow toHash to be @safe.
//
//To remove this hack, need a typeid(string).getHash() replacement that does not take a pointer.
hash_t getHash(ref string str) const nothrow @trusted
{
return typeid(string).getHash(&str);
}
}