diff --git a/YamlDotNet.Core/Constants.cs b/YamlDotNet.Core/Constants.cs index ef522b0..d128666 100644 --- a/YamlDotNet.Core/Constants.cs +++ b/YamlDotNet.Core/Constants.cs @@ -19,26 +19,26 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; -using YamlDotNet.Core.Tokens; - -namespace YamlDotNet.Core -{ - /// - /// Defines constants thar relate to the YAML specification. - /// - internal static class Constants - { - public static readonly TagDirective[] DefaultTagDirectives = new[] - { - new TagDirective("!", "!"), - new TagDirective("!!", "tag:yaml.org,2002:"), - }; - - public const int MajorVersion = 1; - public const int MinorVersion = 1; - - public const char HandleCharacter = '!'; - public const string DefaultHandle = "!"; - } +using System; +using YamlDotNet.Core.Tokens; + +namespace YamlDotNet.Core +{ + /// + /// Defines constants thar relate to the YAML specification. + /// + internal static class Constants + { + public static readonly TagDirective[] DefaultTagDirectives = new[] + { + new TagDirective("!", "!"), + new TagDirective("!!", "tag:yaml.org,2002:"), + }; + + public const int MajorVersion = 1; + public const int MinorVersion = 1; + + public const char HandleCharacter = '!'; + public const string DefaultHandle = "!"; + } } \ No newline at end of file diff --git a/YamlDotNet.Core/Emitter.cs b/YamlDotNet.Core/Emitter.cs index 00ceebb..93a6ac2 100644 --- a/YamlDotNet.Core/Emitter.cs +++ b/YamlDotNet.Core/Emitter.cs @@ -764,7 +764,7 @@ namespace YamlDotNet.Core { WriteIndicator("...", true, false, false); WriteIndent(); - } + } state = EmitterState.YAML_EMIT_END_STATE; } @@ -1861,4 +1861,4 @@ namespace YamlDotNet.Core } } } -} +} diff --git a/YamlDotNet.Core/Events/AnchorAlias.cs b/YamlDotNet.Core/Events/AnchorAlias.cs index af36540..75f4fc0 100644 --- a/YamlDotNet.Core/Events/AnchorAlias.cs +++ b/YamlDotNet.Core/Events/AnchorAlias.cs @@ -29,10 +29,10 @@ namespace YamlDotNet.Core.Events /// public class AnchorAlias : ParsingEvent, IAnchorAlias { - /// + /// /// Gets a value indicating the variation of depth caused by this event. /// The value can be either -1, 0 or 1. For start events, it will be 1, - /// for end events, it will be -1, and for the remaining events, it will be 0. + /// for end events, it will be -1, and for the remaining events, it will be 0. /// public override int NestingIncrease { get { diff --git a/YamlDotNet.Core/Events/DocumentEnd.cs b/YamlDotNet.Core/Events/DocumentEnd.cs index 3e84ae7..5b38df1 100644 --- a/YamlDotNet.Core/Events/DocumentEnd.cs +++ b/YamlDotNet.Core/Events/DocumentEnd.cs @@ -29,10 +29,10 @@ namespace YamlDotNet.Core.Events /// public class DocumentEnd : ParsingEvent, IDocumentEnd { - /// + /// /// Gets a value indicating the variation of depth caused by this event. /// The value can be either -1, 0 or 1. For start events, it will be 1, - /// for end events, it will be -1, and for the remaining events, it will be 0. + /// for end events, it will be -1, and for the remaining events, it will be 0. /// public override int NestingIncrease { get { diff --git a/YamlDotNet.Core/Events/DocumentStart.cs b/YamlDotNet.Core/Events/DocumentStart.cs index 0da4686..cda89ed 100644 --- a/YamlDotNet.Core/Events/DocumentStart.cs +++ b/YamlDotNet.Core/Events/DocumentStart.cs @@ -30,10 +30,10 @@ namespace YamlDotNet.Core.Events /// public class DocumentStart : ParsingEvent, IDocumentStart { - /// + /// /// Gets a value indicating the variation of depth caused by this event. /// The value can be either -1, 0 or 1. For start events, it will be 1, - /// for end events, it will be -1, and for the remaining events, it will be 0. + /// for end events, it will be -1, and for the remaining events, it will be 0. /// public override int NestingIncrease { get { diff --git a/YamlDotNet.Core/Events/EventType.cs b/YamlDotNet.Core/Events/EventType.cs index d6780f9..f1ecb4e 100644 --- a/YamlDotNet.Core/Events/EventType.cs +++ b/YamlDotNet.Core/Events/EventType.cs @@ -19,68 +19,68 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; - -namespace YamlDotNet.Core.Events -{ - /// - /// Defines the event types. This allows for simpler type comparisons. - /// - internal enum EventType - { - /// - /// An empty event. - /// - YAML_NO_EVENT, - - /// - /// A STREAM-START event. - /// - YAML_STREAM_START_EVENT, - - /// - /// A STREAM-END event. - /// - YAML_STREAM_END_EVENT, - - /// - /// A DOCUMENT-START event. - /// - YAML_DOCUMENT_START_EVENT, - - /// - /// A DOCUMENT-END event. - /// - YAML_DOCUMENT_END_EVENT, - - /// - /// An ALIAS event. - /// - YAML_ALIAS_EVENT, - - /// - /// A SCALAR event. - /// - YAML_SCALAR_EVENT, - - /// - /// A SEQUENCE-START event. - /// - YAML_SEQUENCE_START_EVENT, - - /// - /// A SEQUENCE-END event. - /// - YAML_SEQUENCE_END_EVENT, - - /// - /// A MAPPING-START event. - /// - YAML_MAPPING_START_EVENT, - - /// - /// A MAPPING-END event. - /// - YAML_MAPPING_END_EVENT, - } -} +using System; + +namespace YamlDotNet.Core.Events +{ + /// + /// Defines the event types. This allows for simpler type comparisons. + /// + internal enum EventType + { + /// + /// An empty event. + /// + YAML_NO_EVENT, + + /// + /// A STREAM-START event. + /// + YAML_STREAM_START_EVENT, + + /// + /// A STREAM-END event. + /// + YAML_STREAM_END_EVENT, + + /// + /// A DOCUMENT-START event. + /// + YAML_DOCUMENT_START_EVENT, + + /// + /// A DOCUMENT-END event. + /// + YAML_DOCUMENT_END_EVENT, + + /// + /// An ALIAS event. + /// + YAML_ALIAS_EVENT, + + /// + /// A SCALAR event. + /// + YAML_SCALAR_EVENT, + + /// + /// A SEQUENCE-START event. + /// + YAML_SEQUENCE_START_EVENT, + + /// + /// A SEQUENCE-END event. + /// + YAML_SEQUENCE_END_EVENT, + + /// + /// A MAPPING-START event. + /// + YAML_MAPPING_START_EVENT, + + /// + /// A MAPPING-END event. + /// + YAML_MAPPING_END_EVENT, + } +} diff --git a/YamlDotNet.Core/Events/MappingEnd.cs b/YamlDotNet.Core/Events/MappingEnd.cs index 1d13c03..7406463 100644 --- a/YamlDotNet.Core/Events/MappingEnd.cs +++ b/YamlDotNet.Core/Events/MappingEnd.cs @@ -28,10 +28,10 @@ namespace YamlDotNet.Core.Events /// public class MappingEnd : ParsingEvent, IMappingEnd { - /// + /// /// Gets a value indicating the variation of depth caused by this event. /// The value can be either -1, 0 or 1. For start events, it will be 1, - /// for end events, it will be -1, and for the remaining events, it will be 0. + /// for end events, it will be -1, and for the remaining events, it will be 0. /// public override int NestingIncrease { get { diff --git a/YamlDotNet.Core/Events/MappingStart.cs b/YamlDotNet.Core/Events/MappingStart.cs index 2c4d5c9..7c98cbd 100644 --- a/YamlDotNet.Core/Events/MappingStart.cs +++ b/YamlDotNet.Core/Events/MappingStart.cs @@ -29,10 +29,10 @@ namespace YamlDotNet.Core.Events /// public class MappingStart : NodeEvent, IMappingStart { - /// + /// /// Gets a value indicating the variation of depth caused by this event. /// The value can be either -1, 0 or 1. For start events, it will be 1, - /// for end events, it will be -1, and for the remaining events, it will be 0. + /// for end events, it will be -1, and for the remaining events, it will be 0. /// public override int NestingIncrease { get { diff --git a/YamlDotNet.Core/Events/MappingStyle.cs b/YamlDotNet.Core/Events/MappingStyle.cs index 320963d..007531e 100644 --- a/YamlDotNet.Core/Events/MappingStyle.cs +++ b/YamlDotNet.Core/Events/MappingStyle.cs @@ -19,28 +19,28 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; - -namespace YamlDotNet.Core.Events -{ - /// - /// Specifies the style of a mapping. - /// - public enum MappingStyle - { - /// - /// Let the emitter choose the style. - /// - Any, - - /// - /// The block mapping style. - /// - Block, - - /// - /// The flow mapping style. - /// - Flow - } +using System; + +namespace YamlDotNet.Core.Events +{ + /// + /// Specifies the style of a mapping. + /// + public enum MappingStyle + { + /// + /// Let the emitter choose the style. + /// + Any, + + /// + /// The block mapping style. + /// + Block, + + /// + /// The flow mapping style. + /// + Flow + } } \ No newline at end of file diff --git a/YamlDotNet.Core/Events/ParsingEvent.cs b/YamlDotNet.Core/Events/ParsingEvent.cs index 08641ff..b45a57a 100644 --- a/YamlDotNet.Core/Events/ParsingEvent.cs +++ b/YamlDotNet.Core/Events/ParsingEvent.cs @@ -19,66 +19,66 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; - -namespace YamlDotNet.Core.Events -{ - /// - /// Base class for parsing events. - /// - public abstract class ParsingEvent : IParsingEvent - { - /// +using System; + +namespace YamlDotNet.Core.Events +{ + /// + /// Base class for parsing events. + /// + public abstract class ParsingEvent : IParsingEvent + { + /// /// Gets a value indicating the variation of depth caused by this event. /// The value can be either -1, 0 or 1. For start events, it will be 1, - /// for end events, it will be -1, and for the remaining events, it will be 0. + /// for end events, it will be -1, and for the remaining events, it will be 0. /// public abstract int NestingIncrease { get; } - - /// - /// Gets the event type, which allows for simpler type comparisons. - /// - internal abstract EventType Type { - get; - } - - private readonly Mark start; - - /// - /// Gets the position in the input stream where the event starts. - /// - public Mark Start - { - get - { - return start; - } - } - - private readonly Mark end; - - /// - /// Gets the position in the input stream where the event ends. - /// - public Mark End - { - get - { - return end; - } - } - - /// - /// Initializes a new instance of the class. - /// - /// The start position of the event. - /// The end position of the event. - internal ParsingEvent(Mark start, Mark end) - { - this.start = start; - this.end = end; - } - } + + /// + /// Gets the event type, which allows for simpler type comparisons. + /// + internal abstract EventType Type { + get; + } + + private readonly Mark start; + + /// + /// Gets the position in the input stream where the event starts. + /// + public Mark Start + { + get + { + return start; + } + } + + private readonly Mark end; + + /// + /// Gets the position in the input stream where the event ends. + /// + public Mark End + { + get + { + return end; + } + } + + /// + /// Initializes a new instance of the class. + /// + /// The start position of the event. + /// The end position of the event. + internal ParsingEvent(Mark start, Mark end) + { + this.start = start; + this.end = end; + } + } } \ No newline at end of file diff --git a/YamlDotNet.Core/Events/Scalar.cs b/YamlDotNet.Core/Events/Scalar.cs index ca499aa..fc4757d 100644 --- a/YamlDotNet.Core/Events/Scalar.cs +++ b/YamlDotNet.Core/Events/Scalar.cs @@ -29,10 +29,10 @@ namespace YamlDotNet.Core.Events /// public class Scalar : NodeEvent, IScalar { - /// + /// /// Gets a value indicating the variation of depth caused by this event. /// The value can be either -1, 0 or 1. For start events, it will be 1, - /// for end events, it will be -1, and for the remaining events, it will be 0. + /// for end events, it will be -1, and for the remaining events, it will be 0. /// public override int NestingIncrease { get { diff --git a/YamlDotNet.Core/Events/SequenceEnd.cs b/YamlDotNet.Core/Events/SequenceEnd.cs index c6a4a94..2e36ee4 100644 --- a/YamlDotNet.Core/Events/SequenceEnd.cs +++ b/YamlDotNet.Core/Events/SequenceEnd.cs @@ -28,10 +28,10 @@ namespace YamlDotNet.Core.Events /// public class SequenceEnd : ParsingEvent, ISequenceEnd { - /// + /// /// Gets a value indicating the variation of depth caused by this event. /// The value can be either -1, 0 or 1. For start events, it will be 1, - /// for end events, it will be -1, and for the remaining events, it will be 0. + /// for end events, it will be -1, and for the remaining events, it will be 0. /// public override int NestingIncrease { get { diff --git a/YamlDotNet.Core/Events/SequenceStart.cs b/YamlDotNet.Core/Events/SequenceStart.cs index 42adacf..eb200a4 100644 --- a/YamlDotNet.Core/Events/SequenceStart.cs +++ b/YamlDotNet.Core/Events/SequenceStart.cs @@ -29,10 +29,10 @@ namespace YamlDotNet.Core.Events /// public class SequenceStart : NodeEvent, ISequenceStart { - /// + /// /// Gets a value indicating the variation of depth caused by this event. /// The value can be either -1, 0 or 1. For start events, it will be 1, - /// for end events, it will be -1, and for the remaining events, it will be 0. + /// for end events, it will be -1, and for the remaining events, it will be 0. /// public override int NestingIncrease { get { diff --git a/YamlDotNet.Core/Events/SequenceStyle.cs b/YamlDotNet.Core/Events/SequenceStyle.cs index 1891c43..2d43b58 100644 --- a/YamlDotNet.Core/Events/SequenceStyle.cs +++ b/YamlDotNet.Core/Events/SequenceStyle.cs @@ -19,28 +19,28 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; - -namespace YamlDotNet.Core.Events -{ - /// - /// Specifies the style of a sequence. - /// - public enum SequenceStyle - { - /// - /// Let the emitter choose the style. - /// - Any, - - /// - /// The block sequence style. - /// - Block, - - /// - /// The flow sequence style. - /// - Flow - } +using System; + +namespace YamlDotNet.Core.Events +{ + /// + /// Specifies the style of a sequence. + /// + public enum SequenceStyle + { + /// + /// Let the emitter choose the style. + /// + Any, + + /// + /// The block sequence style. + /// + Block, + + /// + /// The flow sequence style. + /// + Flow + } } \ No newline at end of file diff --git a/YamlDotNet.Core/Events/StreamEnd.cs b/YamlDotNet.Core/Events/StreamEnd.cs index 02e7c2d..500f3e6 100644 --- a/YamlDotNet.Core/Events/StreamEnd.cs +++ b/YamlDotNet.Core/Events/StreamEnd.cs @@ -28,10 +28,10 @@ namespace YamlDotNet.Core.Events /// public class StreamEnd : ParsingEvent, IStreamEnd { - /// + /// /// Gets a value indicating the variation of depth caused by this event. /// The value can be either -1, 0 or 1. For start events, it will be 1, - /// for end events, it will be -1, and for the remaining events, it will be 0. + /// for end events, it will be -1, and for the remaining events, it will be 0. /// public override int NestingIncrease { get { diff --git a/YamlDotNet.Core/Events/StreamStart.cs b/YamlDotNet.Core/Events/StreamStart.cs index 9a696f8..cdaab0d 100644 --- a/YamlDotNet.Core/Events/StreamStart.cs +++ b/YamlDotNet.Core/Events/StreamStart.cs @@ -28,10 +28,10 @@ namespace YamlDotNet.Core.Events /// public class StreamStart : ParsingEvent, IStreamStart { - /// + /// /// Gets a value indicating the variation of depth caused by this event. /// The value can be either -1, 0 or 1. For start events, it will be 1, - /// for end events, it will be -1, and for the remaining events, it will be 0. + /// for end events, it will be -1, and for the remaining events, it will be 0. /// public override int NestingIncrease { get { diff --git a/YamlDotNet.Core/FakeList.cs b/YamlDotNet.Core/FakeList.cs index fca214e..3b08292 100644 --- a/YamlDotNet.Core/FakeList.cs +++ b/YamlDotNet.Core/FakeList.cs @@ -19,60 +19,60 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; -using System.Collections.Generic; - -namespace YamlDotNet.Core -{ - /// - /// Implements an indexer through an IEnumerator<T>. - /// - public class FakeList - { - private readonly IEnumerator collection; - private int currentIndex = -1; - - /// - /// Initializes a new instance of FakeList<T>. - /// - /// The enumerator to use to implement the indexer. - public FakeList(IEnumerator collection) - { - this.collection = collection; - } - - /// - /// Initializes a new instance of FakeList<T>. - /// - /// The collection to use to implement the indexer. - public FakeList(IEnumerable collection) - : this(collection.GetEnumerator()) - { - } - - /// - /// Gets the element at the specified index. - /// - /// - /// If index is greater or equal than the last used index, this operation is O(index - lastIndex), - /// else this operation is O(index). - /// - public T this[int index] { - get { - if(index < currentIndex) { - collection.Reset(); - currentIndex = -1; - } - - while(currentIndex < index) { - if(!collection.MoveNext()) { - throw new ArgumentOutOfRangeException("index"); - } - ++currentIndex; - } - - return collection.Current; - } - } - } +using System; +using System.Collections.Generic; + +namespace YamlDotNet.Core +{ + /// + /// Implements an indexer through an IEnumerator<T>. + /// + public class FakeList + { + private readonly IEnumerator collection; + private int currentIndex = -1; + + /// + /// Initializes a new instance of FakeList<T>. + /// + /// The enumerator to use to implement the indexer. + public FakeList(IEnumerator collection) + { + this.collection = collection; + } + + /// + /// Initializes a new instance of FakeList<T>. + /// + /// The collection to use to implement the indexer. + public FakeList(IEnumerable collection) + : this(collection.GetEnumerator()) + { + } + + /// + /// Gets the element at the specified index. + /// + /// + /// If index is greater or equal than the last used index, this operation is O(index - lastIndex), + /// else this operation is O(index). + /// + public T this[int index] { + get { + if(index < currentIndex) { + collection.Reset(); + currentIndex = -1; + } + + while(currentIndex < index) { + if(!collection.MoveNext()) { + throw new ArgumentOutOfRangeException("index"); + } + ++currentIndex; + } + + return collection.Current; + } + } + } } \ No newline at end of file diff --git a/YamlDotNet.Core/Parser.cs b/YamlDotNet.Core/Parser.cs index 302d4b0..26c80d3 100644 --- a/YamlDotNet.Core/Parser.cs +++ b/YamlDotNet.Core/Parser.cs @@ -19,912 +19,912 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; -using System.Diagnostics; -using System.Collections.Generic; -using System.IO; -using YamlDotNet.Core.Tokens; -using Event = YamlDotNet.Core.Events.ParsingEvent; -using SequenceStyle = YamlDotNet.Core.Events.SequenceStyle; -using MappingStyle = YamlDotNet.Core.Events.MappingStyle; - -namespace YamlDotNet.Core -{ - /// - /// Parses YAML streams. - /// - public class Parser : IParser - { - private readonly Stack states = new Stack(); - private readonly TagDirectiveCollection tagDirectives = new TagDirectiveCollection(); - private ParserState state; - - private readonly Scanner scanner; - private Event current; - - private Token currentToken; - - private Token GetCurrentToken() - { - if (currentToken == null) - { - if (scanner.InternalMoveNext()) - { - currentToken = scanner.Current; - } - } - return currentToken; - } - - /// - /// Initializes a new instance of the class. - /// - /// The input where the YAML stream is to be read. - public Parser(TextReader input) - { - scanner = new Scanner(input); - } - - /// - /// Gets the current event. - /// - public Event Current - { - get - { - return current; - } - } - - /// - /// Moves to the next event. - /// - /// Returns true if there are more events available, otherwise returns false. - public bool MoveNext() - { - // No events after the end of the stream or error. - if (state == ParserState.YAML_PARSE_END_STATE) - { - current = null; - return false; - } - else - { - // Generate the next event. - current = StateMachine(); - return true; - } - } - - private Event StateMachine() - { - switch (state) - { - case ParserState.YAML_PARSE_STREAM_START_STATE: - return ParseStreamStart(); - - case ParserState.YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE: - return ParseDocumentStart(true); - - case ParserState.YAML_PARSE_DOCUMENT_START_STATE: - return ParseDocumentStart(false); - - case ParserState.YAML_PARSE_DOCUMENT_CONTENT_STATE: - return ParseDocumentContent(); - - case ParserState.YAML_PARSE_DOCUMENT_END_STATE: - return ParseDocumentEnd(); - - case ParserState.YAML_PARSE_BLOCK_NODE_STATE: - return ParseNode(true, false); - - case ParserState.YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: - return ParseNode(true, true); - - case ParserState.YAML_PARSE_FLOW_NODE_STATE: - return ParseNode(false, false); - - case ParserState.YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: - return ParseBlockSequenceEntry(true); - - case ParserState.YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: - return ParseBlockSequenceEntry(false); - - case ParserState.YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: - return ParseIndentlessSequenceEntry(); - - case ParserState.YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: - return ParseBlockMappingKey(true); - - case ParserState.YAML_PARSE_BLOCK_MAPPING_KEY_STATE: - return ParseBlockMappingKey(false); - - case ParserState.YAML_PARSE_BLOCK_MAPPING_VALUE_STATE: - return ParseBlockMappingValue(); - - case ParserState.YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: - return ParseFlowSequenceEntry(true); - - case ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE: - return ParseFlowSequenceEntry(false); - - case ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: - return ParseFlowSequenceEntryMappingKey(); - - case ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: - return ParseFlowSequenceEntryMappingValue(); - - case ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: - return ParseFlowSequenceEntryMappingEnd(); - - case ParserState.YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: - return ParseFlowMappingKey(true); - - case ParserState.YAML_PARSE_FLOW_MAPPING_KEY_STATE: - return ParseFlowMappingKey(false); - - case ParserState.YAML_PARSE_FLOW_MAPPING_VALUE_STATE: - return ParseFlowMappingValue(false); - - case ParserState.YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: - return ParseFlowMappingValue(true); - - default: - Debug.Assert(false, "Invalid state"); // Invalid state. - throw new InvalidOperationException(); - } - } - - private void Skip() - { - if (currentToken != null) - { - currentToken = null; - scanner.ConsumeCurrent(); - } - } - - /// - /// Parse the production: - /// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END - /// ************ - /// - private Event ParseStreamStart() - { - StreamStart streamStart = GetCurrentToken() as StreamStart; - if (streamStart == null) - { - var current = GetCurrentToken(); - throw new SemanticErrorException(current.Start, current.End, "Did not find expected ."); - } - Skip(); - - state = ParserState.YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE; - return new Events.StreamStart(streamStart.Start, streamStart.End); - } - - /// - /// Parse the productions: - /// implicit_document ::= block_node DOCUMENT-END* - /// * - /// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* - /// ************************* - /// - private Event ParseDocumentStart(bool isImplicit) - { - // Parse extra document end indicators. - - if (!isImplicit) - { - while (GetCurrentToken() is DocumentEnd) - { - Skip(); - } - } - - // Parse an isImplicit document. - - if (isImplicit && !(GetCurrentToken() is VersionDirective || GetCurrentToken() is TagDirective || GetCurrentToken() is DocumentStart || GetCurrentToken() is StreamEnd)) - { - TagDirectiveCollection directives = new TagDirectiveCollection(); - ProcessDirectives(directives); - - states.Push(ParserState.YAML_PARSE_DOCUMENT_END_STATE); - - state = ParserState.YAML_PARSE_BLOCK_NODE_STATE; - - return new Events.DocumentStart(null, directives, true, GetCurrentToken().Start, GetCurrentToken().End); - } - - // Parse an explicit document. - - else if (!(GetCurrentToken() is StreamEnd)) - { - Mark start = GetCurrentToken().Start; - TagDirectiveCollection directives = new TagDirectiveCollection(); +using System; +using System.Diagnostics; +using System.Collections.Generic; +using System.IO; +using YamlDotNet.Core.Tokens; +using Event = YamlDotNet.Core.Events.ParsingEvent; +using SequenceStyle = YamlDotNet.Core.Events.SequenceStyle; +using MappingStyle = YamlDotNet.Core.Events.MappingStyle; + +namespace YamlDotNet.Core +{ + /// + /// Parses YAML streams. + /// + public class Parser : IParser + { + private readonly Stack states = new Stack(); + private readonly TagDirectiveCollection tagDirectives = new TagDirectiveCollection(); + private ParserState state; + + private readonly Scanner scanner; + private Event current; + + private Token currentToken; + + private Token GetCurrentToken() + { + if (currentToken == null) + { + if (scanner.InternalMoveNext()) + { + currentToken = scanner.Current; + } + } + return currentToken; + } + + /// + /// Initializes a new instance of the class. + /// + /// The input where the YAML stream is to be read. + public Parser(TextReader input) + { + scanner = new Scanner(input); + } + + /// + /// Gets the current event. + /// + public Event Current + { + get + { + return current; + } + } + + /// + /// Moves to the next event. + /// + /// Returns true if there are more events available, otherwise returns false. + public bool MoveNext() + { + // No events after the end of the stream or error. + if (state == ParserState.YAML_PARSE_END_STATE) + { + current = null; + return false; + } + else + { + // Generate the next event. + current = StateMachine(); + return true; + } + } + + private Event StateMachine() + { + switch (state) + { + case ParserState.YAML_PARSE_STREAM_START_STATE: + return ParseStreamStart(); + + case ParserState.YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE: + return ParseDocumentStart(true); + + case ParserState.YAML_PARSE_DOCUMENT_START_STATE: + return ParseDocumentStart(false); + + case ParserState.YAML_PARSE_DOCUMENT_CONTENT_STATE: + return ParseDocumentContent(); + + case ParserState.YAML_PARSE_DOCUMENT_END_STATE: + return ParseDocumentEnd(); + + case ParserState.YAML_PARSE_BLOCK_NODE_STATE: + return ParseNode(true, false); + + case ParserState.YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: + return ParseNode(true, true); + + case ParserState.YAML_PARSE_FLOW_NODE_STATE: + return ParseNode(false, false); + + case ParserState.YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: + return ParseBlockSequenceEntry(true); + + case ParserState.YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: + return ParseBlockSequenceEntry(false); + + case ParserState.YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: + return ParseIndentlessSequenceEntry(); + + case ParserState.YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: + return ParseBlockMappingKey(true); + + case ParserState.YAML_PARSE_BLOCK_MAPPING_KEY_STATE: + return ParseBlockMappingKey(false); + + case ParserState.YAML_PARSE_BLOCK_MAPPING_VALUE_STATE: + return ParseBlockMappingValue(); + + case ParserState.YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: + return ParseFlowSequenceEntry(true); + + case ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE: + return ParseFlowSequenceEntry(false); + + case ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: + return ParseFlowSequenceEntryMappingKey(); + + case ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: + return ParseFlowSequenceEntryMappingValue(); + + case ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: + return ParseFlowSequenceEntryMappingEnd(); + + case ParserState.YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: + return ParseFlowMappingKey(true); + + case ParserState.YAML_PARSE_FLOW_MAPPING_KEY_STATE: + return ParseFlowMappingKey(false); + + case ParserState.YAML_PARSE_FLOW_MAPPING_VALUE_STATE: + return ParseFlowMappingValue(false); + + case ParserState.YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: + return ParseFlowMappingValue(true); + + default: + Debug.Assert(false, "Invalid state"); // Invalid state. + throw new InvalidOperationException(); + } + } + + private void Skip() + { + if (currentToken != null) + { + currentToken = null; + scanner.ConsumeCurrent(); + } + } + + /// + /// Parse the production: + /// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END + /// ************ + /// + private Event ParseStreamStart() + { + StreamStart streamStart = GetCurrentToken() as StreamStart; + if (streamStart == null) + { + var current = GetCurrentToken(); + throw new SemanticErrorException(current.Start, current.End, "Did not find expected ."); + } + Skip(); + + state = ParserState.YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE; + return new Events.StreamStart(streamStart.Start, streamStart.End); + } + + /// + /// Parse the productions: + /// implicit_document ::= block_node DOCUMENT-END* + /// * + /// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + /// ************************* + /// + private Event ParseDocumentStart(bool isImplicit) + { + // Parse extra document end indicators. + + if (!isImplicit) + { + while (GetCurrentToken() is DocumentEnd) + { + Skip(); + } + } + + // Parse an isImplicit document. + + if (isImplicit && !(GetCurrentToken() is VersionDirective || GetCurrentToken() is TagDirective || GetCurrentToken() is DocumentStart || GetCurrentToken() is StreamEnd)) + { + TagDirectiveCollection directives = new TagDirectiveCollection(); + ProcessDirectives(directives); + + states.Push(ParserState.YAML_PARSE_DOCUMENT_END_STATE); + + state = ParserState.YAML_PARSE_BLOCK_NODE_STATE; + + return new Events.DocumentStart(null, directives, true, GetCurrentToken().Start, GetCurrentToken().End); + } + + // Parse an explicit document. + + else if (!(GetCurrentToken() is StreamEnd)) + { + Mark start = GetCurrentToken().Start; + TagDirectiveCollection directives = new TagDirectiveCollection(); VersionDirective versionDirective = ProcessDirectives(directives); var current = GetCurrentToken(); - if (!(current is DocumentStart)) - { - throw new SemanticErrorException(current.Start, current.End, "Did not find expected ."); - } - - states.Push(ParserState.YAML_PARSE_DOCUMENT_END_STATE); - + if (!(current is DocumentStart)) + { + throw new SemanticErrorException(current.Start, current.End, "Did not find expected ."); + } + + states.Push(ParserState.YAML_PARSE_DOCUMENT_END_STATE); + state = ParserState.YAML_PARSE_DOCUMENT_CONTENT_STATE; - Event evt = new Events.DocumentStart(versionDirective, directives, false, start, current.End); - Skip(); - return evt; - } - - // Parse the stream end. - - else - { - state = ParserState.YAML_PARSE_END_STATE; - - Event evt = new Events.StreamEnd(GetCurrentToken().Start, GetCurrentToken().End); - // Do not call skip here because that would throw an exception - if (scanner.InternalMoveNext()) - { - throw new InvalidOperationException("The scanner should contain no more tokens."); - } - return evt; - } - } - - /// - /// Parse directives. - /// - private VersionDirective ProcessDirectives(TagDirectiveCollection tags) - { - VersionDirective version = null; - - while (true) - { - VersionDirective currentVersion; - TagDirective tag; - - if ((currentVersion = GetCurrentToken() as VersionDirective) != null) - { - if (version != null) - { - throw new SemanticErrorException(currentVersion.Start, currentVersion.End, "Found duplicate %YAML directive."); - } - - if (currentVersion.Version.Major != Constants.MajorVersion || currentVersion.Version.Minor != Constants.MinorVersion) + Event evt = new Events.DocumentStart(versionDirective, directives, false, start, current.End); + Skip(); + return evt; + } + + // Parse the stream end. + + else + { + state = ParserState.YAML_PARSE_END_STATE; + + Event evt = new Events.StreamEnd(GetCurrentToken().Start, GetCurrentToken().End); + // Do not call skip here because that would throw an exception + if (scanner.InternalMoveNext()) + { + throw new InvalidOperationException("The scanner should contain no more tokens."); + } + return evt; + } + } + + /// + /// Parse directives. + /// + private VersionDirective ProcessDirectives(TagDirectiveCollection tags) + { + VersionDirective version = null; + + while (true) + { + VersionDirective currentVersion; + TagDirective tag; + + if ((currentVersion = GetCurrentToken() as VersionDirective) != null) + { + if (version != null) { - throw new SemanticErrorException(currentVersion.Start, currentVersion.End, "Found incompatible YAML document."); - } - - version = currentVersion; - } - else if ((tag = GetCurrentToken() as TagDirective) != null) - { - if (tagDirectives.Contains(tag.Handle)) - { - throw new SemanticErrorException(tag.Start, tag.End, "Found duplicate %TAG directive."); - } - tagDirectives.Add(tag); - if (tags != null) - { - tags.Add(tag); - } - } - else - { - break; - } - - Skip(); - } - - if (tags != null) - { - AddDefaultTagDirectives(tags); - } - AddDefaultTagDirectives(tagDirectives); - - return version; - } - - private static void AddDefaultTagDirectives(TagDirectiveCollection directives) - { - foreach(var directive in Constants.DefaultTagDirectives) - { - if (!directives.Contains(directive)) - { - directives.Add(directive); - } - } - } - - /// - /// Parse the productions: - /// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* - /// *********** - /// - private Event ParseDocumentContent() - { - if ( - GetCurrentToken() is VersionDirective || - GetCurrentToken() is TagDirective || - GetCurrentToken() is DocumentStart || - GetCurrentToken() is DocumentEnd || - GetCurrentToken() is StreamEnd - ) - { - state = states.Pop(); - return ProcessEmptyScalar(scanner.CurrentPosition); - } - else - { - return ParseNode(true, false); - } - } - - /// - /// Generate an empty scalar event. - /// - private static Event ProcessEmptyScalar(Mark position) - { - return new Events.Scalar(null, null, string.Empty, ScalarStyle.Plain, true, false, position, position); - } - - /// - /// Parse the productions: - /// block_node_or_indentless_sequence ::= - /// ALIAS - /// ***** - /// | properties (block_content | indentless_block_sequence)? - /// ********** * - /// | block_content | indentless_block_sequence - /// * - /// block_node ::= ALIAS - /// ***** - /// | properties block_content? - /// ********** * - /// | block_content - /// * - /// flow_node ::= ALIAS - /// ***** - /// | properties flow_content? - /// ********** * - /// | flow_content - /// * - /// properties ::= TAG ANCHOR? | ANCHOR TAG? - /// ************************* - /// block_content ::= block_collection | flow_collection | SCALAR - /// ****** - /// flow_content ::= flow_collection | SCALAR - /// ****** - /// - private Event ParseNode(bool isBlock, bool isIndentlessSequence) - { - AnchorAlias alias = GetCurrentToken() as AnchorAlias; - if (alias != null) - { - state = states.Pop(); - Event evt = new Events.AnchorAlias(alias.Value, alias.Start, alias.End); - Skip(); - return evt; - } - - Mark start = GetCurrentToken().Start; - - Anchor anchor = null; - Tag tag = null; - - // The anchor and the tag can be in any order. This loop repeats at most twice. - while (true) - { - if (anchor == null && (anchor = GetCurrentToken() as Anchor) != null) - { - Skip(); - } - else if (tag == null && (tag = GetCurrentToken() as Tag) != null) - { - Skip(); - } - else - { - break; - } - } - - string tagName = null; - if (tag != null) - { - if (string.IsNullOrEmpty(tag.Handle)) - { - tagName = tag.Suffix; - } - else if (tagDirectives.Contains(tag.Handle)) - { - tagName = string.Concat(tagDirectives[tag.Handle].Prefix, tag.Suffix); - } - else - { - throw new SemanticErrorException(tag.Start, tag.End, "While parsing a node, find undefined tag handle."); - } - } - if (string.IsNullOrEmpty(tagName)) - { - tagName = null; - } - - string anchorName = anchor != null ? string.IsNullOrEmpty(anchor.Value) ? null : anchor.Value : null; - - bool isImplicit = string.IsNullOrEmpty(tagName); - - if (isIndentlessSequence && GetCurrentToken() is BlockEntry) - { - state = ParserState.YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; - - return new Events.SequenceStart( - anchorName, - tagName, - isImplicit, - SequenceStyle.Block, - start, - GetCurrentToken().End - ); - } - else - { - Scalar scalar = GetCurrentToken() as Scalar; - if (scalar != null) - { - bool isPlainImplicit = false; - bool isQuotedImplicit = false; - if ((scalar.Style == ScalarStyle.Plain && tagName == null) || tagName == Constants.DefaultHandle) - { - isPlainImplicit = true; - } - else if (tagName == null) - { - isQuotedImplicit = true; - } - - state = states.Pop(); - Event evt = new Events.Scalar(anchorName, tagName, scalar.Value, scalar.Style, isPlainImplicit, isQuotedImplicit, start, scalar.End); - - Skip(); - return evt; - } - - FlowSequenceStart flowSequenceStart = GetCurrentToken() as FlowSequenceStart; - if (flowSequenceStart != null) - { - state = ParserState.YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE; - return new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Flow, start, flowSequenceStart.End); - } - - FlowMappingStart flowMappingStart = GetCurrentToken() as FlowMappingStart; - if (flowMappingStart != null) - { - state = ParserState.YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE; - return new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Flow, start, flowMappingStart.End); - } - - if (isBlock) - { - BlockSequenceStart blockSequenceStart = GetCurrentToken() as BlockSequenceStart; - if (blockSequenceStart != null) - { - state = ParserState.YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE; - return new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Block, start, blockSequenceStart.End); - } - - BlockMappingStart blockMappingStart = GetCurrentToken() as BlockMappingStart; - if (blockMappingStart != null) - { - state = ParserState.YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE; - return new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Block, start, GetCurrentToken().End); - } - } - - if (anchorName != null || tag != null) - { - state = states.Pop(); - return new Events.Scalar(anchorName, tagName, string.Empty, ScalarStyle.Plain, isImplicit, false, start, GetCurrentToken().End); + throw new SemanticErrorException(currentVersion.Start, currentVersion.End, "Found duplicate %YAML directive."); + } + + if (currentVersion.Version.Major != Constants.MajorVersion || currentVersion.Version.Minor != Constants.MinorVersion) + { + throw new SemanticErrorException(currentVersion.Start, currentVersion.End, "Found incompatible YAML document."); + } + + version = currentVersion; + } + else if ((tag = GetCurrentToken() as TagDirective) != null) + { + if (tagDirectives.Contains(tag.Handle)) + { + throw new SemanticErrorException(tag.Start, tag.End, "Found duplicate %TAG directive."); + } + tagDirectives.Add(tag); + if (tags != null) + { + tags.Add(tag); + } + } + else + { + break; + } + + Skip(); + } + + if (tags != null) + { + AddDefaultTagDirectives(tags); + } + AddDefaultTagDirectives(tagDirectives); + + return version; + } + + private static void AddDefaultTagDirectives(TagDirectiveCollection directives) + { + foreach(var directive in Constants.DefaultTagDirectives) + { + if (!directives.Contains(directive)) + { + directives.Add(directive); + } + } + } + + /// + /// Parse the productions: + /// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + /// *********** + /// + private Event ParseDocumentContent() + { + if ( + GetCurrentToken() is VersionDirective || + GetCurrentToken() is TagDirective || + GetCurrentToken() is DocumentStart || + GetCurrentToken() is DocumentEnd || + GetCurrentToken() is StreamEnd + ) + { + state = states.Pop(); + return ProcessEmptyScalar(scanner.CurrentPosition); + } + else + { + return ParseNode(true, false); + } + } + + /// + /// Generate an empty scalar event. + /// + private static Event ProcessEmptyScalar(Mark position) + { + return new Events.Scalar(null, null, string.Empty, ScalarStyle.Plain, true, false, position, position); + } + + /// + /// Parse the productions: + /// block_node_or_indentless_sequence ::= + /// ALIAS + /// ***** + /// | properties (block_content | indentless_block_sequence)? + /// ********** * + /// | block_content | indentless_block_sequence + /// * + /// block_node ::= ALIAS + /// ***** + /// | properties block_content? + /// ********** * + /// | block_content + /// * + /// flow_node ::= ALIAS + /// ***** + /// | properties flow_content? + /// ********** * + /// | flow_content + /// * + /// properties ::= TAG ANCHOR? | ANCHOR TAG? + /// ************************* + /// block_content ::= block_collection | flow_collection | SCALAR + /// ****** + /// flow_content ::= flow_collection | SCALAR + /// ****** + /// + private Event ParseNode(bool isBlock, bool isIndentlessSequence) + { + AnchorAlias alias = GetCurrentToken() as AnchorAlias; + if (alias != null) + { + state = states.Pop(); + Event evt = new Events.AnchorAlias(alias.Value, alias.Start, alias.End); + Skip(); + return evt; + } + + Mark start = GetCurrentToken().Start; + + Anchor anchor = null; + Tag tag = null; + + // The anchor and the tag can be in any order. This loop repeats at most twice. + while (true) + { + if (anchor == null && (anchor = GetCurrentToken() as Anchor) != null) + { + Skip(); + } + else if (tag == null && (tag = GetCurrentToken() as Tag) != null) + { + Skip(); + } + else + { + break; + } + } + + string tagName = null; + if (tag != null) + { + if (string.IsNullOrEmpty(tag.Handle)) + { + tagName = tag.Suffix; + } + else if (tagDirectives.Contains(tag.Handle)) + { + tagName = string.Concat(tagDirectives[tag.Handle].Prefix, tag.Suffix); + } + else + { + throw new SemanticErrorException(tag.Start, tag.End, "While parsing a node, find undefined tag handle."); + } + } + if (string.IsNullOrEmpty(tagName)) + { + tagName = null; + } + + string anchorName = anchor != null ? string.IsNullOrEmpty(anchor.Value) ? null : anchor.Value : null; + + bool isImplicit = string.IsNullOrEmpty(tagName); + + if (isIndentlessSequence && GetCurrentToken() is BlockEntry) + { + state = ParserState.YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; + + return new Events.SequenceStart( + anchorName, + tagName, + isImplicit, + SequenceStyle.Block, + start, + GetCurrentToken().End + ); + } + else + { + Scalar scalar = GetCurrentToken() as Scalar; + if (scalar != null) + { + bool isPlainImplicit = false; + bool isQuotedImplicit = false; + if ((scalar.Style == ScalarStyle.Plain && tagName == null) || tagName == Constants.DefaultHandle) + { + isPlainImplicit = true; + } + else if (tagName == null) + { + isQuotedImplicit = true; + } + + state = states.Pop(); + Event evt = new Events.Scalar(anchorName, tagName, scalar.Value, scalar.Style, isPlainImplicit, isQuotedImplicit, start, scalar.End); + + Skip(); + return evt; + } + + FlowSequenceStart flowSequenceStart = GetCurrentToken() as FlowSequenceStart; + if (flowSequenceStart != null) + { + state = ParserState.YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE; + return new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Flow, start, flowSequenceStart.End); + } + + FlowMappingStart flowMappingStart = GetCurrentToken() as FlowMappingStart; + if (flowMappingStart != null) + { + state = ParserState.YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE; + return new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Flow, start, flowMappingStart.End); + } + + if (isBlock) + { + BlockSequenceStart blockSequenceStart = GetCurrentToken() as BlockSequenceStart; + if (blockSequenceStart != null) + { + state = ParserState.YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE; + return new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Block, start, blockSequenceStart.End); + } + + BlockMappingStart blockMappingStart = GetCurrentToken() as BlockMappingStart; + if (blockMappingStart != null) + { + state = ParserState.YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE; + return new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Block, start, GetCurrentToken().End); + } + } + + if (anchorName != null || tag != null) + { + state = states.Pop(); + return new Events.Scalar(anchorName, tagName, string.Empty, ScalarStyle.Plain, isImplicit, false, start, GetCurrentToken().End); } var current = GetCurrentToken(); - throw new SemanticErrorException(current.Start, current.End, "While parsing a node, did not find expected node content."); - } - } - - /// - /// Parse the productions: - /// implicit_document ::= block_node DOCUMENT-END* - /// ************* - /// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* - /// ************* - /// - - private Event ParseDocumentEnd() - { - bool isImplicit = true; - Mark start = GetCurrentToken().Start; - Mark end = start; - - if (GetCurrentToken() is DocumentEnd) - { - end = GetCurrentToken().End; - Skip(); - isImplicit = false; - } - - tagDirectives.Clear(); - - state = ParserState.YAML_PARSE_DOCUMENT_START_STATE; - return new Events.DocumentEnd(isImplicit, start, end); - } - - /// - /// Parse the productions: - /// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END - /// ******************** *********** * ********* - /// - - private Event ParseBlockSequenceEntry(bool isFirst) - { - if (isFirst) - { - GetCurrentToken(); - Skip(); - } - - if (GetCurrentToken() is BlockEntry) - { - Mark mark = GetCurrentToken().End; - - Skip(); - if (!(GetCurrentToken() is BlockEntry || GetCurrentToken() is BlockEnd)) - { - states.Push(ParserState.YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE); - return ParseNode(true, false); - } - else - { - state = ParserState.YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE; - return ProcessEmptyScalar(mark); - } - } - - else if (GetCurrentToken() is BlockEnd) - { - state = states.Pop(); - Event evt = new Events.SequenceEnd(GetCurrentToken().Start, GetCurrentToken().End); - Skip(); - return evt; - } - - else + throw new SemanticErrorException(current.Start, current.End, "While parsing a node, did not find expected node content."); + } + } + + /// + /// Parse the productions: + /// implicit_document ::= block_node DOCUMENT-END* + /// ************* + /// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + /// ************* + /// + + private Event ParseDocumentEnd() + { + bool isImplicit = true; + Mark start = GetCurrentToken().Start; + Mark end = start; + + if (GetCurrentToken() is DocumentEnd) { - var current = GetCurrentToken(); - throw new SemanticErrorException(current.Start, current.End, "While parsing a block collection, did not find expected '-' indicator."); - } - } - - /// - /// Parse the productions: - /// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ - /// *********** * - /// - private Event ParseIndentlessSequenceEntry() - { - if (GetCurrentToken() is BlockEntry) - { - Mark mark = GetCurrentToken().End; - Skip(); - - if (!(GetCurrentToken() is BlockEntry || GetCurrentToken() is Key || GetCurrentToken() is Value || GetCurrentToken() is BlockEnd)) - { - states.Push(ParserState.YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE); - return ParseNode(true, false); - } - else - { - state = ParserState.YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; - return ProcessEmptyScalar(mark); - } - } - else - { - state = states.Pop(); - return new Events.SequenceEnd(GetCurrentToken().Start, GetCurrentToken().End); - } - } - - /// - /// Parse the productions: - /// block_mapping ::= BLOCK-MAPPING_START - /// ******************* - /// ((KEY block_node_or_indentless_sequence?)? - /// *** * - /// (VALUE block_node_or_indentless_sequence?)?)* - /// - /// BLOCK-END - /// ********* - /// - private Event ParseBlockMappingKey(bool isFirst) - { - if (isFirst) - { - GetCurrentToken(); - Skip(); - } - - if (GetCurrentToken() is Key) - { - Mark mark = GetCurrentToken().End; - Skip(); - if (!(GetCurrentToken() is Key || GetCurrentToken() is Value || GetCurrentToken() is BlockEnd)) - { - states.Push(ParserState.YAML_PARSE_BLOCK_MAPPING_VALUE_STATE); - return ParseNode(true, true); - } - else - { - state = ParserState.YAML_PARSE_BLOCK_MAPPING_VALUE_STATE; - return ProcessEmptyScalar(mark); - } - } - - else if (GetCurrentToken() is BlockEnd) - { - state = states.Pop(); - Event evt = new Events.MappingEnd(GetCurrentToken().Start, GetCurrentToken().End); - Skip(); - return evt; - } - - else + end = GetCurrentToken().End; + Skip(); + isImplicit = false; + } + + tagDirectives.Clear(); + + state = ParserState.YAML_PARSE_DOCUMENT_START_STATE; + return new Events.DocumentEnd(isImplicit, start, end); + } + + /// + /// Parse the productions: + /// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END + /// ******************** *********** * ********* + /// + + private Event ParseBlockSequenceEntry(bool isFirst) + { + if (isFirst) + { + GetCurrentToken(); + Skip(); + } + + if (GetCurrentToken() is BlockEntry) + { + Mark mark = GetCurrentToken().End; + + Skip(); + if (!(GetCurrentToken() is BlockEntry || GetCurrentToken() is BlockEnd)) + { + states.Push(ParserState.YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE); + return ParseNode(true, false); + } + else + { + state = ParserState.YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE; + return ProcessEmptyScalar(mark); + } + } + + else if (GetCurrentToken() is BlockEnd) + { + state = states.Pop(); + Event evt = new Events.SequenceEnd(GetCurrentToken().Start, GetCurrentToken().End); + Skip(); + return evt; + } + + else { var current = GetCurrentToken(); - throw new SemanticErrorException(current.Start, current.End, "While parsing a block mapping, did not find expected key."); - } - } - - /// - /// Parse the productions: - /// block_mapping ::= BLOCK-MAPPING_START - /// - /// ((KEY block_node_or_indentless_sequence?)? - /// - /// (VALUE block_node_or_indentless_sequence?)?)* - /// ***** * - /// BLOCK-END - /// - /// - private Event ParseBlockMappingValue() - { - if (GetCurrentToken() is Value) - { - Mark mark = GetCurrentToken().End; - Skip(); - - if (!(GetCurrentToken() is Key || GetCurrentToken() is Value || GetCurrentToken() is BlockEnd)) - { - states.Push(ParserState.YAML_PARSE_BLOCK_MAPPING_KEY_STATE); - return ParseNode(true, true); - } - else - { - state = ParserState.YAML_PARSE_BLOCK_MAPPING_KEY_STATE; - return ProcessEmptyScalar(mark); - } - } - - else - { - state = ParserState.YAML_PARSE_BLOCK_MAPPING_KEY_STATE; - return ProcessEmptyScalar(GetCurrentToken().Start); - } - } - - /// - /// Parse the productions: - /// flow_sequence ::= FLOW-SEQUENCE-START - /// ******************* - /// (flow_sequence_entry FLOW-ENTRY)* - /// * ********** - /// flow_sequence_entry? - /// * - /// FLOW-SEQUENCE-END - /// ***************** - /// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - /// * - /// - private Event ParseFlowSequenceEntry(bool isFirst) - { - if (isFirst) - { - GetCurrentToken(); - Skip(); - } - - Event evt; - if (!(GetCurrentToken() is FlowSequenceEnd)) - { - if (!isFirst) - { - if (GetCurrentToken() is FlowEntry) - { - Skip(); - } - else + throw new SemanticErrorException(current.Start, current.End, "While parsing a block collection, did not find expected '-' indicator."); + } + } + + /// + /// Parse the productions: + /// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ + /// *********** * + /// + private Event ParseIndentlessSequenceEntry() + { + if (GetCurrentToken() is BlockEntry) + { + Mark mark = GetCurrentToken().End; + Skip(); + + if (!(GetCurrentToken() is BlockEntry || GetCurrentToken() is Key || GetCurrentToken() is Value || GetCurrentToken() is BlockEnd)) + { + states.Push(ParserState.YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE); + return ParseNode(true, false); + } + else + { + state = ParserState.YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; + return ProcessEmptyScalar(mark); + } + } + else + { + state = states.Pop(); + return new Events.SequenceEnd(GetCurrentToken().Start, GetCurrentToken().End); + } + } + + /// + /// Parse the productions: + /// block_mapping ::= BLOCK-MAPPING_START + /// ******************* + /// ((KEY block_node_or_indentless_sequence?)? + /// *** * + /// (VALUE block_node_or_indentless_sequence?)?)* + /// + /// BLOCK-END + /// ********* + /// + private Event ParseBlockMappingKey(bool isFirst) + { + if (isFirst) + { + GetCurrentToken(); + Skip(); + } + + if (GetCurrentToken() is Key) + { + Mark mark = GetCurrentToken().End; + Skip(); + if (!(GetCurrentToken() is Key || GetCurrentToken() is Value || GetCurrentToken() is BlockEnd)) + { + states.Push(ParserState.YAML_PARSE_BLOCK_MAPPING_VALUE_STATE); + return ParseNode(true, true); + } + else + { + state = ParserState.YAML_PARSE_BLOCK_MAPPING_VALUE_STATE; + return ProcessEmptyScalar(mark); + } + } + + else if (GetCurrentToken() is BlockEnd) + { + state = states.Pop(); + Event evt = new Events.MappingEnd(GetCurrentToken().Start, GetCurrentToken().End); + Skip(); + return evt; + } + + else + { + var current = GetCurrentToken(); + throw new SemanticErrorException(current.Start, current.End, "While parsing a block mapping, did not find expected key."); + } + } + + /// + /// Parse the productions: + /// block_mapping ::= BLOCK-MAPPING_START + /// + /// ((KEY block_node_or_indentless_sequence?)? + /// + /// (VALUE block_node_or_indentless_sequence?)?)* + /// ***** * + /// BLOCK-END + /// + /// + private Event ParseBlockMappingValue() + { + if (GetCurrentToken() is Value) + { + Mark mark = GetCurrentToken().End; + Skip(); + + if (!(GetCurrentToken() is Key || GetCurrentToken() is Value || GetCurrentToken() is BlockEnd)) + { + states.Push(ParserState.YAML_PARSE_BLOCK_MAPPING_KEY_STATE); + return ParseNode(true, true); + } + else + { + state = ParserState.YAML_PARSE_BLOCK_MAPPING_KEY_STATE; + return ProcessEmptyScalar(mark); + } + } + + else + { + state = ParserState.YAML_PARSE_BLOCK_MAPPING_KEY_STATE; + return ProcessEmptyScalar(GetCurrentToken().Start); + } + } + + /// + /// Parse the productions: + /// flow_sequence ::= FLOW-SEQUENCE-START + /// ******************* + /// (flow_sequence_entry FLOW-ENTRY)* + /// * ********** + /// flow_sequence_entry? + /// * + /// FLOW-SEQUENCE-END + /// ***************** + /// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + /// * + /// + private Event ParseFlowSequenceEntry(bool isFirst) + { + if (isFirst) + { + GetCurrentToken(); + Skip(); + } + + Event evt; + if (!(GetCurrentToken() is FlowSequenceEnd)) + { + if (!isFirst) + { + if (GetCurrentToken() is FlowEntry) + { + Skip(); + } + else { var current = GetCurrentToken(); - throw new SemanticErrorException(current.Start, current.End, "While parsing a flow sequence, did not find expected ',' or ']'."); - } - } - - if (GetCurrentToken() is Key) - { - state = ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE; - evt = new Events.MappingStart(null, null, true, MappingStyle.Flow); - Skip(); - return evt; - } - else if (!(GetCurrentToken() is FlowSequenceEnd)) - { - states.Push(ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE); - return ParseNode(false, false); - } - } - - state = states.Pop(); - evt = new Events.SequenceEnd(GetCurrentToken().Start, GetCurrentToken().End); - Skip(); - return evt; - } - - /// - /// Parse the productions: - /// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - /// *** * - /// - private Event ParseFlowSequenceEntryMappingKey() - { - if (!(GetCurrentToken() is Value || GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowSequenceEnd)) - { - states.Push(ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE); - return ParseNode(false, false); - } - else - { - Mark mark = GetCurrentToken().End; - Skip(); - state = ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE; - return ProcessEmptyScalar(mark); - } - } - - /// - /// Parse the productions: - /// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - /// ***** * - /// - private Event ParseFlowSequenceEntryMappingValue() - { - if (GetCurrentToken() is Value) - { - Skip(); - if (!(GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowSequenceEnd)) - { - states.Push(ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE); - return ParseNode(false, false); - } - } - state = ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE; - return ProcessEmptyScalar(GetCurrentToken().Start); - } - - /// - /// Parse the productions: - /// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - /// * - /// - private Event ParseFlowSequenceEntryMappingEnd() - { - state = ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE; - return new Events.MappingEnd(GetCurrentToken().Start, GetCurrentToken().End); - } - - /// - /// Parse the productions: - /// flow_mapping ::= FLOW-MAPPING-START - /// ****************** - /// (flow_mapping_entry FLOW-ENTRY)* - /// * ********** - /// flow_mapping_entry? - /// ****************** - /// FLOW-MAPPING-END - /// **************** - /// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - /// * *** * - /// - private Event ParseFlowMappingKey(bool isFirst) - { - if (isFirst) - { - GetCurrentToken(); - Skip(); - } - - if (!(GetCurrentToken() is FlowMappingEnd)) - { - if (!isFirst) - { - if (GetCurrentToken() is FlowEntry) - { - Skip(); - } - else + throw new SemanticErrorException(current.Start, current.End, "While parsing a flow sequence, did not find expected ',' or ']'."); + } + } + + if (GetCurrentToken() is Key) + { + state = ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE; + evt = new Events.MappingStart(null, null, true, MappingStyle.Flow); + Skip(); + return evt; + } + else if (!(GetCurrentToken() is FlowSequenceEnd)) + { + states.Push(ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE); + return ParseNode(false, false); + } + } + + state = states.Pop(); + evt = new Events.SequenceEnd(GetCurrentToken().Start, GetCurrentToken().End); + Skip(); + return evt; + } + + /// + /// Parse the productions: + /// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + /// *** * + /// + private Event ParseFlowSequenceEntryMappingKey() + { + if (!(GetCurrentToken() is Value || GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowSequenceEnd)) + { + states.Push(ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE); + return ParseNode(false, false); + } + else + { + Mark mark = GetCurrentToken().End; + Skip(); + state = ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE; + return ProcessEmptyScalar(mark); + } + } + + /// + /// Parse the productions: + /// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + /// ***** * + /// + private Event ParseFlowSequenceEntryMappingValue() + { + if (GetCurrentToken() is Value) + { + Skip(); + if (!(GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowSequenceEnd)) + { + states.Push(ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE); + return ParseNode(false, false); + } + } + state = ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE; + return ProcessEmptyScalar(GetCurrentToken().Start); + } + + /// + /// Parse the productions: + /// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + /// * + /// + private Event ParseFlowSequenceEntryMappingEnd() + { + state = ParserState.YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE; + return new Events.MappingEnd(GetCurrentToken().Start, GetCurrentToken().End); + } + + /// + /// Parse the productions: + /// flow_mapping ::= FLOW-MAPPING-START + /// ****************** + /// (flow_mapping_entry FLOW-ENTRY)* + /// * ********** + /// flow_mapping_entry? + /// ****************** + /// FLOW-MAPPING-END + /// **************** + /// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + /// * *** * + /// + private Event ParseFlowMappingKey(bool isFirst) + { + if (isFirst) + { + GetCurrentToken(); + Skip(); + } + + if (!(GetCurrentToken() is FlowMappingEnd)) + { + if (!isFirst) + { + if (GetCurrentToken() is FlowEntry) + { + Skip(); + } + else { var current = GetCurrentToken(); - throw new SemanticErrorException(current.Start, current.End, "While parsing a flow mapping, did not find expected ',' or '}'."); - } - } - - if (GetCurrentToken() is Key) - { - Skip(); - - if (!(GetCurrentToken() is Value || GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowMappingEnd)) - { - states.Push(ParserState.YAML_PARSE_FLOW_MAPPING_VALUE_STATE); - return ParseNode(false, false); - } - else - { - state = ParserState.YAML_PARSE_FLOW_MAPPING_VALUE_STATE; - return ProcessEmptyScalar(GetCurrentToken().Start); - } - } - else if (!(GetCurrentToken() is FlowMappingEnd)) - { - states.Push(ParserState.YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE); - return ParseNode(false, false); - } - } - - state = states.Pop(); - Event evt = new Events.MappingEnd(GetCurrentToken().Start, GetCurrentToken().End); - Skip(); - return evt; - } - - /// - /// Parse the productions: - /// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - /// * ***** * - /// - private Event ParseFlowMappingValue(bool isEmpty) - { - if (isEmpty) - { - state = ParserState.YAML_PARSE_FLOW_MAPPING_KEY_STATE; - return ProcessEmptyScalar(GetCurrentToken().Start); - } - - if (GetCurrentToken() is Value) - { - Skip(); - if (!(GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowMappingEnd)) - { - states.Push(ParserState.YAML_PARSE_FLOW_MAPPING_KEY_STATE); - return ParseNode(false, false); - } - } - - state = ParserState.YAML_PARSE_FLOW_MAPPING_KEY_STATE; - return ProcessEmptyScalar(GetCurrentToken().Start); - } - } -} + throw new SemanticErrorException(current.Start, current.End, "While parsing a flow mapping, did not find expected ',' or '}'."); + } + } + + if (GetCurrentToken() is Key) + { + Skip(); + + if (!(GetCurrentToken() is Value || GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowMappingEnd)) + { + states.Push(ParserState.YAML_PARSE_FLOW_MAPPING_VALUE_STATE); + return ParseNode(false, false); + } + else + { + state = ParserState.YAML_PARSE_FLOW_MAPPING_VALUE_STATE; + return ProcessEmptyScalar(GetCurrentToken().Start); + } + } + else if (!(GetCurrentToken() is FlowMappingEnd)) + { + states.Push(ParserState.YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE); + return ParseNode(false, false); + } + } + + state = states.Pop(); + Event evt = new Events.MappingEnd(GetCurrentToken().Start, GetCurrentToken().End); + Skip(); + return evt; + } + + /// + /// Parse the productions: + /// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + /// * ***** * + /// + private Event ParseFlowMappingValue(bool isEmpty) + { + if (isEmpty) + { + state = ParserState.YAML_PARSE_FLOW_MAPPING_KEY_STATE; + return ProcessEmptyScalar(GetCurrentToken().Start); + } + + if (GetCurrentToken() is Value) + { + Skip(); + if (!(GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowMappingEnd)) + { + states.Push(ParserState.YAML_PARSE_FLOW_MAPPING_KEY_STATE); + return ParseNode(false, false); + } + } + + state = ParserState.YAML_PARSE_FLOW_MAPPING_KEY_STATE; + return ProcessEmptyScalar(GetCurrentToken().Start); + } + } +} diff --git a/YamlDotNet.Core/ScalarStyle.cs b/YamlDotNet.Core/ScalarStyle.cs index 88d123c..c2a0e51 100644 --- a/YamlDotNet.Core/ScalarStyle.cs +++ b/YamlDotNet.Core/ScalarStyle.cs @@ -19,43 +19,43 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; - -namespace YamlDotNet.Core -{ - /// - /// Specifies the style of a YAML scalar. - /// - public enum ScalarStyle - { - /// - /// Let the emitter choose the style. - /// - Any, - - /// - /// The plain scalar style. - /// - Plain, - - /// - /// The single-quoted scalar style. - /// - SingleQuoted, - - /// - /// The double-quoted scalar style. - /// - DoubleQuoted, - - /// - /// The literal scalar style. - /// - Literal, - - /// - /// The folded scalar style. - /// - Folded, - } +using System; + +namespace YamlDotNet.Core +{ + /// + /// Specifies the style of a YAML scalar. + /// + public enum ScalarStyle + { + /// + /// Let the emitter choose the style. + /// + Any, + + /// + /// The plain scalar style. + /// + Plain, + + /// + /// The single-quoted scalar style. + /// + SingleQuoted, + + /// + /// The double-quoted scalar style. + /// + DoubleQuoted, + + /// + /// The literal scalar style. + /// + Literal, + + /// + /// The folded scalar style. + /// + Folded, + } } \ No newline at end of file diff --git a/YamlDotNet.Core/StringLookAheadBuffer.cs b/YamlDotNet.Core/StringLookAheadBuffer.cs index dbe18f0..059f7cc 100644 --- a/YamlDotNet.Core/StringLookAheadBuffer.cs +++ b/YamlDotNet.Core/StringLookAheadBuffer.cs @@ -19,54 +19,54 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; - -namespace YamlDotNet.Core -{ - internal class StringLookAheadBuffer : ILookAheadBuffer - { - private readonly string value; - private int currentIndex; - - public int Length { - get { - return value.Length; - } - } - - public int Position { - get { - return currentIndex; - } - } - - private bool IsOutside(int index) { - return index >= value.Length; - } - - public bool EndOfInput { - get { - return IsOutside(currentIndex); - } - } - - public StringLookAheadBuffer(string value) - { - this.value = value; - } - - public char Peek(int offset) - { - int index = currentIndex + offset; - return IsOutside(index) ? '\0' : value[index]; - } - - public void Skip(int length) - { - if(length < 0) { - throw new ArgumentOutOfRangeException("length", "The length must be positive."); - } - currentIndex += length; - } - } +using System; + +namespace YamlDotNet.Core +{ + internal class StringLookAheadBuffer : ILookAheadBuffer + { + private readonly string value; + private int currentIndex; + + public int Length { + get { + return value.Length; + } + } + + public int Position { + get { + return currentIndex; + } + } + + private bool IsOutside(int index) { + return index >= value.Length; + } + + public bool EndOfInput { + get { + return IsOutside(currentIndex); + } + } + + public StringLookAheadBuffer(string value) + { + this.value = value; + } + + public char Peek(int offset) + { + int index = currentIndex + offset; + return IsOutside(index) ? '\0' : value[index]; + } + + public void Skip(int length) + { + if(length < 0) { + throw new ArgumentOutOfRangeException("length", "The length must be positive."); + } + currentIndex += length; + } + } } \ No newline at end of file diff --git a/YamlDotNet.Core/Tokens/AnchorAlias.cs b/YamlDotNet.Core/Tokens/AnchorAlias.cs index 1a94a7a..6f0e7c5 100644 --- a/YamlDotNet.Core/Tokens/AnchorAlias.cs +++ b/YamlDotNet.Core/Tokens/AnchorAlias.cs @@ -19,48 +19,48 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. - -using System; - -namespace YamlDotNet.Core.Tokens -{ - /// - /// Represents an alias token. - /// - public class AnchorAlias : Token - { - private readonly string value; - - /// - /// Gets the value of the alias. - /// - public string Value - { - get - { - return value; - } - } - - /// - /// Initializes a new instance of the class. - /// - /// The value of the anchor. - public AnchorAlias(string value) - : this(value, Mark.Empty, Mark.Empty) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The value of the anchor. - /// The start position of the event. - /// The end position of the event. - public AnchorAlias(string value, Mark start, Mark end) - : base(start, end) - { - this.value = value; - } - } + +using System; + +namespace YamlDotNet.Core.Tokens +{ + /// + /// Represents an alias token. + /// + public class AnchorAlias : Token + { + private readonly string value; + + /// + /// Gets the value of the alias. + /// + public string Value + { + get + { + return value; + } + } + + /// + /// Initializes a new instance of the class. + /// + /// The value of the anchor. + public AnchorAlias(string value) + : this(value, Mark.Empty, Mark.Empty) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The value of the anchor. + /// The start position of the event. + /// The end position of the event. + public AnchorAlias(string value, Mark start, Mark end) + : base(start, end) + { + this.value = value; + } + } } \ No newline at end of file diff --git a/YamlDotNet.Core/YamlException.cs b/YamlDotNet.Core/YamlException.cs index e3a308a..df9a6c0 100644 --- a/YamlDotNet.Core/YamlException.cs +++ b/YamlDotNet.Core/YamlException.cs @@ -39,7 +39,7 @@ namespace YamlDotNet.Core /// /// Gets the position in the input stream where the event that originated the exception ends. /// - public Mark End { get; private set; } + public Mark End { get; private set; } /// /// Initializes a new instance of the class. diff --git a/YamlDotNet.RepresentationModel/IYamlVisitor.cs b/YamlDotNet.RepresentationModel/IYamlVisitor.cs index 25d9ed8..8f4232b 100644 --- a/YamlDotNet.RepresentationModel/IYamlVisitor.cs +++ b/YamlDotNet.RepresentationModel/IYamlVisitor.cs @@ -19,53 +19,53 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; - -namespace YamlDotNet.RepresentationModel -{ - /// - /// Defines the method needed to be able to visit Yaml elements. - /// - public interface IYamlVisitor - { - /// - /// Visits a . - /// - /// - /// The that is being visited. - /// - void Visit(YamlStream stream); - - /// - /// Visits a . - /// - /// - /// The that is being visited. - /// - void Visit(YamlDocument document); - - /// - /// Visits a . - /// - /// - /// The that is being visited. - /// - void Visit(YamlScalarNode scalar); - - /// - /// Visits a . - /// - /// - /// The that is being visited. - /// - void Visit(YamlSequenceNode sequence); - - /// - /// Visits a . - /// - /// - /// The that is being visited. - /// - void Visit(YamlMappingNode mapping); - } +using System; + +namespace YamlDotNet.RepresentationModel +{ + /// + /// Defines the method needed to be able to visit Yaml elements. + /// + public interface IYamlVisitor + { + /// + /// Visits a . + /// + /// + /// The that is being visited. + /// + void Visit(YamlStream stream); + + /// + /// Visits a . + /// + /// + /// The that is being visited. + /// + void Visit(YamlDocument document); + + /// + /// Visits a . + /// + /// + /// The that is being visited. + /// + void Visit(YamlScalarNode scalar); + + /// + /// Visits a . + /// + /// + /// The that is being visited. + /// + void Visit(YamlSequenceNode sequence); + + /// + /// Visits a . + /// + /// + /// The that is being visited. + /// + void Visit(YamlMappingNode mapping); + } } \ No newline at end of file diff --git a/YamlDotNet.RepresentationModel/Serialization/AliasValueDeserializer.cs b/YamlDotNet.RepresentationModel/Serialization/AliasValueDeserializer.cs index 9f647b1..317af8b 100644 --- a/YamlDotNet.RepresentationModel/Serialization/AliasValueDeserializer.cs +++ b/YamlDotNet.RepresentationModel/Serialization/AliasValueDeserializer.cs @@ -1,31 +1,31 @@ -// This file is part of YamlDotNet - A .NET library for YAML. -// Copyright (c) 2013 Antoine Aubry -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Collections.Generic; -using YamlDotNet.Core; -using YamlDotNet.Core.Events; - -namespace YamlDotNet.RepresentationModel.Serialization -{ +// This file is part of YamlDotNet - A .NET library for YAML. +// Copyright (c) 2013 Antoine Aubry +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using YamlDotNet.Core; +using YamlDotNet.Core.Events; + +namespace YamlDotNet.RepresentationModel.Serialization +{ public sealed class AliasValueDeserializer : IValueDeserializer { private readonly IValueDeserializer innerDeserializer; @@ -35,12 +35,12 @@ namespace YamlDotNet.RepresentationModel.Serialization if (innerDeserializer == null) { throw new ArgumentNullException ("innerDeserializer"); - } + } this.innerDeserializer = innerDeserializer; } - private sealed class AliasState : Dictionary, IDisposable + private sealed class AliasState : Dictionary, IDisposable { public void Dispose() { @@ -103,39 +103,39 @@ namespace YamlDotNet.RepresentationModel.Serialization } } } - } + } public object DeserializeValue (EventReader reader, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) - { - object value; - var alias = reader.Allow(); - if(alias != null) - { + { + object value; + var alias = reader.Allow(); + if(alias != null) + { var aliasState = state.Get(); - ValuePromise valuePromise; - if(!aliasState.TryGetValue(alias.Value, out valuePromise)) + ValuePromise valuePromise; + if(!aliasState.TryGetValue(alias.Value, out valuePromise)) { valuePromise = new ValuePromise(alias); - aliasState.Add(alias.Value, valuePromise); + aliasState.Add(alias.Value, valuePromise); } - return valuePromise.HasValue ? valuePromise.Value : valuePromise; - } - - string anchor = null; - - var nodeEvent = reader.Peek(); - if(nodeEvent != null && !string.IsNullOrEmpty(nodeEvent.Anchor)) - { - anchor = nodeEvent.Anchor; - } + return valuePromise.HasValue ? valuePromise.Value : valuePromise; + } - value = innerDeserializer.DeserializeValue(reader, expectedType, state, nestedObjectDeserializer); - - if(anchor != null) - { - var aliasState = state.Get(); - + string anchor = null; + + var nodeEvent = reader.Peek(); + if(nodeEvent != null && !string.IsNullOrEmpty(nodeEvent.Anchor)) + { + anchor = nodeEvent.Anchor; + } + + value = innerDeserializer.DeserializeValue(reader, expectedType, state, nestedObjectDeserializer); + + if(anchor != null) + { + var aliasState = state.Get(); + ValuePromise valuePromise; if (!aliasState.TryGetValue(anchor, out valuePromise)) { @@ -151,10 +151,10 @@ namespace YamlDotNet.RepresentationModel.Serialization "Anchor '{0}' already defined", alias.Value )); - } - } - + } + } + return value; } - } -} + } +} diff --git a/YamlDotNet.RepresentationModel/Serialization/Deserializer.cs b/YamlDotNet.RepresentationModel/Serialization/Deserializer.cs index 92ed197..32db8fb 100644 --- a/YamlDotNet.RepresentationModel/Serialization/Deserializer.cs +++ b/YamlDotNet.RepresentationModel/Serialization/Deserializer.cs @@ -1,22 +1,22 @@ -// This file is part of YamlDotNet - A .NET library for YAML. -// Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Antoine Aubry - -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -// of the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// This file is part of YamlDotNet - A .NET library for YAML. +// Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Antoine Aubry + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +// of the Software, and to permit persons to whom the Software is furnished to do +// so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. using System; @@ -28,76 +28,76 @@ using YamlDotNet.RepresentationModel.Serialization.NamingConventions; using YamlDotNet.RepresentationModel.Serialization.NodeDeserializers; using YamlDotNet.RepresentationModel.Serialization.NodeTypeResolvers; -namespace YamlDotNet.RepresentationModel.Serialization -{ - /// - /// A façade for the YAML library with the standard configuration. - /// - public sealed class Deserializer - { - private static readonly Dictionary predefinedTagMappings = new Dictionary - { - { "tag:yaml.org,2002:map", typeof(Dictionary) }, - { "tag:yaml.org,2002:bool", typeof(bool) }, - { "tag:yaml.org,2002:float", typeof(double) }, - { "tag:yaml.org,2002:int", typeof(int) }, - { "tag:yaml.org,2002:str", typeof(string) }, - { "tag:yaml.org,2002:timestamp", typeof(DateTime) }, - }; - - private readonly Dictionary tagMappings; - private readonly List converters; +namespace YamlDotNet.RepresentationModel.Serialization +{ + /// + /// A façade for the YAML library with the standard configuration. + /// + public sealed class Deserializer + { + private static readonly Dictionary predefinedTagMappings = new Dictionary + { + { "tag:yaml.org,2002:map", typeof(Dictionary) }, + { "tag:yaml.org,2002:bool", typeof(bool) }, + { "tag:yaml.org,2002:float", typeof(double) }, + { "tag:yaml.org,2002:int", typeof(int) }, + { "tag:yaml.org,2002:str", typeof(string) }, + { "tag:yaml.org,2002:timestamp", typeof(DateTime) }, + }; + + private readonly Dictionary tagMappings; + private readonly List converters; private TypeDescriptorProxy typeDescriptor = new TypeDescriptorProxy(); - private IValueDeserializer valueDeserializer; + private IValueDeserializer valueDeserializer; public IList NodeDeserializers { get; private set; } public IList TypeResolvers { get; private set; } - - private class TypeDescriptorProxy : ITypeDescriptor - { - public ITypeDescriptor TypeDescriptor; - - public IEnumerable GetProperties(Type type) - { - return TypeDescriptor.GetProperties(type); - } - - public IPropertyDescriptor GetProperty(Type type, string name) - { - return TypeDescriptor.GetProperty(type, name); - } + + private class TypeDescriptorProxy : ITypeDescriptor + { + public ITypeDescriptor TypeDescriptor; + + public IEnumerable GetProperties(Type type) + { + return TypeDescriptor.GetProperties(type); + } + + public IPropertyDescriptor GetProperty(Type type, string name) + { + return TypeDescriptor.GetProperty(type, name); + } } public Deserializer(IObjectFactory objectFactory = null, INamingConvention namingConvention = null) { objectFactory = objectFactory ?? new DefaultObjectFactory(); namingConvention = namingConvention ?? new NullNamingConvention(); - - typeDescriptor.TypeDescriptor = - new YamlAttributesTypeDescriptor( - new NamingConventionTypeDescriptor( - new ReadableAndWritablePropertiesTypeDescriptor(), - namingConvention - ) - ); - + + typeDescriptor.TypeDescriptor = + new YamlAttributesTypeDescriptor( + new NamingConventionTypeDescriptor( + new ReadableAndWritablePropertiesTypeDescriptor(), + namingConvention + ) + ); + converters = new List(); - NodeDeserializers = new List(); - NodeDeserializers.Add(new TypeConverterNodeDeserializer(converters)); - NodeDeserializers.Add(new NullNodeDeserializer()); - NodeDeserializers.Add(new ScalarNodeDeserializer()); - NodeDeserializers.Add(new ArrayNodeDeserializer()); - NodeDeserializers.Add(new GenericDictionaryNodeDeserializer(objectFactory)); - NodeDeserializers.Add(new NonGenericDictionaryNodeDeserializer(objectFactory)); - NodeDeserializers.Add(new GenericCollectionNodeDeserializer(objectFactory)); - NodeDeserializers.Add(new NonGenericListNodeDeserializer(objectFactory)); - NodeDeserializers.Add(new EnumerableNodeDeserializer()); - NodeDeserializers.Add(new ObjectNodeDeserializer(objectFactory, typeDescriptor)); - - tagMappings = new Dictionary(predefinedTagMappings); + NodeDeserializers = new List(); + NodeDeserializers.Add(new TypeConverterNodeDeserializer(converters)); + NodeDeserializers.Add(new NullNodeDeserializer()); + NodeDeserializers.Add(new ScalarNodeDeserializer()); + NodeDeserializers.Add(new ArrayNodeDeserializer()); + NodeDeserializers.Add(new GenericDictionaryNodeDeserializer(objectFactory)); + NodeDeserializers.Add(new NonGenericDictionaryNodeDeserializer(objectFactory)); + NodeDeserializers.Add(new GenericCollectionNodeDeserializer(objectFactory)); + NodeDeserializers.Add(new NonGenericListNodeDeserializer(objectFactory)); + NodeDeserializers.Add(new EnumerableNodeDeserializer()); + NodeDeserializers.Add(new ObjectNodeDeserializer(objectFactory, typeDescriptor)); + + tagMappings = new Dictionary(predefinedTagMappings); TypeResolvers = new List(); - TypeResolvers.Add(new TagNodeTypeResolver(tagMappings)); - TypeResolvers.Add(new TypeNameInTagNodeTypeResolver()); + TypeResolvers.Add(new TagNodeTypeResolver(tagMappings)); + TypeResolvers.Add(new TypeNameInTagNodeTypeResolver()); TypeResolvers.Add(new DefaultContainersNodeTypeResolver()); valueDeserializer = @@ -106,17 +106,17 @@ namespace YamlDotNet.RepresentationModel.Serialization NodeDeserializers, TypeResolvers ) - ); - } - - public void RegisterTagMapping(string tag, Type type) - { - tagMappings.Add(tag, type); - } - - public void RegisterTypeConverter(IYamlTypeConverter typeConverter) - { - converters.Add(typeConverter); + ); + } + + public void RegisterTagMapping(string tag, Type type) + { + tagMappings.Add(tag, type); + } + + public void RegisterTypeConverter(IYamlTypeConverter typeConverter) + { + converters.Add(typeConverter); } public T Deserialize(TextReader input) @@ -187,5 +187,5 @@ namespace YamlDotNet.RepresentationModel.Serialization return result; } - } + } } \ No newline at end of file diff --git a/YamlDotNet.RepresentationModel/Serialization/INodeDeserializer.cs b/YamlDotNet.RepresentationModel/Serialization/INodeDeserializer.cs index 4395175..be8c9db 100644 --- a/YamlDotNet.RepresentationModel/Serialization/INodeDeserializer.cs +++ b/YamlDotNet.RepresentationModel/Serialization/INodeDeserializer.cs @@ -18,7 +18,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - + using System; using YamlDotNet.Core; diff --git a/YamlDotNet.RepresentationModel/Serialization/INodeTypeResolver.cs b/YamlDotNet.RepresentationModel/Serialization/INodeTypeResolver.cs index 6b142cb..4fae906 100644 --- a/YamlDotNet.RepresentationModel/Serialization/INodeTypeResolver.cs +++ b/YamlDotNet.RepresentationModel/Serialization/INodeTypeResolver.cs @@ -18,7 +18,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - + using System; using YamlDotNet.Core.Events; diff --git a/YamlDotNet.RepresentationModel/Serialization/IValueDeserializer.cs b/YamlDotNet.RepresentationModel/Serialization/IValueDeserializer.cs index 52a6092..d9c16f6 100644 --- a/YamlDotNet.RepresentationModel/Serialization/IValueDeserializer.cs +++ b/YamlDotNet.RepresentationModel/Serialization/IValueDeserializer.cs @@ -1,31 +1,31 @@ -// This file is part of YamlDotNet - A .NET library for YAML. -// Copyright (c) 2013 Antoine Aubry -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using YamlDotNet.Core; - -namespace YamlDotNet.RepresentationModel.Serialization -{ +// This file is part of YamlDotNet - A .NET library for YAML. +// Copyright (c) 2013 Antoine Aubry +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using YamlDotNet.Core; + +namespace YamlDotNet.RepresentationModel.Serialization +{ public interface IValueDeserializer { object DeserializeValue(EventReader reader, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer); - } -} + } +} diff --git a/YamlDotNet.RepresentationModel/Serialization/IYamlSerializable.cs b/YamlDotNet.RepresentationModel/Serialization/IYamlSerializable.cs index 3594193..d6d6dc5 100644 --- a/YamlDotNet.RepresentationModel/Serialization/IYamlSerializable.cs +++ b/YamlDotNet.RepresentationModel/Serialization/IYamlSerializable.cs @@ -19,24 +19,24 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; -using YamlDotNet.Core; - -namespace YamlDotNet.RepresentationModel -{ - /// - /// Allows an object to customize how it is serialized and deserialized. - /// - public interface IYamlSerializable - { - /// - /// Reads this object's state from a YAML parser. +using System; +using YamlDotNet.Core; + +namespace YamlDotNet.RepresentationModel +{ + /// + /// Allows an object to customize how it is serialized and deserialized. + /// + public interface IYamlSerializable + { + /// + /// Reads this object's state from a YAML parser. /// - void ReadYaml(IParser parser); - - /// - /// Writes this object's state to a YAML emitter. - /// - void WriteYaml(IEmitter emitter); - } + void ReadYaml(IParser parser); + + /// + /// Writes this object's state to a YAML emitter. + /// + void WriteYaml(IEmitter emitter); + } } \ No newline at end of file diff --git a/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/EnumerableNodeDeserializer.cs b/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/EnumerableNodeDeserializer.cs index 5525450..bbc0658 100644 --- a/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/EnumerableNodeDeserializer.cs +++ b/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/EnumerableNodeDeserializer.cs @@ -26,6 +26,31 @@ using YamlDotNet.Core; namespace YamlDotNet.RepresentationModel.Serialization.NodeDeserializers { - public sealed class EnumerableNodeDeserializer : INodeDeserializer { bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) { Type itemsType; if (expectedType == typeof(IEnumerable)) { itemsType = typeof(object); } else { var iEnumerable = ReflectionUtility.GetImplementedGenericInterface(expectedType, typeof(IEnumerable<>)); if (iEnumerable != expectedType) { value = null; return false; } itemsType = iEnumerable.GetGenericArguments()[0]; } var collectionType = typeof(List<>).MakeGenericType(itemsType); value = nestedObjectDeserializer(reader, collectionType); return true; } } + public sealed class EnumerableNodeDeserializer : INodeDeserializer + { + bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) + { + Type itemsType; + if (expectedType == typeof(IEnumerable)) + { + itemsType = typeof(object); + } + else + { + var iEnumerable = ReflectionUtility.GetImplementedGenericInterface(expectedType, typeof(IEnumerable<>)); + if (iEnumerable != expectedType) + { + value = null; + return false; + } + + itemsType = iEnumerable.GetGenericArguments()[0]; + } + + var collectionType = typeof(List<>).MakeGenericType(itemsType); + value = nestedObjectDeserializer(reader, collectionType); + return true; + } + } } diff --git a/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/GenericCollectionNodeDeserializer.cs b/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/GenericCollectionNodeDeserializer.cs index c272059..7644523 100644 --- a/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/GenericCollectionNodeDeserializer.cs +++ b/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/GenericCollectionNodeDeserializer.cs @@ -18,7 +18,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - + using System; using System.Collections.Generic; using YamlDotNet.Core; diff --git a/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/GenericDictionaryNodeDeserializer.cs b/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/GenericDictionaryNodeDeserializer.cs index 1639df6..4566bea 100644 --- a/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/GenericDictionaryNodeDeserializer.cs +++ b/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/GenericDictionaryNodeDeserializer.cs @@ -18,7 +18,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - + using System; using System.Collections.Generic; using System.Reflection; diff --git a/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/NonGenericDictionaryNodeDeserializer.cs b/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/NonGenericDictionaryNodeDeserializer.cs index 4b25a34..a946dc4 100644 --- a/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/NonGenericDictionaryNodeDeserializer.cs +++ b/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/NonGenericDictionaryNodeDeserializer.cs @@ -18,7 +18,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - + using System; using System.Collections; using YamlDotNet.Core; diff --git a/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs b/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs index 640ddd4..709dad3 100644 --- a/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs +++ b/YamlDotNet.RepresentationModel/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs @@ -18,7 +18,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - + using System; using System.ComponentModel; using System.Globalization; diff --git a/YamlDotNet.RepresentationModel/Serialization/NodeTypeResolvers/DefaultContainersNodeTypeResolver.cs b/YamlDotNet.RepresentationModel/Serialization/NodeTypeResolvers/DefaultContainersNodeTypeResolver.cs index fe1aa6d..fded3d7 100644 --- a/YamlDotNet.RepresentationModel/Serialization/NodeTypeResolvers/DefaultContainersNodeTypeResolver.cs +++ b/YamlDotNet.RepresentationModel/Serialization/NodeTypeResolvers/DefaultContainersNodeTypeResolver.cs @@ -18,7 +18,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - + using System; using System.Collections.Generic; using YamlDotNet.Core.Events; diff --git a/YamlDotNet.RepresentationModel/Serialization/NodeTypeResolvers/TagNodeTypeResolver.cs b/YamlDotNet.RepresentationModel/Serialization/NodeTypeResolvers/TagNodeTypeResolver.cs index 3d5bd73..9b3f1a4 100644 --- a/YamlDotNet.RepresentationModel/Serialization/NodeTypeResolvers/TagNodeTypeResolver.cs +++ b/YamlDotNet.RepresentationModel/Serialization/NodeTypeResolvers/TagNodeTypeResolver.cs @@ -18,7 +18,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - + using System; using System.Collections.Generic; using YamlDotNet.Core.Events; diff --git a/YamlDotNet.RepresentationModel/Serialization/NodeTypeResolvers/TypeNameInTagNodeTypeResolver.cs b/YamlDotNet.RepresentationModel/Serialization/NodeTypeResolvers/TypeNameInTagNodeTypeResolver.cs index 94e0416..4696e36 100644 --- a/YamlDotNet.RepresentationModel/Serialization/NodeTypeResolvers/TypeNameInTagNodeTypeResolver.cs +++ b/YamlDotNet.RepresentationModel/Serialization/NodeTypeResolvers/TypeNameInTagNodeTypeResolver.cs @@ -18,7 +18,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - + using System; using YamlDotNet.Core.Events; diff --git a/YamlDotNet.RepresentationModel/Serialization/NodeValueDeserializer.cs b/YamlDotNet.RepresentationModel/Serialization/NodeValueDeserializer.cs index aed2a19..de3ae45 100644 --- a/YamlDotNet.RepresentationModel/Serialization/NodeValueDeserializer.cs +++ b/YamlDotNet.RepresentationModel/Serialization/NodeValueDeserializer.cs @@ -1,32 +1,32 @@ -// This file is part of YamlDotNet - A .NET library for YAML. -// Copyright (c) 2013 Antoine Aubry -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; -using YamlDotNet.Core; -using YamlDotNet.Core.Events; - -namespace YamlDotNet.RepresentationModel.Serialization -{ +// This file is part of YamlDotNet - A .NET library for YAML. +// Copyright (c) 2013 Antoine Aubry +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using YamlDotNet.Core; +using YamlDotNet.Core.Events; + +namespace YamlDotNet.RepresentationModel.Serialization +{ public sealed class NodeValueDeserializer : IValueDeserializer { private readonly IList deserializers; @@ -83,5 +83,5 @@ namespace YamlDotNet.RepresentationModel.Serialization } return currentType; } - } -} + } +} diff --git a/YamlDotNet.RepresentationModel/Serialization/SerializerState.cs b/YamlDotNet.RepresentationModel/Serialization/SerializerState.cs index e5f403b..f28a3d5 100644 --- a/YamlDotNet.RepresentationModel/Serialization/SerializerState.cs +++ b/YamlDotNet.RepresentationModel/Serialization/SerializerState.cs @@ -1,48 +1,48 @@ -// This file is part of YamlDotNet - A .NET library for YAML. -// Copyright (c) 2013 Antoine Aubry -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; +// This file is part of YamlDotNet - A .NET library for YAML. +// Copyright (c) 2013 Antoine Aubry +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; using System.Collections.Generic; -using System.Linq; - -namespace YamlDotNet.RepresentationModel.Serialization -{ +using System.Linq; + +namespace YamlDotNet.RepresentationModel.Serialization +{ /// /// A generic container that is preserved during the entire deserialization process. /// Any disposable object added to this collecion will be disposed when this object is disposed. - /// - public sealed class SerializerState : IDisposable - { - private readonly IDictionary items = new Dictionary(); - - public T Get() - where T : class, new() - { - object value; - if(!items.TryGetValue(typeof(T), out value)) - { - value = new T(); - items.Add(typeof(T), value); - } - return (T)value; + /// + public sealed class SerializerState : IDisposable + { + private readonly IDictionary items = new Dictionary(); + + public T Get() + where T : class, new() + { + object value; + if(!items.TryGetValue(typeof(T), out value)) + { + value = new T(); + items.Add(typeof(T), value); + } + return (T)value; } public void Dispose() @@ -52,5 +52,5 @@ namespace YamlDotNet.RepresentationModel.Serialization disposable.Dispose(); } } - } -} + } +} diff --git a/YamlDotNet.RepresentationModel/Serialization/StreamFragment.cs b/YamlDotNet.RepresentationModel/Serialization/StreamFragment.cs index b81fd09..0f3942d 100644 --- a/YamlDotNet.RepresentationModel/Serialization/StreamFragment.cs +++ b/YamlDotNet.RepresentationModel/Serialization/StreamFragment.cs @@ -67,7 +67,7 @@ namespace YamlDotNet.RepresentationModel.Serialization depth += parser.Current.NestingIncrease; } while (depth > 0); - Debug.Assert(depth == 0); + Debug.Assert(depth == 0); } /// diff --git a/YamlDotNet.RepresentationModel/Serialization/StringExtensions.cs b/YamlDotNet.RepresentationModel/Serialization/StringExtensions.cs index 64b8e23..8da603b 100644 --- a/YamlDotNet.RepresentationModel/Serialization/StringExtensions.cs +++ b/YamlDotNet.RepresentationModel/Serialization/StringExtensions.cs @@ -1,58 +1,58 @@ using System; using System.Text.RegularExpressions; -namespace YamlDotNet.RepresentationModel.Serialization -{ - /// - /// Various string extension methods - /// - internal static class StringExtensions - { +namespace YamlDotNet.RepresentationModel.Serialization +{ + /// + /// Various string extension methods + /// + internal static class StringExtensions + { private static string ToCamelOrPascalCase(string str, Func firstLetterTransform) { var text = Regex.Replace(str, "([_\\-])(?[a-z])", match => match.Groups["char"].Value.ToUpperInvariant(), RegexOptions.IgnoreCase); return firstLetterTransform(text[0]) + text.Substring(1); } - - /// - /// Convert the string with underscores (this_is_a_test) or hyphens (this-is-a-test) to - /// camel case (thisIsATest). Camel case is the same as Pascal case, except the first letter - /// is lowercase. - /// - /// String to convert - /// Converted string - public static string ToCamelCase(this string str) - { - return ToCamelOrPascalCase(str, char.ToLowerInvariant); - } - - /// - /// Convert the string with underscores (this_is_a_test) or hyphens (this-is-a-test) to - /// pascal case (ThisIsATest). Pascal case is the same as camel case, except the first letter - /// is uppercase. - /// - /// String to convert - /// Converted string - public static string ToPascalCase(this string str) - { + + /// + /// Convert the string with underscores (this_is_a_test) or hyphens (this-is-a-test) to + /// camel case (thisIsATest). Camel case is the same as Pascal case, except the first letter + /// is lowercase. + /// + /// String to convert + /// Converted string + public static string ToCamelCase(this string str) + { + return ToCamelOrPascalCase(str, char.ToLowerInvariant); + } + + /// + /// Convert the string with underscores (this_is_a_test) or hyphens (this-is-a-test) to + /// pascal case (ThisIsATest). Pascal case is the same as camel case, except the first letter + /// is uppercase. + /// + /// String to convert + /// Converted string + public static string ToPascalCase(this string str) + { return ToCamelOrPascalCase(str, char.ToUpperInvariant); - } - - /// - /// Convert the string from camelcase (thisIsATest) to a hyphenated (this-is-a-test) or - /// underscored (this_is_a_test) string - /// - /// String to convert - /// Separator to use between segments - /// Converted string - public static string FromCamelCase(this string str, string separator) - { - // Ensure first letter is always lowercase - str = char.ToLower(str[0]) + str.Substring(1); - - str = Regex.Replace(str.ToCamelCase(), "(?[A-Z])", match => separator + match.Groups["char"].Value.ToLowerInvariant()); - return str; - } - } -} + } + + /// + /// Convert the string from camelcase (thisIsATest) to a hyphenated (this-is-a-test) or + /// underscored (this_is_a_test) string + /// + /// String to convert + /// Separator to use between segments + /// Converted string + public static string FromCamelCase(this string str, string separator) + { + // Ensure first letter is always lowercase + str = char.ToLower(str[0]) + str.Substring(1); + + str = Regex.Replace(str.ToCamelCase(), "(?[A-Z])", match => separator + match.Groups["char"].Value.ToLowerInvariant()); + return str; + } + } +} diff --git a/YamlDotNet.RepresentationModel/Serialization/TypeDescriptorSkeleton.cs b/YamlDotNet.RepresentationModel/Serialization/TypeDescriptorSkeleton.cs index afa990e..1a93be3 100644 --- a/YamlDotNet.RepresentationModel/Serialization/TypeDescriptorSkeleton.cs +++ b/YamlDotNet.RepresentationModel/Serialization/TypeDescriptorSkeleton.cs @@ -18,7 +18,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. - + using System; using System.Collections.Generic; using System.Linq; diff --git a/YamlDotNet.RepresentationModel/YamlNode.cs b/YamlDotNet.RepresentationModel/YamlNode.cs index 78f073b..caacc58 100644 --- a/YamlDotNet.RepresentationModel/YamlNode.cs +++ b/YamlDotNet.RepresentationModel/YamlNode.cs @@ -51,7 +51,7 @@ namespace YamlDotNet.RepresentationModel /// /// Gets the position in the input stream where the event that originated the node ends. /// - public Mark End { get; private set; } + public Mark End { get; private set; } /// /// Loads the specified event. diff --git a/YamlDotNet.RepresentationModel/YamlVisitor.cs b/YamlDotNet.RepresentationModel/YamlVisitor.cs index 55d4800..119f615 100644 --- a/YamlDotNet.RepresentationModel/YamlVisitor.cs +++ b/YamlDotNet.RepresentationModel/YamlVisitor.cs @@ -19,204 +19,204 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; - -namespace YamlDotNet.RepresentationModel -{ - /// - /// Abstract implementation of that knows how to walk a complete Yaml object model. - /// - public abstract class YamlVisitor : IYamlVisitor { - /// - /// Called when this object is visiting a . - /// - /// - /// The that is being visited. - /// - protected virtual void Visit (YamlStream stream) - { - // Do nothing. - } - - /// - /// Called after this object finishes visiting a . - /// - /// - /// The that has been visited. - /// - protected virtual void Visited (YamlStream stream) - { - // Do nothing. - } - - /// - /// Called when this object is visiting a . - /// - /// - /// The that is being visited. - /// - protected virtual void Visit (YamlDocument document) { - // Do nothing. - } - - /// - /// Called after this object finishes visiting a . - /// - /// - /// The that has been visited. - /// - protected virtual void Visited (YamlDocument document) - { - // Do nothing. - } - - /// - /// Called when this object is visiting a . - /// - /// - /// The that is being visited. - /// - protected virtual void Visit (YamlScalarNode scalar) - { - // Do nothing. - } - - /// - /// Called after this object finishes visiting a . - /// - /// - /// The that has been visited. - /// - protected virtual void Visited (YamlScalarNode scalar) - { - // Do nothing. - } - - /// - /// Called when this object is visiting a . - /// - /// - /// The that is being visited. - /// - protected virtual void Visit (YamlSequenceNode sequence) - { - // Do nothing. - } - - /// - /// Called after this object finishes visiting a . - /// - /// - /// The that has been visited. - /// - protected virtual void Visited (YamlSequenceNode sequence) - { - // Do nothing. - } - - /// - /// Called when this object is visiting a . - /// - /// - /// The that is being visited. - /// - protected virtual void Visit (YamlMappingNode mapping) - { - // Do nothing. - } - - /// - /// Called after this object finishes visiting a . - /// - /// - /// The that has been visited. - /// - protected virtual void Visited (YamlMappingNode mapping) - { - // Do nothing. - } - - /// - /// Visits every child of a . - /// - /// - /// The that is being visited. - /// - protected virtual void VisitChildren(YamlStream stream) { - foreach (var document in stream.Documents) { - document.Accept(this); - } - } - - /// - /// Visits every child of a . - /// - /// - /// The that is being visited. - /// - protected virtual void VisitChildren(YamlDocument document) { - if(document.RootNode != null) { - document.RootNode.Accept(this); - } - } - - /// - /// Visits every child of a . - /// - /// - /// The that is being visited. - /// - protected virtual void VisitChildren(YamlSequenceNode sequence) { - foreach (var node in sequence.Children) { - node.Accept(this); - } - } - - /// - /// Visits every child of a . - /// - /// - /// The that is being visited. - /// - protected virtual void VisitChildren(YamlMappingNode mapping) { - foreach (var pair in mapping.Children) { - pair.Key.Accept(this); - pair.Value.Accept(this); - } - } - - void IYamlVisitor.Visit (YamlStream stream) - { - Visit(stream); - VisitChildren(stream); - Visited(stream); - } - - void IYamlVisitor.Visit (YamlDocument document) - { - Visit(document); - VisitChildren(document); - Visited(document); - } - - void IYamlVisitor.Visit (YamlScalarNode scalar) - { - Visit(scalar); - Visited(scalar); - } - - void IYamlVisitor.Visit (YamlSequenceNode sequence) - { - Visit(sequence); - VisitChildren(sequence); - Visited(sequence); - } - - void IYamlVisitor.Visit (YamlMappingNode mapping) - { - Visit(mapping); - VisitChildren(mapping); - Visited(mapping); - } - } +using System; + +namespace YamlDotNet.RepresentationModel +{ + /// + /// Abstract implementation of that knows how to walk a complete Yaml object model. + /// + public abstract class YamlVisitor : IYamlVisitor { + /// + /// Called when this object is visiting a . + /// + /// + /// The that is being visited. + /// + protected virtual void Visit (YamlStream stream) + { + // Do nothing. + } + + /// + /// Called after this object finishes visiting a . + /// + /// + /// The that has been visited. + /// + protected virtual void Visited (YamlStream stream) + { + // Do nothing. + } + + /// + /// Called when this object is visiting a . + /// + /// + /// The that is being visited. + /// + protected virtual void Visit (YamlDocument document) { + // Do nothing. + } + + /// + /// Called after this object finishes visiting a . + /// + /// + /// The that has been visited. + /// + protected virtual void Visited (YamlDocument document) + { + // Do nothing. + } + + /// + /// Called when this object is visiting a . + /// + /// + /// The that is being visited. + /// + protected virtual void Visit (YamlScalarNode scalar) + { + // Do nothing. + } + + /// + /// Called after this object finishes visiting a . + /// + /// + /// The that has been visited. + /// + protected virtual void Visited (YamlScalarNode scalar) + { + // Do nothing. + } + + /// + /// Called when this object is visiting a . + /// + /// + /// The that is being visited. + /// + protected virtual void Visit (YamlSequenceNode sequence) + { + // Do nothing. + } + + /// + /// Called after this object finishes visiting a . + /// + /// + /// The that has been visited. + /// + protected virtual void Visited (YamlSequenceNode sequence) + { + // Do nothing. + } + + /// + /// Called when this object is visiting a . + /// + /// + /// The that is being visited. + /// + protected virtual void Visit (YamlMappingNode mapping) + { + // Do nothing. + } + + /// + /// Called after this object finishes visiting a . + /// + /// + /// The that has been visited. + /// + protected virtual void Visited (YamlMappingNode mapping) + { + // Do nothing. + } + + /// + /// Visits every child of a . + /// + /// + /// The that is being visited. + /// + protected virtual void VisitChildren(YamlStream stream) { + foreach (var document in stream.Documents) { + document.Accept(this); + } + } + + /// + /// Visits every child of a . + /// + /// + /// The that is being visited. + /// + protected virtual void VisitChildren(YamlDocument document) { + if(document.RootNode != null) { + document.RootNode.Accept(this); + } + } + + /// + /// Visits every child of a . + /// + /// + /// The that is being visited. + /// + protected virtual void VisitChildren(YamlSequenceNode sequence) { + foreach (var node in sequence.Children) { + node.Accept(this); + } + } + + /// + /// Visits every child of a . + /// + /// + /// The that is being visited. + /// + protected virtual void VisitChildren(YamlMappingNode mapping) { + foreach (var pair in mapping.Children) { + pair.Key.Accept(this); + pair.Value.Accept(this); + } + } + + void IYamlVisitor.Visit (YamlStream stream) + { + Visit(stream); + VisitChildren(stream); + Visited(stream); + } + + void IYamlVisitor.Visit (YamlDocument document) + { + Visit(document); + VisitChildren(document); + Visited(document); + } + + void IYamlVisitor.Visit (YamlScalarNode scalar) + { + Visit(scalar); + Visited(scalar); + } + + void IYamlVisitor.Visit (YamlSequenceNode sequence) + { + Visit(sequence); + VisitChildren(sequence); + Visited(sequence); + } + + void IYamlVisitor.Visit (YamlMappingNode mapping) + { + Visit(mapping); + VisitChildren(mapping); + Visited(mapping); + } + } } \ No newline at end of file diff --git a/YamlDotNet.Samples/DeserializeObjectGraph.cs b/YamlDotNet.Samples/DeserializeObjectGraph.cs index 8c50733..67fe411 100644 --- a/YamlDotNet.Samples/DeserializeObjectGraph.cs +++ b/YamlDotNet.Samples/DeserializeObjectGraph.cs @@ -1,90 +1,90 @@ -using System; -using System.IO; -using YamlDotNet.RepresentationModel.Serialization; - -namespace YamlDotNet.Samples -{ - public class DeserializeObjectGraph - { - public void Run(string[] args) - { - // Setup the input - var input = new StringReader(_document); - +using System; +using System.IO; +using YamlDotNet.RepresentationModel.Serialization; + +namespace YamlDotNet.Samples +{ + public class DeserializeObjectGraph + { + public void Run(string[] args) + { + // Setup the input + var input = new StringReader(_document); + var deserializer = new Deserializer(); - var order = (Order)deserializer.Deserialize(input, typeof(Order)); - - Console.WriteLine("Receipt: {0}", order.Receipt); - Console.WriteLine("Customer: {0} {1}", order.Customer.Given, order.Customer.Family); - } - - private class Order - { - public string Receipt { get; set; } - public DateTime Date { get; set; } - public Customer Customer { get; set; } - public Item[] Items { get; set; } - public Address BillTo { get; set; } - public Address ShipTo { get; set; } - public string SpecialDelivery { get; set; } - } - - private class Customer - { - public string Given { get; set; } - public string Family { get; set; } - } - - public class Item - { - public string PartNo { get; set; } - public decimal Price { get; set; } - public int Quantity { get; set; } - - - [YamlAlias("descrip")] - public string Description { get; set; } - } - - public class Address - { - public string Street { get; set; } - public string City { get; set; } - public string State { get; set; } - } - - private const string _document = @"--- - receipt: Oz-Ware Purchase Invoice - date: 2007-08-06 - customer: - given: Dorothy - family: Gale - - items: - - part_no: A4786 - descrip: Water Bucket (Filled) - price: 1.47 - quantity: 4 - - - part_no: E1628 - descrip: High Heeled ""Ruby"" Slippers - price: 100.27 - quantity: 1 - - bill-to: &id001 - street: | - 123 Tornado Alley - Suite 16 - city: East Westville - state: KS - - ship-to: *id001 - - specialDelivery: > - Follow the Yellow Brick - Road to the Emerald City. - Pay no attention to the - man behind the curtain. -..."; - } -} + var order = (Order)deserializer.Deserialize(input, typeof(Order)); + + Console.WriteLine("Receipt: {0}", order.Receipt); + Console.WriteLine("Customer: {0} {1}", order.Customer.Given, order.Customer.Family); + } + + private class Order + { + public string Receipt { get; set; } + public DateTime Date { get; set; } + public Customer Customer { get; set; } + public Item[] Items { get; set; } + public Address BillTo { get; set; } + public Address ShipTo { get; set; } + public string SpecialDelivery { get; set; } + } + + private class Customer + { + public string Given { get; set; } + public string Family { get; set; } + } + + public class Item + { + public string PartNo { get; set; } + public decimal Price { get; set; } + public int Quantity { get; set; } + + + [YamlAlias("descrip")] + public string Description { get; set; } + } + + public class Address + { + public string Street { get; set; } + public string City { get; set; } + public string State { get; set; } + } + + private const string _document = @"--- + receipt: Oz-Ware Purchase Invoice + date: 2007-08-06 + customer: + given: Dorothy + family: Gale + + items: + - part_no: A4786 + descrip: Water Bucket (Filled) + price: 1.47 + quantity: 4 + + - part_no: E1628 + descrip: High Heeled ""Ruby"" Slippers + price: 100.27 + quantity: 1 + + bill-to: &id001 + street: | + 123 Tornado Alley + Suite 16 + city: East Westville + state: KS + + ship-to: *id001 + + specialDelivery: > + Follow the Yellow Brick + Road to the Emerald City. + Pay no attention to the + man behind the curtain. +..."; + } +} diff --git a/YamlDotNet.UnitTests/Converters/Xml/XmlConverterTests.cs b/YamlDotNet.UnitTests/Converters/Xml/XmlConverterTests.cs index c1f7224..8e0d814 100644 --- a/YamlDotNet.UnitTests/Converters/Xml/XmlConverterTests.cs +++ b/YamlDotNet.UnitTests/Converters/Xml/XmlConverterTests.cs @@ -9,7 +9,7 @@ // so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. +// copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/YamlDotNet.UnitTests/Core/EmitterTests.cs b/YamlDotNet.UnitTests/Core/EmitterTests.cs index c97e75f..575bb98 100644 --- a/YamlDotNet.UnitTests/Core/EmitterTests.cs +++ b/YamlDotNet.UnitTests/Core/EmitterTests.cs @@ -27,151 +27,235 @@ using Xunit; using Xunit.Extensions; using YamlDotNet.Core; using YamlDotNet.Core.Events; -using YamlDotNet.RepresentationModel; - -namespace YamlDotNet.UnitTests -{ - public class EmitterTests : YamlTest - { - private void ParseAndEmit(string name) { - string testText = YamlFile(name).ReadToEnd(); - - IParser parser = new Parser(new StringReader(testText)); - using(StringWriter output = new StringWriter()) { - IEmitter emitter = new Emitter(output, 2, int.MaxValue, false); - while(parser.MoveNext()) { - //Console.WriteLine(parser.Current.GetType().Name); - Console.Error.WriteLine(parser.Current); - emitter.Emit(parser.Current); - } - - string result = output.ToString(); - - Console.WriteLine(); - Console.WriteLine("------------------------------"); - Console.WriteLine(); - Console.WriteLine(testText); - Console.WriteLine(); - Console.WriteLine("------------------------------"); - Console.WriteLine(); - Console.WriteLine(result); - Console.WriteLine(); - Console.WriteLine("------------------------------"); - Console.WriteLine(); - - /* - Parser resultParser = new Parser(new StringReader(result)); - while(resultParser.MoveNext()) { - Console.WriteLine(resultParser.Current.GetType().Name); - } - */ - /* - - if(testText != result) { - Console.WriteLine(); - Console.WriteLine("------------------------------"); - Console.WriteLine(); - Console.WriteLine("Expected:"); - Console.WriteLine(); - Console.WriteLine(testText); - Console.WriteLine(); - Console.WriteLine("------------------------------"); - Console.WriteLine(); - Console.WriteLine("Result:"); - Console.WriteLine(); - Console.WriteLine(result); - Console.WriteLine(); - Console.WriteLine("------------------------------"); - Console.WriteLine(); - } - - Assert.Equal(testText, result); - */ - } - } - - [Fact] - public void EmitExample1() - { - ParseAndEmit("test1.yaml"); - } - - [Fact] - public void EmitExample2() - { - ParseAndEmit("test2.yaml"); - } - - [Fact] - public void EmitExample3() - { - ParseAndEmit("test3.yaml"); - } - - [Fact] - public void EmitExample4() - { - ParseAndEmit("test4.yaml"); - } - - [Fact] - public void EmitExample5() - { - ParseAndEmit("test5.yaml"); - } - - [Fact] - public void EmitExample6() - { - ParseAndEmit("test6.yaml"); - } - - [Fact] - public void EmitExample7() - { - ParseAndEmit("test7.yaml"); - } - - [Fact] - public void EmitExample8() - { - ParseAndEmit("test8.yaml"); - } - - [Fact] - public void EmitExample9() - { - ParseAndEmit("test9.yaml"); - } - - [Fact] - public void EmitExample10() - { - ParseAndEmit("test10.yaml"); - } - - [Fact] - public void EmitExample11() - { - ParseAndEmit("test11.yaml"); - } - - [Fact] - public void EmitExample12() - { - ParseAndEmit("test12.yaml"); - } - - [Fact] - public void EmitExample13() - { - ParseAndEmit("test13.yaml"); - } - - [Fact] - public void EmitExample14() - { - ParseAndEmit("test14.yaml"); +using YamlDotNet.RepresentationModel; + +namespace YamlDotNet.UnitTests +{ + public class EmitterTests : YamlTest + { + private void ParseAndEmit(string name) { + string testText = YamlFile(name).ReadToEnd(); + + IParser parser = new Parser(new StringReader(testText)); + using(StringWriter output = new StringWriter()) { + IEmitter emitter = new Emitter(output, 2, int.MaxValue, false); + while(parser.MoveNext()) { + //Console.WriteLine(parser.Current.GetType().Name); + Console.Error.WriteLine(parser.Current); + emitter.Emit(parser.Current); + } + + string result = output.ToString(); + + Console.WriteLine(); + Console.WriteLine("------------------------------"); + Console.WriteLine(); + Console.WriteLine(testText); + Console.WriteLine(); + Console.WriteLine("------------------------------"); + Console.WriteLine(); + Console.WriteLine(result); + Console.WriteLine(); + Console.WriteLine("------------------------------"); + Console.WriteLine(); + + /* + Parser resultParser = new Parser(new StringReader(result)); + while(resultParser.MoveNext()) { + Console.WriteLine(resultParser.Current.GetType().Name); + } + */ + /* + + if(testText != result) { + Console.WriteLine(); + Console.WriteLine("------------------------------"); + Console.WriteLine(); + Console.WriteLine("Expected:"); + Console.WriteLine(); + Console.WriteLine(testText); + Console.WriteLine(); + Console.WriteLine("------------------------------"); + Console.WriteLine(); + Console.WriteLine("Result:"); + Console.WriteLine(); + Console.WriteLine(result); + Console.WriteLine(); + Console.WriteLine("------------------------------"); + Console.WriteLine(); + } + + Assert.Equal(testText, result); + */ + } + } + + [Fact] + public void EmitExample1() + { + ParseAndEmit("test1.yaml"); + } + + [Fact] + public void EmitExample2() + { + ParseAndEmit("test2.yaml"); + } + + [Fact] + public void EmitExample3() + { + ParseAndEmit("test3.yaml"); + } + + [Fact] + public void EmitExample4() + { + ParseAndEmit("test4.yaml"); + } + + [Fact] + public void EmitExample5() + { + ParseAndEmit("test5.yaml"); + } + + [Fact] + public void EmitExample6() + { + ParseAndEmit("test6.yaml"); + } + + [Fact] + public void EmitExample7() + { + ParseAndEmit("test7.yaml"); + } + + [Fact] + public void EmitExample8() + { + ParseAndEmit("test8.yaml"); + } + + [Fact] + public void EmitExample9() + { + ParseAndEmit("test9.yaml"); + } + + [Fact] + public void EmitExample10() + { + ParseAndEmit("test10.yaml"); + } + + [Fact] + public void EmitExample11() + { + ParseAndEmit("test11.yaml"); + } + + [Fact] + public void EmitExample12() + { + ParseAndEmit("test12.yaml"); + } + + [Fact] + public void EmitExample13() + { + ParseAndEmit("test13.yaml"); + } + + [Fact] + public void EmitExample14() + { + ParseAndEmit("test14.yaml"); + } + + [Fact] + public void EmitExample1() + { + ParseAndEmit("test1.yaml"); + } + + [Fact] + public void EmitExample2() + { + ParseAndEmit("test2.yaml"); + } + + [Fact] + public void EmitExample3() + { + ParseAndEmit("test3.yaml"); + } + + [Fact] + public void EmitExample4() + { + ParseAndEmit("test4.yaml"); + } + + [Fact] + public void EmitExample5() + { + ParseAndEmit("test5.yaml"); + } + + [Fact] + public void EmitExample6() + { + ParseAndEmit("test6.yaml"); + } + + [Fact] + public void EmitExample7() + { + ParseAndEmit("test7.yaml"); + } + + [Fact] + public void EmitExample8() + { + ParseAndEmit("test8.yaml"); + } + + [Fact] + public void EmitExample9() + { + ParseAndEmit("test9.yaml"); + } + + [Fact] + public void EmitExample10() + { + ParseAndEmit("test10.yaml"); + } + + [Fact] + public void EmitExample11() + { + ParseAndEmit("test11.yaml"); + } + + [Fact] + public void EmitExample12() + { + ParseAndEmit("test12.yaml"); + } + + [Fact] + public void EmitExample13() + { + ParseAndEmit("test13.yaml"); + } + + [Fact] + public void EmitExample14() + { + ParseAndEmit("test14.yaml"); } private string EmitScalar(Scalar scalar) @@ -270,5 +354,5 @@ namespace YamlDotNet.UnitTests Assert.Equal(input, value.Value); } - } + } } \ No newline at end of file diff --git a/YamlDotNet.UnitTests/Core/InsertionQueueTests.cs b/YamlDotNet.UnitTests/Core/InsertionQueueTests.cs index 7ac4b7b..3c17d9d 100644 --- a/YamlDotNet.UnitTests/Core/InsertionQueueTests.cs +++ b/YamlDotNet.UnitTests/Core/InsertionQueueTests.cs @@ -19,100 +19,100 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; -using YamlDotNet.Core; -using Xunit; - -namespace YamlDotNet.UnitTests -{ - public class InsertionQueueTests - { - [Fact] - public void QueueWorks() { - InsertionQueue queue = new InsertionQueue(); - - for (int i = 0; i < 100; ++i) { - queue.Enqueue(i); - } - - for (int i = 0; i < 100; ++i) { - Assert.Equal(i, queue.Dequeue()); - } - - for (int i = 0; i < 50; ++i) { - queue.Enqueue(i); - } - - for (int i = 0; i < 10; ++i) { - Assert.Equal(i, queue.Dequeue()); - } - - for (int i = 50; i < 100; ++i) { - queue.Enqueue(i); - } - - for (int i = 10; i < 100; ++i) { - Assert.Equal(i, queue.Dequeue()); - } - } - - [Fact] - public void InsertWorks() { - InsertionQueue queue = new InsertionQueue(); - - for(int j = 0; j < 2; ++j) { - for (int i = 0; i < 10; ++i) { - queue.Enqueue(i); - } - - queue.Insert(5, 99); - - for (int i = 0; i < 5; ++i) { - Assert.Equal(i, queue.Dequeue()); - } - - Assert.Equal(99, queue.Dequeue()); - - for (int i = 5; i < 10; ++i) { - Assert.Equal(i, queue.Dequeue()); - } - } - - for (int i = 0; i < 5; ++i) { - queue.Enqueue(i); - queue.Dequeue(); - } - - for (int i = 0; i < 20; ++i) { - queue.Enqueue(i); - } - - queue.Insert(5, 99); - - for (int i = 0; i < 5; ++i) { - Assert.Equal(i, queue.Dequeue()); - } - - Assert.Equal(99, queue.Dequeue()); - - for (int i = 5; i < 20; ++i) { - Assert.Equal(i, queue.Dequeue()); - } - } - - [Fact] - public void Dequeue_ThrowsExceptionWhenEmpty() { - InsertionQueue queue = new InsertionQueue(); - - for (int i = 0; i < 10; ++i) { - queue.Enqueue(i); - } - - for (int i = 0; i < 10; ++i) { - Assert.Equal(i, queue.Dequeue()); - } - - Assert.Throws(() => queue.Dequeue()); - } - } +using System; +using YamlDotNet.Core; +using Xunit; + +namespace YamlDotNet.UnitTests +{ + public class InsertionQueueTests + { + [Fact] + public void QueueWorks() { + InsertionQueue queue = new InsertionQueue(); + + for (int i = 0; i < 100; ++i) { + queue.Enqueue(i); + } + + for (int i = 0; i < 100; ++i) { + Assert.Equal(i, queue.Dequeue()); + } + + for (int i = 0; i < 50; ++i) { + queue.Enqueue(i); + } + + for (int i = 0; i < 10; ++i) { + Assert.Equal(i, queue.Dequeue()); + } + + for (int i = 50; i < 100; ++i) { + queue.Enqueue(i); + } + + for (int i = 10; i < 100; ++i) { + Assert.Equal(i, queue.Dequeue()); + } + } + + [Fact] + public void InsertWorks() { + InsertionQueue queue = new InsertionQueue(); + + for(int j = 0; j < 2; ++j) { + for (int i = 0; i < 10; ++i) { + queue.Enqueue(i); + } + + queue.Insert(5, 99); + + for (int i = 0; i < 5; ++i) { + Assert.Equal(i, queue.Dequeue()); + } + + Assert.Equal(99, queue.Dequeue()); + + for (int i = 5; i < 10; ++i) { + Assert.Equal(i, queue.Dequeue()); + } + } + + for (int i = 0; i < 5; ++i) { + queue.Enqueue(i); + queue.Dequeue(); + } + + for (int i = 0; i < 20; ++i) { + queue.Enqueue(i); + } + + queue.Insert(5, 99); + + for (int i = 0; i < 5; ++i) { + Assert.Equal(i, queue.Dequeue()); + } + + Assert.Equal(99, queue.Dequeue()); + + for (int i = 5; i < 20; ++i) { + Assert.Equal(i, queue.Dequeue()); + } + } + + [Fact] + public void Dequeue_ThrowsExceptionWhenEmpty() { + InsertionQueue queue = new InsertionQueue(); + + for (int i = 0; i < 10; ++i) { + queue.Enqueue(i); + } + + for (int i = 0; i < 10; ++i) { + Assert.Equal(i, queue.Dequeue()); + } + + Assert.Throws(() => queue.Dequeue()); + } + } } \ No newline at end of file diff --git a/YamlDotNet.UnitTests/Core/LookAheadBufferTests.cs b/YamlDotNet.UnitTests/Core/LookAheadBufferTests.cs index 8ef7063..8258469 100644 --- a/YamlDotNet.UnitTests/Core/LookAheadBufferTests.cs +++ b/YamlDotNet.UnitTests/Core/LookAheadBufferTests.cs @@ -19,74 +19,74 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System; -using System.IO; -using System.Reflection; -using Xunit; -using YamlDotNet.Core; -using YamlDotNet.Core.Events; - -namespace YamlDotNet.UnitTests -{ - public class LookAheadBufferTests - { - private static LookAheadBuffer CreateBuffer(string text, int capacity) { - return new LookAheadBuffer(new StringReader(text), capacity); - } - - [Fact] - public void ReadingWorks() - { - LookAheadBuffer buffer = CreateBuffer("abcdefghi", 4); - - FieldInfo count = buffer.GetType().GetField("count", BindingFlags.Instance | BindingFlags.NonPublic); - Assert.NotNull(count); - - Assert.Equal(0, count.GetValue(buffer)); - Assert.Equal('a', buffer.Peek(0)); - Assert.Equal(1, count.GetValue(buffer)); - Assert.Equal('b', buffer.Peek(1)); - Assert.Equal(2, count.GetValue(buffer)); - Assert.Equal('c', buffer.Peek(2)); - Assert.Equal(3, count.GetValue(buffer)); - buffer.Skip(1); - Assert.Equal(2, count.GetValue(buffer)); - Assert.Equal('b', buffer.Peek(0)); - Assert.Equal(2, count.GetValue(buffer)); - Assert.Equal('c', buffer.Peek(1)); - Assert.Equal(2, count.GetValue(buffer)); - Assert.Equal('d', buffer.Peek(2)); - Assert.Equal(3, count.GetValue(buffer)); - Assert.Equal('e', buffer.Peek(3)); - Assert.Equal(4, count.GetValue(buffer)); - buffer.Skip(1); - Assert.Equal(3, count.GetValue(buffer)); - buffer.Skip(1); - Assert.Equal(2, count.GetValue(buffer)); - buffer.Skip(1); - Assert.Equal(1, count.GetValue(buffer)); - buffer.Skip(1); - Assert.Equal(0, count.GetValue(buffer)); - Assert.Equal('f', buffer.Peek(0)); - Assert.Equal(1, count.GetValue(buffer)); - buffer.Skip(1); - Assert.Equal(0, count.GetValue(buffer)); - Assert.Equal('g', buffer.Peek(0)); - Assert.Equal(1, count.GetValue(buffer)); - buffer.Skip(1); - Assert.Equal(0, count.GetValue(buffer)); - Assert.Equal('h', buffer.Peek(0)); - Assert.Equal(1, count.GetValue(buffer)); - buffer.Skip(1); - Assert.Equal(0, count.GetValue(buffer)); - Assert.Equal('i', buffer.Peek(0)); - Assert.Equal(1, count.GetValue(buffer)); - buffer.Skip(1); - Assert.Equal(0, count.GetValue(buffer)); - Assert.False(buffer.EndOfInput); - Assert.Equal('\0', buffer.Peek(0)); - Assert.True(buffer.EndOfInput); - Assert.Equal(0, count.GetValue(buffer)); - } - } +using System; +using System.IO; +using System.Reflection; +using Xunit; +using YamlDotNet.Core; +using YamlDotNet.Core.Events; + +namespace YamlDotNet.UnitTests +{ + public class LookAheadBufferTests + { + private static LookAheadBuffer CreateBuffer(string text, int capacity) { + return new LookAheadBuffer(new StringReader(text), capacity); + } + + [Fact] + public void ReadingWorks() + { + LookAheadBuffer buffer = CreateBuffer("abcdefghi", 4); + + FieldInfo count = buffer.GetType().GetField("count", BindingFlags.Instance | BindingFlags.NonPublic); + Assert.NotNull(count); + + Assert.Equal(0, count.GetValue(buffer)); + Assert.Equal('a', buffer.Peek(0)); + Assert.Equal(1, count.GetValue(buffer)); + Assert.Equal('b', buffer.Peek(1)); + Assert.Equal(2, count.GetValue(buffer)); + Assert.Equal('c', buffer.Peek(2)); + Assert.Equal(3, count.GetValue(buffer)); + buffer.Skip(1); + Assert.Equal(2, count.GetValue(buffer)); + Assert.Equal('b', buffer.Peek(0)); + Assert.Equal(2, count.GetValue(buffer)); + Assert.Equal('c', buffer.Peek(1)); + Assert.Equal(2, count.GetValue(buffer)); + Assert.Equal('d', buffer.Peek(2)); + Assert.Equal(3, count.GetValue(buffer)); + Assert.Equal('e', buffer.Peek(3)); + Assert.Equal(4, count.GetValue(buffer)); + buffer.Skip(1); + Assert.Equal(3, count.GetValue(buffer)); + buffer.Skip(1); + Assert.Equal(2, count.GetValue(buffer)); + buffer.Skip(1); + Assert.Equal(1, count.GetValue(buffer)); + buffer.Skip(1); + Assert.Equal(0, count.GetValue(buffer)); + Assert.Equal('f', buffer.Peek(0)); + Assert.Equal(1, count.GetValue(buffer)); + buffer.Skip(1); + Assert.Equal(0, count.GetValue(buffer)); + Assert.Equal('g', buffer.Peek(0)); + Assert.Equal(1, count.GetValue(buffer)); + buffer.Skip(1); + Assert.Equal(0, count.GetValue(buffer)); + Assert.Equal('h', buffer.Peek(0)); + Assert.Equal(1, count.GetValue(buffer)); + buffer.Skip(1); + Assert.Equal(0, count.GetValue(buffer)); + Assert.Equal('i', buffer.Peek(0)); + Assert.Equal(1, count.GetValue(buffer)); + buffer.Skip(1); + Assert.Equal(0, count.GetValue(buffer)); + Assert.False(buffer.EndOfInput); + Assert.Equal('\0', buffer.Peek(0)); + Assert.True(buffer.EndOfInput); + Assert.Equal(0, count.GetValue(buffer)); + } + } } \ No newline at end of file diff --git a/YamlDotNet.UnitTests/RepresentationModel/NamingConventionTests.cs b/YamlDotNet.UnitTests/RepresentationModel/NamingConventionTests.cs index 380faab..890d872 100644 --- a/YamlDotNet.UnitTests/RepresentationModel/NamingConventionTests.cs +++ b/YamlDotNet.UnitTests/RepresentationModel/NamingConventionTests.cs @@ -1,43 +1,43 @@ -using Xunit; -using Xunit.Extensions; +using Xunit; +using Xunit.Extensions; using YamlDotNet.RepresentationModel; using YamlDotNet.RepresentationModel.Serialization; -using YamlDotNet.RepresentationModel.Serialization.NamingConventions; - -namespace YamlDotNet.UnitTests.RepresentationModel -{ - public class NamingConventionTests - { - [Theory] - [InlineData("test", "test")] - [InlineData("thisIsATest", "this-is-a-test")] - [InlineData("thisIsATest", "this_is_a_test")] - [InlineData("thisIsATest", "ThisIsATest")] - public void TestCamelCase(string expected, string input) +using YamlDotNet.RepresentationModel.Serialization.NamingConventions; + +namespace YamlDotNet.UnitTests.RepresentationModel +{ + public class NamingConventionTests + { + [Theory] + [InlineData("test", "test")] + [InlineData("thisIsATest", "this-is-a-test")] + [InlineData("thisIsATest", "this_is_a_test")] + [InlineData("thisIsATest", "ThisIsATest")] + public void TestCamelCase(string expected, string input) { var sut = new CamelCaseNamingConvention(); - Assert.Equal(expected, sut.Apply(input)); - } - - [Theory] - [InlineData("Test", "test")] - [InlineData("ThisIsATest", "this-is-a-test")] - [InlineData("ThisIsATest", "this_is_a_test")] - [InlineData("ThisIsATest", "thisIsATest")] - public void TestPascalCase(string expected, string input) + Assert.Equal(expected, sut.Apply(input)); + } + + [Theory] + [InlineData("Test", "test")] + [InlineData("ThisIsATest", "this-is-a-test")] + [InlineData("ThisIsATest", "this_is_a_test")] + [InlineData("ThisIsATest", "thisIsATest")] + public void TestPascalCase(string expected, string input) { var sut = new PascalCaseNamingConvention(); - Assert.Equal(expected, sut.Apply(input)); - } - - [Theory] - [InlineData("test", "test")] - [InlineData("this-is-a-test", "thisIsATest")] - [InlineData("this-is-a-test", "this-is-a-test")] - public void TestHyphenated(string expected, string input) + Assert.Equal(expected, sut.Apply(input)); + } + + [Theory] + [InlineData("test", "test")] + [InlineData("this-is-a-test", "thisIsATest")] + [InlineData("this-is-a-test", "this-is-a-test")] + public void TestHyphenated(string expected, string input) { var sut = new HyphenatedNamingConvention(); - Assert.Equal(expected, sut.Apply(input)); + Assert.Equal(expected, sut.Apply(input)); } [Theory] @@ -49,5 +49,5 @@ namespace YamlDotNet.UnitTests.RepresentationModel var sut = new UnderscoredNamingConvention(); Assert.Equal(expected, sut.Apply(input)); } - } -} + } +} diff --git a/YamlDotNet.UnitTests/RepresentationModel/SerializationTests.cs b/YamlDotNet.UnitTests/RepresentationModel/SerializationTests.cs index 385f6e8..a854f02 100644 --- a/YamlDotNet.UnitTests/RepresentationModel/SerializationTests.cs +++ b/YamlDotNet.UnitTests/RepresentationModel/SerializationTests.cs @@ -1,22 +1,22 @@ -// This file is part of YamlDotNet - A .NET library for YAML. -// Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Antoine Aubry - -// Permission is hereby granted, free of charge, to any person obtaining a copy of -// this software and associated documentation files (the "Software"), to deal in -// the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -// of the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// This file is part of YamlDotNet - A .NET library for YAML. +// Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Antoine Aubry + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +// of the Software, and to permit persons to whom the Software is furnished to do +// so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. using System; @@ -34,1068 +34,1068 @@ using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.RepresentationModel; using YamlDotNet.RepresentationModel.Serialization; -using YamlDotNet.RepresentationModel.Serialization.NamingConventions; - -namespace YamlDotNet.UnitTests.RepresentationModel -{ - public class SerializationTests : YamlTest - { - private class X - { - private bool myFlag; - - public bool MyFlag - { - get - { - return myFlag; - } - set - { - myFlag = value; - } - } - - private string nothing; - - public string Nothing - { - get - { - return nothing; - } - set - { - nothing = value; - } - } - - private int myInt = 1234; - - public int MyInt - { - get - { - return myInt; - } - set - { - myInt = value; - } - } - - private double myDouble = 6789.1011; - - public double MyDouble - { - get - { - return myDouble; - } - set - { - myDouble = value; - } - } - - private string myString = "Hello world"; - - public string MyString - { - get - { - return myString; - } - set - { - myString = value; - } - } - - private DateTime myDate = DateTime.Now; - - public DateTime MyDate - { - get - { - return myDate; - } - set - { - myDate = value; - } - } - - private TimeSpan myTimeSpan = TimeSpan.FromHours(1); - - public TimeSpan MyTimeSpan - { - get - { - return myTimeSpan; - } - set - { - myTimeSpan = value; - } - } - - private Point myPoint = new Point(100, 200); - - public Point MyPoint - { - get - { - return myPoint; - } - set - { - myPoint = value; - } - } - - private int? myNullableWithValue = 8; - - public int? MyNullableWithValue - { - get { return myNullableWithValue; } - set { myNullableWithValue = value; } - } - - private int? myNullableWithoutValue = null; - - public int? MyNullableWithoutValue - { - get { return myNullableWithoutValue; } - set { myNullableWithoutValue = value; } - } - } - - [Fact] - public void Roundtrip() - { - var serializer = new Serializer(SerializationOptions.Roundtrip); - - using (StringWriter buffer = new StringWriter()) - { - X original = new X(); - serializer.Serialize(buffer, original); - - Console.WriteLine(buffer.ToString()); - - var deserializer = new Deserializer(); - X copy = deserializer.Deserialize(new StringReader(buffer.ToString())); - - foreach (var property in typeof(X).GetProperties(BindingFlags.Public | BindingFlags.Instance)) - { - if (property.CanRead && property.CanWrite) - { - Assert.Equal( - property.GetValue(original, null), - property.GetValue(copy, null) - ); - } - } - } - } - - [Fact] - public void RoundtripWithDefaults() - { - var serializer = new Serializer(SerializationOptions.Roundtrip | SerializationOptions.EmitDefaults); - - using (StringWriter buffer = new StringWriter()) - { - X original = new X(); - serializer.Serialize(buffer, original); - - Console.WriteLine(buffer.ToString()); - - var deserializer = new Deserializer(); - X copy = deserializer.Deserialize(new StringReader(buffer.ToString())); - - foreach (var property in typeof(X).GetProperties(BindingFlags.Public | BindingFlags.Instance)) - { - if (property.CanRead && property.CanWrite) - { - Assert.Equal( - property.GetValue(original, null), - property.GetValue(copy, null) - ); - } - } - } - } - - - private class Y - { - private Y child; - - public Y Child - { - get - { - return child; - } - set - { - child = value; - } - } - - private Y child2; - - public Y Child2 - { - get - { - return child2; - } - set - { - child2 = value; - } - } - } - - - [Fact] - public void CircularReference() - { - var serializer = new Serializer(SerializationOptions.Roundtrip); - - using (StringWriter buffer = new StringWriter()) - { - Y original = new Y(); - original.Child = new Y - { - Child = original, - Child2 = original - }; - - serializer.Serialize(buffer, original, typeof(Y)); - - Console.WriteLine(buffer.ToString()); - } - } - - public class Z - { - public string aaa - { - get; - set; - } - } - - [Fact] - public void DeserializeScalar() - { - var sut = new Deserializer(); - object result = sut.Deserialize(YamlFile("test2.yaml"), typeof(object)); - - Assert.Equal("a scalar", result); - } - - [Fact] - public void DeserializeExplicitType() - { - var serializer = new Deserializer(); - object result = serializer.Deserialize(YamlFile("explicitType.yaml"), typeof(object)); - - Assert.True(typeof(Z).IsAssignableFrom(result.GetType())); - Assert.Equal("bbb", ((Z)result).aaa); - } - - [Fact] - public void DeserializeDictionary() - { - var serializer = new Deserializer(); - object result = serializer.Deserialize(YamlFile("dictionary.yaml")); - - Assert.True(typeof(IDictionary).IsAssignableFrom(result.GetType()), "The deserialized object has the wrong type."); - - IDictionary dictionary = (IDictionary)result; - Assert.Equal("value1", dictionary["key1"]); - Assert.Equal("value2", dictionary["key2"]); - } - - [Fact] - public void DeserializeExplicitDictionary() - { - var serializer = new Deserializer(); - object result = serializer.Deserialize(YamlFile("dictionaryExplicit.yaml")); - - Assert.True(typeof(IDictionary).IsAssignableFrom(result.GetType()), "The deserialized object has the wrong type."); - - IDictionary dictionary = (IDictionary)result; - Assert.Equal(1, dictionary["key1"]); - Assert.Equal(2, dictionary["key2"]); - } - - [Fact] - public void DeserializeListOfDictionaries() - { - var serializer = new Deserializer(); - object result = serializer.Deserialize(YamlFile("listOfDictionaries.yaml"), typeof(List>)); - - Assert.IsType>>(result); - - var list = (List>)result; - Assert.Equal("conn1", list[0]["connection"]); - Assert.Equal("path1", list[0]["path"]); - Assert.Equal("conn2", list[1]["connection"]); - Assert.Equal("path2", list[1]["path"]); - } - - [Fact] - public void DeserializeList() - { - var serializer = new Deserializer(); - object result = serializer.Deserialize(YamlFile("list.yaml")); - - Assert.True(typeof(IList).IsAssignableFrom(result.GetType())); - - IList list = (IList)result; - Assert.Equal("one", list[0]); - Assert.Equal("two", list[1]); - Assert.Equal("three", list[2]); - } - - [Fact] - public void DeserializeExplicitList() - { - var serializer = new Deserializer(); - object result = serializer.Deserialize(YamlFile("listExplicit.yaml")); - - Assert.True(typeof(IList).IsAssignableFrom(result.GetType())); - - IList list = (IList)result; - Assert.Equal(3, list[0]); - Assert.Equal(4, list[1]); - Assert.Equal(5, list[2]); - } - - [Fact] - public void DeserializeEnumerable() - { - Z[] z = new[] { new Z() { aaa = "Yo" }}; - Serializer serializer = new Serializer(); - StringWriter buffer = new StringWriter(); - serializer.Serialize(buffer, z); - - var deserializer = new Deserializer(); - var result = (IEnumerable)deserializer.Deserialize(new StringReader(buffer.ToString()), typeof(IEnumerable)); - Assert.Equal(1, result.Count()); - Assert.Equal("Yo", result.First().aaa); - } - - [Fact] - public void RoundtripList() - { - var serializer = new Serializer(SerializationOptions.Roundtrip); - var deserializer = new Deserializer(); - - using (StringWriter buffer = new StringWriter()) - { - List original = new List(); - original.Add(2); - original.Add(4); - original.Add(6); - serializer.Serialize(buffer, original, typeof(List)); - - Console.WriteLine(buffer.ToString()); - - List copy = (List)deserializer.Deserialize(new StringReader(buffer.ToString()), typeof(List)); - - Assert.Equal(original.Count, copy.Count); - - for (int i = 0; i < original.Count; ++i) - { - Assert.Equal(original[i], copy[i]); - } - } - } - - [Fact] - public void DeserializeArray() - { - var serializer = new Deserializer(); - object result = serializer.Deserialize(YamlFile("list.yaml"), typeof(String[])); - - Assert.True(result is String[]); - - String[] array = (String[])result; - Assert.Equal("one", array[0]); - Assert.Equal("two", array[1]); - Assert.Equal("three", array[2]); - } - - [Fact] - public void Enums() - { - var serializer = new Serializer(); - var deserializer = new Deserializer(); - - StringFormatFlags flags = StringFormatFlags.NoClip | StringFormatFlags.NoFontFallback; - - StringWriter buffer = new StringWriter(); - serializer.Serialize(buffer, flags); - - var deserialized = (StringFormatFlags)deserializer.Deserialize(new StringReader(buffer.ToString()), typeof(StringFormatFlags)); - - Assert.Equal(flags, deserialized); - } - - [Fact] - public void CustomTags() - { - var deserializer = new Deserializer(); - deserializer.RegisterTagMapping("tag:yaml.org,2002:point", typeof(Point)); - object result = deserializer.Deserialize(YamlFile("tags.yaml")); - - Assert.Equal(typeof(Point), result.GetType()); - - Point value = (Point)result; - Assert.Equal(10, value.X); - Assert.Equal(20, value.Y); - } - - [Fact] - public void DeserializeConvertible() - { - var serializer = new Deserializer(); - object result = serializer.Deserialize(YamlFile("convertible.yaml"), typeof(Z)); - - Assert.True(typeof(Z).IsAssignableFrom(result.GetType())); - Assert.Equal("[hello, world]", ((Z)result).aaa); - } - - public class Converter : System.ComponentModel.TypeConverter - { - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) - { - return sourceType == typeof(string); - } - - public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) - { - return false; - } - - public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) - { - string[] parts = ((string)value).Split(' '); - return new Convertible - { - Left = parts[0], - Right = parts[1] - }; - } - } - - [TypeConverter(typeof(Converter))] - public class Convertible : IConvertible - { - public string Left - { - get; - set; - } - - public string Right - { - get; - set; - } - - #region IConvertible Members - - public TypeCode GetTypeCode() - { - throw new NotImplementedException(); - } - - public bool ToBoolean(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - public byte ToByte(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - public char ToChar(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - public DateTime ToDateTime(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - public decimal ToDecimal(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - public double ToDouble(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - public short ToInt16(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - public int ToInt32(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - public long ToInt64(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - public sbyte ToSByte(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - public float ToSingle(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - public string ToString(IFormatProvider provider) - { - Assert.Equal(CultureInfo.InvariantCulture, provider); - - return string.Format(provider, "[{0}, {1}]", Left, Right); - } - - public object ToType(Type conversionType, IFormatProvider provider) - { - Assert.Equal(typeof(string), conversionType); - return ToString(provider); - } - - public ushort ToUInt16(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - public uint ToUInt32(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - public ulong ToUInt64(IFormatProvider provider) - { - throw new NotImplementedException(); - } - - #endregion - } - - class SomeCustomeType - { - // Test specifically with no parameterless, supposed to fail unless a type converter is specified - public SomeCustomeType(string value) { Value = value; } - public string Value; - } - - public class CustomTypeConverter : IYamlTypeConverter - { - public bool Accepts(Type type) { return type == typeof(SomeCustomeType); } - - public object ReadYaml(IParser parser, Type type) - { - var value = ((Scalar)parser.Current).Value; - parser.MoveNext(); - return new SomeCustomeType(value); - } - - public void WriteYaml(IEmitter emitter, object value, Type type) - { - emitter.Emit(new Scalar(((SomeCustomeType)value).Value)); - } - } - - [Fact] - public void RoundtripWithTypeConverter() - { - SomeCustomeType x = new SomeCustomeType("Yo"); - var serializer = new Serializer(SerializationOptions.Roundtrip); - serializer.RegisterTypeConverter(new CustomTypeConverter()); - StringWriter buffer = new StringWriter(); - serializer.Serialize(buffer, x); - - Console.WriteLine(buffer.ToString()); - - var deserializer = new Deserializer(); - deserializer.RegisterTypeConverter(new CustomTypeConverter()); - - var copy = deserializer.Deserialize(new StringReader(buffer.ToString())); - Assert.Equal("Yo", copy.Value); - } - - [Fact] - public void RoundtripDictionary() - { - Dictionary entries = new Dictionary - { - { "key1", "value1" }, - { "key2", "value2" }, - { "key3", "value3" }, - }; - - var serializer = new Serializer(); - - StringWriter buffer = new StringWriter(); - serializer.Serialize(buffer, entries); - - Console.WriteLine(buffer.ToString()); - - var deserializer = new Deserializer(); - var deserialized = deserializer.Deserialize>(new StringReader(buffer.ToString())); - - foreach (var pair in deserialized) - { - Assert.Equal(entries[pair.Key], pair.Value); - } - } - - [Fact] - public void SerializeAnonymousType() - { - var data = new { Key = 3 }; - - var serializer = new Serializer(); - - StringWriter buffer = new StringWriter(); - serializer.Serialize(buffer, data); - - Console.WriteLine(buffer.ToString()); - - var deserializer = new Deserializer(); - var parsed = deserializer.Deserialize>(new StringReader(buffer.ToString())); - - Assert.NotNull(parsed); - Assert.Equal(1, parsed.Count); - } - - [Fact] - public void SerializationIncludesNullWhenAsked_BugFix() - { - var serializer = new Serializer(SerializationOptions.EmitDefaults); - - using (StringWriter buffer = new StringWriter()) - { - var original = new { MyString = (string)null }; - serializer.Serialize(buffer, original, original.GetType()); - - Console.WriteLine(buffer.ToString()); - - Assert.True(buffer.ToString().Contains("MyString")); - } - } - - [Fact] - public void SerializationIncludesNullWhenAsked() - { - var serializer = new Serializer(SerializationOptions.EmitDefaults); - - using (StringWriter buffer = new StringWriter()) - { - X original = new X { MyString = null }; - serializer.Serialize(buffer, original, typeof(X)); - - Console.WriteLine(buffer.ToString()); - - Assert.True(buffer.ToString().Contains("MyString")); - } - } - - [Fact] - public void SerializationDoesNotIncludeNullWhenNotAsked() - { - var serializer = new Serializer(); - - using (StringWriter buffer = new StringWriter()) - { - X original = new X { MyString = null }; - serializer.Serialize(buffer, original, typeof(X)); - - Console.WriteLine(buffer.ToString()); - - Assert.False(buffer.ToString().Contains("MyString")); - } - } - - [Fact] - public void SerializationOfNullWorksInJson() - { - var serializer = new Serializer(SerializationOptions.EmitDefaults | SerializationOptions.JsonCompatible); - - using (StringWriter buffer = new StringWriter()) - { - X original = new X { MyString = null }; - serializer.Serialize(buffer, original, typeof(X)); - - Console.WriteLine(buffer.ToString()); - - Assert.True(buffer.ToString().Contains("MyString")); - } - } - - [Fact] - public void DeserializationOfNullWorksInJson() - { - var serializer = new Serializer(SerializationOptions.EmitDefaults | SerializationOptions.JsonCompatible | SerializationOptions.Roundtrip); - var deserializer = new Deserializer(); - - using (StringWriter buffer = new StringWriter()) - { - X original = new X { MyString = null }; - serializer.Serialize(buffer, original, typeof(X)); - - Console.WriteLine(buffer.ToString()); - - X copy = (X)deserializer.Deserialize(new StringReader(buffer.ToString()), typeof(X)); - - Assert.Null(copy.MyString); - } - } - - class ContainsIgnore - { - [YamlIgnore] - public String IgnoreMe { get; set; } - } - - [Fact] - public void SerializationRespectsYamlIgnoreAttribute() - { - var serializer = new Serializer(); - var deserializer = new Deserializer(); - - using (StringWriter buffer = new StringWriter()) - { - var orig = new ContainsIgnore { IgnoreMe = "Some Text" }; - serializer.Serialize(buffer, orig); - Console.WriteLine(buffer.ToString()); - var copy = (ContainsIgnore)deserializer.Deserialize(new StringReader(buffer.ToString()), typeof(ContainsIgnore)); - Assert.Null(copy.IgnoreMe); - } - } - - [Fact] - public void SerializeArrayOfIdenticalObjects() - { - var obj1 = new Z { aaa = "abc" }; - - var objects = new[] { obj1, obj1, obj1 }; - - var result = SerializeThenDeserialize(objects); - - Assert.NotNull(result); - Assert.Equal(3, result.Length); - Assert.Equal(obj1.aaa, result[0].aaa); - Assert.Equal(obj1.aaa, result[1].aaa); - Assert.Equal(obj1.aaa, result[2].aaa); - Assert.Same(result[0], result[1]); - Assert.Same(result[1], result[2]); - } - - [Fact] - public void SerializeUsingCamelCaseNaming() - { - var obj = new { foo = "bar", moreFoo = "More bar", evenMoreFoo = "Awesome" }; - var result = SerializeWithNaming(obj, new CamelCaseNamingConvention()); - Assert.Contains("foo: bar", result); - Assert.Contains("moreFoo: More bar", result); - Assert.Contains("evenMoreFoo: Awesome", result); - } - - [Fact] - public void SerializeUsingPascalCaseNaming() - { - var obj = new { foo = "bar", moreFoo = "More bar", evenMoreFoo = "Awesome" }; - var result = SerializeWithNaming(obj, new PascalCaseNamingConvention()); - - Console.WriteLine(result); - - Assert.Contains("Foo: bar", result); - Assert.Contains("MoreFoo: More bar", result); - Assert.Contains("EvenMoreFoo: Awesome", result); - } - - - [Fact] - public void SerializeUsingHyphenation() - { - var obj = new { foo = "bar", moreFoo = "More bar", EvenMoreFoo = "Awesome" }; - var result = SerializeWithNaming(obj, new HyphenatedNamingConvention()); - Assert.Contains("foo: bar", result); - Assert.Contains("more-foo: More bar", result); - Assert.Contains("even-more-foo: Awesome", result); - } - - private string SerializeWithNaming(T input, INamingConvention naming) - { - var serializer = new Serializer(namingConvention: naming); - using (var writer = new StringWriter()) - { - serializer.Serialize(writer, input, typeof(T)); - return writer.ToString(); - } - } - - private T SerializeThenDeserialize(T input) - { - Serializer serializer = new Serializer(); - TextWriter writer = new StringWriter(); - serializer.Serialize(writer, input, typeof(T)); - - string serialized = writer.ToString(); - Console.WriteLine("serialized =\n-----\n{0}", serialized); - - var deserializer = new Deserializer(); - return deserializer.Deserialize(new StringReader(serialized)); - } - - private class ConventionTest - { - public string FirstTest { get; set; } - public string SecondTest { get; set; } - public string ThirdTest { get; set; } - [YamlAlias("fourthTest")] - public string AliasTest { get; set; } - [YamlIgnore] - public string fourthTest { get; set; } - } - - private void DeserializeUsingNamingConvention(string yaml, INamingConvention convention) - { - var serializer = new Deserializer(namingConvention: convention); - var result = serializer.Deserialize(YamlText(yaml)); - - Assert.Equal("First", result.FirstTest); - Assert.Equal("Second", result.SecondTest); - Assert.Equal("Third", result.ThirdTest); - Assert.Equal("Fourth", result.AliasTest); - } - - [Fact] - public void DeserializeUsingCamelCaseNamingConvention() - { - DeserializeUsingNamingConvention(@" - firstTest: First - secondTest: Second - thirdTest: Third - fourthTest: Fourth - ", new CamelCaseNamingConvention()); - } - - [Fact] - public void DeserializeUsingHyphenatedNamingConvention() - { - DeserializeUsingNamingConvention(@" - first-test: First - second-test: Second - third-test: Third - fourthTest: Fourth - ", new HyphenatedNamingConvention()); - } - - [Fact] - public void DeserializeUsingPascalCaseNamingConvention() - { - DeserializeUsingNamingConvention(@" - FirstTest: First - SecondTest: Second - ThirdTest: Third - fourthTest: Fourth - ", new PascalCaseNamingConvention()); - } - - [Fact] - public void DeserializeUsingUnderscoredNamingConvention() - { - DeserializeUsingNamingConvention(@" - first_test: First - second_test: Second - third_test: Third - fourthTest: Fourth - ", new UnderscoredNamingConvention()); - } - - [Fact] - public void RoundtripAlias() - { - var input = new ConventionTest { AliasTest = "Fourth" }; - var serializer = new Serializer(); - var writer = new StringWriter(); - serializer.Serialize(writer, input, input.GetType()); - string serialized = writer.ToString(); - - // Ensure serialisation is correct - Assert.Equal("fourthTest: Fourth", serialized.TrimEnd('\r', '\n')); - - var deserializer = new Deserializer(); - var output = deserializer.Deserialize(new StringReader(serialized)); - - // Ensure round-trip retains value - Assert.Equal(input.AliasTest, output.AliasTest); - } - - public class HasDefaults - { - public const string DefaultValue = "myDefault"; - - [DefaultValue(DefaultValue)] - public string Value { get; set; } - } - - [Fact] - public void DefaultValueAttributeIsUsedWhenPresentWithoutEmitDefaults() - { - var input = new HasDefaults { Value = HasDefaults.DefaultValue }; - - var serializer = new Serializer(); - var writer = new StringWriter(); - serializer.Serialize(writer, input); - var serialized = writer.ToString(); - - Console.WriteLine(serialized); - - Assert.False(serialized.Contains("Value")); - } - - [Fact] - public void DefaultValueAttributeIsIgnoredWhenPresentWithEmitDefaults() - { - var input = new HasDefaults { Value = HasDefaults.DefaultValue }; - - var serializer = new Serializer(SerializationOptions.EmitDefaults); - var writer = new StringWriter(); - serializer.Serialize(writer, input); - var serialized = writer.ToString(); - - Console.WriteLine(serialized); - - Assert.True(serialized.Contains("Value")); - } - - [Fact] - public void DefaultValueAttributeIsIgnoredWhenValueIsDifferent() - { - var input = new HasDefaults { Value = "non-default" }; - - var serializer = new Serializer(); - var writer = new StringWriter(); - serializer.Serialize(writer, input); - var serialized = writer.ToString(); - - Console.WriteLine(serialized); - - Assert.True(serialized.Contains("Value")); - } - - [Fact] - public void NullValuesInListsAreAlwaysEmittedWithoutEmitDefaults() - { - var input = new string[] { "foo", null, "bar" }; - - var serializer = new Serializer(); - var writer = new StringWriter(); - serializer.Serialize(writer, input); - var serialized = writer.ToString(); - - Console.WriteLine(serialized); - - Assert.Equal(3, Regex.Matches(serialized, "-").Count); - } - - [Fact] - public void NullValuesInListsAreAlwaysEmittedWithEmitDefaults() - { - var input = new string[] { "foo", null, "bar" }; - - var serializer = new Serializer(SerializationOptions.EmitDefaults); - var writer = new StringWriter(); - serializer.Serialize(writer, input); - var serialized = writer.ToString(); - - Console.WriteLine(serialized); - - Assert.Equal(3, Regex.Matches(serialized, "-").Count); - } - - public class Person - { - public string Name { get; set; } - } - - [Fact] - public void DeserializeTwoDocuments() - { - var yaml = @"--- -Name: Andy ---- -Name: Brad -..."; - - var serializer = new Deserializer(); - - var reader = new EventReader(new Parser(new StringReader(yaml))); - - reader.Expect(); - - var andy = serializer.Deserialize(reader); - Assert.NotNull(andy); - Assert.Equal("Andy", andy.Name); - - var brad = serializer.Deserialize(reader); - Assert.NotNull(brad); - Assert.Equal("Brad", brad.Name); - } - - [Fact] - public void DeserializeManyDocuments() - { - var yaml = @"--- -Name: Andy ---- -Name: Brad ---- -Name: Charles -..."; - - var serializer = new Deserializer(); - var reader = new EventReader(new Parser(new StringReader(yaml))); - - reader.Allow(); - - var people = new List(); - while (!reader.Accept()) - { - var person = serializer.Deserialize(reader); - people.Add(person); - } - - Assert.Equal(3, people.Count); - Assert.Equal("Andy", people[0].Name); - Assert.Equal("Brad", people[1].Name); - Assert.Equal("Charles", people[2].Name); - } - +using YamlDotNet.RepresentationModel.Serialization.NamingConventions; + +namespace YamlDotNet.UnitTests.RepresentationModel +{ + public class SerializationTests : YamlTest + { + private class X + { + private bool myFlag; + + public bool MyFlag + { + get + { + return myFlag; + } + set + { + myFlag = value; + } + } + + private string nothing; + + public string Nothing + { + get + { + return nothing; + } + set + { + nothing = value; + } + } + + private int myInt = 1234; + + public int MyInt + { + get + { + return myInt; + } + set + { + myInt = value; + } + } + + private double myDouble = 6789.1011; + + public double MyDouble + { + get + { + return myDouble; + } + set + { + myDouble = value; + } + } + + private string myString = "Hello world"; + + public string MyString + { + get + { + return myString; + } + set + { + myString = value; + } + } + + private DateTime myDate = DateTime.Now; + + public DateTime MyDate + { + get + { + return myDate; + } + set + { + myDate = value; + } + } + + private TimeSpan myTimeSpan = TimeSpan.FromHours(1); + + public TimeSpan MyTimeSpan + { + get + { + return myTimeSpan; + } + set + { + myTimeSpan = value; + } + } + + private Point myPoint = new Point(100, 200); + + public Point MyPoint + { + get + { + return myPoint; + } + set + { + myPoint = value; + } + } + + private int? myNullableWithValue = 8; + + public int? MyNullableWithValue + { + get { return myNullableWithValue; } + set { myNullableWithValue = value; } + } + + private int? myNullableWithoutValue = null; + + public int? MyNullableWithoutValue + { + get { return myNullableWithoutValue; } + set { myNullableWithoutValue = value; } + } + } + + [Fact] + public void Roundtrip() + { + var serializer = new Serializer(SerializationOptions.Roundtrip); + + using (StringWriter buffer = new StringWriter()) + { + X original = new X(); + serializer.Serialize(buffer, original); + + Console.WriteLine(buffer.ToString()); + + var deserializer = new Deserializer(); + X copy = deserializer.Deserialize(new StringReader(buffer.ToString())); + + foreach (var property in typeof(X).GetProperties(BindingFlags.Public | BindingFlags.Instance)) + { + if (property.CanRead && property.CanWrite) + { + Assert.Equal( + property.GetValue(original, null), + property.GetValue(copy, null) + ); + } + } + } + } + + [Fact] + public void RoundtripWithDefaults() + { + var serializer = new Serializer(SerializationOptions.Roundtrip | SerializationOptions.EmitDefaults); + + using (StringWriter buffer = new StringWriter()) + { + X original = new X(); + serializer.Serialize(buffer, original); + + Console.WriteLine(buffer.ToString()); + + var deserializer = new Deserializer(); + X copy = deserializer.Deserialize(new StringReader(buffer.ToString())); + + foreach (var property in typeof(X).GetProperties(BindingFlags.Public | BindingFlags.Instance)) + { + if (property.CanRead && property.CanWrite) + { + Assert.Equal( + property.GetValue(original, null), + property.GetValue(copy, null) + ); + } + } + } + } + + + private class Y + { + private Y child; + + public Y Child + { + get + { + return child; + } + set + { + child = value; + } + } + + private Y child2; + + public Y Child2 + { + get + { + return child2; + } + set + { + child2 = value; + } + } + } + + + [Fact] + public void CircularReference() + { + var serializer = new Serializer(SerializationOptions.Roundtrip); + + using (StringWriter buffer = new StringWriter()) + { + Y original = new Y(); + original.Child = new Y + { + Child = original, + Child2 = original + }; + + serializer.Serialize(buffer, original, typeof(Y)); + + Console.WriteLine(buffer.ToString()); + } + } + + public class Z + { + public string aaa + { + get; + set; + } + } + + [Fact] + public void DeserializeScalar() + { + var sut = new Deserializer(); + object result = sut.Deserialize(YamlFile("test2.yaml"), typeof(object)); + + Assert.Equal("a scalar", result); + } + + [Fact] + public void DeserializeExplicitType() + { + var serializer = new Deserializer(); + object result = serializer.Deserialize(YamlFile("explicitType.yaml"), typeof(object)); + + Assert.True(typeof(Z).IsAssignableFrom(result.GetType())); + Assert.Equal("bbb", ((Z)result).aaa); + } + + [Fact] + public void DeserializeDictionary() + { + var serializer = new Deserializer(); + object result = serializer.Deserialize(YamlFile("dictionary.yaml")); + + Assert.True(typeof(IDictionary).IsAssignableFrom(result.GetType()), "The deserialized object has the wrong type."); + + IDictionary dictionary = (IDictionary)result; + Assert.Equal("value1", dictionary["key1"]); + Assert.Equal("value2", dictionary["key2"]); + } + + [Fact] + public void DeserializeExplicitDictionary() + { + var serializer = new Deserializer(); + object result = serializer.Deserialize(YamlFile("dictionaryExplicit.yaml")); + + Assert.True(typeof(IDictionary).IsAssignableFrom(result.GetType()), "The deserialized object has the wrong type."); + + IDictionary dictionary = (IDictionary)result; + Assert.Equal(1, dictionary["key1"]); + Assert.Equal(2, dictionary["key2"]); + } + + [Fact] + public void DeserializeListOfDictionaries() + { + var serializer = new Deserializer(); + object result = serializer.Deserialize(YamlFile("listOfDictionaries.yaml"), typeof(List>)); + + Assert.IsType>>(result); + + var list = (List>)result; + Assert.Equal("conn1", list[0]["connection"]); + Assert.Equal("path1", list[0]["path"]); + Assert.Equal("conn2", list[1]["connection"]); + Assert.Equal("path2", list[1]["path"]); + } + + [Fact] + public void DeserializeList() + { + var serializer = new Deserializer(); + object result = serializer.Deserialize(YamlFile("list.yaml")); + + Assert.True(typeof(IList).IsAssignableFrom(result.GetType())); + + IList list = (IList)result; + Assert.Equal("one", list[0]); + Assert.Equal("two", list[1]); + Assert.Equal("three", list[2]); + } + + [Fact] + public void DeserializeExplicitList() + { + var serializer = new Deserializer(); + object result = serializer.Deserialize(YamlFile("listExplicit.yaml")); + + Assert.True(typeof(IList).IsAssignableFrom(result.GetType())); + + IList list = (IList)result; + Assert.Equal(3, list[0]); + Assert.Equal(4, list[1]); + Assert.Equal(5, list[2]); + } + + [Fact] + public void DeserializeEnumerable() + { + Z[] z = new[] { new Z() { aaa = "Yo" }}; + Serializer serializer = new Serializer(); + StringWriter buffer = new StringWriter(); + serializer.Serialize(buffer, z); + + var deserializer = new Deserializer(); + var result = (IEnumerable)deserializer.Deserialize(new StringReader(buffer.ToString()), typeof(IEnumerable)); + Assert.Equal(1, result.Count()); + Assert.Equal("Yo", result.First().aaa); + } + + [Fact] + public void RoundtripList() + { + var serializer = new Serializer(SerializationOptions.Roundtrip); + var deserializer = new Deserializer(); + + using (StringWriter buffer = new StringWriter()) + { + List original = new List(); + original.Add(2); + original.Add(4); + original.Add(6); + serializer.Serialize(buffer, original, typeof(List)); + + Console.WriteLine(buffer.ToString()); + + List copy = (List)deserializer.Deserialize(new StringReader(buffer.ToString()), typeof(List)); + + Assert.Equal(original.Count, copy.Count); + + for (int i = 0; i < original.Count; ++i) + { + Assert.Equal(original[i], copy[i]); + } + } + } + + [Fact] + public void DeserializeArray() + { + var serializer = new Deserializer(); + object result = serializer.Deserialize(YamlFile("list.yaml"), typeof(String[])); + + Assert.True(result is String[]); + + String[] array = (String[])result; + Assert.Equal("one", array[0]); + Assert.Equal("two", array[1]); + Assert.Equal("three", array[2]); + } + + [Fact] + public void Enums() + { + var serializer = new Serializer(); + var deserializer = new Deserializer(); + + StringFormatFlags flags = StringFormatFlags.NoClip | StringFormatFlags.NoFontFallback; + + StringWriter buffer = new StringWriter(); + serializer.Serialize(buffer, flags); + + var deserialized = (StringFormatFlags)deserializer.Deserialize(new StringReader(buffer.ToString()), typeof(StringFormatFlags)); + + Assert.Equal(flags, deserialized); + } + + [Fact] + public void CustomTags() + { + var deserializer = new Deserializer(); + deserializer.RegisterTagMapping("tag:yaml.org,2002:point", typeof(Point)); + object result = deserializer.Deserialize(YamlFile("tags.yaml")); + + Assert.Equal(typeof(Point), result.GetType()); + + Point value = (Point)result; + Assert.Equal(10, value.X); + Assert.Equal(20, value.Y); + } + + [Fact] + public void DeserializeConvertible() + { + var serializer = new Deserializer(); + object result = serializer.Deserialize(YamlFile("convertible.yaml"), typeof(Z)); + + Assert.True(typeof(Z).IsAssignableFrom(result.GetType())); + Assert.Equal("[hello, world]", ((Z)result).aaa); + } + + public class Converter : System.ComponentModel.TypeConverter + { + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(string); + } + + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return false; + } + + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + string[] parts = ((string)value).Split(' '); + return new Convertible + { + Left = parts[0], + Right = parts[1] + }; + } + } + + [TypeConverter(typeof(Converter))] + public class Convertible : IConvertible + { + public string Left + { + get; + set; + } + + public string Right + { + get; + set; + } + + #region IConvertible Members + + public TypeCode GetTypeCode() + { + throw new NotImplementedException(); + } + + public bool ToBoolean(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public byte ToByte(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public char ToChar(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public DateTime ToDateTime(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public decimal ToDecimal(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public double ToDouble(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public short ToInt16(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public int ToInt32(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public long ToInt64(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public sbyte ToSByte(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public float ToSingle(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public string ToString(IFormatProvider provider) + { + Assert.Equal(CultureInfo.InvariantCulture, provider); + + return string.Format(provider, "[{0}, {1}]", Left, Right); + } + + public object ToType(Type conversionType, IFormatProvider provider) + { + Assert.Equal(typeof(string), conversionType); + return ToString(provider); + } + + public ushort ToUInt16(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public uint ToUInt32(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + public ulong ToUInt64(IFormatProvider provider) + { + throw new NotImplementedException(); + } + + #endregion + } + + class SomeCustomeType + { + // Test specifically with no parameterless, supposed to fail unless a type converter is specified + public SomeCustomeType(string value) { Value = value; } + public string Value; + } + + public class CustomTypeConverter : IYamlTypeConverter + { + public bool Accepts(Type type) { return type == typeof(SomeCustomeType); } + + public object ReadYaml(Parser parser, Type type) + { + var value = ((Scalar)parser.Current).Value; + parser.MoveNext(); + return new SomeCustomeType(value); + } + + public void WriteYaml(Emitter emitter, object value, Type type) + { + emitter.Emit(new Scalar(((SomeCustomeType)value).Value)); + } + } + + [Fact] + public void RoundtripWithTypeConverter() + { + SomeCustomeType x = new SomeCustomeType("Yo"); + var serializer = new Serializer(SerializationOptions.Roundtrip); + serializer.RegisterTypeConverter(new CustomTypeConverter()); + StringWriter buffer = new StringWriter(); + serializer.Serialize(buffer, x); + + Console.WriteLine(buffer.ToString()); + + var deserializer = new Deserializer(); + deserializer.RegisterTypeConverter(new CustomTypeConverter()); + + var copy = deserializer.Deserialize(new StringReader(buffer.ToString())); + Assert.Equal("Yo", copy.Value); + } + + [Fact] + public void RoundtripDictionary() + { + Dictionary entries = new Dictionary + { + { "key1", "value1" }, + { "key2", "value2" }, + { "key3", "value3" }, + }; + + var serializer = new Serializer(); + + StringWriter buffer = new StringWriter(); + serializer.Serialize(buffer, entries); + + Console.WriteLine(buffer.ToString()); + + var deserializer = new Deserializer(); + var deserialized = deserializer.Deserialize>(new StringReader(buffer.ToString())); + + foreach (var pair in deserialized) + { + Assert.Equal(entries[pair.Key], pair.Value); + } + } + + [Fact] + public void SerializeAnonymousType() + { + var data = new { Key = 3 }; + + var serializer = new Serializer(); + + StringWriter buffer = new StringWriter(); + serializer.Serialize(buffer, data); + + Console.WriteLine(buffer.ToString()); + + var deserializer = new Deserializer(); + var parsed = deserializer.Deserialize>(new StringReader(buffer.ToString())); + + Assert.NotNull(parsed); + Assert.Equal(1, parsed.Count); + } + + [Fact] + public void SerializationIncludesNullWhenAsked_BugFix() + { + var serializer = new Serializer(SerializationOptions.EmitDefaults); + + using (StringWriter buffer = new StringWriter()) + { + var original = new { MyString = (string)null }; + serializer.Serialize(buffer, original, original.GetType()); + + Console.WriteLine(buffer.ToString()); + + Assert.True(buffer.ToString().Contains("MyString")); + } + } + + [Fact] + public void SerializationIncludesNullWhenAsked() + { + var serializer = new Serializer(SerializationOptions.EmitDefaults); + + using (StringWriter buffer = new StringWriter()) + { + X original = new X { MyString = null }; + serializer.Serialize(buffer, original, typeof(X)); + + Console.WriteLine(buffer.ToString()); + + Assert.True(buffer.ToString().Contains("MyString")); + } + } + + [Fact] + public void SerializationDoesNotIncludeNullWhenNotAsked() + { + var serializer = new Serializer(); + + using (StringWriter buffer = new StringWriter()) + { + X original = new X { MyString = null }; + serializer.Serialize(buffer, original, typeof(X)); + + Console.WriteLine(buffer.ToString()); + + Assert.False(buffer.ToString().Contains("MyString")); + } + } + + [Fact] + public void SerializationOfNullWorksInJson() + { + var serializer = new Serializer(SerializationOptions.EmitDefaults | SerializationOptions.JsonCompatible); + + using (StringWriter buffer = new StringWriter()) + { + X original = new X { MyString = null }; + serializer.Serialize(buffer, original, typeof(X)); + + Console.WriteLine(buffer.ToString()); + + Assert.True(buffer.ToString().Contains("MyString")); + } + } + + [Fact] + public void DeserializationOfNullWorksInJson() + { + var serializer = new Serializer(SerializationOptions.EmitDefaults | SerializationOptions.JsonCompatible | SerializationOptions.Roundtrip); + var deserializer = new Deserializer(); + + using (StringWriter buffer = new StringWriter()) + { + X original = new X { MyString = null }; + serializer.Serialize(buffer, original, typeof(X)); + + Console.WriteLine(buffer.ToString()); + + X copy = (X)deserializer.Deserialize(new StringReader(buffer.ToString()), typeof(X)); + + Assert.Null(copy.MyString); + } + } + + class ContainsIgnore + { + [YamlIgnore] + public String IgnoreMe { get; set; } + } + + [Fact] + public void SerializationRespectsYamlIgnoreAttribute() + { + var serializer = new Serializer(); + var deserializer = new Deserializer(); + + using (StringWriter buffer = new StringWriter()) + { + var orig = new ContainsIgnore { IgnoreMe = "Some Text" }; + serializer.Serialize(buffer, orig); + Console.WriteLine(buffer.ToString()); + var copy = (ContainsIgnore)deserializer.Deserialize(new StringReader(buffer.ToString()), typeof(ContainsIgnore)); + Assert.Null(copy.IgnoreMe); + } + } + + [Fact] + public void SerializeArrayOfIdenticalObjects() + { + var obj1 = new Z { aaa = "abc" }; + + var objects = new[] { obj1, obj1, obj1 }; + + var result = SerializeThenDeserialize(objects); + + Assert.NotNull(result); + Assert.Equal(3, result.Length); + Assert.Equal(obj1.aaa, result[0].aaa); + Assert.Equal(obj1.aaa, result[1].aaa); + Assert.Equal(obj1.aaa, result[2].aaa); + Assert.Same(result[0], result[1]); + Assert.Same(result[1], result[2]); + } + + [Fact] + public void SerializeUsingCamelCaseNaming() + { + var obj = new { foo = "bar", moreFoo = "More bar", evenMoreFoo = "Awesome" }; + var result = SerializeWithNaming(obj, new CamelCaseNamingConvention()); + Assert.Contains("foo: bar", result); + Assert.Contains("moreFoo: More bar", result); + Assert.Contains("evenMoreFoo: Awesome", result); + } + + [Fact] + public void SerializeUsingPascalCaseNaming() + { + var obj = new { foo = "bar", moreFoo = "More bar", evenMoreFoo = "Awesome" }; + var result = SerializeWithNaming(obj, new PascalCaseNamingConvention()); + + Console.WriteLine(result); + + Assert.Contains("Foo: bar", result); + Assert.Contains("MoreFoo: More bar", result); + Assert.Contains("EvenMoreFoo: Awesome", result); + } + + + [Fact] + public void SerializeUsingHyphenation() + { + var obj = new { foo = "bar", moreFoo = "More bar", EvenMoreFoo = "Awesome" }; + var result = SerializeWithNaming(obj, new HyphenatedNamingConvention()); + Assert.Contains("foo: bar", result); + Assert.Contains("more-foo: More bar", result); + Assert.Contains("even-more-foo: Awesome", result); + } + + private string SerializeWithNaming(T input, INamingConvention naming) + { + var serializer = new Serializer(namingConvention: naming); + using (var writer = new StringWriter()) + { + serializer.Serialize(writer, input, typeof(T)); + return writer.ToString(); + } + } + + private T SerializeThenDeserialize(T input) + { + Serializer serializer = new Serializer(); + TextWriter writer = new StringWriter(); + serializer.Serialize(writer, input, typeof(T)); + + string serialized = writer.ToString(); + Console.WriteLine("serialized =\n-----\n{0}", serialized); + + var deserializer = new Deserializer(); + return deserializer.Deserialize(new StringReader(serialized)); + } + + private class ConventionTest + { + public string FirstTest { get; set; } + public string SecondTest { get; set; } + public string ThirdTest { get; set; } + [YamlAlias("fourthTest")] + public string AliasTest { get; set; } + [YamlIgnore] + public string fourthTest { get; set; } + } + + private void DeserializeUsingNamingConvention(string yaml, INamingConvention convention) + { + var serializer = new Deserializer(namingConvention: convention); + var result = serializer.Deserialize(YamlText(yaml)); + + Assert.Equal("First", result.FirstTest); + Assert.Equal("Second", result.SecondTest); + Assert.Equal("Third", result.ThirdTest); + Assert.Equal("Fourth", result.AliasTest); + } + + [Fact] + public void DeserializeUsingCamelCaseNamingConvention() + { + DeserializeUsingNamingConvention(@" + firstTest: First + secondTest: Second + thirdTest: Third + fourthTest: Fourth + ", new CamelCaseNamingConvention()); + } + + [Fact] + public void DeserializeUsingHyphenatedNamingConvention() + { + DeserializeUsingNamingConvention(@" + first-test: First + second-test: Second + third-test: Third + fourthTest: Fourth + ", new HyphenatedNamingConvention()); + } + + [Fact] + public void DeserializeUsingPascalCaseNamingConvention() + { + DeserializeUsingNamingConvention(@" + FirstTest: First + SecondTest: Second + ThirdTest: Third + fourthTest: Fourth + ", new PascalCaseNamingConvention()); + } + + [Fact] + public void DeserializeUsingUnderscoredNamingConvention() + { + DeserializeUsingNamingConvention(@" + first_test: First + second_test: Second + third_test: Third + fourthTest: Fourth + ", new UnderscoredNamingConvention()); + } + + [Fact] + public void RoundtripAlias() + { + var input = new ConventionTest { AliasTest = "Fourth" }; + var serializer = new Serializer(); + var writer = new StringWriter(); + serializer.Serialize(writer, input, input.GetType()); + string serialized = writer.ToString(); + + // Ensure serialisation is correct + Assert.Equal("fourthTest: Fourth", serialized.TrimEnd('\r', '\n')); + + var deserializer = new Deserializer(); + var output = deserializer.Deserialize(new StringReader(serialized)); + + // Ensure round-trip retains value + Assert.Equal(input.AliasTest, output.AliasTest); + } + + public class HasDefaults + { + public const string DefaultValue = "myDefault"; + + [DefaultValue(DefaultValue)] + public string Value { get; set; } + } + + [Fact] + public void DefaultValueAttributeIsUsedWhenPresentWithoutEmitDefaults() + { + var input = new HasDefaults { Value = HasDefaults.DefaultValue }; + + var serializer = new Serializer(); + var writer = new StringWriter(); + serializer.Serialize(writer, input); + var serialized = writer.ToString(); + + Console.WriteLine(serialized); + + Assert.False(serialized.Contains("Value")); + } + + [Fact] + public void DefaultValueAttributeIsIgnoredWhenPresentWithEmitDefaults() + { + var input = new HasDefaults { Value = HasDefaults.DefaultValue }; + + var serializer = new Serializer(SerializationOptions.EmitDefaults); + var writer = new StringWriter(); + serializer.Serialize(writer, input); + var serialized = writer.ToString(); + + Console.WriteLine(serialized); + + Assert.True(serialized.Contains("Value")); + } + + [Fact] + public void DefaultValueAttributeIsIgnoredWhenValueIsDifferent() + { + var input = new HasDefaults { Value = "non-default" }; + + var serializer = new Serializer(); + var writer = new StringWriter(); + serializer.Serialize(writer, input); + var serialized = writer.ToString(); + + Console.WriteLine(serialized); + + Assert.True(serialized.Contains("Value")); + } + + [Fact] + public void NullValuesInListsAreAlwaysEmittedWithoutEmitDefaults() + { + var input = new string[] { "foo", null, "bar" }; + + var serializer = new Serializer(); + var writer = new StringWriter(); + serializer.Serialize(writer, input); + var serialized = writer.ToString(); + + Console.WriteLine(serialized); + + Assert.Equal(3, Regex.Matches(serialized, "-").Count); + } + + [Fact] + public void NullValuesInListsAreAlwaysEmittedWithEmitDefaults() + { + var input = new string[] { "foo", null, "bar" }; + + var serializer = new Serializer(SerializationOptions.EmitDefaults); + var writer = new StringWriter(); + serializer.Serialize(writer, input); + var serialized = writer.ToString(); + + Console.WriteLine(serialized); + + Assert.Equal(3, Regex.Matches(serialized, "-").Count); + } + + public class Person + { + public string Name { get; set; } + } + + [Fact] + public void DeserializeTwoDocuments() + { + var yaml = @"--- +Name: Andy +--- +Name: Brad +..."; + + var serializer = new Deserializer(); + + var reader = new EventReader(new Parser(new StringReader(yaml))); + + reader.Expect(); + + var andy = serializer.Deserialize(reader); + Assert.NotNull(andy); + Assert.Equal("Andy", andy.Name); + + var brad = serializer.Deserialize(reader); + Assert.NotNull(brad); + Assert.Equal("Brad", brad.Name); + } + + [Fact] + public void DeserializeManyDocuments() + { + var yaml = @"--- +Name: Andy +--- +Name: Brad +--- +Name: Charles +..."; + + var serializer = new Deserializer(); + var reader = new EventReader(new Parser(new StringReader(yaml))); + + reader.Allow(); + + var people = new List(); + while (!reader.Accept()) + { + var person = serializer.Deserialize(reader); + people.Add(person); + } + + Assert.Equal(3, people.Count); + Assert.Equal("Andy", people[0].Name); + Assert.Equal("Brad", people[1].Name); + Assert.Equal("Charles", people[2].Name); + } + [Fact] public void DeserializeEmptyDocument() { @@ -1322,6 +1322,6 @@ Name: Charles ")) ); } - } -} - + } +} + diff --git a/YamlDotNetEditor/FileAndContentTypeDefinitions.cs b/YamlDotNetEditor/FileAndContentTypeDefinitions.cs index 6fe8ca1..497d658 100644 --- a/YamlDotNetEditor/FileAndContentTypeDefinitions.cs +++ b/YamlDotNetEditor/FileAndContentTypeDefinitions.cs @@ -20,7 +20,7 @@ // SOFTWARE. using Microsoft.VisualStudio.Utilities; -using System.ComponentModel.Composition; +using System.ComponentModel.Composition; namespace YamlDotNetEditor {