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')
|
pkgc = import('pkgconfig')
|
||||||
|
|
||||||
dyaml_src = [
|
dyaml_src = [
|
||||||
'source/dyaml/anchor.d',
|
|
||||||
'source/dyaml/composer.d',
|
'source/dyaml/composer.d',
|
||||||
'source/dyaml/constructor.d',
|
'source/dyaml/constructor.d',
|
||||||
'source/dyaml/dumper.d',
|
'source/dyaml/dumper.d',
|
||||||
|
@ -36,7 +35,6 @@ dyaml_src = [
|
||||||
'source/dyaml/serializer.d',
|
'source/dyaml/serializer.d',
|
||||||
'source/dyaml/stream.d',
|
'source/dyaml/stream.d',
|
||||||
'source/dyaml/style.d',
|
'source/dyaml/style.d',
|
||||||
'source/dyaml/tag.d',
|
|
||||||
'source/dyaml/tagdirective.d',
|
'source/dyaml/tagdirective.d',
|
||||||
'source/dyaml/test/common.d',
|
'source/dyaml/test/common.d',
|
||||||
'source/dyaml/test/compare.d',
|
'source/dyaml/test/compare.d',
|
||||||
|
@ -49,8 +47,7 @@ dyaml_src = [
|
||||||
'source/dyaml/test/resolver.d',
|
'source/dyaml/test/resolver.d',
|
||||||
'source/dyaml/test/tokens.d',
|
'source/dyaml/test/tokens.d',
|
||||||
'source/dyaml/token.d',
|
'source/dyaml/token.d',
|
||||||
'source/dyaml/unused.d',
|
'source/dyaml/unused.d'
|
||||||
'source/dyaml/zerostring.d'
|
|
||||||
]
|
]
|
||||||
install_subdir('source/dyaml', install_dir: 'include/d/yaml/')
|
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.exception;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
|
|
||||||
import dyaml.anchor;
|
|
||||||
import dyaml.constructor;
|
import dyaml.constructor;
|
||||||
import dyaml.event;
|
import dyaml.event;
|
||||||
import dyaml.exception;
|
import dyaml.exception;
|
||||||
|
@ -48,7 +47,7 @@ final class Composer
|
||||||
///Constructor constructing YAML values.
|
///Constructor constructing YAML values.
|
||||||
Constructor constructor_;
|
Constructor constructor_;
|
||||||
///Nodes associated with anchors. Used by YAML aliases.
|
///Nodes associated with anchors. Used by YAML aliases.
|
||||||
Node[Anchor] anchors_;
|
Node[string] anchors_;
|
||||||
|
|
||||||
///Used to reduce allocations when creating pair arrays.
|
///Used to reduce allocations when creating pair arrays.
|
||||||
///
|
///
|
||||||
|
@ -182,14 +181,14 @@ final class Composer
|
||||||
immutable event = parser_.getEvent();
|
immutable event = parser_.getEvent();
|
||||||
const anchor = event.anchor;
|
const anchor = event.anchor;
|
||||||
enforce((anchor in anchors_) !is null,
|
enforce((anchor in anchors_) !is null,
|
||||||
new ComposerException("Found undefined alias: " ~ anchor.get,
|
new ComposerException("Found undefined alias: " ~ anchor,
|
||||||
event.startMark));
|
event.startMark));
|
||||||
|
|
||||||
//If the node referenced by the anchor is uninitialized,
|
//If the node referenced by the anchor is uninitialized,
|
||||||
//it's not finished, i.e. we're currently composing it
|
//it's not finished, i.e. we're currently composing it
|
||||||
//and trying to use it recursively here.
|
//and trying to use it recursively here.
|
||||||
enforce(anchors_[anchor] != Node(),
|
enforce(anchors_[anchor] != Node(),
|
||||||
new ComposerException("Found recursive alias: " ~ anchor.get,
|
new ComposerException("Found recursive alias: " ~ anchor,
|
||||||
event.startMark));
|
event.startMark));
|
||||||
|
|
||||||
return anchors_[anchor];
|
return anchors_[anchor];
|
||||||
|
@ -197,16 +196,16 @@ final class Composer
|
||||||
|
|
||||||
immutable event = parser_.peekEvent();
|
immutable event = parser_.peekEvent();
|
||||||
const anchor = event.anchor;
|
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);
|
event.startMark);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node result;
|
Node result;
|
||||||
//Associate the anchor, if any, with an uninitialized node.
|
//Associate the anchor, if any, with an uninitialized node.
|
||||||
//used to detect duplicate and recursive anchors.
|
//used to detect duplicate and recursive anchors.
|
||||||
if(!anchor.isNull())
|
if(anchor !is null)
|
||||||
{
|
{
|
||||||
anchors_[anchor] = Node();
|
anchors_[anchor] = Node();
|
||||||
}
|
}
|
||||||
|
@ -225,7 +224,7 @@ final class Composer
|
||||||
}
|
}
|
||||||
else{assert(false, "This code should never be reached");}
|
else{assert(false, "This code should never be reached");}
|
||||||
|
|
||||||
if(!anchor.isNull())
|
if(anchor !is null)
|
||||||
{
|
{
|
||||||
anchors_[anchor] = result;
|
anchors_[anchor] = result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ import std.utf;
|
||||||
|
|
||||||
import dyaml.node;
|
import dyaml.node;
|
||||||
import dyaml.exception;
|
import dyaml.exception;
|
||||||
import dyaml.tag;
|
|
||||||
import dyaml.style;
|
import dyaml.style;
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,11 +66,11 @@ final class Constructor
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// Constructor functions from scalars.
|
// Constructor functions from scalars.
|
||||||
Node.Value delegate(ref Node)[Tag] fromScalar_;
|
Node.Value delegate(ref Node)[string] fromScalar_;
|
||||||
// Constructor functions from sequences.
|
// Constructor functions from sequences.
|
||||||
Node.Value delegate(ref Node)[Tag] fromSequence_;
|
Node.Value delegate(ref Node)[string] fromSequence_;
|
||||||
// Constructor functions from mappings.
|
// Constructor functions from mappings.
|
||||||
Node.Value delegate(ref Node)[Tag] fromMapping_;
|
Node.Value delegate(ref Node)[string] fromMapping_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Construct a Constructor.
|
/// Construct a Constructor.
|
||||||
|
@ -185,7 +184,7 @@ final class Constructor
|
||||||
void addConstructorScalar(T)(const string tag, T function(ref Node) ctor)
|
void addConstructorScalar(T)(const string tag, T function(ref Node) ctor)
|
||||||
@safe nothrow
|
@safe nothrow
|
||||||
{
|
{
|
||||||
const t = Tag(tag);
|
const t = tag;
|
||||||
auto deleg = addConstructor!T(t, ctor);
|
auto deleg = addConstructor!T(t, ctor);
|
||||||
(*delegates!string)[t] = deleg;
|
(*delegates!string)[t] = deleg;
|
||||||
}
|
}
|
||||||
|
@ -236,7 +235,7 @@ final class Constructor
|
||||||
void addConstructorSequence(T)(const string tag, T function(ref Node) ctor)
|
void addConstructorSequence(T)(const string tag, T function(ref Node) ctor)
|
||||||
@safe nothrow
|
@safe nothrow
|
||||||
{
|
{
|
||||||
const t = Tag(tag);
|
const t = tag;
|
||||||
auto deleg = addConstructor!T(t, ctor);
|
auto deleg = addConstructor!T(t, ctor);
|
||||||
(*delegates!(Node[]))[t] = deleg;
|
(*delegates!(Node[]))[t] = deleg;
|
||||||
}
|
}
|
||||||
|
@ -287,7 +286,7 @@ final class Constructor
|
||||||
void addConstructorMapping(T)(const string tag, T function(ref Node) ctor)
|
void addConstructorMapping(T)(const string tag, T function(ref Node) ctor)
|
||||||
@safe nothrow
|
@safe nothrow
|
||||||
{
|
{
|
||||||
const t = Tag(tag);
|
const t = tag;
|
||||||
auto deleg = addConstructor!T(t, ctor);
|
auto deleg = addConstructor!T(t, ctor);
|
||||||
(*delegates!(Node.Pair[]))[t] = deleg;
|
(*delegates!(Node.Pair[]))[t] = deleg;
|
||||||
}
|
}
|
||||||
|
@ -304,7 +303,7 @@ final class Constructor
|
||||||
*
|
*
|
||||||
* Returns: Constructed node.
|
* 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
|
T value, U style) @trusted
|
||||||
if((is(T : string) || is(T == Node[]) || is(T == Node.Pair[])) &&
|
if((is(T : string) || is(T == Node[]) || is(T == Node.Pair[])) &&
|
||||||
(is(U : CollectionStyle) || is(U : ScalarStyle)))
|
(is(U : CollectionStyle) || is(U : ScalarStyle)))
|
||||||
|
@ -315,7 +314,7 @@ final class Constructor
|
||||||
"ERROR";
|
"ERROR";
|
||||||
enforce((tag in *delegates!T) !is null,
|
enforce((tag in *delegates!T) !is null,
|
||||||
new Error("No constructor function from " ~ type ~
|
new Error("No constructor function from " ~ type ~
|
||||||
" for tag " ~ tag.get(), start, end));
|
" for tag " ~ tag, start, end));
|
||||||
|
|
||||||
Node node = Node(value);
|
Node node = Node(value);
|
||||||
try
|
try
|
||||||
|
@ -346,13 +345,13 @@ final class Constructor
|
||||||
* Params: tag = Tag for the function to handle.
|
* Params: tag = Tag for the function to handle.
|
||||||
* ctor = Constructor function.
|
* 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
|
@safe nothrow
|
||||||
{
|
{
|
||||||
assert((tag in fromScalar_) is null &&
|
assert((tag in fromScalar_) is null &&
|
||||||
(tag in fromSequence_) is null &&
|
(tag in fromSequence_) is null &&
|
||||||
(tag in fromMapping_) 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.");
|
"specified. Can't specify another one.");
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ module dyaml.dumper;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
|
|
||||||
import dyaml.stream;
|
import dyaml.stream;
|
||||||
import dyaml.anchor;
|
|
||||||
import dyaml.emitter;
|
import dyaml.emitter;
|
||||||
import dyaml.encoding;
|
import dyaml.encoding;
|
||||||
import dyaml.event;
|
import dyaml.event;
|
||||||
|
|
|
@ -24,7 +24,6 @@ import std.typecons;
|
||||||
import std.utf;
|
import std.utf;
|
||||||
|
|
||||||
import dyaml.stream;
|
import dyaml.stream;
|
||||||
import dyaml.anchor;
|
|
||||||
import dyaml.encoding;
|
import dyaml.encoding;
|
||||||
import dyaml.escapes;
|
import dyaml.escapes;
|
||||||
import dyaml.event;
|
import dyaml.event;
|
||||||
|
@ -34,7 +33,6 @@ import dyaml.flags;
|
||||||
import dyaml.linebreak;
|
import dyaml.linebreak;
|
||||||
import dyaml.queue;
|
import dyaml.queue;
|
||||||
import dyaml.style;
|
import dyaml.style;
|
||||||
import dyaml.tag;
|
|
||||||
import dyaml.tagdirective;
|
import dyaml.tagdirective;
|
||||||
|
|
||||||
|
|
||||||
|
@ -500,7 +498,7 @@ struct Emitter
|
||||||
///Handle an alias.
|
///Handle an alias.
|
||||||
void expectAlias() @trusted
|
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("*");
|
processAnchor("*");
|
||||||
state_ = popState();
|
state_ = popState();
|
||||||
}
|
}
|
||||||
|
@ -707,8 +705,8 @@ struct Emitter
|
||||||
}
|
}
|
||||||
|
|
||||||
const event = events_.peek();
|
const event = events_.peek();
|
||||||
const emptyScalar = event.id == EventID.Scalar && event.anchor.isNull() &&
|
const emptyScalar = event.id == EventID.Scalar && (event.anchor is null) &&
|
||||||
event.tag.isNull() && event.implicit && event.value == "";
|
(event.tag is null) && event.implicit && event.value == "";
|
||||||
return emptyScalar;
|
return emptyScalar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,8 +719,8 @@ struct Emitter
|
||||||
const collectionStart = id == EventID.MappingStart ||
|
const collectionStart = id == EventID.MappingStart ||
|
||||||
id == EventID.SequenceStart;
|
id == EventID.SequenceStart;
|
||||||
|
|
||||||
if((id == EventID.Alias || scalar || collectionStart)
|
if((id == EventID.Alias || scalar || collectionStart)
|
||||||
&& !event_.anchor.isNull())
|
&& (event_.anchor !is null))
|
||||||
{
|
{
|
||||||
if(preparedAnchor_ is null)
|
if(preparedAnchor_ is null)
|
||||||
{
|
{
|
||||||
|
@ -731,7 +729,7 @@ struct Emitter
|
||||||
length += preparedAnchor_.length;
|
length += preparedAnchor_.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((scalar || collectionStart) && !event_.tag.isNull())
|
if((scalar || collectionStart) && (event_.tag !is null))
|
||||||
{
|
{
|
||||||
if(preparedTag_ is null){preparedTag_ = prepareTag(event_.tag);}
|
if(preparedTag_ is null){preparedTag_ = prepareTag(event_.tag);}
|
||||||
length += preparedTag_.length;
|
length += preparedTag_.length;
|
||||||
|
@ -784,7 +782,7 @@ struct Emitter
|
||||||
///Process and write an anchor/alias.
|
///Process and write an anchor/alias.
|
||||||
void processAnchor(const string indicator) @trusted
|
void processAnchor(const string indicator) @trusted
|
||||||
{
|
{
|
||||||
if(event_.anchor.isNull())
|
if(event_.anchor is null)
|
||||||
{
|
{
|
||||||
preparedAnchor_ = null;
|
preparedAnchor_ = null;
|
||||||
return;
|
return;
|
||||||
|
@ -804,30 +802,30 @@ struct Emitter
|
||||||
///Process and write a tag.
|
///Process and write a tag.
|
||||||
void processTag() @trusted
|
void processTag() @trusted
|
||||||
{
|
{
|
||||||
Tag tag = event_.tag;
|
string tag = event_.tag;
|
||||||
|
|
||||||
if(event_.id == EventID.Scalar)
|
if(event_.id == EventID.Scalar)
|
||||||
{
|
{
|
||||||
if(style_ == ScalarStyle.Invalid){style_ = chooseScalarStyle();}
|
if(style_ == ScalarStyle.Invalid){style_ = chooseScalarStyle();}
|
||||||
if((!canonical_ || tag.isNull()) &&
|
if((!canonical_ || (tag is null)) &&
|
||||||
(style_ == ScalarStyle.Plain ? event_.implicit : event_.implicit_2))
|
(style_ == ScalarStyle.Plain ? event_.implicit : event_.implicit_2))
|
||||||
{
|
{
|
||||||
preparedTag_ = null;
|
preparedTag_ = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(event_.implicit && tag.isNull())
|
if(event_.implicit && (tag is null))
|
||||||
{
|
{
|
||||||
tag = Tag("!");
|
tag = "!";
|
||||||
preparedTag_ = null;
|
preparedTag_ = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if((!canonical_ || tag.isNull()) && event_.implicit)
|
else if((!canonical_ || (tag is null)) && event_.implicit)
|
||||||
{
|
{
|
||||||
preparedTag_ = null;
|
preparedTag_ = null;
|
||||||
return;
|
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_ = prepareTag(tag);}
|
||||||
if(preparedTag_ !is null && preparedTag_ != "")
|
if(preparedTag_ !is null && preparedTag_ != "")
|
||||||
{
|
{
|
||||||
|
@ -946,11 +944,11 @@ struct Emitter
|
||||||
}
|
}
|
||||||
|
|
||||||
///Prepare tag for output.
|
///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;}
|
if(tagString == "!"){return tagString;}
|
||||||
string handle = null;
|
string handle = null;
|
||||||
string suffix = tagString;
|
string suffix = tagString;
|
||||||
|
@ -993,11 +991,11 @@ struct Emitter
|
||||||
}
|
}
|
||||||
|
|
||||||
///Prepare anchor for output.
|
///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"));
|
new Error("Anchor must not be empty"));
|
||||||
const str = anchor.get;
|
const str = anchor;
|
||||||
foreach(const dchar c; str)
|
foreach(const dchar c; str)
|
||||||
{
|
{
|
||||||
enforce(isAlphaNum(c) || "-_"d.canFind(c),
|
enforce(isAlphaNum(c) || "-_"d.canFind(c),
|
||||||
|
|
|
@ -14,11 +14,9 @@ import std.array;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
|
|
||||||
import dyaml.anchor;
|
|
||||||
import dyaml.encoding;
|
import dyaml.encoding;
|
||||||
import dyaml.exception;
|
import dyaml.exception;
|
||||||
import dyaml.reader;
|
import dyaml.reader;
|
||||||
import dyaml.tag;
|
|
||||||
import dyaml.tagdirective;
|
import dyaml.tagdirective;
|
||||||
import dyaml.style;
|
import dyaml.style;
|
||||||
|
|
||||||
|
@ -60,9 +58,9 @@ struct Event
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
///Anchor of the event, if any.
|
///Anchor of the event, if any.
|
||||||
Anchor anchor;
|
string anchor;
|
||||||
///Tag of the event, if any.
|
///Tag of the event, if any.
|
||||||
Tag tag;
|
string tag;
|
||||||
}
|
}
|
||||||
///Tag directives, if this is a DocumentStart.
|
///Tag directives, if this is a DocumentStart.
|
||||||
//TagDirectives tagDirectives;
|
//TagDirectives tagDirectives;
|
||||||
|
@ -96,7 +94,7 @@ struct Event
|
||||||
///Get string representation of the token ID.
|
///Get string representation of the token ID.
|
||||||
@property string idString() const @system {return to!string(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.
|
* end = End position of the event in the file/stream.
|
||||||
* anchor = Anchor, if this is an alias event.
|
* 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
|
pure @trusted nothrow
|
||||||
{
|
{
|
||||||
Event result;
|
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?
|
* implicit = Should the tag be implicitly resolved?
|
||||||
*/
|
*/
|
||||||
Event collectionStartEvent(EventID id)
|
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
|
const bool implicit, const CollectionStyle style) pure @trusted nothrow
|
||||||
{
|
{
|
||||||
static assert(id == EventID.SequenceStart || id == EventID.SequenceEnd ||
|
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?
|
/// implicit = Should the tag be implicitly resolved?
|
||||||
/// value = String value of the scalar.
|
/// value = String value of the scalar.
|
||||||
/// style = Scalar style.
|
/// 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 Tuple!(bool, bool) implicit, const string value,
|
||||||
const ScalarStyle style = ScalarStyle.Invalid) @safe pure nothrow @nogc
|
const ScalarStyle style = ScalarStyle.Invalid) @safe pure nothrow @nogc
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,8 +25,6 @@ import std.variant;
|
||||||
import dyaml.event;
|
import dyaml.event;
|
||||||
import dyaml.exception;
|
import dyaml.exception;
|
||||||
import dyaml.style;
|
import dyaml.style;
|
||||||
import dyaml.tag;
|
|
||||||
|
|
||||||
|
|
||||||
/// Exception thrown at node related errors.
|
/// Exception thrown at node related errors.
|
||||||
class NodeException : YAMLException
|
class NodeException : YAMLException
|
||||||
|
@ -212,14 +210,14 @@ struct Node
|
||||||
|
|
||||||
package:
|
package:
|
||||||
// Tag of the node.
|
// Tag of the node.
|
||||||
Tag tag_;
|
string tag_;
|
||||||
// Node scalar style. Used to remember style this node was loaded with.
|
// Node scalar style. Used to remember style this node was loaded with.
|
||||||
ScalarStyle scalarStyle = ScalarStyle.Invalid;
|
ScalarStyle scalarStyle = ScalarStyle.Invalid;
|
||||||
// Node collection style. Used to remember style this node was loaded with.
|
// Node collection style. Used to remember style this node was loaded with.
|
||||||
CollectionStyle collectionStyle = CollectionStyle.Invalid;
|
CollectionStyle collectionStyle = CollectionStyle.Invalid;
|
||||||
|
|
||||||
static assert(Value.sizeof <= 24, "Unexpected YAML value size");
|
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.
|
// 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
|
this(T)(T value, const string tag = null) @trusted
|
||||||
if(!scalarCtorNothrow!T && (!isArray!T && !isAssociativeArray!T))
|
if(!scalarCtorNothrow!T && (!isArray!T && !isAssociativeArray!T))
|
||||||
{
|
{
|
||||||
tag_ = Tag(tag);
|
tag_ = tag;
|
||||||
|
|
||||||
// No copyconstruction.
|
// No copyconstruction.
|
||||||
static assert(!is(Unqual!T == Node));
|
static assert(!is(Unqual!T == Node));
|
||||||
|
@ -270,7 +268,7 @@ struct Node
|
||||||
this(T)(T value, const string tag = null) @trusted pure nothrow
|
this(T)(T value, const string tag = null) @trusted pure nothrow
|
||||||
if(scalarCtorNothrow!T)
|
if(scalarCtorNothrow!T)
|
||||||
{
|
{
|
||||||
tag_ = Tag(tag);
|
tag_ = tag;
|
||||||
// We can easily store ints, floats, strings.
|
// We can easily store ints, floats, strings.
|
||||||
static if(isIntegral!T) { value_ = Value(cast(long)value); }
|
static if(isIntegral!T) { value_ = Value(cast(long)value); }
|
||||||
else static if(is(Unqual!T==bool)){ value_ = Value(cast(bool)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
|
this(T)(T[] array, const string tag = null) @trusted
|
||||||
if (!isSomeString!(T[]))
|
if (!isSomeString!(T[]))
|
||||||
{
|
{
|
||||||
tag_ = Tag(tag);
|
tag_ = tag;
|
||||||
|
|
||||||
// Construction from raw node or pair array.
|
// Construction from raw node or pair array.
|
||||||
static if(is(Unqual!T == Node) || is(Unqual!T == Node.Pair))
|
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
|
this(K, V)(V[K] array, const string tag = null) @trusted
|
||||||
{
|
{
|
||||||
tag_ = Tag(tag);
|
tag_ = tag;
|
||||||
|
|
||||||
Node.Pair[] pairs;
|
Node.Pair[] pairs;
|
||||||
foreach(key, ref value; array){pairs ~= Pair(key, value);}
|
foreach(key, ref value; array){pairs ~= Pair(key, value);}
|
||||||
|
@ -461,7 +459,7 @@ struct Node
|
||||||
}
|
}
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
tag_ = Tag(tag);
|
tag_ = tag;
|
||||||
|
|
||||||
Node.Pair[] pairs;
|
Node.Pair[] pairs;
|
||||||
foreach(i; 0 .. keys.length){pairs ~= Pair(keys[i], values[i]);}
|
foreach(i; 0 .. keys.length){pairs ~= Pair(keys[i], values[i]);}
|
||||||
|
@ -521,7 +519,7 @@ struct Node
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return tag of the 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.
|
/** Equality test.
|
||||||
*
|
*
|
||||||
|
@ -1634,9 +1632,9 @@ struct Node
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute hash of the 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.
|
// Variant toHash is not const at the moment, so we need to const-cast.
|
||||||
return tagHash + value_.toHash();
|
return tagHash + value_.toHash();
|
||||||
}
|
}
|
||||||
|
@ -1655,7 +1653,7 @@ struct Node
|
||||||
// collectionStyle = Collection style of the node.
|
// collectionStyle = Collection style of the node.
|
||||||
//
|
//
|
||||||
// Returns: Constructed 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 ScalarStyle scalarStyle,
|
||||||
const CollectionStyle collectionStyle) @trusted
|
const CollectionStyle collectionStyle) @trusted
|
||||||
{
|
{
|
||||||
|
@ -1739,8 +1737,8 @@ struct Node
|
||||||
// Compare tags - if equal or both null, we need to compare further.
|
// Compare tags - if equal or both null, we need to compare further.
|
||||||
static if(useTag)
|
static if(useTag)
|
||||||
{
|
{
|
||||||
const tagCmp = tag_.isNull ? rhs.tag_.isNull ? 0 : -1
|
const tagCmp = (tag_ is null) ? (rhs.tag_ is null) ? 0 : -1
|
||||||
: rhs.tag_.isNull ? 1 : tag_.opCmp(rhs.tag_);
|
: (rhs.tag_ is null) ? 1 : std.algorithm.comparison.cmp(tag_, rhs.tag_);
|
||||||
if(tagCmp != 0){return tagCmp;}
|
if(tagCmp != 0){return tagCmp;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,13 +18,11 @@ import std.conv;
|
||||||
import std.exception;
|
import std.exception;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
|
|
||||||
import dyaml.anchor;
|
|
||||||
import dyaml.event;
|
import dyaml.event;
|
||||||
import dyaml.exception;
|
import dyaml.exception;
|
||||||
import dyaml.scanner;
|
import dyaml.scanner;
|
||||||
import dyaml.style;
|
import dyaml.style;
|
||||||
import dyaml.token;
|
import dyaml.token;
|
||||||
import dyaml.tag;
|
|
||||||
import dyaml.tagdirective;
|
import dyaml.tagdirective;
|
||||||
|
|
||||||
|
|
||||||
|
@ -422,8 +420,8 @@ final class Parser
|
||||||
{
|
{
|
||||||
const token = scanner_.getToken();
|
const token = scanner_.getToken();
|
||||||
state_ = popState();
|
state_ = popState();
|
||||||
return aliasEvent(token.startMark, token.endMark,
|
return aliasEvent(token.startMark, token.endMark,
|
||||||
Anchor(cast(string)token.value));
|
cast(string)token.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
string anchor = null;
|
string anchor = null;
|
||||||
|
@ -467,8 +465,8 @@ final class Parser
|
||||||
{
|
{
|
||||||
state_ = &parseIndentlessSequenceEntry;
|
state_ = &parseIndentlessSequenceEntry;
|
||||||
return sequenceStartEvent
|
return sequenceStartEvent
|
||||||
(startMark, scanner_.peekToken().endMark, Anchor(anchor),
|
(startMark, scanner_.peekToken().endMark, anchor,
|
||||||
Tag(tag), implicit, CollectionStyle.Block);
|
tag, implicit, CollectionStyle.Block);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(scanner_.checkToken(TokenID.Scalar))
|
if(scanner_.checkToken(TokenID.Scalar))
|
||||||
|
@ -481,7 +479,7 @@ final class Parser
|
||||||
implicit = (token.style == ScalarStyle.Plain && tag is null) || tag == "!";
|
implicit = (token.style == ScalarStyle.Plain && tag is null) || tag == "!";
|
||||||
bool implicit_2 = (!implicit) && tag is null;
|
bool implicit_2 = (!implicit) && tag is null;
|
||||||
state_ = popState();
|
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);
|
tuple(implicit, implicit_2), value, token.style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,7 +487,7 @@ final class Parser
|
||||||
{
|
{
|
||||||
endMark = scanner_.peekToken().endMark;
|
endMark = scanner_.peekToken().endMark;
|
||||||
state_ = &parseFlowSequenceEntry!(Yes.first);
|
state_ = &parseFlowSequenceEntry!(Yes.first);
|
||||||
return sequenceStartEvent(startMark, endMark, Anchor(anchor), Tag(tag),
|
return sequenceStartEvent(startMark, endMark, anchor, tag,
|
||||||
implicit, CollectionStyle.Flow);
|
implicit, CollectionStyle.Flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,7 +495,7 @@ final class Parser
|
||||||
{
|
{
|
||||||
endMark = scanner_.peekToken().endMark;
|
endMark = scanner_.peekToken().endMark;
|
||||||
state_ = &parseFlowMappingKey!(Yes.first);
|
state_ = &parseFlowMappingKey!(Yes.first);
|
||||||
return mappingStartEvent(startMark, endMark, Anchor(anchor), Tag(tag),
|
return mappingStartEvent(startMark, endMark, anchor, tag,
|
||||||
implicit, CollectionStyle.Flow);
|
implicit, CollectionStyle.Flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,7 +503,7 @@ final class Parser
|
||||||
{
|
{
|
||||||
endMark = scanner_.peekToken().endMark;
|
endMark = scanner_.peekToken().endMark;
|
||||||
state_ = &parseBlockSequenceEntry!(Yes.first);
|
state_ = &parseBlockSequenceEntry!(Yes.first);
|
||||||
return sequenceStartEvent(startMark, endMark, Anchor(anchor), Tag(tag),
|
return sequenceStartEvent(startMark, endMark, anchor, tag,
|
||||||
implicit, CollectionStyle.Block);
|
implicit, CollectionStyle.Block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,11 +511,11 @@ final class Parser
|
||||||
{
|
{
|
||||||
endMark = scanner_.peekToken().endMark;
|
endMark = scanner_.peekToken().endMark;
|
||||||
state_ = &parseBlockMappingKey!(Yes.first);
|
state_ = &parseBlockMappingKey!(Yes.first);
|
||||||
return mappingStartEvent(startMark, endMark, Anchor(anchor), Tag(tag),
|
return mappingStartEvent(startMark, endMark, anchor, tag,
|
||||||
implicit, CollectionStyle.Block);
|
implicit, CollectionStyle.Block);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(anchor != null || tag !is null)
|
if(anchor !is null || tag !is null)
|
||||||
{
|
{
|
||||||
state_ = popState();
|
state_ = popState();
|
||||||
|
|
||||||
|
@ -525,7 +523,7 @@ final class Parser
|
||||||
//but the second bool is never used after that - so we don't use it.
|
//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.
|
//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) , "");
|
tuple(implicit, false) , "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,7 +813,7 @@ final class Parser
|
||||||
const token = scanner_.peekToken();
|
const token = scanner_.peekToken();
|
||||||
state_ = &parseFlowSequenceEntryMappingKey;
|
state_ = &parseFlowSequenceEntryMappingKey;
|
||||||
return mappingStartEvent(token.startMark, token.endMark,
|
return mappingStartEvent(token.startMark, token.endMark,
|
||||||
Anchor(), Tag(), true, CollectionStyle.Flow);
|
null, null, true, CollectionStyle.Flow);
|
||||||
}
|
}
|
||||||
else if(!scanner_.checkToken(TokenID.FlowSequenceEnd))
|
else if(!scanner_.checkToken(TokenID.FlowSequenceEnd))
|
||||||
{
|
{
|
||||||
|
@ -952,6 +950,6 @@ final class Parser
|
||||||
///Return an empty scalar.
|
///Return an empty scalar.
|
||||||
Event processEmptyScalar(const Mark mark) @safe pure nothrow const @nogc
|
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.node;
|
||||||
import dyaml.serializer;
|
import dyaml.serializer;
|
||||||
import dyaml.style;
|
import dyaml.style;
|
||||||
import dyaml.tag;
|
|
||||||
|
|
||||||
|
|
||||||
///Exception thrown on Representer errors.
|
///Exception thrown on Representer errors.
|
||||||
|
@ -277,7 +276,7 @@ final class Representer
|
||||||
ScalarStyle style = ScalarStyle.Invalid) @trusted
|
ScalarStyle style = ScalarStyle.Invalid) @trusted
|
||||||
{
|
{
|
||||||
if(style == ScalarStyle.Invalid){style = defaultScalarStyle_;}
|
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);
|
CollectionStyle.Invalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,7 +345,7 @@ final class Representer
|
||||||
? defaultCollectionStyle_
|
? defaultCollectionStyle_
|
||||||
: bestStyle;
|
: bestStyle;
|
||||||
}
|
}
|
||||||
return Node.rawNode(Node.Value(value), Mark(), Tag(tag),
|
return Node.rawNode(Node.Value(value), Mark(), tag,
|
||||||
ScalarStyle.Invalid, style);
|
ScalarStyle.Invalid, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +422,7 @@ final class Representer
|
||||||
? defaultCollectionStyle_
|
? defaultCollectionStyle_
|
||||||
: bestStyle;
|
: bestStyle;
|
||||||
}
|
}
|
||||||
return Node.rawNode(Node.Value(value), Mark(), Tag(tag),
|
return Node.rawNode(Node.Value(value), Mark(), tag,
|
||||||
ScalarStyle.Invalid, style);
|
ScalarStyle.Invalid, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,7 +439,7 @@ final class Representer
|
||||||
Node result = representers_[type](data, this);
|
Node result = representers_[type](data, this);
|
||||||
|
|
||||||
//Override tag if specified.
|
//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.
|
//Remember style if this was loaded before.
|
||||||
if(data.scalarStyle != ScalarStyle.Invalid)
|
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
|
Node representNodes(ref Node node, Representer representer) @safe
|
||||||
{
|
{
|
||||||
auto nodes = node.as!(Node[]);
|
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.
|
///YAML sets are mapping with null values.
|
||||||
Node.Pair[] pairs;
|
Node.Pair[] pairs;
|
||||||
|
@ -537,7 +536,7 @@ Node representNodes(ref Node node, Representer representer) @safe
|
||||||
{
|
{
|
||||||
pairs[idx] = Node.Pair(key, representNull(dummy, representer));
|
pairs[idx] = Node.Pair(key, representNull(dummy, representer));
|
||||||
}
|
}
|
||||||
return representer.representMapping(node.tag_.get, pairs);
|
return representer.representMapping(node.tag_, pairs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -574,15 +573,15 @@ Node representPairs(ref Node node, Representer representer) @system
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node.tag_ == Tag("tag:yaml.org,2002:omap"))
|
if(node.tag_ == "tag:yaml.org,2002:omap")
|
||||||
{
|
{
|
||||||
enforce(!hasDuplicates(pairs),
|
enforce(!hasDuplicates(pairs),
|
||||||
new RepresenterException("Duplicate entry in an ordered map"));
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,7 +23,6 @@ import std.utf;
|
||||||
|
|
||||||
import dyaml.node;
|
import dyaml.node;
|
||||||
import dyaml.exception;
|
import dyaml.exception;
|
||||||
import dyaml.tag;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,11 +34,11 @@ final class Resolver
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// Default tag to use for scalars.
|
// Default tag to use for scalars.
|
||||||
Tag defaultScalarTag_;
|
string defaultScalarTag_;
|
||||||
// Default tag to use for sequences.
|
// Default tag to use for sequences.
|
||||||
Tag defaultSequenceTag_;
|
string defaultSequenceTag_;
|
||||||
// Default tag to use for mappings.
|
// Default tag to use for mappings.
|
||||||
Tag defaultMappingTag_;
|
string defaultMappingTag_;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Arrays of scalar resolver tuples indexed by starting character of a scalar.
|
* 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,
|
* Each tuple stores regular expression the scalar must match,
|
||||||
* and tag to assign to it if it matches.
|
* and tag to assign to it if it matches.
|
||||||
*/
|
*/
|
||||||
Tuple!(Tag, Regex!char)[][dchar] yamlImplicitResolvers_;
|
Tuple!(string, Regex!char)[][dchar] yamlImplicitResolvers_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@disable bool opEquals(ref Resolver);
|
@disable bool opEquals(ref Resolver);
|
||||||
|
@ -64,9 +63,9 @@ final class Resolver
|
||||||
this(Flag!"useDefaultImplicitResolvers" defaultImplicitResolvers = Yes.useDefaultImplicitResolvers)
|
this(Flag!"useDefaultImplicitResolvers" defaultImplicitResolvers = Yes.useDefaultImplicitResolvers)
|
||||||
@safe
|
@safe
|
||||||
{
|
{
|
||||||
defaultScalarTag_ = Tag("tag:yaml.org,2002:str");
|
defaultScalarTag_ = "tag:yaml.org,2002:str";
|
||||||
defaultSequenceTag_ = Tag("tag:yaml.org,2002:seq");
|
defaultSequenceTag_ = "tag:yaml.org,2002:seq";
|
||||||
defaultMappingTag_ = Tag("tag:yaml.org,2002:map");
|
defaultMappingTag_ = "tag:yaml.org,2002:map";
|
||||||
if(defaultImplicitResolvers){addImplicitResolvers();}
|
if(defaultImplicitResolvers){addImplicitResolvers();}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +124,7 @@ final class Resolver
|
||||||
{
|
{
|
||||||
yamlImplicitResolvers_[c] = [];
|
yamlImplicitResolvers_[c] = [];
|
||||||
}
|
}
|
||||||
yamlImplicitResolvers_[c] ~= tuple(Tag(tag), regexp);
|
yamlImplicitResolvers_[c] ~= tuple(tag, regexp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,10 +142,10 @@ final class Resolver
|
||||||
*
|
*
|
||||||
* Returns: Resolved tag.
|
* 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
|
const bool implicit) @safe
|
||||||
{
|
{
|
||||||
if(!tag.isNull() && tag.get() != "!"){return tag;}
|
if((tag !is null) && tag != "!"){return tag;}
|
||||||
|
|
||||||
if(kind == NodeID.Scalar)
|
if(kind == NodeID.Scalar)
|
||||||
{
|
{
|
||||||
|
@ -178,10 +177,10 @@ final class Resolver
|
||||||
|
|
||||||
bool tagMatch(string tag, string[] values)
|
bool tagMatch(string tag, string[] values)
|
||||||
{
|
{
|
||||||
Tag expected = Tag(tag);
|
string expected = tag;
|
||||||
foreach(value; values)
|
foreach(value; values)
|
||||||
{
|
{
|
||||||
Tag resolved = resolver.resolve(NodeID.Scalar, Tag(), value, true);
|
string resolved = resolver.resolve(NodeID.Scalar, null, value, true);
|
||||||
if(expected != resolved)
|
if(expected != resolved)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -213,13 +212,13 @@ final class Resolver
|
||||||
}
|
}
|
||||||
|
|
||||||
///Return default scalar tag.
|
///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.
|
///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.
|
///Return default mapping tag.
|
||||||
@property Tag defaultMappingTag() const pure @safe nothrow {return defaultMappingTag_;}
|
@property string defaultMappingTag() const pure @safe nothrow {return defaultMappingTag_;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Add default implicit resolvers.
|
// Add default implicit resolvers.
|
||||||
|
|
|
@ -15,14 +15,12 @@ import std.array;
|
||||||
import std.format;
|
import std.format;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
|
|
||||||
import dyaml.anchor;
|
|
||||||
import dyaml.emitter;
|
import dyaml.emitter;
|
||||||
import dyaml.encoding;
|
import dyaml.encoding;
|
||||||
import dyaml.event;
|
import dyaml.event;
|
||||||
import dyaml.exception;
|
import dyaml.exception;
|
||||||
import dyaml.node;
|
import dyaml.node;
|
||||||
import dyaml.resolver;
|
import dyaml.resolver;
|
||||||
import dyaml.tag;
|
|
||||||
import dyaml.tagdirective;
|
import dyaml.tagdirective;
|
||||||
import dyaml.token;
|
import dyaml.token;
|
||||||
|
|
||||||
|
@ -50,7 +48,7 @@ struct Serializer
|
||||||
|
|
||||||
//TODO Use something with more deterministic memory usage.
|
//TODO Use something with more deterministic memory usage.
|
||||||
///Nodes with assigned anchors.
|
///Nodes with assigned anchors.
|
||||||
Anchor[Node] anchors_;
|
string[Node] anchors_;
|
||||||
///Nodes with assigned anchors that are already serialized.
|
///Nodes with assigned anchors that are already serialized.
|
||||||
bool[Node] serializedNodes_;
|
bool[Node] serializedNodes_;
|
||||||
///ID of the last anchor generated.
|
///ID of the last anchor generated.
|
||||||
|
@ -105,7 +103,7 @@ struct Serializer
|
||||||
emitter_.emit(documentEndEvent(Mark(), Mark(), explicitEnd_));
|
emitter_.emit(documentEndEvent(Mark(), Mark(), explicitEnd_));
|
||||||
serializedNodes_.destroy();
|
serializedNodes_.destroy();
|
||||||
anchors_.destroy();
|
anchors_.destroy();
|
||||||
Anchor[Node] emptyAnchors;
|
string[Node] emptyAnchors;
|
||||||
anchors_ = emptyAnchors;
|
anchors_ = emptyAnchors;
|
||||||
lastAnchorID_ = 0;
|
lastAnchorID_ = 0;
|
||||||
}
|
}
|
||||||
|
@ -139,14 +137,14 @@ struct Serializer
|
||||||
|
|
||||||
if((node in anchors_) !is null)
|
if((node in anchors_) !is null)
|
||||||
{
|
{
|
||||||
if(anchors_[node].isNull())
|
if(anchors_[node] is null)
|
||||||
{
|
{
|
||||||
anchors_[node] = generateAnchor();
|
anchors_[node] = generateAnchor();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
anchors_[node] = Anchor(null);
|
anchors_[node] = null;
|
||||||
if(node.isSequence) foreach(ref Node item; node)
|
if(node.isSequence) foreach(ref Node item; node)
|
||||||
{
|
{
|
||||||
anchorNode(item);
|
anchorNode(item);
|
||||||
|
@ -159,12 +157,12 @@ struct Serializer
|
||||||
}
|
}
|
||||||
|
|
||||||
///Generate and return a new anchor.
|
///Generate and return a new anchor.
|
||||||
Anchor generateAnchor() @trusted
|
string generateAnchor() @trusted
|
||||||
{
|
{
|
||||||
++lastAnchorID_;
|
++lastAnchorID_;
|
||||||
auto appender = appender!string();
|
auto appender = appender!string();
|
||||||
formattedWrite(appender, "id%03d", lastAnchorID_);
|
formattedWrite(appender, "id%03d", lastAnchorID_);
|
||||||
return Anchor(appender.data);
|
return appender.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
///Serialize a node and all its subnodes.
|
///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
|
//If the node has an anchor, emit an anchor (as aliasEvent) on the
|
||||||
//first occurrence, save it in serializedNodes_, and emit an alias
|
//first occurrence, save it in serializedNodes_, and emit an alias
|
||||||
//if it reappears.
|
//if it reappears.
|
||||||
Anchor aliased = Anchor(null);
|
string aliased = null;
|
||||||
if(anchorable(node) && (node in anchors_) !is null)
|
if(anchorable(node) && (node in anchors_) !is null)
|
||||||
{
|
{
|
||||||
aliased = anchors_[node];
|
aliased = anchors_[node];
|
||||||
|
@ -189,8 +187,8 @@ struct Serializer
|
||||||
{
|
{
|
||||||
assert(node.isType!string, "Scalar node type must be string before serialized");
|
assert(node.isType!string, "Scalar node type must be string before serialized");
|
||||||
auto value = node.as!string;
|
auto value = node.as!string;
|
||||||
const detectedTag = resolver_.resolve(NodeID.Scalar, Tag(null), value, true);
|
const detectedTag = resolver_.resolve(NodeID.Scalar, null, value, true);
|
||||||
const defaultTag = resolver_.resolve(NodeID.Scalar, Tag(null), value, false);
|
const defaultTag = resolver_.resolve(NodeID.Scalar, null, value, false);
|
||||||
bool isDetected = node.tag_ == detectedTag;
|
bool isDetected = node.tag_ == detectedTag;
|
||||||
bool isDefault = node.tag_ == defaultTag;
|
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.string;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
|
|
||||||
import dyaml.tag;
|
|
||||||
import dyaml.test.common;
|
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