diff --git a/meson.build b/meson.build index 0514a4f..904e15d 100644 --- a/meson.build +++ b/meson.build @@ -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/') diff --git a/source/dyaml/anchor.d b/source/dyaml/anchor.d deleted file mode 100644 index 967af74..0000000 --- a/source/dyaml/anchor.d +++ /dev/null @@ -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; diff --git a/source/dyaml/composer.d b/source/dyaml/composer.d index 70f08f6..a9da3d7 100644 --- a/source/dyaml/composer.d +++ b/source/dyaml/composer.d @@ -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; } diff --git a/source/dyaml/constructor.d b/source/dyaml/constructor.d index 51fa15c..ff1ddbe 100644 --- a/source/dyaml/constructor.d +++ b/source/dyaml/constructor.d @@ -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."); diff --git a/source/dyaml/dumper.d b/source/dyaml/dumper.d index 46bb8c1..47fb463 100644 --- a/source/dyaml/dumper.d +++ b/source/dyaml/dumper.d @@ -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; diff --git a/source/dyaml/emitter.d b/source/dyaml/emitter.d index cbe1177..d96320c 100644 --- a/source/dyaml/emitter.d +++ b/source/dyaml/emitter.d @@ -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; } @@ -721,8 +719,8 @@ struct Emitter const collectionStart = id == EventID.MappingStart || id == EventID.SequenceStart; - if((id == EventID.Alias || scalar || collectionStart) - && !event_.anchor.isNull()) + if((id == EventID.Alias || scalar || collectionStart) + && (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), diff --git a/source/dyaml/event.d b/source/dyaml/event.d index 40afe2f..dac8492 100644 --- a/source/dyaml/event.d +++ b/source/dyaml/event.d @@ -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 { diff --git a/source/dyaml/node.d b/source/dyaml/node.d index 368cfe9..8f950f5 100644 --- a/source/dyaml/node.d +++ b/source/dyaml/node.d @@ -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;} } diff --git a/source/dyaml/parser.d b/source/dyaml/parser.d index b570291..710dcd8 100644 --- a/source/dyaml/parser.d +++ b/source/dyaml/parser.d @@ -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; @@ -422,8 +420,8 @@ final class Parser { const token = scanner_.getToken(); state_ = popState(); - return aliasEvent(token.startMark, token.endMark, - Anchor(cast(string)token.value)); + return aliasEvent(token.startMark, token.endMark, + 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), ""); } } diff --git a/source/dyaml/representer.d b/source/dyaml/representer.d index daedb0b..916f8ce 100644 --- a/source/dyaml/representer.d +++ b/source/dyaml/representer.d @@ -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 { diff --git a/source/dyaml/resolver.d b/source/dyaml/resolver.d index 9344c7e..2f41c59 100644 --- a/source/dyaml/resolver.d +++ b/source/dyaml/resolver.d @@ -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, - const bool implicit) @safe + 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. diff --git a/source/dyaml/serializer.d b/source/dyaml/serializer.d index b483b5c..dd5ea0d 100644 --- a/source/dyaml/serializer.d +++ b/source/dyaml/serializer.d @@ -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; diff --git a/source/dyaml/tag.d b/source/dyaml/tag.d deleted file mode 100644 index 467f385..0000000 --- a/source/dyaml/tag.d +++ /dev/null @@ -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; diff --git a/source/dyaml/test/constructor.d b/source/dyaml/test/constructor.d index 628fa8a..854a89e 100644 --- a/source/dyaml/test/constructor.d +++ b/source/dyaml/test/constructor.d @@ -16,7 +16,6 @@ import std.path; import std.string; import std.typecons; -import dyaml.tag; import dyaml.test.common; diff --git a/source/dyaml/zerostring.d b/source/dyaml/zerostring.d deleted file mode 100644 index 21ee438..0000000 --- a/source/dyaml/zerostring.d +++ /dev/null @@ -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); - } -}