remove zerostring (#94)
remove zerostring merged-on-behalf-of: BBasile <BBasile@users.noreply.github.com>
This commit is contained in:
parent
72995df864
commit
683335aa3e
|
@ -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/')
|
||||
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.");
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;}
|
||||
}
|
||||
|
||||
|
|
|
@ -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), "");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
|
@ -16,7 +16,6 @@ import std.path;
|
|||
import std.string;
|
||||
import std.typecons;
|
||||
|
||||
import dyaml.tag;
|
||||
import dyaml.test.common;
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue