diff --git a/dyaml/constructor.d b/dyaml/constructor.d index 9c4beab..55c2ed2 100644 --- a/dyaml/constructor.d +++ b/dyaml/constructor.d @@ -500,8 +500,7 @@ ubyte[] constructBinary(Mark start, Mark end, ref Node node) try{return Base64.decode(value.removechars("\n"));} catch(Exception e) { - throw new Error("Unable to decode base64 value: " ~ e.msg, - start, end); + throw new Error("Unable to decode base64 value: " ~ e.msg, start, end); } } catch(UtfException e) diff --git a/dyaml/emitter.d b/dyaml/emitter.d index 7b05b03..d3027c9 100644 --- a/dyaml/emitter.d +++ b/dyaml/emitter.d @@ -93,7 +93,7 @@ struct Emitter Event event_; ///Stack of previous indentation levels. - int[] indents_; + Array!int indents_; ///Current indentation level. int indent_ = -1; @@ -161,6 +161,7 @@ struct Emitter body { states_.reserve(32); + indents_.reserve(32); stream_ = stream; canonical_ = canonical; state_ = &expectStreamStart; @@ -179,7 +180,6 @@ struct Emitter clear(states_); clear(events_); clear(indents_); - indents_ = null; clear(tagDirectives_); tagDirectives_ = null; clear(preparedAnchor_); @@ -217,8 +217,8 @@ struct Emitter enforce(indents_.length > 0, new YAMLException("Emitter: Need to pop an indent level but there" " are no indent levels left")); - const result = indents_.back(); - indents_.popBack; + const result = indents_.back; + indents_.length = indents_.length - 1; return result; } @@ -1328,7 +1328,7 @@ struct ScalarWriter emitter_.writeIndent(); } } - else if((c == dcharNone || "\' "d.canFind(c) || newlineSearch_.canFind(c)) + else if((c == dcharNone || c == '\'' || c == ' ' || newlineSearch_.canFind(c)) && startChar_ < endChar_) { writeCurrentRange(Flag!"UpdateColumn".yes); @@ -1342,6 +1342,7 @@ struct ScalarWriter } updateBreaks(c, Flag!"UpdateSpaces".yes); }while(endByte_ < text_.length) + emitter_.writeIndicator("\'", false); } diff --git a/dyaml/queue.d b/dyaml/queue.d index 242fc45..85b3a26 100644 --- a/dyaml/queue.d +++ b/dyaml/queue.d @@ -12,6 +12,7 @@ import core.stdc.stdlib; import core.memory; import std.container; +import std.traits; package: @@ -184,7 +185,7 @@ T* allocate(T, Args...)(Args args) T* ptr = cast(T*)malloc(T.sizeof); *ptr = T(args); //The struct might contain references to GC-allocated memory, so tell the GC about it. - GC.addRange(cast(void*)ptr, T.sizeof); + if(hasIndirections!T){GC.addRange(cast(void*)ptr, T.sizeof);} return ptr; } @@ -192,7 +193,7 @@ T* allocate(T, Args...)(Args args) void free(T)(T* ptr) { //GC doesn't need to care about any references in this struct anymore. - GC.removeRange(cast(void*)ptr); + if(hasIndirections!T){GC.removeRange(cast(void*)ptr);} clear(*ptr); std.c.stdlib.free(ptr); } diff --git a/dyaml/resolver.d b/dyaml/resolver.d index 51f30f6..dad33aa 100644 --- a/dyaml/resolver.d +++ b/dyaml/resolver.d @@ -248,7 +248,8 @@ final class Resolver "[0-9]?-[0-9][0-9]?[Tt]|[ \t]+[0-9]" "[0-9]?:[0-9][0-9]:[0-9][0-9]" "(?:\\.[0-9]*)?(?:[ \t]*Z|[-+][0-9]" - "[0-9]?(?::[0-9][0-9])?)?$"), "0123456789"); + "[0-9]?(?::[0-9][0-9])?)?$"), + "0123456789"); addImplicitResolver("tag:yaml.org,2002:value", regex(r"^=$"), "="); diff --git a/dyaml/scanner.d b/dyaml/scanner.d index 69a0226..e19ed65 100644 --- a/dyaml/scanner.d +++ b/dyaml/scanner.d @@ -1395,6 +1395,9 @@ final class Scanner //document separators at the beginning of the line. //if(indent == 0){indent = 1;} dstring spaces; + + mixin FastCharSearch!" \t\0\n\r\u0085\u2028\u2029"d search; + for(;;) { if(reader_.peek() == '#'){break;} @@ -1405,9 +1408,8 @@ final class Scanner for(;;) { c = reader_.peek(length); - bool done = " \t\0\n\r\u0085\u2028\u2029"d.canFind(c) || - (flowLevel_ == 0 && c == ':' && - " \t\0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek(length + 1))) || + bool done = search.canFind(c) || (flowLevel_ == 0 && c == ':' && + search.canFind(reader_.peek(length + 1))) || (flowLevel_ > 0 && ",:?[]{}"d.canFind(c)); if(done){break;} ++length; @@ -1415,7 +1417,7 @@ final class Scanner //It's not clear what we should do with ':' in the flow context. if(flowLevel_ > 0 && c == ':' && - !" \t\0\n\r\u0085\u2028\u2029"d.canFind(reader_.peek(length + 1)) && + !search.canFind(reader_.peek(length + 1)) && !",[]{}"d.canFind(reader_.peek(length + 1))) { reader_.forward(length); @@ -1606,7 +1608,7 @@ final class Scanner * '\r\n' : '\n' * '\r' : '\n' * '\n' : '\n' - * '\u0085' : '\n' + * '\u0085' : '\n' * '\u2028' : '\u2028' * '\u2029 : '\u2029' * no break : '\0' @@ -1615,13 +1617,13 @@ final class Scanner { const c = reader_.peek(); - if("\r\n\u0085"d.canFind(c)) + if(c == '\n' || c == '\r' || c == '\u0085') { if(reader_.prefix(2) == "\r\n"d){reader_.forward(2);} else{reader_.forward();} return '\n'; } - if("\u2028\u2029"d.canFind(c)) + if(c == '\u2028' || c == '\u2029') { reader_.forward(); return c;