From 480726699da336ca3d0ce3daaef37c6b43456e18 Mon Sep 17 00:00:00 2001 From: Fredrik Ludvigsen Date: Thu, 28 Jan 2016 13:12:27 +0100 Subject: [PATCH 1/5] Now support negative integers :-) --- .../Serialization/NodeDeserializers/ScalarNodeDeserializer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YamlDotNet/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs b/YamlDotNet/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs index c7e125b91..f980c9872 100644 --- a/YamlDotNet/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs +++ b/YamlDotNet/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs @@ -194,7 +194,7 @@ private object DeserializeIntegerHelper(TypeCode typeCode, string value, IFormat else { // Could be decimal or base 60 - string[] chunks = value.Split(':'); + string[] chunks = value.Substring(currentIndex).Split(':'); result = 0; for (int chunkIndex = 0; chunkIndex < chunks.Length; chunkIndex++) From 6f467fee48f49a62c6885a7d274f6b3f602ef0ad Mon Sep 17 00:00:00 2001 From: Antoine Aubry Date: Mon, 1 Feb 2016 14:53:25 +0000 Subject: [PATCH 2/5] Add unit test for negative integers. --- .../Serialization/SerializationTests.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/YamlDotNet.Test/Serialization/SerializationTests.cs b/YamlDotNet.Test/Serialization/SerializationTests.cs index b9a771110..3c511e9f0 100644 --- a/YamlDotNet.Test/Serialization/SerializationTests.cs +++ b/YamlDotNet.Test/Serialization/SerializationTests.cs @@ -1020,10 +1020,10 @@ public void SpecialFloatsAreDeserializedCorrectly() [Fact] public void SpecialFloatsAreSerializedCorrectly() { - var deserializer = new Serializer(); + var serializer = new Serializer(); var buffer = new StringWriter(); - deserializer.Serialize(buffer, new double[] + serializer.Serialize(buffer, new double[] { double.NaN, double.PositiveInfinity, @@ -1037,6 +1037,17 @@ public void SpecialFloatsAreSerializedCorrectly() Assert.Contains("- -.inf", text); } + [Fact] + public void NegativeIntegersCanBeDeserialized() + { + var deserializer = new Deserializer(); + + var value = deserializer.Deserialize(Yaml.ReaderForText(@" + '-123' + ")); + Assert.Equal(-123, value); + } + #region Test Dictionary that implements IDictionary<,>, but not IDictionary public class GenericTestDictionary : IDictionary { From e5ace2fd6912d3c1c7a111c84e523d20526756ca Mon Sep 17 00:00:00 2001 From: Antoine Aubry Date: Mon, 1 Feb 2016 15:24:35 +0000 Subject: [PATCH 3/5] Use spaces for indentation, as discussed in #143. This should make it easier for everyone who wishes to contribute, since it seems that most people prefer to use spaces. --- CONTRIBUTING.md | 2 +- .../ISerializationTest.cs | 8 +- .../ISerializerAdapter.cs | 8 +- .../PerformanceTestRunner.cs | 76 +- .../Tests/Receipt.cs | 94 +- .../Program.cs | 232 +- .../Program.cs | 26 +- .../Program.cs | 26 +- .../Program.cs | 26 +- .../Program.cs | 26 +- YamlDotNet.Test/Core/EmitterTests.cs | 524 +-- YamlDotNet.Test/Core/EmitterTestsHelper.cs | 168 +- YamlDotNet.Test/Core/EventsHelper.cs | 494 +-- YamlDotNet.Test/Core/InsertionQueueTests.cs | 194 +- YamlDotNet.Test/Core/LookAheadBufferTests.cs | 486 +-- YamlDotNet.Test/Core/MarkCursorTests.cs | 22 +- YamlDotNet.Test/Core/ParserTests.cs | 792 ++-- YamlDotNet.Test/Core/ScannerTests.cs | 806 ++-- YamlDotNet.Test/Core/TokenHelper.cs | 276 +- YamlDotNet.Test/Dump.cs | 66 +- YamlDotNet.Test/EnumerableExtensions.cs | 36 +- .../BinarySerlializationTests.cs | 38 +- .../RepresentationModel/YamlStreamTests.cs | 486 +-- .../Serialization/CodeValidations.cs | 30 +- .../Serialization/NamingConventionTests.cs | 82 +- .../Serialization/ObjectFactoryTests.cs | 42 +- .../Serialization/SerializationTestHelper.cs | 968 ++--- .../Serialization/SerializationTests.cs | 2066 ++++----- YamlDotNet.Test/Yaml.cs | 132 +- YamlDotNet.Test/files/09-flow-mapping.yaml | 4 +- .../files/dictionary-explicit.yaml | 4 +- YamlDotNet.Test/files/dictionary.yaml | 4 +- YamlDotNet.Test/files/explicit-type.template | 2 +- YamlDotNet.sln | 1 + YamlDotNet/Core/AnchorNotFoundException.cs | 96 +- YamlDotNet/Core/CharacterAnalyzer.cs | 300 +- YamlDotNet/Core/Constants.cs | 34 +- YamlDotNet/Core/Cursor.cs | 82 +- YamlDotNet/Core/DuplicateAnchorException.cs | 92 +- YamlDotNet/Core/Emitter.cs | 3448 ++++++++-------- YamlDotNet/Core/EmitterState.cs | 42 +- YamlDotNet/Core/EventReader.cs | 220 +- YamlDotNet/Core/Events/AnchorAlias.cs | 140 +- YamlDotNet/Core/Events/Comment.cs | 54 +- YamlDotNet/Core/Events/DocumentEnd.cs | 160 +- YamlDotNet/Core/Events/DocumentStart.cs | 252 +- YamlDotNet/Core/Events/EventType.cs | 30 +- .../Core/Events/IParsingEventVisitor.cs | 34 +- YamlDotNet/Core/Events/MappingEnd.cs | 118 +- YamlDotNet/Core/Events/MappingStart.cs | 232 +- YamlDotNet/Core/Events/MappingStyle.cs | 36 +- YamlDotNet/Core/Events/NodeEvent.cs | 142 +- YamlDotNet/Core/Events/ParsingEvent.cs | 116 +- YamlDotNet/Core/Events/Scalar.cs | 336 +- YamlDotNet/Core/Events/SequenceEnd.cs | 118 +- YamlDotNet/Core/Events/SequenceStart.cs | 212 +- YamlDotNet/Core/Events/SequenceStyle.cs | 36 +- YamlDotNet/Core/Events/StreamEnd.cs | 118 +- YamlDotNet/Core/Events/StreamStart.cs | 118 +- YamlDotNet/Core/FakeList.cs | 100 +- .../ForwardAnchorNotSupportedException.cs | 94 +- YamlDotNet/Core/HashCode.cs | 28 +- YamlDotNet/Core/IEmitter.cs | 20 +- YamlDotNet/Core/ILookAheadBuffer.cs | 40 +- YamlDotNet/Core/IParser.cs | 30 +- YamlDotNet/Core/IScanner.cs | 52 +- YamlDotNet/Core/InsertionQueue.cs | 100 +- YamlDotNet/Core/LookAheadBuffer.cs | 224 +- YamlDotNet/Core/Mark.cs | 206 +- YamlDotNet/Core/MergingParser.cs | 332 +- YamlDotNet/Core/Parser.cs | 1834 ++++---- YamlDotNet/Core/ParserState.cs | 54 +- YamlDotNet/Core/ScalarStyle.cs | 60 +- YamlDotNet/Core/Scanner.cs | 3674 ++++++++--------- YamlDotNet/Core/SemanticErrorException.cs | 92 +- YamlDotNet/Core/SimpleKey.cs | 46 +- YamlDotNet/Core/StringLookAheadBuffer.cs | 78 +- YamlDotNet/Core/SyntaxErrorException.cs | 92 +- YamlDotNet/Core/TagDirectiveCollection.cs | 72 +- YamlDotNet/Core/Tokens/Anchor.cs | 76 +- YamlDotNet/Core/Tokens/AnchorAlias.cs | 74 +- YamlDotNet/Core/Tokens/BlockEnd.cs | 46 +- YamlDotNet/Core/Tokens/BlockEntry.cs | 46 +- YamlDotNet/Core/Tokens/BlockMappingStart.cs | 46 +- YamlDotNet/Core/Tokens/BlockSequenceStart.cs | 46 +- YamlDotNet/Core/Tokens/Comment.cs | 68 +- YamlDotNet/Core/Tokens/DocumentEnd.cs | 46 +- YamlDotNet/Core/Tokens/DocumentStart.cs | 46 +- YamlDotNet/Core/Tokens/FlowEntry.cs | 46 +- YamlDotNet/Core/Tokens/FlowMappingEnd.cs | 46 +- YamlDotNet/Core/Tokens/FlowMappingStart.cs | 46 +- YamlDotNet/Core/Tokens/FlowSequenceEnd.cs | 46 +- YamlDotNet/Core/Tokens/FlowSequenceStart.cs | 46 +- YamlDotNet/Core/Tokens/Key.cs | 46 +- YamlDotNet/Core/Tokens/Scalar.cs | 122 +- YamlDotNet/Core/Tokens/StreamEnd.cs | 46 +- YamlDotNet/Core/Tokens/StreamStart.cs | 46 +- YamlDotNet/Core/Tokens/Tag.cs | 106 +- YamlDotNet/Core/Tokens/TagDirective.cs | 188 +- YamlDotNet/Core/Tokens/Token.cs | 78 +- YamlDotNet/Core/Tokens/Value.cs | 46 +- YamlDotNet/Core/Tokens/VersionDirective.cs | 120 +- YamlDotNet/Core/Version.cs | 94 +- YamlDotNet/Core/YamlException.cs | 58 +- YamlDotNet/Helpers/Portability.cs | 606 +-- .../DocumentLoadingState.cs | 150 +- .../RepresentationModel/EmitterState.cs | 36 +- .../RepresentationModel/IYamlVisitor.cs | 82 +- .../RepresentationModel/YamlAliasNode.cs | 156 +- .../RepresentationModel/YamlDocument.cs | 342 +- .../RepresentationModel/YamlMappingNode.cs | 688 +-- YamlDotNet/RepresentationModel/YamlNode.cs | 358 +- .../YamlNodeIdentityEqualityComparer.cs | 36 +- .../RepresentationModel/YamlScalarNode.cs | 252 +- .../RepresentationModel/YamlSequenceNode.cs | 474 +-- YamlDotNet/RepresentationModel/YamlStream.cs | 238 +- YamlDotNet/RepresentationModel/YamlVisitor.cs | 392 +- YamlDotNet/Serialization/Deserializer.cs | 336 +- .../EventEmitters/ChainedEventEmitter.cs | 80 +- .../EventEmitters/JsonEventEmitter.cs | 164 +- .../TypeAssigningEventEmitter.cs | 206 +- .../EventEmitters/WriterEventEmitter.cs | 64 +- YamlDotNet/Serialization/EventInfo.cs | 138 +- YamlDotNet/Serialization/IAliasProvider.cs | 8 +- YamlDotNet/Serialization/IEventEmitter.cs | 18 +- YamlDotNet/Serialization/INamingConvention.cs | 14 +- YamlDotNet/Serialization/INodeDeserializer.cs | 8 +- YamlDotNet/Serialization/INodeTypeResolver.cs | 26 +- YamlDotNet/Serialization/IObjectDescriptor.cs | 44 +- YamlDotNet/Serialization/IObjectFactory.cs | 26 +- .../IObjectGraphTraversalStrategy.cs | 24 +- .../Serialization/IObjectGraphVisitor.cs | 116 +- .../Serialization/IPropertyDescriptor.cs | 22 +- YamlDotNet/Serialization/ITypeInspector.cs | 50 +- YamlDotNet/Serialization/ITypeResolver.cs | 14 +- .../Serialization/IValueDeserializer.cs | 8 +- YamlDotNet/Serialization/IValuePromise.cs | 10 +- YamlDotNet/Serialization/IYamlSerializable.cs | 28 +- .../Serialization/IYamlTypeConverter.cs | 36 +- .../CamelCaseNamingConvention.cs | 24 +- .../HyphenatedNamingConvention.cs | 20 +- .../NamingConventions/NullNamingConvention.cs | 20 +- .../PascalCaseNamingConvention.cs | 24 +- .../UnderscoredNamingConvention.cs | 20 +- .../ArrayNodeDeserializer.cs | 46 +- .../EnumerableNodeDeserializer.cs | 52 +- .../GenericCollectionNodeDeserializer.cs | 102 +- .../GenericDictionaryNodeDeserializer.cs | 174 +- .../NonGenericDictionaryNodeDeserializer.cs | 156 +- .../NonGenericListNodeDeserializer.cs | 72 +- .../NodeDeserializers/NullNodeDeserializer.cs | 56 +- .../ObjectNodeDeserializer.cs | 102 +- .../ScalarNodeDeserializer.cs | 428 +- .../TypeConverterNodeDeserializer.cs | 54 +- .../DefaultContainersNodeTypeResolver.cs | 40 +- .../NodeTypeResolvers/TagNodeTypeResolver.cs | 46 +- .../TypeNameInTagNodeTypeResolver.cs | 36 +- YamlDotNet/Serialization/ObjectDescriptor.cs | 66 +- .../ObjectFactories/DefaultObjectFactory.cs | 66 +- .../ObjectFactories/LambdaObjectFactory.cs | 38 +- .../FullObjectGraphTraversalStrategy.cs | 444 +- .../RoundtripObjectGraphTraversalStrategy.cs | 40 +- .../ObjectGraphVisitors/AnchorAssigner.cs | 108 +- .../AnchorAssigningObjectGraphVisitor.cs | 68 +- .../ChainedObjectGraphVisitor.cs | 80 +- .../CustomSerializationObjectGraphVisitor.cs | 58 +- .../DefaultExclusiveObjectGraphVisitor.cs | 50 +- .../EmittingObjectGraphVisitor.cs | 80 +- .../Serialization/PropertyDescriptor.cs | 76 +- .../Serialization/SerializationOptions.cs | 76 +- YamlDotNet/Serialization/Serializer.cs | 352 +- YamlDotNet/Serialization/StreamFragment.cs | 100 +- YamlDotNet/Serialization/TagMappings.cs | 96 +- .../TypeInspectors/CachedTypeInspector.cs | 56 +- .../NamingConventionTypeInspector.cs | 54 +- ...dableAndWritablePropertiesTypeInspector.cs | 34 +- .../ReadablePropertiesTypeInspector.cs | 118 +- .../TypeInspectors/TypeInspectorSkeleton.cs | 86 +- .../TypeResolvers/DynamicTypeResolver.cs | 20 +- .../TypeResolvers/StaticTypeResolver.cs | 20 +- .../Utilities/IPostDeserializationCallback.cs | 16 +- .../Utilities/ObjectAnchorCollection.cs | 88 +- .../Utilities/ReflectionUtility.cs | 172 +- .../Utilities/SerializerState.cs | 76 +- .../Utilities/StringExtensions.cs | 98 +- .../Serialization/Utilities/TypeConverter.cs | 426 +- .../Utilities/YamlTypeConverters.cs | 16 +- .../AliasValueDeserializer.cs | 240 +- .../NodeValueDeserializer.cs | 128 +- .../Serialization/YamlAliasAttribute.cs | 40 +- .../YamlAttributesTypeInspector.cs | 90 +- YamlDotNet/Serialization/YamlFormatter.cs | 68 +- YamlDotNet/Serialization/YamlMember.cs | 46 +- YamlDotNet/YamlDotNet.Signed.nuspec | 38 +- YamlDotNet/YamlDotNet.Unsigned.nuspec | 38 +- build.ps1 | 12 +- prebuild.ps1 | 2 +- 197 files changed, 17109 insertions(+), 17108 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4cc68b862..a556929ee 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -66,7 +66,7 @@ Attempt to follow the [SOLID](https://en.wikipedia.org/wiki/SOLID_%28object-orie As long as you keep the code readable, I don't care too much about any specific coding convention. There are only a few rules that should be honored: -* Use **tabs** instead of spaces. The entire code base is tab-indented, and there's no value in changing. +* Use **4 spaces** to indent. * Each class / interface / struct / delegate **goes to its own file**. * The only acceptable exception is for small and closely related types. * Use sane indentation rules. Break long lines when needed, but don't be obsessive: diff --git a/PerformanceTests/YamlDotNet.PerformanceTests.Lib/ISerializationTest.cs b/PerformanceTests/YamlDotNet.PerformanceTests.Lib/ISerializationTest.cs index 6397a6148..2205b8c90 100644 --- a/PerformanceTests/YamlDotNet.PerformanceTests.Lib/ISerializationTest.cs +++ b/PerformanceTests/YamlDotNet.PerformanceTests.Lib/ISerializationTest.cs @@ -23,8 +23,8 @@ namespace YamlDotNet.PerformanceTests.Lib { - public interface ISerializationTest - { - object Graph { get; } - } + public interface ISerializationTest + { + object Graph { get; } + } } \ No newline at end of file diff --git a/PerformanceTests/YamlDotNet.PerformanceTests.Lib/ISerializerAdapter.cs b/PerformanceTests/YamlDotNet.PerformanceTests.Lib/ISerializerAdapter.cs index c68756a79..2a855a008 100644 --- a/PerformanceTests/YamlDotNet.PerformanceTests.Lib/ISerializerAdapter.cs +++ b/PerformanceTests/YamlDotNet.PerformanceTests.Lib/ISerializerAdapter.cs @@ -24,8 +24,8 @@ namespace YamlDotNet.PerformanceTests.Lib { - public interface ISerializerAdapter - { - void Serialize (TextWriter writer, object graph); - } + public interface ISerializerAdapter + { + void Serialize (TextWriter writer, object graph); + } } \ No newline at end of file diff --git a/PerformanceTests/YamlDotNet.PerformanceTests.Lib/PerformanceTestRunner.cs b/PerformanceTests/YamlDotNet.PerformanceTests.Lib/PerformanceTestRunner.cs index 2559d9b84..7af3f55c0 100644 --- a/PerformanceTests/YamlDotNet.PerformanceTests.Lib/PerformanceTestRunner.cs +++ b/PerformanceTests/YamlDotNet.PerformanceTests.Lib/PerformanceTestRunner.cs @@ -26,52 +26,52 @@ namespace YamlDotNet.PerformanceTests.Lib { - public class PerformanceTestRunner - { - private const int _defaultIterations = 10000; + public class PerformanceTestRunner + { + private const int _defaultIterations = 10000; - public void Run(ISerializerAdapter serializer, string[] args) - { - var iterations = args.Length > 0 - ? int.Parse(args[0]) - : _defaultIterations; + public void Run(ISerializerAdapter serializer, string[] args) + { + var iterations = args.Length > 0 + ? int.Parse(args[0]) + : _defaultIterations; - var adapterName = serializer.GetType().Namespace.Split('.').Last(); + var adapterName = serializer.GetType().Namespace.Split('.').Last(); - var tests = typeof(ISerializationTest).Assembly - .GetTypes() - .Where(t => t.IsClass && typeof(ISerializationTest).IsAssignableFrom(t)) - .Select(t => (ISerializationTest)Activator.CreateInstance(t)); + var tests = typeof(ISerializationTest).Assembly + .GetTypes() + .Where(t => t.IsClass && typeof(ISerializationTest).IsAssignableFrom(t)) + .Select(t => (ISerializationTest)Activator.CreateInstance(t)); - foreach(var test in tests) - { - Console.Write("{0}\t{1}\t", adapterName, test.GetType().Name); + foreach(var test in tests) + { + Console.Write("{0}\t{1}\t", adapterName, test.GetType().Name); - var graph = test.Graph; + var graph = test.Graph; - // Warmup - RunTest(serializer, graph); + // Warmup + RunTest(serializer, graph); - if(!Stopwatch.IsHighResolution) - { - Console.Error.WriteLine("Stopwatch is not high resolution!"); - } + if(!Stopwatch.IsHighResolution) + { + Console.Error.WriteLine("Stopwatch is not high resolution!"); + } - var timer = Stopwatch.StartNew(); - for (var i = 0; i < iterations; ++i) - { - RunTest(serializer, graph); - } - var duration = timer.Elapsed; - Console.WriteLine("{0}", duration.TotalMilliseconds / iterations); - } - } + var timer = Stopwatch.StartNew(); + for (var i = 0; i < iterations; ++i) + { + RunTest(serializer, graph); + } + var duration = timer.Elapsed; + Console.WriteLine("{0}", duration.TotalMilliseconds / iterations); + } + } - private void RunTest(ISerializerAdapter serializer, object graph) - { - var buffer = new StringWriter(); - serializer.Serialize(buffer, graph); - } - } + private void RunTest(ISerializerAdapter serializer, object graph) + { + var buffer = new StringWriter(); + serializer.Serialize(buffer, graph); + } + } } diff --git a/PerformanceTests/YamlDotNet.PerformanceTests.Lib/Tests/Receipt.cs b/PerformanceTests/YamlDotNet.PerformanceTests.Lib/Tests/Receipt.cs index 8bfc9dac5..dbae8b19e 100644 --- a/PerformanceTests/YamlDotNet.PerformanceTests.Lib/Tests/Receipt.cs +++ b/PerformanceTests/YamlDotNet.PerformanceTests.Lib/Tests/Receipt.cs @@ -23,54 +23,54 @@ namespace YamlDotNet.PerformanceTests.Lib { - public class Receipt : ISerializationTest - { - public object Graph { - get { - var address = new - { - street = "123 Tornado Alley\nSuite 16", - city = "East Westville", - state = "KS" - }; + public class Receipt : ISerializationTest + { + public object Graph { + get { + var address = new + { + street = "123 Tornado Alley\nSuite 16", + city = "East Westville", + state = "KS" + }; - var receipt = new - { - receipt = "Oz-Ware Purchase Invoice", - date = new DateTime(2007, 8, 6), - customer = new - { - given = "Dorothy", - family = "Gale" - }, - items = new[] - { - new - { - part_no = "A4786", - descrip = "Water Bucket (Filled)", - price = 1.47M, - quantity = 4 - }, - new - { - part_no = "E1628", - descrip = "High Heeled \"Ruby\" Slippers", - price = 100.27M, - quantity = 1 - } - }, - bill_to = address, - ship_to = address, - specialDelivery = "Follow the Yellow Brick\n" + - "Road to the Emerald City.\n" + - "Pay no attention to the\n" + - "man behind the curtain." - }; + var receipt = new + { + receipt = "Oz-Ware Purchase Invoice", + date = new DateTime(2007, 8, 6), + customer = new + { + given = "Dorothy", + family = "Gale" + }, + items = new[] + { + new + { + part_no = "A4786", + descrip = "Water Bucket (Filled)", + price = 1.47M, + quantity = 4 + }, + new + { + part_no = "E1628", + descrip = "High Heeled \"Ruby\" Slippers", + price = 100.27M, + quantity = 1 + } + }, + bill_to = address, + ship_to = address, + specialDelivery = "Follow the Yellow Brick\n" + + "Road to the Emerald City.\n" + + "Pay no attention to the\n" + + "man behind the curtain." + }; - return receipt; - } - } - } + return receipt; + } + } + } } diff --git a/PerformanceTests/YamlDotNet.PerformanceTests.Runner/Program.cs b/PerformanceTests/YamlDotNet.PerformanceTests.Runner/Program.cs index 2218f4a2a..77af125ac 100644 --- a/PerformanceTests/YamlDotNet.PerformanceTests.Runner/Program.cs +++ b/PerformanceTests/YamlDotNet.PerformanceTests.Runner/Program.cs @@ -27,120 +27,120 @@ namespace YamlDotNet.PerformanceTests.Runner { - class MainClass - { - public static void Main(string[] args) - { - var configuration = Path.GetFileName(Directory.GetCurrentDirectory()); - - var currentDir = Directory.GetCurrentDirectory(); - var baseDir = currentDir; - for(var i = 0; i < 3; ++i) - { - baseDir = Path.GetDirectoryName(baseDir); - } - - var testPrograms = Directory.GetDirectories(baseDir) - .Select(d => Path.Combine(d, Path.Combine("bin", configuration))) - .Where(d => d != currentDir) - .SelectMany(d => Directory.GetFiles(d, "*.exe")); - - var testResults = new List(); - foreach(var testProgram in testPrograms) - { - Console.Error.WriteLine("Running {0}", Path.GetFileName(testProgram)); - RunTest(testProgram, testResults); - } - - var versions = testResults - .Select(r => r.Version) - .Distinct() - .OrderBy(r => r) - .ToList(); - - const int columnWidth = 10; - var initialColumnWidth = testResults.Max(r => r.Test.Length) + 1; - - Console.WriteLine(); - Console.Write(new String(' ', initialColumnWidth)); - foreach(var version in versions) - { - Console.Write("{0}", version.PadLeft(10)); - } - Console.WriteLine(); - - Console.WriteLine(new String('-', initialColumnWidth + columnWidth * versions.Count)); - - foreach(var resultGroup in testResults.GroupBy(r => r.Test)) - { - Console.Write(resultGroup.Key.PadRight(initialColumnWidth)); - - foreach(var version in versions) - { - var result = resultGroup.FirstOrDefault(r => r.Version == version); - if(result != null) - { - Console.Write(result.Duration.ToString("##0.00 ms").PadLeft(columnWidth)); - } - else - { - Console.Write("N/A".PadRight(columnWidth)); - } - } - - Console.WriteLine(); - } - - Console.Error.WriteLine(); - Console.Error.WriteLine("Done."); - } - - private static void RunTest(string testProgram, List testResults) - { - var startInfo = new ProcessStartInfo - { - UseShellExecute = false, - RedirectStandardOutput = true, - }; - - switch(Environment.OSVersion.Platform) - { - case PlatformID.Unix: - startInfo.FileName = "mono"; - startInfo.Arguments = testProgram; - break; - - default: - startInfo.FileName = testProgram; - break; - } - - var testProcess = Process.Start(startInfo); - testProcess.OutputDataReceived += (s, e) => ProcessTestResult(e.Data, testResults); - testProcess.BeginOutputReadLine(); - - testProcess.WaitForExit(); - } - - private class TestResult - { - public string Version { get; set; } - public string Test { get; set; } - public double Duration { get; set; } - } - - private static void ProcessTestResult(string data, List testResults) - { - if (data != null) - { - var parts = data.Split('\t'); - testResults.Add(new TestResult - { - Version = parts[0], - Test = parts[1], - Duration = double.Parse(parts[2]), - }); - } - } - } + class MainClass + { + public static void Main(string[] args) + { + var configuration = Path.GetFileName(Directory.GetCurrentDirectory()); + + var currentDir = Directory.GetCurrentDirectory(); + var baseDir = currentDir; + for(var i = 0; i < 3; ++i) + { + baseDir = Path.GetDirectoryName(baseDir); + } + + var testPrograms = Directory.GetDirectories(baseDir) + .Select(d => Path.Combine(d, Path.Combine("bin", configuration))) + .Where(d => d != currentDir) + .SelectMany(d => Directory.GetFiles(d, "*.exe")); + + var testResults = new List(); + foreach(var testProgram in testPrograms) + { + Console.Error.WriteLine("Running {0}", Path.GetFileName(testProgram)); + RunTest(testProgram, testResults); + } + + var versions = testResults + .Select(r => r.Version) + .Distinct() + .OrderBy(r => r) + .ToList(); + + const int columnWidth = 10; + var initialColumnWidth = testResults.Max(r => r.Test.Length) + 1; + + Console.WriteLine(); + Console.Write(new String(' ', initialColumnWidth)); + foreach(var version in versions) + { + Console.Write("{0}", version.PadLeft(10)); + } + Console.WriteLine(); + + Console.WriteLine(new String('-', initialColumnWidth + columnWidth * versions.Count)); + + foreach(var resultGroup in testResults.GroupBy(r => r.Test)) + { + Console.Write(resultGroup.Key.PadRight(initialColumnWidth)); + + foreach(var version in versions) + { + var result = resultGroup.FirstOrDefault(r => r.Version == version); + if(result != null) + { + Console.Write(result.Duration.ToString("##0.00 ms").PadLeft(columnWidth)); + } + else + { + Console.Write("N/A".PadRight(columnWidth)); + } + } + + Console.WriteLine(); + } + + Console.Error.WriteLine(); + Console.Error.WriteLine("Done."); + } + + private static void RunTest(string testProgram, List testResults) + { + var startInfo = new ProcessStartInfo + { + UseShellExecute = false, + RedirectStandardOutput = true, + }; + + switch(Environment.OSVersion.Platform) + { + case PlatformID.Unix: + startInfo.FileName = "mono"; + startInfo.Arguments = testProgram; + break; + + default: + startInfo.FileName = testProgram; + break; + } + + var testProcess = Process.Start(startInfo); + testProcess.OutputDataReceived += (s, e) => ProcessTestResult(e.Data, testResults); + testProcess.BeginOutputReadLine(); + + testProcess.WaitForExit(); + } + + private class TestResult + { + public string Version { get; set; } + public string Test { get; set; } + public double Duration { get; set; } + } + + private static void ProcessTestResult(string data, List testResults) + { + if (data != null) + { + var parts = data.Split('\t'); + testResults.Add(new TestResult + { + Version = parts[0], + Test = parts[1], + Duration = double.Parse(parts[2]), + }); + } + } + } } diff --git a/PerformanceTests/YamlDotNet.PerformanceTests.v1.2.1/Program.cs b/PerformanceTests/YamlDotNet.PerformanceTests.v1.2.1/Program.cs index 57221bbdc..b4db20337 100644 --- a/PerformanceTests/YamlDotNet.PerformanceTests.v1.2.1/Program.cs +++ b/PerformanceTests/YamlDotNet.PerformanceTests.v1.2.1/Program.cs @@ -26,19 +26,19 @@ namespace YamlDotNet.PerformanceTests.v1_2_1 { - public class Program : ISerializerAdapter - { - public static void Main(string[] args) - { - var runner = new PerformanceTestRunner(); - runner.Run(new Program(), args); - } + public class Program : ISerializerAdapter + { + public static void Main(string[] args) + { + var runner = new PerformanceTestRunner(); + runner.Run(new Program(), args); + } - private readonly Serializer _serializer = new Serializer(); + private readonly Serializer _serializer = new Serializer(); - public void Serialize (TextWriter writer, object graph) - { - _serializer.Serialize (writer, graph); - } - } + public void Serialize (TextWriter writer, object graph) + { + _serializer.Serialize (writer, graph); + } + } } diff --git a/PerformanceTests/YamlDotNet.PerformanceTests.v2.2.0/Program.cs b/PerformanceTests/YamlDotNet.PerformanceTests.v2.2.0/Program.cs index 3f26f8a9e..05c1f6bda 100644 --- a/PerformanceTests/YamlDotNet.PerformanceTests.v2.2.0/Program.cs +++ b/PerformanceTests/YamlDotNet.PerformanceTests.v2.2.0/Program.cs @@ -26,19 +26,19 @@ namespace YamlDotNet.PerformanceTests.v2_2_0 { - public class Program : ISerializerAdapter - { - public static void Main(string[] args) - { - var runner = new PerformanceTestRunner(); - runner.Run(new Program(), args); - } + public class Program : ISerializerAdapter + { + public static void Main(string[] args) + { + var runner = new PerformanceTestRunner(); + runner.Run(new Program(), args); + } - private readonly Serializer _serializer = new Serializer(); + private readonly Serializer _serializer = new Serializer(); - public void Serialize (TextWriter writer, object graph) - { - _serializer.Serialize (writer, graph); - } - } + public void Serialize (TextWriter writer, object graph) + { + _serializer.Serialize (writer, graph); + } + } } \ No newline at end of file diff --git a/PerformanceTests/YamlDotNet.PerformanceTests.v2.3.0/Program.cs b/PerformanceTests/YamlDotNet.PerformanceTests.v2.3.0/Program.cs index 9c32f0ccc..488e79e44 100644 --- a/PerformanceTests/YamlDotNet.PerformanceTests.v2.3.0/Program.cs +++ b/PerformanceTests/YamlDotNet.PerformanceTests.v2.3.0/Program.cs @@ -26,19 +26,19 @@ namespace YamlDotNet.PerformanceTests.v2_3_0 { - public class Program : ISerializerAdapter - { - public static void Main(string[] args) - { - var runner = new PerformanceTestRunner(); - runner.Run(new Program(), args); - } + public class Program : ISerializerAdapter + { + public static void Main(string[] args) + { + var runner = new PerformanceTestRunner(); + runner.Run(new Program(), args); + } - private readonly Serializer _serializer = new Serializer(); + private readonly Serializer _serializer = new Serializer(); - public void Serialize (TextWriter writer, object graph) - { - _serializer.Serialize (writer, graph); - } - } + public void Serialize (TextWriter writer, object graph) + { + _serializer.Serialize (writer, graph); + } + } } \ No newline at end of file diff --git a/PerformanceTests/YamlDotNet.PerformanceTests.vlatest/Program.cs b/PerformanceTests/YamlDotNet.PerformanceTests.vlatest/Program.cs index 10ecf9669..728a0200a 100644 --- a/PerformanceTests/YamlDotNet.PerformanceTests.vlatest/Program.cs +++ b/PerformanceTests/YamlDotNet.PerformanceTests.vlatest/Program.cs @@ -26,19 +26,19 @@ namespace YamlDotNet.PerformanceTests.vlatest { - public class Program : ISerializerAdapter - { - public static void Main(string[] args) - { - var runner = new PerformanceTestRunner(); - runner.Run(new Program(), args); - } + public class Program : ISerializerAdapter + { + public static void Main(string[] args) + { + var runner = new PerformanceTestRunner(); + runner.Run(new Program(), args); + } - private readonly Serializer _serializer = new Serializer(); + private readonly Serializer _serializer = new Serializer(); - public void Serialize(TextWriter writer, object graph) - { - _serializer.Serialize(writer, graph); - } - } + public void Serialize(TextWriter writer, object graph) + { + _serializer.Serialize(writer, graph); + } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/Core/EmitterTests.cs b/YamlDotNet.Test/Core/EmitterTests.cs index a7dd721fb..75655e384 100644 --- a/YamlDotNet.Test/Core/EmitterTests.cs +++ b/YamlDotNet.Test/Core/EmitterTests.cs @@ -32,261 +32,261 @@ namespace YamlDotNet.Test.Core { - public class EmitterTests : EmitterTestsHelper - { - [Theory] - [InlineData("01-directives.yaml")] - [InlineData("02-scalar-in-imp-doc.yaml")] - [InlineData("03-scalar-in-exp-doc.yaml")] - [InlineData("04-scalars-in-multi-docs.yaml")] - [InlineData("05-circular-sequence.yaml")] - [InlineData("06-float-tag.yaml")] - [InlineData("07-scalar-styles.yaml")] - [InlineData("08-flow-sequence.yaml")] - [InlineData("09-flow-mapping.yaml")] - [InlineData("10-mixed-nodes-in-sequence.yaml")] - [InlineData("11-mixed-nodes-in-mapping.yaml")] - [InlineData("12-compact-sequence.yaml")] - [InlineData("13-compact-mapping.yaml")] - [InlineData("14-mapping-wo-indent.yaml")] - public void CompareOriginalAndEmittedText(string filename) - { - var stream = Yaml.StreamFrom(filename); - - var originalEvents = ParsingEventsOf(stream.ReadToEnd()); - originalEvents.Run(x => Dump.WriteLine(x)); - var emittedText = EmittedTextFrom(originalEvents); - Dump.WriteLine(emittedText); - var emittedEvents = ParsingEventsOf(emittedText); - emittedEvents.Run(x => Dump.WriteLine(x)); - - emittedEvents.ShouldAllBeEquivalentTo(originalEvents, - opt => opt.Excluding(@event => @event.Start) - .Excluding(@event => @event.End) - .Excluding((ParsingEvent @event) => ((DocumentEnd)@event).IsImplicit)); - } - - private IList ParsingEventsOf(string text) - { - var parser = new Parser(new StringReader(text)); - return EnumerationOf(parser).ToList(); - } - - private IEnumerable EnumerationOf(IParser parser) - { - while (parser.MoveNext()) - { - yield return parser.Current; - } - } - - [Fact] - public void PlainScalarCanBeFollowedByImplicitDocument() - { - var events = StreamOf( - DocumentWith(PlainScalar("test")), - DocumentWith(PlainScalar("test"))); - - var yaml = EmittedTextFrom(events); - - yaml.Should().Contain(Lines("test", "--- test")); - } - - [Fact] - public void PlainScalarCanBeFollowedByDocumentWithVersion() - { - var events = StreamOf( - DocumentWith(PlainScalar("test")), - DocumentWithVersion(PlainScalar("test"))); - - var yaml = EmittedTextFrom(events); - - Dump.WriteLine(yaml); - yaml.Should().Contain(Lines("test", "...", "%YAML 1.1", "--- test")); - } - - [Fact] - public void PlainScalarCanBeFollowedByDocumentWithDefaultTags() - { - var events = StreamOf( - DocumentWith(PlainScalar("test")), - DocumentWithDefaultTags(PlainScalar("test"))); - - var yaml = EmittedTextFrom(events); - - Dump.WriteLine(yaml); - yaml.Should().Contain(Lines("test", "--- test")); - } - - [Fact] - public void PlainScalarCanBeFollowedByDocumentWithCustomTags() - { - var events = StreamOf( - DocumentWith(PlainScalar("test")), - DocumentWithCustomTags(PlainScalar("test"))); - - var yaml = EmittedTextFrom(events); - - Dump.WriteLine(yaml); - yaml.Should().Contain(Lines("test", "...", FooTag, ExTag, ExExTag, "--- test")); - } - - [Fact] - public void BlockCanBeFollowedByImplicitDocument() - { - var events = StreamOf( - DocumentWith(SequenceWith(SingleQuotedScalar("test"))), - DocumentWith(PlainScalar("test"))); - - var yaml = EmittedTextFrom(events); - - Dump.WriteLine(yaml); - - yaml.Should().Contain(Lines("- 'test'", "--- test")); - } - - [Fact] - public void BlockCanBeFollowedByDocumentWithVersion() - { - var events = StreamOf( - DocumentWith(SequenceWith(SingleQuotedScalar("test"))), - DocumentWithVersion(PlainScalar("test"))); - - var yaml = EmittedTextFrom(events); - - Dump.WriteLine(yaml); - yaml.Should().Contain(Lines("- 'test'", "...", "%YAML 1.1", "--- test")); - } - - [Fact] - public void BlockCanBeFollowedByDocumentWithDefaultTags() - { - var events = StreamOf( - DocumentWith(SequenceWith(SingleQuotedScalar("test"))), - DocumentWithDefaultTags(PlainScalar("test"))); - - var yaml = EmittedTextFrom(events); - - Dump.WriteLine(yaml); - yaml.Should().Contain(Lines("- 'test'", "--- test")); - } - - [Fact] - public void BlockCanBeFollowedByDocumentWithCustomTags() - { - var events = StreamOf( - DocumentWith(SequenceWith(SingleQuotedScalar("test"))), - DocumentWithCustomTags(PlainScalar("test"))); - - var yaml = EmittedTextFrom(events); - - Dump.WriteLine(yaml); - yaml.Should().Contain(Lines("- 'test'", "...", FooTag, ExTag, ExExTag, "--- test")); - } - - [Theory] - [InlineData("LF hello\nworld")] - [InlineData("CRLF hello\r\nworld")] - public void FoldedStyleDoesNotLooseCharacters(string text) - { - var events = SequenceWith(FoldedScalar(text)); - - var yaml = EmittedTextFrom(StreamedDocumentWith(events)); - - Dump.WriteLine(yaml); - yaml.Should().Contain("world"); - } - - [Fact] - public void FoldedStyleIsSelectedWhenNewLinesAreFoundInLiteral() - { - var events = SequenceWith(Scalar("hello\nworld").ImplicitPlain); - - var yaml = EmittedTextFrom(StreamedDocumentWith(events)); - - Dump.WriteLine(yaml); - yaml.Should().Contain(">"); - } - - [Fact] - public void FoldedStyleDoesNotGenerateExtraLineBreaks() - { - var events = SequenceWith(FoldedScalar("hello\nworld")); - - var yaml = EmittedTextFrom(StreamedDocumentWith(events)); - - // Todo: Why involve the rep. model when testing the Emitter? Can we match using a regex? - var stream = new YamlStream(); - stream.Load(new StringReader(yaml)); - var sequence = (YamlSequenceNode)stream.Documents[0].RootNode; - var scalar = (YamlScalarNode)sequence.Children[0]; - - Dump.WriteLine(yaml); - scalar.Value.Should().Be("hello\nworld"); - } - - [Fact] - public void FoldedStyleDoesNotCollapseLineBreaks() - { - var events = SequenceWith(FoldedScalar(">+\n")); - - var yaml = EmittedTextFrom(StreamedDocumentWith(events)); - - var stream = new YamlStream(); - stream.Load(new StringReader(yaml)); - var sequence = (YamlSequenceNode)stream.Documents[0].RootNode; - var scalar = (YamlScalarNode)sequence.Children[0]; - - Dump.WriteLine("${0}$", yaml); - scalar.Value.Should().Be(">+\n"); - } - - [Fact] - [Trait("motive", "issue #39")] - public void FoldedStylePreservesNewLines() - { - var input = "id: 0\nPayload:\n X: 5\n Y: 6\n"; - var events = MappingWith( - Scalar("Payload").ImplicitPlain, - FoldedScalar(input)); - - var yaml = EmittedTextFrom(StreamedDocumentWith(events)); - Dump.WriteLine(yaml); - - var stream = new YamlStream(); - stream.Load(new StringReader(yaml)); - - var mapping = (YamlMappingNode)stream.Documents[0].RootNode; - var value = (YamlScalarNode)mapping.Children.First().Value; - - Dump.WriteLine(value.Value); - value.Value.Should().Be(input); - } - - [Fact] - public void CommentsAreEmittedCorrectly() - { - var events = SequenceWith( - StandaloneComment("Top comment"), - StandaloneComment("Second line"), - Scalar("first").ImplicitPlain, - InlineComment("The first value"), - Scalar("second").ImplicitPlain, - InlineComment("The second value"), - StandaloneComment("Bottom comment") - ); - - var yaml = EmittedTextFrom(StreamedDocumentWith(events)); - - Dump.WriteLine("${0}$", yaml); - yaml.Should() - .Contain("# Top comment") - .And.Contain("# Second line") - .And.NotContain("# Top comment # Second line") - .And.Contain("first # The first value") - .And.Contain("second # The second value") - .And.Contain("# Bottom comment"); - } + public class EmitterTests : EmitterTestsHelper + { + [Theory] + [InlineData("01-directives.yaml")] + [InlineData("02-scalar-in-imp-doc.yaml")] + [InlineData("03-scalar-in-exp-doc.yaml")] + [InlineData("04-scalars-in-multi-docs.yaml")] + [InlineData("05-circular-sequence.yaml")] + [InlineData("06-float-tag.yaml")] + [InlineData("07-scalar-styles.yaml")] + [InlineData("08-flow-sequence.yaml")] + [InlineData("09-flow-mapping.yaml")] + [InlineData("10-mixed-nodes-in-sequence.yaml")] + [InlineData("11-mixed-nodes-in-mapping.yaml")] + [InlineData("12-compact-sequence.yaml")] + [InlineData("13-compact-mapping.yaml")] + [InlineData("14-mapping-wo-indent.yaml")] + public void CompareOriginalAndEmittedText(string filename) + { + var stream = Yaml.StreamFrom(filename); + + var originalEvents = ParsingEventsOf(stream.ReadToEnd()); + originalEvents.Run(x => Dump.WriteLine(x)); + var emittedText = EmittedTextFrom(originalEvents); + Dump.WriteLine(emittedText); + var emittedEvents = ParsingEventsOf(emittedText); + emittedEvents.Run(x => Dump.WriteLine(x)); + + emittedEvents.ShouldAllBeEquivalentTo(originalEvents, + opt => opt.Excluding(@event => @event.Start) + .Excluding(@event => @event.End) + .Excluding((ParsingEvent @event) => ((DocumentEnd)@event).IsImplicit)); + } + + private IList ParsingEventsOf(string text) + { + var parser = new Parser(new StringReader(text)); + return EnumerationOf(parser).ToList(); + } + + private IEnumerable EnumerationOf(IParser parser) + { + while (parser.MoveNext()) + { + yield return parser.Current; + } + } + + [Fact] + public void PlainScalarCanBeFollowedByImplicitDocument() + { + var events = StreamOf( + DocumentWith(PlainScalar("test")), + DocumentWith(PlainScalar("test"))); + + var yaml = EmittedTextFrom(events); + + yaml.Should().Contain(Lines("test", "--- test")); + } + + [Fact] + public void PlainScalarCanBeFollowedByDocumentWithVersion() + { + var events = StreamOf( + DocumentWith(PlainScalar("test")), + DocumentWithVersion(PlainScalar("test"))); + + var yaml = EmittedTextFrom(events); + + Dump.WriteLine(yaml); + yaml.Should().Contain(Lines("test", "...", "%YAML 1.1", "--- test")); + } + + [Fact] + public void PlainScalarCanBeFollowedByDocumentWithDefaultTags() + { + var events = StreamOf( + DocumentWith(PlainScalar("test")), + DocumentWithDefaultTags(PlainScalar("test"))); + + var yaml = EmittedTextFrom(events); + + Dump.WriteLine(yaml); + yaml.Should().Contain(Lines("test", "--- test")); + } + + [Fact] + public void PlainScalarCanBeFollowedByDocumentWithCustomTags() + { + var events = StreamOf( + DocumentWith(PlainScalar("test")), + DocumentWithCustomTags(PlainScalar("test"))); + + var yaml = EmittedTextFrom(events); + + Dump.WriteLine(yaml); + yaml.Should().Contain(Lines("test", "...", FooTag, ExTag, ExExTag, "--- test")); + } + + [Fact] + public void BlockCanBeFollowedByImplicitDocument() + { + var events = StreamOf( + DocumentWith(SequenceWith(SingleQuotedScalar("test"))), + DocumentWith(PlainScalar("test"))); + + var yaml = EmittedTextFrom(events); + + Dump.WriteLine(yaml); + + yaml.Should().Contain(Lines("- 'test'", "--- test")); + } + + [Fact] + public void BlockCanBeFollowedByDocumentWithVersion() + { + var events = StreamOf( + DocumentWith(SequenceWith(SingleQuotedScalar("test"))), + DocumentWithVersion(PlainScalar("test"))); + + var yaml = EmittedTextFrom(events); + + Dump.WriteLine(yaml); + yaml.Should().Contain(Lines("- 'test'", "...", "%YAML 1.1", "--- test")); + } + + [Fact] + public void BlockCanBeFollowedByDocumentWithDefaultTags() + { + var events = StreamOf( + DocumentWith(SequenceWith(SingleQuotedScalar("test"))), + DocumentWithDefaultTags(PlainScalar("test"))); + + var yaml = EmittedTextFrom(events); + + Dump.WriteLine(yaml); + yaml.Should().Contain(Lines("- 'test'", "--- test")); + } + + [Fact] + public void BlockCanBeFollowedByDocumentWithCustomTags() + { + var events = StreamOf( + DocumentWith(SequenceWith(SingleQuotedScalar("test"))), + DocumentWithCustomTags(PlainScalar("test"))); + + var yaml = EmittedTextFrom(events); + + Dump.WriteLine(yaml); + yaml.Should().Contain(Lines("- 'test'", "...", FooTag, ExTag, ExExTag, "--- test")); + } + + [Theory] + [InlineData("LF hello\nworld")] + [InlineData("CRLF hello\r\nworld")] + public void FoldedStyleDoesNotLooseCharacters(string text) + { + var events = SequenceWith(FoldedScalar(text)); + + var yaml = EmittedTextFrom(StreamedDocumentWith(events)); + + Dump.WriteLine(yaml); + yaml.Should().Contain("world"); + } + + [Fact] + public void FoldedStyleIsSelectedWhenNewLinesAreFoundInLiteral() + { + var events = SequenceWith(Scalar("hello\nworld").ImplicitPlain); + + var yaml = EmittedTextFrom(StreamedDocumentWith(events)); + + Dump.WriteLine(yaml); + yaml.Should().Contain(">"); + } + + [Fact] + public void FoldedStyleDoesNotGenerateExtraLineBreaks() + { + var events = SequenceWith(FoldedScalar("hello\nworld")); + + var yaml = EmittedTextFrom(StreamedDocumentWith(events)); + + // Todo: Why involve the rep. model when testing the Emitter? Can we match using a regex? + var stream = new YamlStream(); + stream.Load(new StringReader(yaml)); + var sequence = (YamlSequenceNode)stream.Documents[0].RootNode; + var scalar = (YamlScalarNode)sequence.Children[0]; + + Dump.WriteLine(yaml); + scalar.Value.Should().Be("hello\nworld"); + } + + [Fact] + public void FoldedStyleDoesNotCollapseLineBreaks() + { + var events = SequenceWith(FoldedScalar(">+\n")); + + var yaml = EmittedTextFrom(StreamedDocumentWith(events)); + + var stream = new YamlStream(); + stream.Load(new StringReader(yaml)); + var sequence = (YamlSequenceNode)stream.Documents[0].RootNode; + var scalar = (YamlScalarNode)sequence.Children[0]; + + Dump.WriteLine("${0}$", yaml); + scalar.Value.Should().Be(">+\n"); + } + + [Fact] + [Trait("motive", "issue #39")] + public void FoldedStylePreservesNewLines() + { + var input = "id: 0\nPayload:\n X: 5\n Y: 6\n"; + var events = MappingWith( + Scalar("Payload").ImplicitPlain, + FoldedScalar(input)); + + var yaml = EmittedTextFrom(StreamedDocumentWith(events)); + Dump.WriteLine(yaml); + + var stream = new YamlStream(); + stream.Load(new StringReader(yaml)); + + var mapping = (YamlMappingNode)stream.Documents[0].RootNode; + var value = (YamlScalarNode)mapping.Children.First().Value; + + Dump.WriteLine(value.Value); + value.Value.Should().Be(input); + } + + [Fact] + public void CommentsAreEmittedCorrectly() + { + var events = SequenceWith( + StandaloneComment("Top comment"), + StandaloneComment("Second line"), + Scalar("first").ImplicitPlain, + InlineComment("The first value"), + Scalar("second").ImplicitPlain, + InlineComment("The second value"), + StandaloneComment("Bottom comment") + ); + + var yaml = EmittedTextFrom(StreamedDocumentWith(events)); + + Dump.WriteLine("${0}$", yaml); + yaml.Should() + .Contain("# Top comment") + .And.Contain("# Second line") + .And.NotContain("# Top comment # Second line") + .And.Contain("first # The first value") + .And.Contain("second # The second value") + .And.Contain("# Bottom comment"); + } [Theory] [InlineData("Гранит", 28595)] // Cyrillic (ISO) @@ -313,9 +313,9 @@ public void UnicodeInScalarsCanBeSingleQuotedWhenOutputEncodingSupportsIt(string var yaml = encoding.GetString(buffer.ToArray()); - yaml.Should() + yaml.Should() .Contain("'" + text + "'"); - } + } [Fact] public void EmptyStringsAreQuoted() @@ -329,9 +329,9 @@ public void EmptyStringsAreQuoted() .Contain("- ''"); } - private string Lines(params string[] lines) - { - return string.Join(Environment.NewLine, lines); - } - } + private string Lines(params string[] lines) + { + return string.Join(Environment.NewLine, lines); + } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/Core/EmitterTestsHelper.cs b/YamlDotNet.Test/Core/EmitterTestsHelper.cs index a0077e57c..eb2baab03 100644 --- a/YamlDotNet.Test/Core/EmitterTestsHelper.cs +++ b/YamlDotNet.Test/Core/EmitterTestsHelper.cs @@ -29,88 +29,88 @@ namespace YamlDotNet.Test.Core { - public class EmitterTestsHelper : EventsHelper - { - protected const string FooTag = "%TAG !foo! tag:example.org:foo"; - protected const string ExTag = "%TAG ! !"; - protected const string ExExTag = "%TAG !! tag:yaml.org,2002:"; - - protected string EmittedTextFrom(IEnumerable events) - { - return Emit(events, EmitterWithIndentCreator); - } - - private Func EmitterWithIndentCreator - { - get { return writer => new Emitter(writer, 2, int.MaxValue, false); } - } - - protected string Emit(IEnumerable events, Func createEmitter) - { - var writer = new StringWriter(); - var emitter = createEmitter(writer); - events.Run(emitter.Emit); - return writer.ToString(); - } - - protected IEnumerable StreamedDocumentWith(IEnumerable events) - { - return StreamOf(DocumentWith(events.ToArray())); - } - - protected IEnumerable StreamOf(params IEnumerable[] documents) - { - var allEvents = documents.SelectMany(x => x); - return Wrap(allEvents, StreamStart, StreamEnd); - } - - protected IEnumerable DocumentWithVersion(params ParsingEvent[] events) - { - var version = new VersionDirective(new YamlDotNet.Core.Version(1, 1)); - return Wrap(events, DocumentStart(Explicit, version), DocumentEnd(Implicit)); - } - - protected IEnumerable DocumentWithDefaultTags(params ParsingEvent[] events) - { - var tags = Constants.DefaultTagDirectives; - return Wrap(events, DocumentStart(Explicit, null, tags), DocumentEnd(Implicit)); - } - - protected IEnumerable DocumentWithCustomTags(params ParsingEvent[] events) - { - var parts = FooTag.Split(' '); - var tags = new TagDirective(parts[1], parts[2]); - return Wrap(events, DocumentStart(Explicit, null, tags), DocumentEnd(Implicit)); - } - - protected IEnumerable DocumentWith(IEnumerable events) - { - return DocumentWith(events.ToArray()); - } - - protected IEnumerable DocumentWith(params ParsingEvent[] events) - { - return Wrap(events, DocumentStart(Implicit), DocumentEnd(Implicit)); - } - - protected IEnumerable SequenceWith(params ParsingEvent[] events) - { - return Wrap(events, BlockSequenceStart.Explicit, SequenceEnd); - } - - protected IEnumerable MappingWith(params ParsingEvent[] events) - { - return Wrap(events, MappingStart, MappingEnd); - } - - private IEnumerable Wrap(IEnumerable events, ParsingEvent start, ParsingEvent end) - { - yield return start; - foreach (var @event in events) - { - yield return @event; - } - yield return end; - } - } + public class EmitterTestsHelper : EventsHelper + { + protected const string FooTag = "%TAG !foo! tag:example.org:foo"; + protected const string ExTag = "%TAG ! !"; + protected const string ExExTag = "%TAG !! tag:yaml.org,2002:"; + + protected string EmittedTextFrom(IEnumerable events) + { + return Emit(events, EmitterWithIndentCreator); + } + + private Func EmitterWithIndentCreator + { + get { return writer => new Emitter(writer, 2, int.MaxValue, false); } + } + + protected string Emit(IEnumerable events, Func createEmitter) + { + var writer = new StringWriter(); + var emitter = createEmitter(writer); + events.Run(emitter.Emit); + return writer.ToString(); + } + + protected IEnumerable StreamedDocumentWith(IEnumerable events) + { + return StreamOf(DocumentWith(events.ToArray())); + } + + protected IEnumerable StreamOf(params IEnumerable[] documents) + { + var allEvents = documents.SelectMany(x => x); + return Wrap(allEvents, StreamStart, StreamEnd); + } + + protected IEnumerable DocumentWithVersion(params ParsingEvent[] events) + { + var version = new VersionDirective(new YamlDotNet.Core.Version(1, 1)); + return Wrap(events, DocumentStart(Explicit, version), DocumentEnd(Implicit)); + } + + protected IEnumerable DocumentWithDefaultTags(params ParsingEvent[] events) + { + var tags = Constants.DefaultTagDirectives; + return Wrap(events, DocumentStart(Explicit, null, tags), DocumentEnd(Implicit)); + } + + protected IEnumerable DocumentWithCustomTags(params ParsingEvent[] events) + { + var parts = FooTag.Split(' '); + var tags = new TagDirective(parts[1], parts[2]); + return Wrap(events, DocumentStart(Explicit, null, tags), DocumentEnd(Implicit)); + } + + protected IEnumerable DocumentWith(IEnumerable events) + { + return DocumentWith(events.ToArray()); + } + + protected IEnumerable DocumentWith(params ParsingEvent[] events) + { + return Wrap(events, DocumentStart(Implicit), DocumentEnd(Implicit)); + } + + protected IEnumerable SequenceWith(params ParsingEvent[] events) + { + return Wrap(events, BlockSequenceStart.Explicit, SequenceEnd); + } + + protected IEnumerable MappingWith(params ParsingEvent[] events) + { + return Wrap(events, MappingStart, MappingEnd); + } + + private IEnumerable Wrap(IEnumerable events, ParsingEvent start, ParsingEvent end) + { + yield return start; + foreach (var @event in events) + { + yield return @event; + } + yield return end; + } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/Core/EventsHelper.cs b/YamlDotNet.Test/Core/EventsHelper.cs index 99e56caef..e770452ac 100644 --- a/YamlDotNet.Test/Core/EventsHelper.cs +++ b/YamlDotNet.Test/Core/EventsHelper.cs @@ -27,251 +27,251 @@ // ReSharper disable MemberHidesStaticFromOuterClass namespace YamlDotNet.Test.Core { - public class EventsHelper - { - protected const bool Explicit = false; - protected const bool Implicit = true; - protected const string TagYaml = "tag:yaml.org,2002:"; - - protected static readonly TagDirective[] DefaultTags = new[] { - new TagDirective("!", "!"), - new TagDirective("!!", TagYaml) - }; - - protected static StreamStart StreamStart - { - get { return new StreamStart(); } - } - - protected static StreamEnd StreamEnd - { - get { return new StreamEnd(); } - } - - protected DocumentStart DocumentStart(bool isImplicit) - { - return DocumentStart(isImplicit, null, DefaultTags); - } - - protected DocumentStart DocumentStart(bool isImplicit, VersionDirective version, params TagDirective[] tags) - { - return new DocumentStart(version, new TagDirectiveCollection(tags), isImplicit); - } - - protected VersionDirective Version(int major, int minor) - { - return new VersionDirective(new Version(major, minor)); - } - - protected TagDirective TagDirective(string handle, string prefix) - { - return new TagDirective(handle, prefix); - } - - protected DocumentEnd DocumentEnd(bool isImplicit) - { - return new DocumentEnd(isImplicit); - } - - protected ScalarBuilder Scalar(string text) - { - return new ScalarBuilder(text, ScalarStyle.Any); - } - - protected ScalarBuilder PlainScalar(string text) - { - return new ScalarBuilder(text, ScalarStyle.Plain); - } - - protected ScalarBuilder SingleQuotedScalar(string text) - { - return new ScalarBuilder(text, ScalarStyle.SingleQuoted); - } - - protected ScalarBuilder DoubleQuotedScalar(string text) - { - return new ScalarBuilder(text, ScalarStyle.DoubleQuoted); - } - - protected ScalarBuilder LiteralScalar(string text) - { - return new ScalarBuilder(text, ScalarStyle.Literal); - } - - protected ScalarBuilder FoldedScalar(string text) - { - return new ScalarBuilder(text, ScalarStyle.Folded); - } - - protected SequenceStartBuilder BlockSequenceStart - { - get { return new SequenceStartBuilder(SequenceStyle.Block); } - } - - protected SequenceStartBuilder FlowSequenceStart - { - get { return new SequenceStartBuilder(SequenceStyle.Flow); } - } - - protected SequenceEnd SequenceEnd - { - get { return new SequenceEnd(); } - } - - protected MappingStart MappingStart - { - get { return new MappingStart(); } - } - - protected MappingStartBuilder BlockMappingStart - { - get { return new MappingStartBuilder(MappingStyle.Block); } - } - - protected MappingStartBuilder FlowMappingStart - { - get { return new MappingStartBuilder(MappingStyle.Flow); } - } - - protected MappingEnd MappingEnd - { - get { return new MappingEnd(); } - } - - protected AnchorAlias AnchorAlias(string alias) - { - return new AnchorAlias(alias); - } - - protected Comment StandaloneComment(string value) - { - return new Comment(value, false); - } - - protected Comment InlineComment(string value) - { - return new Comment(value, true); - } - - protected class ScalarBuilder - { - private readonly string text; - private readonly ScalarStyle style; - private string tag; - private bool plainImplicit; - private bool quotedImplicit; - - public ScalarBuilder(string text, ScalarStyle style) - { - this.text = text; - this.style = style; - plainImplicit = style == ScalarStyle.Plain; - quotedImplicit = style != ScalarStyle.Plain && - style != ScalarStyle.Any; - } - - public ScalarBuilder T(string tag) - { - this.tag = tag; - plainImplicit = false; - quotedImplicit = false; - return this; - } - - public ScalarBuilder ImplicitPlain - { - get { - plainImplicit = true; - return this; - } - } - - public ScalarBuilder ImplicitQuoted - { - get { - quotedImplicit = true; - return this; - } - } - - public static implicit operator Scalar(ScalarBuilder builder) - { - return new Scalar(null, - builder.tag, - builder.text, - builder.style, - builder.plainImplicit, - builder.quotedImplicit); - } - } - - protected class SequenceStartBuilder - { - private const bool DefaultImplicit = true; - - private readonly SequenceStyle style; - private string anchor; - private bool @implicit; - - public SequenceStartBuilder(SequenceStyle style) - { - this.style = style; - @implicit = DefaultImplicit; - } - - public SequenceStartBuilder A(string anchor) - { - this.anchor = anchor; - return this; - } - - public SequenceStartBuilder Explicit - { - get - { - @implicit = false; - return this; - } - } - - public static implicit operator SequenceStart(SequenceStartBuilder builder) - { - return new SequenceStart(builder.anchor, null, builder.@implicit, builder.style); - } - } - - protected class MappingStartBuilder - { - private const bool DefaultImplicit = true; - - private readonly MappingStyle style; - private string tag; - private bool @implicit; - - public MappingStartBuilder(MappingStyle style) - { - this.style = style; - @implicit = DefaultImplicit; - } - - public MappingStartBuilder T(string tag) - { - this.tag = tag; - return this; - } - - public MappingStartBuilder Explicit - { - get { - @implicit = false; - return this; - } - } - - public static implicit operator MappingStart(MappingStartBuilder builder) - { - return new MappingStart(null, builder.tag, builder.@implicit, builder.style); - } - } - } + public class EventsHelper + { + protected const bool Explicit = false; + protected const bool Implicit = true; + protected const string TagYaml = "tag:yaml.org,2002:"; + + protected static readonly TagDirective[] DefaultTags = new[] { + new TagDirective("!", "!"), + new TagDirective("!!", TagYaml) + }; + + protected static StreamStart StreamStart + { + get { return new StreamStart(); } + } + + protected static StreamEnd StreamEnd + { + get { return new StreamEnd(); } + } + + protected DocumentStart DocumentStart(bool isImplicit) + { + return DocumentStart(isImplicit, null, DefaultTags); + } + + protected DocumentStart DocumentStart(bool isImplicit, VersionDirective version, params TagDirective[] tags) + { + return new DocumentStart(version, new TagDirectiveCollection(tags), isImplicit); + } + + protected VersionDirective Version(int major, int minor) + { + return new VersionDirective(new Version(major, minor)); + } + + protected TagDirective TagDirective(string handle, string prefix) + { + return new TagDirective(handle, prefix); + } + + protected DocumentEnd DocumentEnd(bool isImplicit) + { + return new DocumentEnd(isImplicit); + } + + protected ScalarBuilder Scalar(string text) + { + return new ScalarBuilder(text, ScalarStyle.Any); + } + + protected ScalarBuilder PlainScalar(string text) + { + return new ScalarBuilder(text, ScalarStyle.Plain); + } + + protected ScalarBuilder SingleQuotedScalar(string text) + { + return new ScalarBuilder(text, ScalarStyle.SingleQuoted); + } + + protected ScalarBuilder DoubleQuotedScalar(string text) + { + return new ScalarBuilder(text, ScalarStyle.DoubleQuoted); + } + + protected ScalarBuilder LiteralScalar(string text) + { + return new ScalarBuilder(text, ScalarStyle.Literal); + } + + protected ScalarBuilder FoldedScalar(string text) + { + return new ScalarBuilder(text, ScalarStyle.Folded); + } + + protected SequenceStartBuilder BlockSequenceStart + { + get { return new SequenceStartBuilder(SequenceStyle.Block); } + } + + protected SequenceStartBuilder FlowSequenceStart + { + get { return new SequenceStartBuilder(SequenceStyle.Flow); } + } + + protected SequenceEnd SequenceEnd + { + get { return new SequenceEnd(); } + } + + protected MappingStart MappingStart + { + get { return new MappingStart(); } + } + + protected MappingStartBuilder BlockMappingStart + { + get { return new MappingStartBuilder(MappingStyle.Block); } + } + + protected MappingStartBuilder FlowMappingStart + { + get { return new MappingStartBuilder(MappingStyle.Flow); } + } + + protected MappingEnd MappingEnd + { + get { return new MappingEnd(); } + } + + protected AnchorAlias AnchorAlias(string alias) + { + return new AnchorAlias(alias); + } + + protected Comment StandaloneComment(string value) + { + return new Comment(value, false); + } + + protected Comment InlineComment(string value) + { + return new Comment(value, true); + } + + protected class ScalarBuilder + { + private readonly string text; + private readonly ScalarStyle style; + private string tag; + private bool plainImplicit; + private bool quotedImplicit; + + public ScalarBuilder(string text, ScalarStyle style) + { + this.text = text; + this.style = style; + plainImplicit = style == ScalarStyle.Plain; + quotedImplicit = style != ScalarStyle.Plain && + style != ScalarStyle.Any; + } + + public ScalarBuilder T(string tag) + { + this.tag = tag; + plainImplicit = false; + quotedImplicit = false; + return this; + } + + public ScalarBuilder ImplicitPlain + { + get { + plainImplicit = true; + return this; + } + } + + public ScalarBuilder ImplicitQuoted + { + get { + quotedImplicit = true; + return this; + } + } + + public static implicit operator Scalar(ScalarBuilder builder) + { + return new Scalar(null, + builder.tag, + builder.text, + builder.style, + builder.plainImplicit, + builder.quotedImplicit); + } + } + + protected class SequenceStartBuilder + { + private const bool DefaultImplicit = true; + + private readonly SequenceStyle style; + private string anchor; + private bool @implicit; + + public SequenceStartBuilder(SequenceStyle style) + { + this.style = style; + @implicit = DefaultImplicit; + } + + public SequenceStartBuilder A(string anchor) + { + this.anchor = anchor; + return this; + } + + public SequenceStartBuilder Explicit + { + get + { + @implicit = false; + return this; + } + } + + public static implicit operator SequenceStart(SequenceStartBuilder builder) + { + return new SequenceStart(builder.anchor, null, builder.@implicit, builder.style); + } + } + + protected class MappingStartBuilder + { + private const bool DefaultImplicit = true; + + private readonly MappingStyle style; + private string tag; + private bool @implicit; + + public MappingStartBuilder(MappingStyle style) + { + this.style = style; + @implicit = DefaultImplicit; + } + + public MappingStartBuilder T(string tag) + { + this.tag = tag; + return this; + } + + public MappingStartBuilder Explicit + { + get { + @implicit = false; + return this; + } + } + + public static implicit operator MappingStart(MappingStartBuilder builder) + { + return new MappingStart(null, builder.tag, builder.@implicit, builder.style); + } + } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/Core/InsertionQueueTests.cs b/YamlDotNet.Test/Core/InsertionQueueTests.cs index 914d864d3..f32d3180c 100644 --- a/YamlDotNet.Test/Core/InsertionQueueTests.cs +++ b/YamlDotNet.Test/Core/InsertionQueueTests.cs @@ -28,101 +28,101 @@ namespace YamlDotNet.Test.Core { - public class InsertionQueueTests - { - [Fact] - public void ShouldThrowExceptionWhenDequeuingEmptyContainer() - { - var queue = CreateQueue(); - - Action action = () => queue.Dequeue(); - - action.ShouldThrow(); - } - - [Fact] - public void ShouldThrowExceptionWhenDequeuingContainerThatBecomesEmpty() - { - var queue = CreateQueue(); - - queue.Enqueue(1); - queue.Dequeue(); - Action action = () => queue.Dequeue(); - - action.ShouldThrow(); - } - - [Fact] - public void ShouldCorrectlyDequeueElementsAfterEnqueuing() - { - var queue = CreateQueue(); - - WithTheRange(0, 10).Run(queue.Enqueue); - - OrderOfElementsIn(queue).Should().Equal(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); - } - - [Fact] - public void ShouldCorrectlyDequeueElementsWhenIntermixingEnqueuing() - { - var queue = CreateQueue(); - - WithTheRange(0, 10).Run(queue.Enqueue); - PerformTimes(5, queue.Dequeue); - WithTheRange(10, 15).Run(queue.Enqueue); - - OrderOfElementsIn(queue).Should().Equal(5, 6, 7, 8, 9, 10, 11, 12, 13, 14); - } - - [Fact] - public void ShouldThrowExceptionWhenDequeuingAfterInserting() - { - var queue = CreateQueue(); - - queue.Enqueue(1); - queue.Insert(0, 99); - PerformTimes(2, queue.Dequeue); - Action action = () => queue.Dequeue(); - - action.ShouldThrow(); - } - - [Fact] - public void ShouldCorrectlyDequeueElementsWhenInserting() - { - var queue = CreateQueue(); - - WithTheRange(0, 10).Run(queue.Enqueue); - queue.Insert(5, 99); - - OrderOfElementsIn(queue).Should().Equal(0, 1, 2, 3, 4, 99, 5, 6, 7, 8, 9); - } - - private static InsertionQueue CreateQueue() - { - return new InsertionQueue(); - } - - private IEnumerable WithTheRange(int from, int to) - { - return Enumerable.Range(@from, to - @from); - } - - private IEnumerable OrderOfElementsIn(InsertionQueue queue) - { - while (true) - { - if (queue.Count == 0) - { - yield break; - } - yield return queue.Dequeue(); - } - } - - public void PerformTimes(int times, Func func) - { - WithTheRange(0, times).Run(x => func()); - } - } + public class InsertionQueueTests + { + [Fact] + public void ShouldThrowExceptionWhenDequeuingEmptyContainer() + { + var queue = CreateQueue(); + + Action action = () => queue.Dequeue(); + + action.ShouldThrow(); + } + + [Fact] + public void ShouldThrowExceptionWhenDequeuingContainerThatBecomesEmpty() + { + var queue = CreateQueue(); + + queue.Enqueue(1); + queue.Dequeue(); + Action action = () => queue.Dequeue(); + + action.ShouldThrow(); + } + + [Fact] + public void ShouldCorrectlyDequeueElementsAfterEnqueuing() + { + var queue = CreateQueue(); + + WithTheRange(0, 10).Run(queue.Enqueue); + + OrderOfElementsIn(queue).Should().Equal(0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + } + + [Fact] + public void ShouldCorrectlyDequeueElementsWhenIntermixingEnqueuing() + { + var queue = CreateQueue(); + + WithTheRange(0, 10).Run(queue.Enqueue); + PerformTimes(5, queue.Dequeue); + WithTheRange(10, 15).Run(queue.Enqueue); + + OrderOfElementsIn(queue).Should().Equal(5, 6, 7, 8, 9, 10, 11, 12, 13, 14); + } + + [Fact] + public void ShouldThrowExceptionWhenDequeuingAfterInserting() + { + var queue = CreateQueue(); + + queue.Enqueue(1); + queue.Insert(0, 99); + PerformTimes(2, queue.Dequeue); + Action action = () => queue.Dequeue(); + + action.ShouldThrow(); + } + + [Fact] + public void ShouldCorrectlyDequeueElementsWhenInserting() + { + var queue = CreateQueue(); + + WithTheRange(0, 10).Run(queue.Enqueue); + queue.Insert(5, 99); + + OrderOfElementsIn(queue).Should().Equal(0, 1, 2, 3, 4, 99, 5, 6, 7, 8, 9); + } + + private static InsertionQueue CreateQueue() + { + return new InsertionQueue(); + } + + private IEnumerable WithTheRange(int from, int to) + { + return Enumerable.Range(@from, to - @from); + } + + private IEnumerable OrderOfElementsIn(InsertionQueue queue) + { + while (true) + { + if (queue.Count == 0) + { + yield break; + } + yield return queue.Dequeue(); + } + } + + public void PerformTimes(int times, Func func) + { + WithTheRange(0, times).Run(x => func()); + } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/Core/LookAheadBufferTests.cs b/YamlDotNet.Test/Core/LookAheadBufferTests.cs index 37226e47f..a83ac896f 100644 --- a/YamlDotNet.Test/Core/LookAheadBufferTests.cs +++ b/YamlDotNet.Test/Core/LookAheadBufferTests.cs @@ -29,247 +29,247 @@ namespace YamlDotNet.Test.Core { - public class LookAheadBufferTests - { - private const string TestString = "abcdefghi"; - private const int Capacity = 4; - - [Fact] - public void ShouldHaveReadOnceWhenPeekingAtOffsetZero() - { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - buffer.Peek(0).Should().Be('a'); - A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); - } - - [Fact] - public void ShouldHaveReadTwiceWhenPeekingAtOffsetOne() - { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - buffer.Peek(0); - - buffer.Peek(1).Should().Be('b'); - A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Twice); - } - - [Fact] - public void ShouldHaveReadThriceWhenPeekingAtOffsetTwo() - { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - buffer.Peek(0); - buffer.Peek(1); - - buffer.Peek(2).Should().Be('c'); - A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Times(3)); - } - - [Fact] - public void ShouldNotHaveReadAfterSkippingOneCharacter() - { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - buffer.Peek(2); - - using (OnlyTheseCalls) - { - buffer.Skip(1); - - buffer.Peek(0).Should().Be('b'); - buffer.Peek(1).Should().Be('c'); - A.CallTo(() => reader.Read()).MustNotHaveHappened(); - } - } - - [Fact] - public void ShouldHaveReadOnceAfterSkippingOneCharacter() - { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - buffer.Peek(2); - - using (OnlyTheseCalls) - { - buffer.Skip(1); - - buffer.Peek(2).Should().Be('d'); - A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); - } - } - - [Fact] - public void ShouldHaveReadTwiceAfterSkippingOneCharacter() - { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - buffer.Peek(2); - - using (OnlyTheseCalls) { - buffer.Skip(1); - - buffer.Peek(3).Should().Be('e'); - A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Twice); - } - } - - [Fact] - public void ShouldHaveReadOnceAfterSkippingFiveCharacters() - { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - buffer.Peek(2); - buffer.Skip(1); - buffer.Peek(3); - - using (OnlyTheseCalls) { - buffer.Skip(4); - - buffer.Peek(0).Should().Be('f'); - A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); - } - } - - [Fact] - public void ShouldHaveReadOnceAfterSkippingSixCharacters() - { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - buffer.Peek(2); - buffer.Skip(1); - buffer.Peek(3); - buffer.Skip(4); - buffer.Peek(0); - - using (OnlyTheseCalls) { - buffer.Skip(1); - - buffer.Peek(0).Should().Be('g'); - A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); - } - } - - [Fact] - public void ShouldHaveReadOnceAfterSkippingSevenCharacters() { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - buffer.Peek(2); - buffer.Skip(1); - buffer.Peek(3); - buffer.Skip(4); - buffer.Peek(1); - - using (OnlyTheseCalls) { - buffer.Skip(2); - - buffer.Peek(0).Should().Be('h'); - A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); - } - } - - [Fact] - public void ShouldHaveReadOnceAfterSkippingEightCharacters() - { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - buffer.Peek(2); - buffer.Skip(1); - buffer.Peek(3); - buffer.Skip(4); - buffer.Peek(2); - - using (OnlyTheseCalls) { - buffer.Skip(3); - - buffer.Peek(0).Should().Be('i'); - A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); - } - } - - [Fact] - public void ShouldHaveReadOnceAfterSkippingNineCharacters() - { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - buffer.Peek(2); - buffer.Skip(1); - buffer.Peek(3); - buffer.Skip(4); - buffer.Peek(3); - - using (OnlyTheseCalls) { - buffer.Skip(4); - - buffer.Peek(0).Should().Be('\0'); - A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); - } - } - - [Fact] - public void ShouldFindEndOfInput() - { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - buffer.Peek(2); - buffer.Skip(1); - buffer.Peek(3); - buffer.Skip(4); - buffer.Peek(3); - buffer.Skip(4); - buffer.Peek(0); - - buffer.EndOfInput.Should().BeTrue(); - } - - [Fact] - public void ShouldThrowWhenPeekingBeyondCapacity() - { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - Action action = () => buffer.Peek(4); - - action.ShouldThrow(); - } - - [Fact] - public void ShouldThrowWhenSkippingBeyondCurrentBuffer() - { - var reader = CreateFakeReader(TestString); - var buffer = CreateBuffer(reader, Capacity); - - buffer.Peek(3); - Action action = () => buffer.Skip(5); - - action.ShouldThrow(); - } - - private static TextReader CreateFakeReader(string text) - { - return A.Fake(x => x.Wrapping(new StringReader(text))); - } - - private static LookAheadBuffer CreateBuffer(TextReader reader, int capacity) - { - return new LookAheadBuffer(reader, capacity); - } - - private static IFakeScope OnlyTheseCalls - { - get { return Fake.CreateScope(); } - } - } + public class LookAheadBufferTests + { + private const string TestString = "abcdefghi"; + private const int Capacity = 4; + + [Fact] + public void ShouldHaveReadOnceWhenPeekingAtOffsetZero() + { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + buffer.Peek(0).Should().Be('a'); + A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); + } + + [Fact] + public void ShouldHaveReadTwiceWhenPeekingAtOffsetOne() + { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + buffer.Peek(0); + + buffer.Peek(1).Should().Be('b'); + A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Twice); + } + + [Fact] + public void ShouldHaveReadThriceWhenPeekingAtOffsetTwo() + { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + buffer.Peek(0); + buffer.Peek(1); + + buffer.Peek(2).Should().Be('c'); + A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Times(3)); + } + + [Fact] + public void ShouldNotHaveReadAfterSkippingOneCharacter() + { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + buffer.Peek(2); + + using (OnlyTheseCalls) + { + buffer.Skip(1); + + buffer.Peek(0).Should().Be('b'); + buffer.Peek(1).Should().Be('c'); + A.CallTo(() => reader.Read()).MustNotHaveHappened(); + } + } + + [Fact] + public void ShouldHaveReadOnceAfterSkippingOneCharacter() + { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + buffer.Peek(2); + + using (OnlyTheseCalls) + { + buffer.Skip(1); + + buffer.Peek(2).Should().Be('d'); + A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); + } + } + + [Fact] + public void ShouldHaveReadTwiceAfterSkippingOneCharacter() + { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + buffer.Peek(2); + + using (OnlyTheseCalls) { + buffer.Skip(1); + + buffer.Peek(3).Should().Be('e'); + A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Twice); + } + } + + [Fact] + public void ShouldHaveReadOnceAfterSkippingFiveCharacters() + { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + buffer.Peek(2); + buffer.Skip(1); + buffer.Peek(3); + + using (OnlyTheseCalls) { + buffer.Skip(4); + + buffer.Peek(0).Should().Be('f'); + A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); + } + } + + [Fact] + public void ShouldHaveReadOnceAfterSkippingSixCharacters() + { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + buffer.Peek(2); + buffer.Skip(1); + buffer.Peek(3); + buffer.Skip(4); + buffer.Peek(0); + + using (OnlyTheseCalls) { + buffer.Skip(1); + + buffer.Peek(0).Should().Be('g'); + A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); + } + } + + [Fact] + public void ShouldHaveReadOnceAfterSkippingSevenCharacters() { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + buffer.Peek(2); + buffer.Skip(1); + buffer.Peek(3); + buffer.Skip(4); + buffer.Peek(1); + + using (OnlyTheseCalls) { + buffer.Skip(2); + + buffer.Peek(0).Should().Be('h'); + A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); + } + } + + [Fact] + public void ShouldHaveReadOnceAfterSkippingEightCharacters() + { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + buffer.Peek(2); + buffer.Skip(1); + buffer.Peek(3); + buffer.Skip(4); + buffer.Peek(2); + + using (OnlyTheseCalls) { + buffer.Skip(3); + + buffer.Peek(0).Should().Be('i'); + A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); + } + } + + [Fact] + public void ShouldHaveReadOnceAfterSkippingNineCharacters() + { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + buffer.Peek(2); + buffer.Skip(1); + buffer.Peek(3); + buffer.Skip(4); + buffer.Peek(3); + + using (OnlyTheseCalls) { + buffer.Skip(4); + + buffer.Peek(0).Should().Be('\0'); + A.CallTo(() => reader.Read()).MustHaveHappened(Repeated.Exactly.Once); + } + } + + [Fact] + public void ShouldFindEndOfInput() + { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + buffer.Peek(2); + buffer.Skip(1); + buffer.Peek(3); + buffer.Skip(4); + buffer.Peek(3); + buffer.Skip(4); + buffer.Peek(0); + + buffer.EndOfInput.Should().BeTrue(); + } + + [Fact] + public void ShouldThrowWhenPeekingBeyondCapacity() + { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + Action action = () => buffer.Peek(4); + + action.ShouldThrow(); + } + + [Fact] + public void ShouldThrowWhenSkippingBeyondCurrentBuffer() + { + var reader = CreateFakeReader(TestString); + var buffer = CreateBuffer(reader, Capacity); + + buffer.Peek(3); + Action action = () => buffer.Skip(5); + + action.ShouldThrow(); + } + + private static TextReader CreateFakeReader(string text) + { + return A.Fake(x => x.Wrapping(new StringReader(text))); + } + + private static LookAheadBuffer CreateBuffer(TextReader reader, int capacity) + { + return new LookAheadBuffer(reader, capacity); + } + + private static IFakeScope OnlyTheseCalls + { + get { return Fake.CreateScope(); } + } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/Core/MarkCursorTests.cs b/YamlDotNet.Test/Core/MarkCursorTests.cs index ce3ba41ec..7bfc05bd6 100644 --- a/YamlDotNet.Test/Core/MarkCursorTests.cs +++ b/YamlDotNet.Test/Core/MarkCursorTests.cs @@ -25,17 +25,17 @@ namespace YamlDotNet.Test.Core { - class MarkCursorTests - { - [Fact] - public void ShouldProvideAnOneIndexedMark() - { - var cursor = new Cursor(); + class MarkCursorTests + { + [Fact] + public void ShouldProvideAnOneIndexedMark() + { + var cursor = new Cursor(); - var result = cursor.Mark(); + var result = cursor.Mark(); - result.Line.Should().Be(1, "the mark should be at line 1"); - result.Column.Should().Be(1, "the mark should be at column 1"); - } - } + result.Line.Should().Be(1, "the mark should be at line 1"); + result.Column.Should().Be(1, "the mark should be at column 1"); + } + } } diff --git a/YamlDotNet.Test/Core/ParserTests.cs b/YamlDotNet.Test/Core/ParserTests.cs index 2af450eb8..116b27b1d 100644 --- a/YamlDotNet.Test/Core/ParserTests.cs +++ b/YamlDotNet.Test/Core/ParserTests.cs @@ -27,424 +27,424 @@ namespace YamlDotNet.Test.Core { - public class ParserTests : EventsHelper - { - [Fact] - public void EmptyDocument() - { - AssertSequenceOfEventsFrom(Yaml.ParserForEmptyContent(), - StreamStart, - StreamEnd); - } + public class ParserTests : EventsHelper + { + [Fact] + public void EmptyDocument() + { + AssertSequenceOfEventsFrom(Yaml.ParserForEmptyContent(), + StreamStart, + StreamEnd); + } - [Fact] - public void VerifyEventsOnExample1() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("01-directives.yaml"), - StreamStart, - DocumentStart(Explicit, Version(1, 1), - TagDirective("!", "!foo"), - TagDirective("!yaml!", TagYaml), - TagDirective("!!", TagYaml)), - PlainScalar(string.Empty), - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyEventsOnExample1() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("01-directives.yaml"), + StreamStart, + DocumentStart(Explicit, Version(1, 1), + TagDirective("!", "!foo"), + TagDirective("!yaml!", TagYaml), + TagDirective("!!", TagYaml)), + PlainScalar(string.Empty), + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample2() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("02-scalar-in-imp-doc.yaml"), - StreamStart, - DocumentStart(Implicit), - SingleQuotedScalar("a scalar"), - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample2() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("02-scalar-in-imp-doc.yaml"), + StreamStart, + DocumentStart(Implicit), + SingleQuotedScalar("a scalar"), + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample3() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("03-scalar-in-exp-doc.yaml"), - StreamStart, - DocumentStart(Explicit), - SingleQuotedScalar("a scalar"), - DocumentEnd(Explicit), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample3() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("03-scalar-in-exp-doc.yaml"), + StreamStart, + DocumentStart(Explicit), + SingleQuotedScalar("a scalar"), + DocumentEnd(Explicit), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample4() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("04-scalars-in-multi-docs.yaml"), - StreamStart, - DocumentStart(Implicit), - SingleQuotedScalar("a scalar"), - DocumentEnd(Implicit), - DocumentStart(Explicit), - SingleQuotedScalar("another scalar"), - DocumentEnd(Implicit), - DocumentStart(Explicit), - SingleQuotedScalar("yet another scalar"), - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample4() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("04-scalars-in-multi-docs.yaml"), + StreamStart, + DocumentStart(Implicit), + SingleQuotedScalar("a scalar"), + DocumentEnd(Implicit), + DocumentStart(Explicit), + SingleQuotedScalar("another scalar"), + DocumentEnd(Implicit), + DocumentStart(Explicit), + SingleQuotedScalar("yet another scalar"), + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample5() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("05-circular-sequence.yaml"), - StreamStart, - DocumentStart(Implicit), - FlowSequenceStart.A("A"), - AnchorAlias("A"), - SequenceEnd, - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample5() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("05-circular-sequence.yaml"), + StreamStart, + DocumentStart(Implicit), + FlowSequenceStart.A("A"), + AnchorAlias("A"), + SequenceEnd, + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample6() - { - var parser = Yaml.ParserForResource("06-float-tag.yaml"); - AssertSequenceOfEventsFrom(parser, - StreamStart, - DocumentStart(Implicit), - DoubleQuotedScalar("3.14").T(TagYaml + "float"), - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample6() + { + var parser = Yaml.ParserForResource("06-float-tag.yaml"); + AssertSequenceOfEventsFrom(parser, + StreamStart, + DocumentStart(Implicit), + DoubleQuotedScalar("3.14").T(TagYaml + "float"), + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample7() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("07-scalar-styles.yaml"), - StreamStart, - DocumentStart(Explicit), - PlainScalar(string.Empty), - DocumentEnd(Implicit), - DocumentStart(Explicit), - PlainScalar("a plain scalar"), - DocumentEnd(Implicit), - DocumentStart(Explicit), - SingleQuotedScalar("a single-quoted scalar"), - DocumentEnd(Implicit), - DocumentStart(Explicit), - DoubleQuotedScalar("a double-quoted scalar"), - DocumentEnd(Implicit), - DocumentStart(Explicit), - LiteralScalar("a literal scalar"), - DocumentEnd(Implicit), - DocumentStart(Explicit), - FoldedScalar("a folded scalar"), - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample7() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("07-scalar-styles.yaml"), + StreamStart, + DocumentStart(Explicit), + PlainScalar(string.Empty), + DocumentEnd(Implicit), + DocumentStart(Explicit), + PlainScalar("a plain scalar"), + DocumentEnd(Implicit), + DocumentStart(Explicit), + SingleQuotedScalar("a single-quoted scalar"), + DocumentEnd(Implicit), + DocumentStart(Explicit), + DoubleQuotedScalar("a double-quoted scalar"), + DocumentEnd(Implicit), + DocumentStart(Explicit), + LiteralScalar("a literal scalar"), + DocumentEnd(Implicit), + DocumentStart(Explicit), + FoldedScalar("a folded scalar"), + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample8() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("08-flow-sequence.yaml"), - StreamStart, - DocumentStart(Implicit), - FlowSequenceStart, - PlainScalar("item 1"), - PlainScalar("item 2"), - PlainScalar("item 3"), - SequenceEnd, - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample8() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("08-flow-sequence.yaml"), + StreamStart, + DocumentStart(Implicit), + FlowSequenceStart, + PlainScalar("item 1"), + PlainScalar("item 2"), + PlainScalar("item 3"), + SequenceEnd, + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample9() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("09-flow-mapping.yaml"), - StreamStart, - DocumentStart(Implicit), - FlowMappingStart, - PlainScalar("a simple key"), - PlainScalar("a value"), - PlainScalar("a complex key"), - PlainScalar("another value"), - MappingEnd, - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample9() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("09-flow-mapping.yaml"), + StreamStart, + DocumentStart(Implicit), + FlowMappingStart, + PlainScalar("a simple key"), + PlainScalar("a value"), + PlainScalar("a complex key"), + PlainScalar("another value"), + MappingEnd, + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample10() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("10-mixed-nodes-in-sequence.yaml"), - StreamStart, - DocumentStart(Implicit), - BlockSequenceStart, - PlainScalar("item 1"), - PlainScalar("item 2"), - BlockSequenceStart, - PlainScalar("item 3.1"), - PlainScalar("item 3.2"), - SequenceEnd, - BlockMappingStart, - PlainScalar("key 1"), - PlainScalar("value 1"), - PlainScalar("key 2"), - PlainScalar("value 2"), - MappingEnd, - SequenceEnd, - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample10() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("10-mixed-nodes-in-sequence.yaml"), + StreamStart, + DocumentStart(Implicit), + BlockSequenceStart, + PlainScalar("item 1"), + PlainScalar("item 2"), + BlockSequenceStart, + PlainScalar("item 3.1"), + PlainScalar("item 3.2"), + SequenceEnd, + BlockMappingStart, + PlainScalar("key 1"), + PlainScalar("value 1"), + PlainScalar("key 2"), + PlainScalar("value 2"), + MappingEnd, + SequenceEnd, + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample11() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("11-mixed-nodes-in-mapping.yaml"), - StreamStart, - DocumentStart(Implicit), - BlockMappingStart, - PlainScalar("a simple key"), - PlainScalar("a value"), - PlainScalar("a complex key"), - PlainScalar("another value"), - PlainScalar("a mapping"), - BlockMappingStart, - PlainScalar("key 1"), - PlainScalar("value 1"), - PlainScalar("key 2"), - PlainScalar("value 2"), - MappingEnd, - PlainScalar("a sequence"), - BlockSequenceStart, - PlainScalar("item 1"), - PlainScalar("item 2"), - SequenceEnd, - MappingEnd, - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample11() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("11-mixed-nodes-in-mapping.yaml"), + StreamStart, + DocumentStart(Implicit), + BlockMappingStart, + PlainScalar("a simple key"), + PlainScalar("a value"), + PlainScalar("a complex key"), + PlainScalar("another value"), + PlainScalar("a mapping"), + BlockMappingStart, + PlainScalar("key 1"), + PlainScalar("value 1"), + PlainScalar("key 2"), + PlainScalar("value 2"), + MappingEnd, + PlainScalar("a sequence"), + BlockSequenceStart, + PlainScalar("item 1"), + PlainScalar("item 2"), + SequenceEnd, + MappingEnd, + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample12() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("12-compact-sequence.yaml"), - StreamStart, - DocumentStart(Implicit), - BlockSequenceStart, - BlockSequenceStart, - PlainScalar("item 1"), - PlainScalar("item 2"), - SequenceEnd, - BlockMappingStart, - PlainScalar("key 1"), - PlainScalar("value 1"), - PlainScalar("key 2"), - PlainScalar("value 2"), - MappingEnd, - BlockMappingStart, - PlainScalar("complex key"), - PlainScalar("complex value"), - MappingEnd, - SequenceEnd, - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample12() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("12-compact-sequence.yaml"), + StreamStart, + DocumentStart(Implicit), + BlockSequenceStart, + BlockSequenceStart, + PlainScalar("item 1"), + PlainScalar("item 2"), + SequenceEnd, + BlockMappingStart, + PlainScalar("key 1"), + PlainScalar("value 1"), + PlainScalar("key 2"), + PlainScalar("value 2"), + MappingEnd, + BlockMappingStart, + PlainScalar("complex key"), + PlainScalar("complex value"), + MappingEnd, + SequenceEnd, + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample13() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("13-compact-mapping.yaml"), - StreamStart, - DocumentStart(Implicit), - BlockMappingStart, - PlainScalar("a sequence"), - BlockSequenceStart, - PlainScalar("item 1"), - PlainScalar("item 2"), - SequenceEnd, - PlainScalar("a mapping"), - BlockMappingStart, - PlainScalar("key 1"), - PlainScalar("value 1"), - PlainScalar("key 2"), - PlainScalar("value 2"), - MappingEnd, - MappingEnd, - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample13() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("13-compact-mapping.yaml"), + StreamStart, + DocumentStart(Implicit), + BlockMappingStart, + PlainScalar("a sequence"), + BlockSequenceStart, + PlainScalar("item 1"), + PlainScalar("item 2"), + SequenceEnd, + PlainScalar("a mapping"), + BlockMappingStart, + PlainScalar("key 1"), + PlainScalar("value 1"), + PlainScalar("key 2"), + PlainScalar("value 2"), + MappingEnd, + MappingEnd, + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample14() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("14-mapping-wo-indent.yaml"), - StreamStart, - DocumentStart(Implicit), - BlockMappingStart, - PlainScalar("key"), - BlockSequenceStart, - PlainScalar("item 1"), - PlainScalar("item 2"), - SequenceEnd, - MappingEnd, - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample14() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("14-mapping-wo-indent.yaml"), + StreamStart, + DocumentStart(Implicit), + BlockMappingStart, + PlainScalar("key"), + BlockSequenceStart, + PlainScalar("item 1"), + PlainScalar("item 2"), + SequenceEnd, + MappingEnd, + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void VerifyTokenWithLocalTags() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("local-tags.yaml"), - StreamStart, - DocumentStart(Explicit), - BlockMappingStart.T("!MyObject").Explicit, - PlainScalar("a"), - PlainScalar("1.0"), - PlainScalar("b"), - PlainScalar("42"), - PlainScalar("c"), - PlainScalar("-7"), - MappingEnd, - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void VerifyTokenWithLocalTags() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("local-tags.yaml"), + StreamStart, + DocumentStart(Explicit), + BlockMappingStart.T("!MyObject").Explicit, + PlainScalar("a"), + PlainScalar("1.0"), + PlainScalar("b"), + PlainScalar("42"), + PlainScalar("c"), + PlainScalar("-7"), + MappingEnd, + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void CommentsAreReturnedWhenRequested() - { - AssertSequenceOfEventsFrom(new Parser(new Scanner(Yaml.ReaderForText(@" - # Top comment - - first # Comment on first item - - second - - # a mapping - ? key # my key - : value # my value - # Bottom comment - "), skipComments: false)), - StreamStart, - StandaloneComment("Top comment"), - DocumentStart(Implicit), - BlockSequenceStart, - PlainScalar("first"), - InlineComment("Comment on first item"), - PlainScalar("second"), - InlineComment("a mapping"), - BlockMappingStart, - PlainScalar("key"), - InlineComment("my key"), - PlainScalar("value"), - InlineComment("my value"), - StandaloneComment("Bottom comment"), - MappingEnd, - SequenceEnd, - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void CommentsAreReturnedWhenRequested() + { + AssertSequenceOfEventsFrom(new Parser(new Scanner(Yaml.ReaderForText(@" + # Top comment + - first # Comment on first item + - second + - # a mapping + ? key # my key + : value # my value + # Bottom comment + "), skipComments: false)), + StreamStart, + StandaloneComment("Top comment"), + DocumentStart(Implicit), + BlockSequenceStart, + PlainScalar("first"), + InlineComment("Comment on first item"), + PlainScalar("second"), + InlineComment("a mapping"), + BlockMappingStart, + PlainScalar("key"), + InlineComment("my key"), + PlainScalar("value"), + InlineComment("my value"), + StandaloneComment("Bottom comment"), + MappingEnd, + SequenceEnd, + DocumentEnd(Implicit), + StreamEnd); + } - [Fact] - public void CommentsAreOmittedUnlessRequested() - { - AssertSequenceOfEventsFrom(Yaml.ParserForText(@" - # Top comment - - first # Comment on first item - - second - - # a mapping - ? key # my key - : value # my value - # Bottom comment - "), - StreamStart, - DocumentStart(Implicit), - BlockSequenceStart, - PlainScalar("first"), - PlainScalar("second"), - BlockMappingStart, - PlainScalar("key"), - PlainScalar("value"), - MappingEnd, - SequenceEnd, - DocumentEnd(Implicit), - StreamEnd); - } + [Fact] + public void CommentsAreOmittedUnlessRequested() + { + AssertSequenceOfEventsFrom(Yaml.ParserForText(@" + # Top comment + - first # Comment on first item + - second + - # a mapping + ? key # my key + : value # my value + # Bottom comment + "), + StreamStart, + DocumentStart(Implicit), + BlockSequenceStart, + PlainScalar("first"), + PlainScalar("second"), + BlockMappingStart, + PlainScalar("key"), + PlainScalar("value"), + MappingEnd, + SequenceEnd, + DocumentEnd(Implicit), + StreamEnd); + } - private void AssertSequenceOfEventsFrom(IParser parser, params ParsingEvent[] events) - { - var eventNumber = 1; - foreach (var expected in events) - { - parser.MoveNext().Should().BeTrue("Missing parse event number {0}", eventNumber); - AssertEvent(expected, parser.Current, eventNumber); - eventNumber++; - } - parser.MoveNext().Should().BeFalse("Found extra parse events"); - } + private void AssertSequenceOfEventsFrom(IParser parser, params ParsingEvent[] events) + { + var eventNumber = 1; + foreach (var expected in events) + { + parser.MoveNext().Should().BeTrue("Missing parse event number {0}", eventNumber); + AssertEvent(expected, parser.Current, eventNumber); + eventNumber++; + } + parser.MoveNext().Should().BeFalse("Found extra parse events"); + } - private void AssertEvent(ParsingEvent expected, ParsingEvent actual, int eventNumber) - { - actual.GetType().Should().Be(expected.GetType(), "Parse event {0} is not of the expected type.", eventNumber); + private void AssertEvent(ParsingEvent expected, ParsingEvent actual, int eventNumber) + { + actual.GetType().Should().Be(expected.GetType(), "Parse event {0} is not of the expected type.", eventNumber); - foreach (var property in expected.GetType().GetProperties()) - { - if (property.PropertyType == typeof(Mark) || !property.CanRead) - { - continue; - } + foreach (var property in expected.GetType().GetProperties()) + { + if (property.PropertyType == typeof(Mark) || !property.CanRead) + { + continue; + } - var value = property.GetValue(actual, null); - var expectedValue = property.GetValue(expected, null); - if (expectedValue is IEnumerable && !(expectedValue is string)) - { - Dump.Write("\t{0} = {{", property.Name); - Dump.Write(string.Join(", ", (IEnumerable)value)); - Dump.WriteLine("}"); + var value = property.GetValue(actual, null); + var expectedValue = property.GetValue(expected, null); + if (expectedValue is IEnumerable && !(expectedValue is string)) + { + Dump.Write("\t{0} = {{", property.Name); + Dump.Write(string.Join(", ", (IEnumerable)value)); + Dump.WriteLine("}"); - if (expectedValue is ICollection && value is ICollection) - { - var expectedCount = ((ICollection)expectedValue).Count; - var valueCount = ((ICollection)value).Count; - valueCount.Should().Be(expectedCount, "Compared size of collections in property {0} in parse event {1}", - property.Name, eventNumber); - } + if (expectedValue is ICollection && value is ICollection) + { + var expectedCount = ((ICollection)expectedValue).Count; + var valueCount = ((ICollection)value).Count; + valueCount.Should().Be(expectedCount, "Compared size of collections in property {0} in parse event {1}", + property.Name, eventNumber); + } - var values = ((IEnumerable)value).GetEnumerator(); - var expectedValues = ((IEnumerable)expectedValue).GetEnumerator(); - while (expectedValues.MoveNext()) - { - values.MoveNext().Should().BeTrue("Property {0} in parse event {1} had too few elements", property.Name, eventNumber); - values.Current.Should().Be(expectedValues.Current, - "Compared element in property {0} in parse event {1}", property.Name, eventNumber); - } - values.MoveNext().Should().BeFalse("Property {0} in parse event {1} had too many elements", property.Name, eventNumber); - } - else - { - Dump.WriteLine("\t{0} = {1}", property.Name, value); - value.Should().Be(expectedValue, "Compared property {0} in parse event {1}", property.Name, eventNumber); - } - } - } + var values = ((IEnumerable)value).GetEnumerator(); + var expectedValues = ((IEnumerable)expectedValue).GetEnumerator(); + while (expectedValues.MoveNext()) + { + values.MoveNext().Should().BeTrue("Property {0} in parse event {1} had too few elements", property.Name, eventNumber); + values.Current.Should().Be(expectedValues.Current, + "Compared element in property {0} in parse event {1}", property.Name, eventNumber); + } + values.MoveNext().Should().BeFalse("Property {0} in parse event {1} had too many elements", property.Name, eventNumber); + } + else + { + Dump.WriteLine("\t{0} = {1}", property.Name, value); + value.Should().Be(expectedValue, "Compared property {0} in parse event {1}", property.Name, eventNumber); + } + } + } - [Fact] - public void VerifyTokenWithMultiDocTag() - { - AssertSequenceOfEventsFrom(Yaml.ParserForResource("multi-doc-tag.yaml"), - StreamStart, - DocumentStart(Explicit, Version(1, 1), - TagDirective("!x!", "tag:example.com,2014:"), - TagDirective("!", "!"), - TagDirective("!!", TagYaml)), - BlockMappingStart.T("tag:example.com,2014:foo").Explicit, - PlainScalar("x"), - PlainScalar("0"), - MappingEnd, - DocumentEnd(Implicit), - DocumentStart(Explicit), - BlockMappingStart.T("tag:example.com,2014:bar").Explicit, - PlainScalar("x"), - PlainScalar("1"), - MappingEnd, - DocumentEnd(Implicit), - StreamEnd); - } - } + [Fact] + public void VerifyTokenWithMultiDocTag() + { + AssertSequenceOfEventsFrom(Yaml.ParserForResource("multi-doc-tag.yaml"), + StreamStart, + DocumentStart(Explicit, Version(1, 1), + TagDirective("!x!", "tag:example.com,2014:"), + TagDirective("!", "!"), + TagDirective("!!", TagYaml)), + BlockMappingStart.T("tag:example.com,2014:foo").Explicit, + PlainScalar("x"), + PlainScalar("0"), + MappingEnd, + DocumentEnd(Implicit), + DocumentStart(Explicit), + BlockMappingStart.T("tag:example.com,2014:bar").Explicit, + PlainScalar("x"), + PlainScalar("1"), + MappingEnd, + DocumentEnd(Implicit), + StreamEnd); + } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/Core/ScannerTests.cs b/YamlDotNet.Test/Core/ScannerTests.cs index cd65d7b67..30e6eab3c 100644 --- a/YamlDotNet.Test/Core/ScannerTests.cs +++ b/YamlDotNet.Test/Core/ScannerTests.cs @@ -28,437 +28,437 @@ namespace YamlDotNet.Test.Core { - public class ScannerTests : TokenHelper - { - [Fact] - public void VerifyTokensOnExample1() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForResource("01-directives.yaml"), - StreamStart, - VersionDirective(1, 1), - TagDirective("!", "!foo"), - TagDirective("!yaml!", "tag:yaml.org,2002:"), - DocumentStart, - StreamEnd); - } + public class ScannerTests : TokenHelper + { + [Fact] + public void VerifyTokensOnExample1() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForResource("01-directives.yaml"), + StreamStart, + VersionDirective(1, 1), + TagDirective("!", "!foo"), + TagDirective("!yaml!", "tag:yaml.org,2002:"), + DocumentStart, + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample2() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForResource("02-scalar-in-imp-doc.yaml"), - StreamStart, - SingleQuotedScalar("a scalar"), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample2() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForResource("02-scalar-in-imp-doc.yaml"), + StreamStart, + SingleQuotedScalar("a scalar"), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample3() - { - Scanner scanner = Yaml.ScannerForResource("03-scalar-in-exp-doc.yaml"); - AssertSequenceOfTokensFrom(scanner, - StreamStart, - DocumentStart, - SingleQuotedScalar("a scalar"), - DocumentEnd, - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample3() + { + Scanner scanner = Yaml.ScannerForResource("03-scalar-in-exp-doc.yaml"); + AssertSequenceOfTokensFrom(scanner, + StreamStart, + DocumentStart, + SingleQuotedScalar("a scalar"), + DocumentEnd, + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample4() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForResource("04-scalars-in-multi-docs.yaml"), - StreamStart, - SingleQuotedScalar("a scalar"), - DocumentStart, - SingleQuotedScalar("another scalar"), - DocumentStart, - SingleQuotedScalar("yet another scalar"), - StreamEnd); - } - - [Fact] - public void VerifyTokensOnExample5() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForResource("05-circular-sequence.yaml"), - StreamStart, - Anchor("A"), - FlowSequenceStart, - AnchorAlias("A"), - FlowSequenceEnd, - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample4() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForResource("04-scalars-in-multi-docs.yaml"), + StreamStart, + SingleQuotedScalar("a scalar"), + DocumentStart, + SingleQuotedScalar("another scalar"), + DocumentStart, + SingleQuotedScalar("yet another scalar"), + StreamEnd); + } + + [Fact] + public void VerifyTokensOnExample5() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForResource("05-circular-sequence.yaml"), + StreamStart, + Anchor("A"), + FlowSequenceStart, + AnchorAlias("A"), + FlowSequenceEnd, + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample6() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForResource("06-float-tag.yaml"), - StreamStart, - Tag("!!", "float"), - DoubleQuotedScalar("3.14"), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample6() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForResource("06-float-tag.yaml"), + StreamStart, + Tag("!!", "float"), + DoubleQuotedScalar("3.14"), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample7() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForResource("07-scalar-styles.yaml"), - StreamStart, - DocumentStart, - DocumentStart, - PlainScalar("a plain scalar"), - DocumentStart, - SingleQuotedScalar("a single-quoted scalar"), - DocumentStart, - DoubleQuotedScalar("a double-quoted scalar"), - DocumentStart, - LiteralScalar("a literal scalar"), - DocumentStart, - FoldedScalar("a folded scalar"), - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample7() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForResource("07-scalar-styles.yaml"), + StreamStart, + DocumentStart, + DocumentStart, + PlainScalar("a plain scalar"), + DocumentStart, + SingleQuotedScalar("a single-quoted scalar"), + DocumentStart, + DoubleQuotedScalar("a double-quoted scalar"), + DocumentStart, + LiteralScalar("a literal scalar"), + DocumentStart, + FoldedScalar("a folded scalar"), + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample8() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForResource("08-flow-sequence.yaml"), - StreamStart, - FlowSequenceStart, - PlainScalar("item 1"), - FlowEntry, - PlainScalar("item 2"), - FlowEntry, - PlainScalar("item 3"), - FlowSequenceEnd, - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample8() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForResource("08-flow-sequence.yaml"), + StreamStart, + FlowSequenceStart, + PlainScalar("item 1"), + FlowEntry, + PlainScalar("item 2"), + FlowEntry, + PlainScalar("item 3"), + FlowSequenceEnd, + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample9() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForResource("09-flow-mapping.yaml"), - StreamStart, - FlowMappingStart, - Key, - PlainScalar("a simple key"), - Value, - PlainScalar("a value"), - FlowEntry, - Key, - PlainScalar("a complex key"), - Value, - PlainScalar("another value"), - FlowEntry, - FlowMappingEnd, - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample9() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForResource("09-flow-mapping.yaml"), + StreamStart, + FlowMappingStart, + Key, + PlainScalar("a simple key"), + Value, + PlainScalar("a value"), + FlowEntry, + Key, + PlainScalar("a complex key"), + Value, + PlainScalar("another value"), + FlowEntry, + FlowMappingEnd, + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample10() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForResource("10-mixed-nodes-in-sequence.yaml"), - StreamStart, - BlockSequenceStart, - BlockEntry, - PlainScalar("item 1"), - BlockEntry, - PlainScalar("item 2"), - BlockEntry, - BlockSequenceStart, - BlockEntry, - PlainScalar("item 3.1"), - BlockEntry, - PlainScalar("item 3.2"), - BlockEnd, - BlockEntry, - BlockMappingStart, - Key, - PlainScalar("key 1"), - Value, - PlainScalar("value 1"), - Key, - PlainScalar("key 2"), - Value, - PlainScalar("value 2"), - BlockEnd, - BlockEnd, - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample10() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForResource("10-mixed-nodes-in-sequence.yaml"), + StreamStart, + BlockSequenceStart, + BlockEntry, + PlainScalar("item 1"), + BlockEntry, + PlainScalar("item 2"), + BlockEntry, + BlockSequenceStart, + BlockEntry, + PlainScalar("item 3.1"), + BlockEntry, + PlainScalar("item 3.2"), + BlockEnd, + BlockEntry, + BlockMappingStart, + Key, + PlainScalar("key 1"), + Value, + PlainScalar("value 1"), + Key, + PlainScalar("key 2"), + Value, + PlainScalar("value 2"), + BlockEnd, + BlockEnd, + StreamEnd); + } - [Fact] - public void VerifyTokensOnExample11() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForResource("11-mixed-nodes-in-mapping.yaml"), - StreamStart, - BlockMappingStart, - Key, - PlainScalar("a simple key"), - Value, - PlainScalar("a value"), - Key, - PlainScalar("a complex key"), - Value, - PlainScalar("another value"), - Key, - PlainScalar("a mapping"), - Value, - BlockMappingStart, - Key, - PlainScalar("key 1"), - Value, - PlainScalar("value 1"), - Key, - PlainScalar("key 2"), - Value, - PlainScalar("value 2"), - BlockEnd, - Key, - PlainScalar("a sequence"), - Value, - BlockSequenceStart, - BlockEntry, - PlainScalar("item 1"), - BlockEntry, - PlainScalar("item 2"), - BlockEnd, - BlockEnd, - StreamEnd); - } - - [Fact] - public void VerifyTokensOnExample12() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForResource("12-compact-sequence.yaml"), - StreamStart, - BlockSequenceStart, - BlockEntry, - BlockSequenceStart, - BlockEntry, - PlainScalar("item 1"), - BlockEntry, - PlainScalar("item 2"), - BlockEnd, - BlockEntry, - BlockMappingStart, - Key, - PlainScalar("key 1"), - Value, - PlainScalar("value 1"), - Key, - PlainScalar("key 2"), - Value, - PlainScalar("value 2"), - BlockEnd, - BlockEntry, - BlockMappingStart, - Key, - PlainScalar("complex key"), - Value, - PlainScalar("complex value"), - BlockEnd, - BlockEnd, - StreamEnd); - } - - [Fact] - public void VerifyTokensOnExample13() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForResource("13-compact-mapping.yaml"), - StreamStart, - BlockMappingStart, - Key, - PlainScalar("a sequence"), - Value, - BlockSequenceStart, - BlockEntry, - PlainScalar("item 1"), - BlockEntry, - PlainScalar("item 2"), - BlockEnd, - Key, - PlainScalar("a mapping"), - Value, - BlockMappingStart, - Key, - PlainScalar("key 1"), - Value, - PlainScalar("value 1"), - Key, - PlainScalar("key 2"), - Value, - PlainScalar("value 2"), - BlockEnd, - BlockEnd, - StreamEnd); - } - - [Fact] - public void VerifyTokensOnExample14() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForResource("14-mapping-wo-indent.yaml"), - StreamStart, - BlockMappingStart, - Key, - PlainScalar("key"), - Value, - BlockEntry, - PlainScalar("item 1"), - BlockEntry, - PlainScalar("item 2"), - BlockEnd, - StreamEnd); - } + [Fact] + public void VerifyTokensOnExample11() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForResource("11-mixed-nodes-in-mapping.yaml"), + StreamStart, + BlockMappingStart, + Key, + PlainScalar("a simple key"), + Value, + PlainScalar("a value"), + Key, + PlainScalar("a complex key"), + Value, + PlainScalar("another value"), + Key, + PlainScalar("a mapping"), + Value, + BlockMappingStart, + Key, + PlainScalar("key 1"), + Value, + PlainScalar("value 1"), + Key, + PlainScalar("key 2"), + Value, + PlainScalar("value 2"), + BlockEnd, + Key, + PlainScalar("a sequence"), + Value, + BlockSequenceStart, + BlockEntry, + PlainScalar("item 1"), + BlockEntry, + PlainScalar("item 2"), + BlockEnd, + BlockEnd, + StreamEnd); + } + + [Fact] + public void VerifyTokensOnExample12() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForResource("12-compact-sequence.yaml"), + StreamStart, + BlockSequenceStart, + BlockEntry, + BlockSequenceStart, + BlockEntry, + PlainScalar("item 1"), + BlockEntry, + PlainScalar("item 2"), + BlockEnd, + BlockEntry, + BlockMappingStart, + Key, + PlainScalar("key 1"), + Value, + PlainScalar("value 1"), + Key, + PlainScalar("key 2"), + Value, + PlainScalar("value 2"), + BlockEnd, + BlockEntry, + BlockMappingStart, + Key, + PlainScalar("complex key"), + Value, + PlainScalar("complex value"), + BlockEnd, + BlockEnd, + StreamEnd); + } + + [Fact] + public void VerifyTokensOnExample13() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForResource("13-compact-mapping.yaml"), + StreamStart, + BlockMappingStart, + Key, + PlainScalar("a sequence"), + Value, + BlockSequenceStart, + BlockEntry, + PlainScalar("item 1"), + BlockEntry, + PlainScalar("item 2"), + BlockEnd, + Key, + PlainScalar("a mapping"), + Value, + BlockMappingStart, + Key, + PlainScalar("key 1"), + Value, + PlainScalar("value 1"), + Key, + PlainScalar("key 2"), + Value, + PlainScalar("value 2"), + BlockEnd, + BlockEnd, + StreamEnd); + } + + [Fact] + public void VerifyTokensOnExample14() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForResource("14-mapping-wo-indent.yaml"), + StreamStart, + BlockMappingStart, + Key, + PlainScalar("key"), + Value, + BlockEntry, + PlainScalar("item 1"), + BlockEntry, + PlainScalar("item 2"), + BlockEnd, + StreamEnd); + } - [Fact] - public void CommentsAreReturnedWhenRequested() - { - AssertSequenceOfTokensFrom(new Scanner(Yaml.ReaderForText(@" - # Top comment - - first # Comment on first item - - second - # Bottom comment - "), skipComments: false), - StreamStart, - StandaloneComment("Top comment"), - BlockSequenceStart, - BlockEntry, - PlainScalar("first"), - InlineComment("Comment on first item"), - BlockEntry, - PlainScalar("second"), - StandaloneComment("Bottom comment"), - BlockEnd, - StreamEnd); - } + [Fact] + public void CommentsAreReturnedWhenRequested() + { + AssertSequenceOfTokensFrom(new Scanner(Yaml.ReaderForText(@" + # Top comment + - first # Comment on first item + - second + # Bottom comment + "), skipComments: false), + StreamStart, + StandaloneComment("Top comment"), + BlockSequenceStart, + BlockEntry, + PlainScalar("first"), + InlineComment("Comment on first item"), + BlockEntry, + PlainScalar("second"), + StandaloneComment("Bottom comment"), + BlockEnd, + StreamEnd); + } - [Fact] - public void CommentsAreCorrectlyMarked() - { - var sut = new Scanner(Yaml.ReaderForText(@" - - first # Comment on first item - "), skipComments: false); + [Fact] + public void CommentsAreCorrectlyMarked() + { + var sut = new Scanner(Yaml.ReaderForText(@" + - first # Comment on first item + "), skipComments: false); - while(sut.MoveNext()) - { - var comment = sut.Current as Comment; - if(comment != null) - { - Assert.Equal(8, comment.Start.Index); - Assert.Equal(31, comment.End.Index); + while(sut.MoveNext()) + { + var comment = sut.Current as Comment; + if(comment != null) + { + Assert.Equal(8, comment.Start.Index); + Assert.Equal(31, comment.End.Index); - return; - } - } + return; + } + } - Assert.True(false, "Did not find a comment"); - } + Assert.True(false, "Did not find a comment"); + } - [Fact] - public void CommentsAreOmittedUnlessRequested() - { - AssertSequenceOfTokensFrom(Yaml.ScannerForText(@" - # Top comment - - first # Comment on first item - - second - # Bottom comment - "), - StreamStart, - BlockSequenceStart, - BlockEntry, - PlainScalar("first"), - BlockEntry, - PlainScalar("second"), - BlockEnd, - StreamEnd); - } + [Fact] + public void CommentsAreOmittedUnlessRequested() + { + AssertSequenceOfTokensFrom(Yaml.ScannerForText(@" + # Top comment + - first # Comment on first item + - second + # Bottom comment + "), + StreamStart, + BlockSequenceStart, + BlockEntry, + PlainScalar("first"), + BlockEntry, + PlainScalar("second"), + BlockEnd, + StreamEnd); + } #if !PORTABLE - [Fact] - public void ScannerIsSerializable() - { - var sut = Yaml.ScannerForText(@" - - one - - two - - three - "); + [Fact] + public void ScannerIsSerializable() + { + var sut = Yaml.ScannerForText(@" + - one + - two + - three + "); - AssertPartialSequenceOfTokensFrom(sut, - StreamStart, - BlockSequenceStart, - BlockEntry, - PlainScalar("one"), - BlockEntry, - PlainScalar("two")); + AssertPartialSequenceOfTokensFrom(sut, + StreamStart, + BlockSequenceStart, + BlockEntry, + PlainScalar("one"), + BlockEntry, + PlainScalar("two")); - var buffer = new MemoryStream(); - var formatter = new BinaryFormatter(); - formatter.Serialize(buffer, sut); + var buffer = new MemoryStream(); + var formatter = new BinaryFormatter(); + formatter.Serialize(buffer, sut); - AssertSequenceOfTokensFrom(sut, - BlockEntry, - PlainScalar("three"), - BlockEnd, - StreamEnd); + AssertSequenceOfTokensFrom(sut, + BlockEntry, + PlainScalar("three"), + BlockEnd, + StreamEnd); - buffer.Position = 0; - sut = (Scanner)formatter.Deserialize(buffer); + buffer.Position = 0; + sut = (Scanner)formatter.Deserialize(buffer); - AssertSequenceOfTokensFrom(sut, - BlockEntry, - PlainScalar("three"), - BlockEnd, - StreamEnd); - } + AssertSequenceOfTokensFrom(sut, + BlockEntry, + PlainScalar("three"), + BlockEnd, + StreamEnd); + } #endif - [Fact] - public void MarksOnDoubleQuotedScalarsAreCorrect() - { - var scanner = Yaml.ScannerForText(@" - ""x"" - "); + [Fact] + public void MarksOnDoubleQuotedScalarsAreCorrect() + { + var scanner = Yaml.ScannerForText(@" + ""x"" + "); - Scalar scalar = null; - while (scanner.MoveNext() && scalar == null) - { - scalar = scanner.Current as Scalar; - } - Assert.Equal(4, scalar.End.Column); - } + Scalar scalar = null; + while (scanner.MoveNext() && scalar == null) + { + scalar = scanner.Current as Scalar; + } + Assert.Equal(4, scalar.End.Column); + } - private void AssertPartialSequenceOfTokensFrom(Scanner scanner, params Token[] tokens) - { - var tokenNumber = 1; - foreach (var expected in tokens) - { - scanner.MoveNext().Should().BeTrue("Missing token number {0}", tokenNumber); - AssertToken(expected, scanner.Current, tokenNumber); - tokenNumber++; - } - } + private void AssertPartialSequenceOfTokensFrom(Scanner scanner, params Token[] tokens) + { + var tokenNumber = 1; + foreach (var expected in tokens) + { + scanner.MoveNext().Should().BeTrue("Missing token number {0}", tokenNumber); + AssertToken(expected, scanner.Current, tokenNumber); + tokenNumber++; + } + } - private void AssertSequenceOfTokensFrom(Scanner scanner, params Token[] tokens) - { - AssertPartialSequenceOfTokensFrom(scanner, tokens); - scanner.MoveNext().Should().BeFalse("Found extra tokens"); - } + private void AssertSequenceOfTokensFrom(Scanner scanner, params Token[] tokens) + { + AssertPartialSequenceOfTokensFrom(scanner, tokens); + scanner.MoveNext().Should().BeFalse("Found extra tokens"); + } - private void AssertToken(Token expected, Token actual, int tokenNumber) - { - Dump.WriteLine(expected.GetType().Name); - actual.Should().NotBeNull(); - actual.GetType().Should().Be(expected.GetType(), "Token {0} is not of the expected type", tokenNumber); + private void AssertToken(Token expected, Token actual, int tokenNumber) + { + Dump.WriteLine(expected.GetType().Name); + actual.Should().NotBeNull(); + actual.GetType().Should().Be(expected.GetType(), "Token {0} is not of the expected type", tokenNumber); - foreach (var property in expected.GetType().GetProperties()) - { - if (property.PropertyType != typeof(Mark) && property.CanRead) - { - var value = property.GetValue(actual, null); - var expectedValue = property.GetValue(expected, null); - Dump.WriteLine("\t{0} = {1}", property.Name, value); - value.Should().Be(expectedValue, "Comparing property {0} in token {1}", property.Name, tokenNumber); - } - } - } - } + foreach (var property in expected.GetType().GetProperties()) + { + if (property.PropertyType != typeof(Mark) && property.CanRead) + { + var value = property.GetValue(actual, null); + var expectedValue = property.GetValue(expected, null); + Dump.WriteLine("\t{0} = {1}", property.Name, value); + value.Should().Be(expectedValue, "Comparing property {0} in token {1}", property.Name, tokenNumber); + } + } + } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/Core/TokenHelper.cs b/YamlDotNet.Test/Core/TokenHelper.cs index 1f807300e..8b0560e3d 100644 --- a/YamlDotNet.Test/Core/TokenHelper.cs +++ b/YamlDotNet.Test/Core/TokenHelper.cs @@ -24,142 +24,142 @@ namespace YamlDotNet.Test.Core { - public class TokenHelper - { - protected static StreamStart StreamStart - { - get { return new StreamStart(); } - } - - protected static StreamEnd StreamEnd - { - get { return new StreamEnd(); } - } - - protected static DocumentStart DocumentStart - { - get { return new DocumentStart(); } - } - - protected static DocumentEnd DocumentEnd - { - get { return new DocumentEnd(); } - } - - protected static VersionDirective VersionDirective(int major, int minor) - { - return new VersionDirective(new Version(major, minor)); - } - - protected static TagDirective TagDirective(string handle, string prefix) - { - return new TagDirective(handle, prefix); - } - - protected static Tag Tag(string handle, string suffix) - { - return new Tag(handle, suffix); - } - - protected static Scalar PlainScalar(string text) - { - return new Scalar(text, ScalarStyle.Plain); - } - - protected static Scalar SingleQuotedScalar(string text) - { - return new Scalar(text, ScalarStyle.SingleQuoted); - } - - protected static Scalar DoubleQuotedScalar(string text) - { - return new Scalar(text, ScalarStyle.DoubleQuoted); - } - - protected static Scalar LiteralScalar(string text) - { - return new Scalar(text, ScalarStyle.Literal); - } - - protected static Scalar FoldedScalar(string text) - { - return new Scalar(text, ScalarStyle.Folded); - } - - protected static FlowSequenceStart FlowSequenceStart - { - get { return new FlowSequenceStart(); } - } - - protected static FlowSequenceEnd FlowSequenceEnd - { - get { return new FlowSequenceEnd(); } - } - - protected static BlockSequenceStart BlockSequenceStart - { - get { return new BlockSequenceStart(); } - } - - protected static FlowMappingStart FlowMappingStart - { - get { return new FlowMappingStart(); } - } - - protected static FlowMappingEnd FlowMappingEnd - { - get { return new FlowMappingEnd(); } - } - - protected static BlockMappingStart BlockMappingStart - { - get { return new BlockMappingStart(); } - } - - protected static Key Key - { - get { return new Key(); } - } - - protected static Value Value - { - get { return new Value(); } - } - - protected static FlowEntry FlowEntry - { - get { return new FlowEntry(); } - } - - protected static BlockEntry BlockEntry - { - get { return new BlockEntry(); } - } - - protected static BlockEnd BlockEnd - { - get { return new BlockEnd(); } - } - - protected static Anchor Anchor(string anchor) - { - return new Anchor(anchor); - } - - protected static AnchorAlias AnchorAlias(string alias) - { - return new AnchorAlias(alias); - } - - protected static Comment StandaloneComment(string text) - { - return new Comment(text, false); - } - - - protected static Comment InlineComment(string text) - { - return new Comment(text, true); - } - } + public class TokenHelper + { + protected static StreamStart StreamStart + { + get { return new StreamStart(); } + } + + protected static StreamEnd StreamEnd + { + get { return new StreamEnd(); } + } + + protected static DocumentStart DocumentStart + { + get { return new DocumentStart(); } + } + + protected static DocumentEnd DocumentEnd + { + get { return new DocumentEnd(); } + } + + protected static VersionDirective VersionDirective(int major, int minor) + { + return new VersionDirective(new Version(major, minor)); + } + + protected static TagDirective TagDirective(string handle, string prefix) + { + return new TagDirective(handle, prefix); + } + + protected static Tag Tag(string handle, string suffix) + { + return new Tag(handle, suffix); + } + + protected static Scalar PlainScalar(string text) + { + return new Scalar(text, ScalarStyle.Plain); + } + + protected static Scalar SingleQuotedScalar(string text) + { + return new Scalar(text, ScalarStyle.SingleQuoted); + } + + protected static Scalar DoubleQuotedScalar(string text) + { + return new Scalar(text, ScalarStyle.DoubleQuoted); + } + + protected static Scalar LiteralScalar(string text) + { + return new Scalar(text, ScalarStyle.Literal); + } + + protected static Scalar FoldedScalar(string text) + { + return new Scalar(text, ScalarStyle.Folded); + } + + protected static FlowSequenceStart FlowSequenceStart + { + get { return new FlowSequenceStart(); } + } + + protected static FlowSequenceEnd FlowSequenceEnd + { + get { return new FlowSequenceEnd(); } + } + + protected static BlockSequenceStart BlockSequenceStart + { + get { return new BlockSequenceStart(); } + } + + protected static FlowMappingStart FlowMappingStart + { + get { return new FlowMappingStart(); } + } + + protected static FlowMappingEnd FlowMappingEnd + { + get { return new FlowMappingEnd(); } + } + + protected static BlockMappingStart BlockMappingStart + { + get { return new BlockMappingStart(); } + } + + protected static Key Key + { + get { return new Key(); } + } + + protected static Value Value + { + get { return new Value(); } + } + + protected static FlowEntry FlowEntry + { + get { return new FlowEntry(); } + } + + protected static BlockEntry BlockEntry + { + get { return new BlockEntry(); } + } + + protected static BlockEnd BlockEnd + { + get { return new BlockEnd(); } + } + + protected static Anchor Anchor(string anchor) + { + return new Anchor(anchor); + } + + protected static AnchorAlias AnchorAlias(string alias) + { + return new AnchorAlias(alias); + } + + protected static Comment StandaloneComment(string text) + { + return new Comment(text, false); + } + + + protected static Comment InlineComment(string text) + { + return new Comment(text, true); + } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/Dump.cs b/YamlDotNet.Test/Dump.cs index 762801d06..7596004c6 100644 --- a/YamlDotNet.Test/Dump.cs +++ b/YamlDotNet.Test/Dump.cs @@ -23,42 +23,42 @@ namespace YamlDotNet.Test { - public class Dump - { - [Conditional("TEST_DUMP")] - public static void Write(object value) - { - Debug.Write(value); - } + public class Dump + { + [Conditional("TEST_DUMP")] + public static void Write(object value) + { + Debug.Write(value); + } - [Conditional("TEST_DUMP")] - public static void Write(string format, params object[] args) - { - Debug.Write(string.Format(format, args)); - } + [Conditional("TEST_DUMP")] + public static void Write(string format, params object[] args) + { + Debug.Write(string.Format(format, args)); + } - [Conditional("TEST_DUMP")] - public static void WriteLine() - { - Debug.WriteLine(string.Empty); - } + [Conditional("TEST_DUMP")] + public static void WriteLine() + { + Debug.WriteLine(string.Empty); + } - [Conditional("TEST_DUMP")] - public static void WriteLine(string value) - { - WriteLine((object)value); - } + [Conditional("TEST_DUMP")] + public static void WriteLine(string value) + { + WriteLine((object)value); + } - [Conditional("TEST_DUMP")] - public static void WriteLine(object value) - { - WriteLine("{0}", value); - } + [Conditional("TEST_DUMP")] + public static void WriteLine(object value) + { + WriteLine("{0}", value); + } - [Conditional("TEST_DUMP")] - public static void WriteLine(string format, params object[] args) - { - Debug.WriteLine(format, args); - } - } + [Conditional("TEST_DUMP")] + public static void WriteLine(string format, params object[] args) + { + Debug.WriteLine(format, args); + } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/EnumerableExtensions.cs b/YamlDotNet.Test/EnumerableExtensions.cs index 4046a85a4..a39f5a782 100644 --- a/YamlDotNet.Test/EnumerableExtensions.cs +++ b/YamlDotNet.Test/EnumerableExtensions.cs @@ -24,23 +24,23 @@ namespace YamlDotNet.Test { - public static class EnumerableExtensions - { - public static IEnumerable Do(this IEnumerable source, Action action) - { - foreach (var item in source) - { - action(item); - yield return item; - } - } + public static class EnumerableExtensions + { + public static IEnumerable Do(this IEnumerable source, Action action) + { + foreach (var item in source) + { + action(item); + yield return item; + } + } - public static void Run(this IEnumerable source, Action action) - { - foreach (var element in source) - { - action(element); - } - } - } + public static void Run(this IEnumerable source, Action action) + { + foreach (var element in source) + { + action(element); + } + } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/RepresentationModel/BinarySerlializationTests.cs b/YamlDotNet.Test/RepresentationModel/BinarySerlializationTests.cs index 227ecc740..992d005b0 100644 --- a/YamlDotNet.Test/RepresentationModel/BinarySerlializationTests.cs +++ b/YamlDotNet.Test/RepresentationModel/BinarySerlializationTests.cs @@ -28,26 +28,26 @@ namespace YamlDotNet.Test.RepresentationModel { - using System.Runtime.Serialization.Formatters.Binary; + using System.Runtime.Serialization.Formatters.Binary; #if !PORTABLE - public class BinarySerlializationTests - { - [Fact] - public void YamlNodeGraphsAreBinarySerializeable() - { - var stream = new YamlStream(); - stream.Load(Yaml.StreamFrom("fail-backreference.yaml")); - - - var formatter = new BinaryFormatter(); - var memoryStream = new MemoryStream(); - formatter.Serialize(memoryStream, stream.Documents[0].RootNode); - - memoryStream.Position = 0; - YamlNode result = (YamlNode)formatter.Deserialize(memoryStream); - Assert.Equal(stream.Documents[0].RootNode, result); - } - } + public class BinarySerlializationTests + { + [Fact] + public void YamlNodeGraphsAreBinarySerializeable() + { + var stream = new YamlStream(); + stream.Load(Yaml.StreamFrom("fail-backreference.yaml")); + + + var formatter = new BinaryFormatter(); + var memoryStream = new MemoryStream(); + formatter.Serialize(memoryStream, stream.Documents[0].RootNode); + + memoryStream.Position = 0; + YamlNode result = (YamlNode)formatter.Deserialize(memoryStream); + Assert.Equal(stream.Documents[0].RootNode, result); + } + } #endif } diff --git a/YamlDotNet.Test/RepresentationModel/YamlStreamTests.cs b/YamlDotNet.Test/RepresentationModel/YamlStreamTests.cs index f452965ef..db6fe5fff 100644 --- a/YamlDotNet.Test/RepresentationModel/YamlStreamTests.cs +++ b/YamlDotNet.Test/RepresentationModel/YamlStreamTests.cs @@ -28,247 +28,247 @@ namespace YamlDotNet.Test.RepresentationModel { - public class YamlStreamTests - { - [Fact] - public void LoadSimpleDocument() { - var stream = new YamlStream(); - stream.Load(Yaml.StreamFrom("02-scalar-in-imp-doc.yaml")); - - Assert.Equal(1, stream.Documents.Count); - Assert.IsType(stream.Documents[0].RootNode); - Assert.Equal("a scalar", ((YamlScalarNode)stream.Documents[0].RootNode).Value); - } - - [Fact] - public void BackwardAliasReferenceWorks() { - var stream = new YamlStream(); - stream.Load(Yaml.StreamFrom("backwards-alias.yaml")); - - Assert.Equal(1, stream.Documents.Count); - Assert.IsType(stream.Documents[0].RootNode); - - var sequence = (YamlSequenceNode)stream.Documents[0].RootNode; - Assert.Equal(3, sequence.Children.Count); - - Assert.Equal("a scalar", ((YamlScalarNode)sequence.Children[0]).Value); - Assert.Equal("another scalar", ((YamlScalarNode)sequence.Children[1]).Value); - Assert.Equal("a scalar", ((YamlScalarNode)sequence.Children[2]).Value); - Assert.Same(sequence.Children[0], sequence.Children[2]); - } - - [Fact] - public void ForwardAliasReferenceWorks() { - var stream = new YamlStream(); - stream.Load(Yaml.StreamFrom("forward-alias.yaml")); - - Assert.Equal(1, stream.Documents.Count); - Assert.IsType(stream.Documents[0].RootNode); - - var sequence = (YamlSequenceNode)stream.Documents[0].RootNode; - Assert.Equal(3, sequence.Children.Count); - - Assert.Equal("a scalar", ((YamlScalarNode)sequence.Children[0]).Value); - Assert.Equal("another scalar", ((YamlScalarNode)sequence.Children[1]).Value); - Assert.Equal("a scalar", ((YamlScalarNode)sequence.Children[2]).Value); - Assert.Same(sequence.Children[0], sequence.Children[2]); - } - - [Fact] - public void RoundtripExample1() - { - RoundtripTest("01-directives.yaml"); - } - - [Fact] - public void RoundtripExample2() - { - RoundtripTest("02-scalar-in-imp-doc.yaml"); - } - - [Fact] - public void RoundtripExample3() - { - RoundtripTest("03-scalar-in-exp-doc.yaml"); - } - - [Fact] - public void RoundtripExample4() - { - RoundtripTest("04-scalars-in-multi-docs.yaml"); - } - - [Fact] - public void RoundtripExample5() - { - RoundtripTest("06-float-tag.yaml"); - } - - [Fact] - public void RoundtripExample6() - { - RoundtripTest("06-float-tag.yaml"); - } - - [Fact] - public void RoundtripExample7() - { - RoundtripTest("07-scalar-styles.yaml"); - } - - [Fact] - public void RoundtripExample8() - { - RoundtripTest("08-flow-sequence.yaml"); - } - - [Fact] - public void RoundtripExample9() - { - RoundtripTest("09-flow-mapping.yaml"); - } - - [Fact] - public void RoundtripExample10() - { - RoundtripTest("10-mixed-nodes-in-sequence.yaml"); - } - - [Fact] - public void RoundtripExample11() - { - RoundtripTest("11-mixed-nodes-in-mapping.yaml"); - } - - [Fact] - public void RoundtripExample12() - { - RoundtripTest("12-compact-sequence.yaml"); - } - - [Fact] - public void RoundtripExample13() - { - RoundtripTest("13-compact-mapping.yaml"); - } - - [Fact] - public void RoundtripExample14() - { - RoundtripTest("14-mapping-wo-indent.yaml"); - } - - [Fact] - public void RoundtripBackreference() - { - RoundtripTest("backreference.yaml"); - } - - [Fact] - public void FailBackreference() - { - RoundtripTest("fail-backreference.yaml"); - } - - [Fact] - public void AllAliasesMustBeResolved() - { - var original = new YamlStream(); - Assert.Throws(() => original.Load(Yaml.StreamFrom("invalid-reference.yaml"))); - } - - private void RoundtripTest(string yamlFileName) - { - var original = new YamlStream(); - original.Load(Yaml.StreamFrom(yamlFileName)); - - var buffer = new StringBuilder(); - original.Save(new StringWriter(buffer)); - - Dump.WriteLine(buffer); - - var final = new YamlStream(); - final.Load(new StringReader(buffer.ToString())); - - var originalBuilder = new YamlDocumentStructureBuilder(); - original.Accept(originalBuilder); - - var finalBuilder = new YamlDocumentStructureBuilder(); - final.Accept(finalBuilder); - - Dump.WriteLine("The original document produced {0} events.", originalBuilder.Events.Count); - Dump.WriteLine("The final document produced {0} events.", finalBuilder.Events.Count); - Assert.Equal(originalBuilder.Events.Count, finalBuilder.Events.Count); - - for (var i = 0; i < originalBuilder.Events.Count; ++i) - { - var originalEvent = originalBuilder.Events[i]; - var finalEvent = finalBuilder.Events[i]; - - Assert.Equal(originalEvent.Type, finalEvent.Type); - Assert.Equal(originalEvent.Value, finalEvent.Value); - } - } - - private class YamlDocumentStructureBuilder : YamlVisitor - { - private readonly List events = new List(); - - public IList Events - { - get { - return events; - } - } - - protected override void Visit(YamlScalarNode scalar) - { - events.Add(new YamlNodeEvent(YamlNodeEventType.Scalar, scalar.Anchor, scalar.Tag, scalar.Value)); - } - - protected override void Visit(YamlSequenceNode sequence) - { - events.Add(new YamlNodeEvent(YamlNodeEventType.SequenceStart, sequence.Anchor, sequence.Tag, null)); - } - - protected override void Visited(YamlSequenceNode sequence) - { - events.Add(new YamlNodeEvent(YamlNodeEventType.SequenceEnd, sequence.Anchor, sequence.Tag, null)); - } - - protected override void Visit(YamlMappingNode mapping) - { - events.Add(new YamlNodeEvent(YamlNodeEventType.MappingStart, mapping.Anchor, mapping.Tag, null)); - } - - protected override void Visited(YamlMappingNode mapping) - { - events.Add(new YamlNodeEvent(YamlNodeEventType.MappingEnd, mapping.Anchor, mapping.Tag, null)); - } - } - - private class YamlNodeEvent - { - public YamlNodeEventType Type { get; private set; } - public string Anchor { get; private set; } - public string Tag { get; private set; } - public string Value { get; private set; } - - public YamlNodeEvent(YamlNodeEventType type, string anchor, string tag, string value) { - Type = type; - Anchor = anchor; - Tag = tag; - Value = value; - } - } - - private enum YamlNodeEventType - { - SequenceStart, - SequenceEnd, - MappingStart, - MappingEnd, - Scalar, - } - } + public class YamlStreamTests + { + [Fact] + public void LoadSimpleDocument() { + var stream = new YamlStream(); + stream.Load(Yaml.StreamFrom("02-scalar-in-imp-doc.yaml")); + + Assert.Equal(1, stream.Documents.Count); + Assert.IsType(stream.Documents[0].RootNode); + Assert.Equal("a scalar", ((YamlScalarNode)stream.Documents[0].RootNode).Value); + } + + [Fact] + public void BackwardAliasReferenceWorks() { + var stream = new YamlStream(); + stream.Load(Yaml.StreamFrom("backwards-alias.yaml")); + + Assert.Equal(1, stream.Documents.Count); + Assert.IsType(stream.Documents[0].RootNode); + + var sequence = (YamlSequenceNode)stream.Documents[0].RootNode; + Assert.Equal(3, sequence.Children.Count); + + Assert.Equal("a scalar", ((YamlScalarNode)sequence.Children[0]).Value); + Assert.Equal("another scalar", ((YamlScalarNode)sequence.Children[1]).Value); + Assert.Equal("a scalar", ((YamlScalarNode)sequence.Children[2]).Value); + Assert.Same(sequence.Children[0], sequence.Children[2]); + } + + [Fact] + public void ForwardAliasReferenceWorks() { + var stream = new YamlStream(); + stream.Load(Yaml.StreamFrom("forward-alias.yaml")); + + Assert.Equal(1, stream.Documents.Count); + Assert.IsType(stream.Documents[0].RootNode); + + var sequence = (YamlSequenceNode)stream.Documents[0].RootNode; + Assert.Equal(3, sequence.Children.Count); + + Assert.Equal("a scalar", ((YamlScalarNode)sequence.Children[0]).Value); + Assert.Equal("another scalar", ((YamlScalarNode)sequence.Children[1]).Value); + Assert.Equal("a scalar", ((YamlScalarNode)sequence.Children[2]).Value); + Assert.Same(sequence.Children[0], sequence.Children[2]); + } + + [Fact] + public void RoundtripExample1() + { + RoundtripTest("01-directives.yaml"); + } + + [Fact] + public void RoundtripExample2() + { + RoundtripTest("02-scalar-in-imp-doc.yaml"); + } + + [Fact] + public void RoundtripExample3() + { + RoundtripTest("03-scalar-in-exp-doc.yaml"); + } + + [Fact] + public void RoundtripExample4() + { + RoundtripTest("04-scalars-in-multi-docs.yaml"); + } + + [Fact] + public void RoundtripExample5() + { + RoundtripTest("06-float-tag.yaml"); + } + + [Fact] + public void RoundtripExample6() + { + RoundtripTest("06-float-tag.yaml"); + } + + [Fact] + public void RoundtripExample7() + { + RoundtripTest("07-scalar-styles.yaml"); + } + + [Fact] + public void RoundtripExample8() + { + RoundtripTest("08-flow-sequence.yaml"); + } + + [Fact] + public void RoundtripExample9() + { + RoundtripTest("09-flow-mapping.yaml"); + } + + [Fact] + public void RoundtripExample10() + { + RoundtripTest("10-mixed-nodes-in-sequence.yaml"); + } + + [Fact] + public void RoundtripExample11() + { + RoundtripTest("11-mixed-nodes-in-mapping.yaml"); + } + + [Fact] + public void RoundtripExample12() + { + RoundtripTest("12-compact-sequence.yaml"); + } + + [Fact] + public void RoundtripExample13() + { + RoundtripTest("13-compact-mapping.yaml"); + } + + [Fact] + public void RoundtripExample14() + { + RoundtripTest("14-mapping-wo-indent.yaml"); + } + + [Fact] + public void RoundtripBackreference() + { + RoundtripTest("backreference.yaml"); + } + + [Fact] + public void FailBackreference() + { + RoundtripTest("fail-backreference.yaml"); + } + + [Fact] + public void AllAliasesMustBeResolved() + { + var original = new YamlStream(); + Assert.Throws(() => original.Load(Yaml.StreamFrom("invalid-reference.yaml"))); + } + + private void RoundtripTest(string yamlFileName) + { + var original = new YamlStream(); + original.Load(Yaml.StreamFrom(yamlFileName)); + + var buffer = new StringBuilder(); + original.Save(new StringWriter(buffer)); + + Dump.WriteLine(buffer); + + var final = new YamlStream(); + final.Load(new StringReader(buffer.ToString())); + + var originalBuilder = new YamlDocumentStructureBuilder(); + original.Accept(originalBuilder); + + var finalBuilder = new YamlDocumentStructureBuilder(); + final.Accept(finalBuilder); + + Dump.WriteLine("The original document produced {0} events.", originalBuilder.Events.Count); + Dump.WriteLine("The final document produced {0} events.", finalBuilder.Events.Count); + Assert.Equal(originalBuilder.Events.Count, finalBuilder.Events.Count); + + for (var i = 0; i < originalBuilder.Events.Count; ++i) + { + var originalEvent = originalBuilder.Events[i]; + var finalEvent = finalBuilder.Events[i]; + + Assert.Equal(originalEvent.Type, finalEvent.Type); + Assert.Equal(originalEvent.Value, finalEvent.Value); + } + } + + private class YamlDocumentStructureBuilder : YamlVisitor + { + private readonly List events = new List(); + + public IList Events + { + get { + return events; + } + } + + protected override void Visit(YamlScalarNode scalar) + { + events.Add(new YamlNodeEvent(YamlNodeEventType.Scalar, scalar.Anchor, scalar.Tag, scalar.Value)); + } + + protected override void Visit(YamlSequenceNode sequence) + { + events.Add(new YamlNodeEvent(YamlNodeEventType.SequenceStart, sequence.Anchor, sequence.Tag, null)); + } + + protected override void Visited(YamlSequenceNode sequence) + { + events.Add(new YamlNodeEvent(YamlNodeEventType.SequenceEnd, sequence.Anchor, sequence.Tag, null)); + } + + protected override void Visit(YamlMappingNode mapping) + { + events.Add(new YamlNodeEvent(YamlNodeEventType.MappingStart, mapping.Anchor, mapping.Tag, null)); + } + + protected override void Visited(YamlMappingNode mapping) + { + events.Add(new YamlNodeEvent(YamlNodeEventType.MappingEnd, mapping.Anchor, mapping.Tag, null)); + } + } + + private class YamlNodeEvent + { + public YamlNodeEventType Type { get; private set; } + public string Anchor { get; private set; } + public string Tag { get; private set; } + public string Value { get; private set; } + + public YamlNodeEvent(YamlNodeEventType type, string anchor, string tag, string value) { + Type = type; + Anchor = anchor; + Tag = tag; + Value = value; + } + } + + private enum YamlNodeEventType + { + SequenceStart, + SequenceEnd, + MappingStart, + MappingEnd, + Scalar, + } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/Serialization/CodeValidations.cs b/YamlDotNet.Test/Serialization/CodeValidations.cs index 1bbc1b303..901125254 100644 --- a/YamlDotNet.Test/Serialization/CodeValidations.cs +++ b/YamlDotNet.Test/Serialization/CodeValidations.cs @@ -6,21 +6,21 @@ namespace YamlDotNet.Test.Serialization { - public class CodeValidations - { - [Fact] - public void AllBuiltInConvertersAreRegistered() - { - var interfaceType = typeof(IYamlTypeConverter); - var converterTypes = interfaceType.Assembly - .GetTypes() - .Where(t => !t.IsInterface && interfaceType.IsAssignableFrom(t)); + public class CodeValidations + { + [Fact] + public void AllBuiltInConvertersAreRegistered() + { + var interfaceType = typeof(IYamlTypeConverter); + var converterTypes = interfaceType.Assembly + .GetTypes() + .Where(t => !t.IsInterface && interfaceType.IsAssignableFrom(t)); - var unregisteredTypes = converterTypes - .Where(t => !YamlTypeConverters.BuiltInConverters.Any(c => c.GetType() == t)) - .ToArray(); + var unregisteredTypes = converterTypes + .Where(t => !YamlTypeConverters.BuiltInConverters.Any(c => c.GetType() == t)) + .ToArray(); - Assert.Equal(new Type[0], unregisteredTypes); - } - } + Assert.Equal(new Type[0], unregisteredTypes); + } + } } diff --git a/YamlDotNet.Test/Serialization/NamingConventionTests.cs b/YamlDotNet.Test/Serialization/NamingConventionTests.cs index ad9485358..eff214ea2 100644 --- a/YamlDotNet.Test/Serialization/NamingConventionTests.cs +++ b/YamlDotNet.Test/Serialization/NamingConventionTests.cs @@ -26,49 +26,49 @@ namespace YamlDotNet.Test.Serialization { - public class NamingConventionTests - { - [Theory] - [InlineData("test", "test")] - [InlineData("thisIsATest", "this-is-a-test")] - [InlineData("thisIsATest", "this_is_a_test")] - [InlineData("thisIsATest", "ThisIsATest")] - public void AppliesCamelCaseConvention(string expectedName, string input) - { - ShouldApplyConventionGiven(input, expectedName, new CamelCaseNamingConvention()); - } + public class NamingConventionTests + { + [Theory] + [InlineData("test", "test")] + [InlineData("thisIsATest", "this-is-a-test")] + [InlineData("thisIsATest", "this_is_a_test")] + [InlineData("thisIsATest", "ThisIsATest")] + public void AppliesCamelCaseConvention(string expectedName, string input) + { + ShouldApplyConventionGiven(input, expectedName, new CamelCaseNamingConvention()); + } - [Theory] - [InlineData("Test", "test")] - [InlineData("ThisIsATest", "this-is-a-test")] - [InlineData("ThisIsATest", "this_is_a_test")] - [InlineData("ThisIsATest", "thisIsATest")] - public void AppliesPascalCaseConvention(string expectedName, string input) - { - ShouldApplyConventionGiven(input, expectedName, new PascalCaseNamingConvention()); - } + [Theory] + [InlineData("Test", "test")] + [InlineData("ThisIsATest", "this-is-a-test")] + [InlineData("ThisIsATest", "this_is_a_test")] + [InlineData("ThisIsATest", "thisIsATest")] + public void AppliesPascalCaseConvention(string expectedName, string input) + { + ShouldApplyConventionGiven(input, expectedName, new PascalCaseNamingConvention()); + } - [Theory] - [InlineData("test", "test")] - [InlineData("this-is-a-test", "thisIsATest")] - [InlineData("this-is-a-test", "this-is-a-test")] - public void AppliesHyphenatedConvention(string expectedName, string input) - { - ShouldApplyConventionGiven(input, expectedName, new HyphenatedNamingConvention()); - } + [Theory] + [InlineData("test", "test")] + [InlineData("this-is-a-test", "thisIsATest")] + [InlineData("this-is-a-test", "this-is-a-test")] + public void AppliesHyphenatedConvention(string expectedName, string input) + { + ShouldApplyConventionGiven(input, expectedName, new HyphenatedNamingConvention()); + } - [Theory] - [InlineData("test", "test")] - [InlineData("this_is_a_test", "thisIsATest")] - [InlineData("this_is_a_test", "this-is-a-test")] - public void AppliesUnderscoredConvention(string expectedName, string input) - { - ShouldApplyConventionGiven(input, expectedName, new UnderscoredNamingConvention()); - } + [Theory] + [InlineData("test", "test")] + [InlineData("this_is_a_test", "thisIsATest")] + [InlineData("this_is_a_test", "this-is-a-test")] + public void AppliesUnderscoredConvention(string expectedName, string input) + { + ShouldApplyConventionGiven(input, expectedName, new UnderscoredNamingConvention()); + } - private void ShouldApplyConventionGiven(string input, string expectedName, INamingConvention convention) - { - convention.Apply(input).Should().Be(expectedName); - } - } + private void ShouldApplyConventionGiven(string input, string expectedName, INamingConvention convention) + { + convention.Apply(input).Should().Be(expectedName); + } + } } diff --git a/YamlDotNet.Test/Serialization/ObjectFactoryTests.cs b/YamlDotNet.Test/Serialization/ObjectFactoryTests.cs index 1631e8829..23b061fd2 100644 --- a/YamlDotNet.Test/Serialization/ObjectFactoryTests.cs +++ b/YamlDotNet.Test/Serialization/ObjectFactoryTests.cs @@ -25,29 +25,29 @@ namespace YamlDotNet.Test.Serialization { - public class ObjectFactoryTests : SerializationTestHelper - { - [Fact] - public void NotSpecifyingObjectFactoryUsesDefault() - { - var text = "!empty {}"; - - Deserializer.RegisterTagMapping("!empty", typeof(EmptyBase)); - var result = Deserializer.Deserialize(UsingReaderFor(text)); + public class ObjectFactoryTests : SerializationTestHelper + { + [Fact] + public void NotSpecifyingObjectFactoryUsesDefault() + { + var text = "!empty {}"; + + Deserializer.RegisterTagMapping("!empty", typeof(EmptyBase)); + var result = Deserializer.Deserialize(UsingReaderFor(text)); - result.Should().BeOfType(); - } + result.Should().BeOfType(); + } - [Fact] - public void ObjectFactoryIsInvoked() - { - AssumingDeserializerWith(new LambdaObjectFactory(t => new EmptyDerived())); - var text = "!empty {}"; + [Fact] + public void ObjectFactoryIsInvoked() + { + AssumingDeserializerWith(new LambdaObjectFactory(t => new EmptyDerived())); + var text = "!empty {}"; - Deserializer.RegisterTagMapping("!empty", typeof(EmptyBase)); - var result = Deserializer.Deserialize(UsingReaderFor(text)); + Deserializer.RegisterTagMapping("!empty", typeof(EmptyBase)); + var result = Deserializer.Deserialize(UsingReaderFor(text)); - result.Should().BeOfType(); - } - } + result.Should().BeOfType(); + } + } } diff --git a/YamlDotNet.Test/Serialization/SerializationTestHelper.cs b/YamlDotNet.Test/Serialization/SerializationTestHelper.cs index 0a0e03512..6fffead17 100644 --- a/YamlDotNet.Test/Serialization/SerializationTestHelper.cs +++ b/YamlDotNet.Test/Serialization/SerializationTestHelper.cs @@ -33,330 +33,330 @@ namespace YamlDotNet.Test.Serialization { - public class SerializationTestHelper - { - private Serializer serializer; - private Deserializer deserializer; - - protected T DoRoundtripFromObjectTo(object obj) - { - return DoRoundtripFromObjectTo(obj, Serializer); - } - - protected T DoRoundtripFromObjectTo(object obj, Serializer serializer) - { - return DoRoundtripFromObjectTo(obj, serializer, Deserializer); - } - - protected T DoRoundtripFromObjectTo(object obj, Serializer serializer, Deserializer deserializer) - { - var writer = new StringWriter(); - serializer.Serialize(writer, obj); - Dump.WriteLine(writer); - return deserializer.Deserialize(UsingReaderFor(writer)); - } - - protected T DoRoundtripOn(object obj) - { - return DoRoundtripOn(obj, Serializer); - } - - protected T DoRoundtripOn(object obj, Serializer serializer) - { - var writer = new StringWriter(); - serializer.Serialize(writer, obj, typeof(T)); - Dump.WriteLine(writer); - return new Deserializer().Deserialize(UsingReaderFor(writer)); - } - - protected Serializer Serializer - { - get { return CurrentOrNew(() => new Serializer()); } - } - - protected Serializer RoundtripSerializer - { - get { return CurrentOrNew(() => new Serializer(SerializationOptions.Roundtrip)); } - } - - protected Serializer EmitDefaultsSerializer - { - get { return CurrentOrNew(() => new Serializer(SerializationOptions.EmitDefaults)); } - } - - protected Serializer RoundtripEmitDefaultsSerializer - { - get { return CurrentOrNew(() => new Serializer(SerializationOptions.Roundtrip | SerializationOptions.EmitDefaults)); } - } - - protected Serializer EmitDefaultsJsonCompatibleSerializer - { - get { return CurrentOrNew(() => new Serializer(SerializationOptions.EmitDefaults | SerializationOptions.JsonCompatible)); } - } - - protected Serializer RoundtripEmitDefaultsJsonCompatibleSerializer - { - get { return CurrentOrNew(() => new Serializer(SerializationOptions.EmitDefaults | - SerializationOptions.JsonCompatible | - SerializationOptions.Roundtrip)); - } - } - - private Serializer CurrentOrNew(Func serializerFactory) - { - return serializer = serializer ?? serializerFactory(); - } - - protected Deserializer Deserializer - { - get { return deserializer = deserializer ?? new Deserializer(); } - } - - protected void AssumingDeserializerWith(IObjectFactory factory) - { - deserializer = new Deserializer(factory); - } - - protected TextReader UsingReaderFor(TextWriter buffer) - { - return UsingReaderFor(buffer.ToString()); - } - - protected TextReader UsingReaderFor(string text) - { - return new StringReader(text); - } - - protected static EventReader EventReaderFor(string yaml) - { - return new EventReader(new Parser(new StringReader(yaml))); - } - - protected string Lines(params string[] lines) - { - return string.Join(Environment.NewLine, lines); - } - - protected object Entry(string key, string value) - { - return new DictionaryEntry(key, value); - } - } - - // ReSharper disable InconsistentNaming - - [Flags] - public enum EnumExample - { - None, - One, - Two - } - - public class CircularReference - { - public CircularReference Child1 { get; set; } - public CircularReference Child2 { get; set; } - } - - [TypeConverter(typeof(ConvertibleConverter))] - public class Convertible : IConvertible - { - public string Left { get; set; } - public string Right { get; set; } - - public object ToType(Type conversionType, IFormatProvider provider) - { - conversionType.Should().Be(); - return ToString(provider); - } - - public string ToString(IFormatProvider provider) - { - provider.Should().Be(CultureInfo.InvariantCulture); - return string.Format(provider, "[{0}, {1}]", Left, Right); - } - - #region Unsupported Members - - public System.TypeCode GetTypeCode() - { - throw new NotSupportedException(); - } - - public bool ToBoolean(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - public byte ToByte(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - public char ToChar(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - public DateTime ToDateTime(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - public decimal ToDecimal(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - public double ToDouble(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - public short ToInt16(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - public int ToInt32(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - public long ToInt64(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - public sbyte ToSByte(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - public float ToSingle(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - public ushort ToUInt16(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - public uint ToUInt32(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - public ulong ToUInt64(IFormatProvider provider) - { - throw new NotSupportedException(); - } - - #endregion - } - - public class ConvertibleConverter : 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) - { - if (!(value is string)) - throw new InvalidOperationException(); - var parts = (value as string).Split(' '); - return new Convertible { - Left = parts[0], - Right = parts[1] - }; - } - } - - public class MissingDefaultCtor - { - public string Value; - - public MissingDefaultCtor(string value) - { - Value = value; - } - } - - public class MissingDefaultCtorConverter : IYamlTypeConverter - { - public bool Accepts(Type type) - { - return type == typeof(MissingDefaultCtor); - } - - public object ReadYaml(IParser parser, Type type) - { - var value = ((Scalar) parser.Current).Value; - parser.MoveNext(); - return new MissingDefaultCtor(value); - } - - public void WriteYaml(IEmitter emitter, object value, Type type) - { - emitter.Emit(new Scalar(((MissingDefaultCtor) value).Value)); - } - } - - public class InheritanceExample - { - public object SomeScalar { get; set; } - public Base RegularBase { get; set; } - - [YamlMember(serializeAs: typeof(Base))] - public Base BaseWithSerializeAs { get; set; } - } - - public class InterfaceExample - { - public IDerived Derived { get; set; } - } - - public interface IBase - { - string BaseProperty { get; set; } - } - - public interface IDerived : IBase - { - string DerivedProperty { get; set; } - } - - public class Base : IBase - { - public string BaseProperty { get; set; } - } - - public class Derived : Base, IDerived - { - public string DerivedProperty { get; set; } - } - - public class EmptyBase - { - } - - public class EmptyDerived : EmptyBase - { - } - - public class Simple - { - public string aaa { get; set; } - } + public class SerializationTestHelper + { + private Serializer serializer; + private Deserializer deserializer; + + protected T DoRoundtripFromObjectTo(object obj) + { + return DoRoundtripFromObjectTo(obj, Serializer); + } + + protected T DoRoundtripFromObjectTo(object obj, Serializer serializer) + { + return DoRoundtripFromObjectTo(obj, serializer, Deserializer); + } + + protected T DoRoundtripFromObjectTo(object obj, Serializer serializer, Deserializer deserializer) + { + var writer = new StringWriter(); + serializer.Serialize(writer, obj); + Dump.WriteLine(writer); + return deserializer.Deserialize(UsingReaderFor(writer)); + } + + protected T DoRoundtripOn(object obj) + { + return DoRoundtripOn(obj, Serializer); + } + + protected T DoRoundtripOn(object obj, Serializer serializer) + { + var writer = new StringWriter(); + serializer.Serialize(writer, obj, typeof(T)); + Dump.WriteLine(writer); + return new Deserializer().Deserialize(UsingReaderFor(writer)); + } + + protected Serializer Serializer + { + get { return CurrentOrNew(() => new Serializer()); } + } + + protected Serializer RoundtripSerializer + { + get { return CurrentOrNew(() => new Serializer(SerializationOptions.Roundtrip)); } + } + + protected Serializer EmitDefaultsSerializer + { + get { return CurrentOrNew(() => new Serializer(SerializationOptions.EmitDefaults)); } + } + + protected Serializer RoundtripEmitDefaultsSerializer + { + get { return CurrentOrNew(() => new Serializer(SerializationOptions.Roundtrip | SerializationOptions.EmitDefaults)); } + } + + protected Serializer EmitDefaultsJsonCompatibleSerializer + { + get { return CurrentOrNew(() => new Serializer(SerializationOptions.EmitDefaults | SerializationOptions.JsonCompatible)); } + } + + protected Serializer RoundtripEmitDefaultsJsonCompatibleSerializer + { + get { return CurrentOrNew(() => new Serializer(SerializationOptions.EmitDefaults | + SerializationOptions.JsonCompatible | + SerializationOptions.Roundtrip)); + } + } + + private Serializer CurrentOrNew(Func serializerFactory) + { + return serializer = serializer ?? serializerFactory(); + } + + protected Deserializer Deserializer + { + get { return deserializer = deserializer ?? new Deserializer(); } + } + + protected void AssumingDeserializerWith(IObjectFactory factory) + { + deserializer = new Deserializer(factory); + } + + protected TextReader UsingReaderFor(TextWriter buffer) + { + return UsingReaderFor(buffer.ToString()); + } + + protected TextReader UsingReaderFor(string text) + { + return new StringReader(text); + } + + protected static EventReader EventReaderFor(string yaml) + { + return new EventReader(new Parser(new StringReader(yaml))); + } + + protected string Lines(params string[] lines) + { + return string.Join(Environment.NewLine, lines); + } + + protected object Entry(string key, string value) + { + return new DictionaryEntry(key, value); + } + } + + // ReSharper disable InconsistentNaming + + [Flags] + public enum EnumExample + { + None, + One, + Two + } + + public class CircularReference + { + public CircularReference Child1 { get; set; } + public CircularReference Child2 { get; set; } + } + + [TypeConverter(typeof(ConvertibleConverter))] + public class Convertible : IConvertible + { + public string Left { get; set; } + public string Right { get; set; } + + public object ToType(Type conversionType, IFormatProvider provider) + { + conversionType.Should().Be(); + return ToString(provider); + } + + public string ToString(IFormatProvider provider) + { + provider.Should().Be(CultureInfo.InvariantCulture); + return string.Format(provider, "[{0}, {1}]", Left, Right); + } + + #region Unsupported Members + + public System.TypeCode GetTypeCode() + { + throw new NotSupportedException(); + } + + public bool ToBoolean(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + public byte ToByte(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + public char ToChar(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + public DateTime ToDateTime(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + public decimal ToDecimal(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + public double ToDouble(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + public short ToInt16(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + public int ToInt32(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + public long ToInt64(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + public sbyte ToSByte(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + public float ToSingle(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + public ushort ToUInt16(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + public uint ToUInt32(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + public ulong ToUInt64(IFormatProvider provider) + { + throw new NotSupportedException(); + } + + #endregion + } + + public class ConvertibleConverter : 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) + { + if (!(value is string)) + throw new InvalidOperationException(); + var parts = (value as string).Split(' '); + return new Convertible { + Left = parts[0], + Right = parts[1] + }; + } + } + + public class MissingDefaultCtor + { + public string Value; + + public MissingDefaultCtor(string value) + { + Value = value; + } + } + + public class MissingDefaultCtorConverter : IYamlTypeConverter + { + public bool Accepts(Type type) + { + return type == typeof(MissingDefaultCtor); + } + + public object ReadYaml(IParser parser, Type type) + { + var value = ((Scalar) parser.Current).Value; + parser.MoveNext(); + return new MissingDefaultCtor(value); + } + + public void WriteYaml(IEmitter emitter, object value, Type type) + { + emitter.Emit(new Scalar(((MissingDefaultCtor) value).Value)); + } + } + + public class InheritanceExample + { + public object SomeScalar { get; set; } + public Base RegularBase { get; set; } + + [YamlMember(serializeAs: typeof(Base))] + public Base BaseWithSerializeAs { get; set; } + } + + public class InterfaceExample + { + public IDerived Derived { get; set; } + } + + public interface IBase + { + string BaseProperty { get; set; } + } + + public interface IDerived : IBase + { + string DerivedProperty { get; set; } + } + + public class Base : IBase + { + public string BaseProperty { get; set; } + } + + public class Derived : Base, IDerived + { + public string DerivedProperty { get; set; } + } + + public class EmptyBase + { + } + + public class EmptyDerived : EmptyBase + { + } + + public class Simple + { + public string aaa { get; set; } + } public class SimpleScratch { @@ -365,30 +365,30 @@ public class SimpleScratch public IEnumerable MappedScratch { get; set; } } - public class Example - { - public bool MyFlag { get; set; } - public string Nothing { get; set; } - public int MyInt { get; set; } - public double MyDouble { get; set; } - public string MyString { get; set; } - public DateTime MyDate { get; set; } - public TimeSpan MyTimeSpan { get; set; } - public Point MyPoint { get; set; } - public int? MyNullableWithValue { get; set; } - public int? MyNullableWithoutValue { get; set; } - - public Example() - { - MyInt = 1234; - MyDouble = 6789.1011; - MyString = "Hello world"; - MyDate = DateTime.Now; - MyTimeSpan = TimeSpan.FromHours(1); - MyPoint = new Point(100, 200); - MyNullableWithValue = 8; - } - } + public class Example + { + public bool MyFlag { get; set; } + public string Nothing { get; set; } + public int MyInt { get; set; } + public double MyDouble { get; set; } + public string MyString { get; set; } + public DateTime MyDate { get; set; } + public TimeSpan MyTimeSpan { get; set; } + public Point MyPoint { get; set; } + public int? MyNullableWithValue { get; set; } + public int? MyNullableWithoutValue { get; set; } + + public Example() + { + MyInt = 1234; + MyDouble = 6789.1011; + MyString = "Hello world"; + MyDate = DateTime.Now; + MyTimeSpan = TimeSpan.FromHours(1); + MyPoint = new Point(100, 200); + MyNullableWithValue = 8; + } + } public class OrderExample { @@ -405,140 +405,140 @@ public OrderExample() public String Order1 { get; set; } } - public class IgnoreExample - { - [YamlIgnore] - public String IgnoreMe - { - get { throw new NotImplementedException("Accessing a [YamlIgnore] property"); } - set { throw new NotImplementedException("Accessing a [YamlIgnore] property"); } - } - } - - public class ScalarStyleExample - { - public ScalarStyleExample() - { - var content = "Test"; - this.LiteralString = content; - this.DoubleQuotedString = content; - } - - [YamlMember(ScalarStyle = ScalarStyle.Literal)] - public String LiteralString { get; set; } - - [YamlMember(ScalarStyle = ScalarStyle.DoubleQuoted)] - public String DoubleQuotedString { get; set; } - } - - public class DefaultsExample - { - public const string DefaultValue = "myDefault"; - - [DefaultValue(DefaultValue)] - public string Value { get; set; } - } - - public class CustomGenericDictionary : IDictionary - { - private readonly Dictionary dictionary = new Dictionary(); - - public void Add(string key, string value) - { - dictionary.Add(key, value); - } - - public IEnumerator> GetEnumerator() - { - return dictionary.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #region Unsupported Members - - public bool ContainsKey(string key) - { - throw new NotSupportedException(); - } - - public ICollection Keys - { - get { throw new NotSupportedException(); } - } - - public bool Remove(string key) - { - throw new NotSupportedException(); - } - - public bool TryGetValue(string key, out string value) - { - throw new NotSupportedException(); - } - - public ICollection Values - { - get { throw new NotSupportedException(); } - } - - public string this[string key] - { - get { throw new NotSupportedException(); } - set { throw new NotSupportedException(); } - } - - public void Add(KeyValuePair item) - { - throw new NotSupportedException(); - } - - public void Clear() - { - throw new NotSupportedException(); - } - - public bool Contains(KeyValuePair item) - { - throw new NotSupportedException(); - } - - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - throw new NotSupportedException(); - } - - public int Count - { - get { throw new NotSupportedException(); } - } - - public bool IsReadOnly - { - get { throw new NotSupportedException(); } - } - - public bool Remove(KeyValuePair item) - { - throw new NotSupportedException(); - } - - #endregion - } - - public class NameConvention - { - public string FirstTest { get; set; } - public string SecondTest { get; set; } - public string ThirdTest { get; set; } - - [YamlMember(Alias = "fourthTest")] - public string AliasTest { get; set; } - - [YamlIgnore] - public string fourthTest { get; set; } - } + public class IgnoreExample + { + [YamlIgnore] + public String IgnoreMe + { + get { throw new NotImplementedException("Accessing a [YamlIgnore] property"); } + set { throw new NotImplementedException("Accessing a [YamlIgnore] property"); } + } + } + + public class ScalarStyleExample + { + public ScalarStyleExample() + { + var content = "Test"; + this.LiteralString = content; + this.DoubleQuotedString = content; + } + + [YamlMember(ScalarStyle = ScalarStyle.Literal)] + public String LiteralString { get; set; } + + [YamlMember(ScalarStyle = ScalarStyle.DoubleQuoted)] + public String DoubleQuotedString { get; set; } + } + + public class DefaultsExample + { + public const string DefaultValue = "myDefault"; + + [DefaultValue(DefaultValue)] + public string Value { get; set; } + } + + public class CustomGenericDictionary : IDictionary + { + private readonly Dictionary dictionary = new Dictionary(); + + public void Add(string key, string value) + { + dictionary.Add(key, value); + } + + public IEnumerator> GetEnumerator() + { + return dictionary.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + #region Unsupported Members + + public bool ContainsKey(string key) + { + throw new NotSupportedException(); + } + + public ICollection Keys + { + get { throw new NotSupportedException(); } + } + + public bool Remove(string key) + { + throw new NotSupportedException(); + } + + public bool TryGetValue(string key, out string value) + { + throw new NotSupportedException(); + } + + public ICollection Values + { + get { throw new NotSupportedException(); } + } + + public string this[string key] + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + public void Add(KeyValuePair item) + { + throw new NotSupportedException(); + } + + public void Clear() + { + throw new NotSupportedException(); + } + + public bool Contains(KeyValuePair item) + { + throw new NotSupportedException(); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + throw new NotSupportedException(); + } + + public int Count + { + get { throw new NotSupportedException(); } + } + + public bool IsReadOnly + { + get { throw new NotSupportedException(); } + } + + public bool Remove(KeyValuePair item) + { + throw new NotSupportedException(); + } + + #endregion + } + + public class NameConvention + { + public string FirstTest { get; set; } + public string SecondTest { get; set; } + public string ThirdTest { get; set; } + + [YamlMember(Alias = "fourthTest")] + public string AliasTest { get; set; } + + [YamlIgnore] + public string fourthTest { get; set; } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/Serialization/SerializationTests.cs b/YamlDotNet.Test/Serialization/SerializationTests.cs index 3c511e9f0..905a32c66 100644 --- a/YamlDotNet.Test/Serialization/SerializationTests.cs +++ b/YamlDotNet.Test/Serialization/SerializationTests.cs @@ -40,1103 +40,1103 @@ namespace YamlDotNet.Test.Serialization { - public class SerializationTests : SerializationTestHelper - { - [Fact] - public void DeserializeEmptyDocument() - { - var emptyText = string.Empty; + public class SerializationTests : SerializationTestHelper + { + [Fact] + public void DeserializeEmptyDocument() + { + var emptyText = string.Empty; - var array = Deserializer.Deserialize(UsingReaderFor(emptyText)); + var array = Deserializer.Deserialize(UsingReaderFor(emptyText)); - array.Should().BeNull(); - } - - [Fact] - public void DeserializeScalar() - { - var stream = Yaml.StreamFrom("02-scalar-in-imp-doc.yaml"); + array.Should().BeNull(); + } + + [Fact] + public void DeserializeScalar() + { + var stream = Yaml.StreamFrom("02-scalar-in-imp-doc.yaml"); - var result = Deserializer.Deserialize(stream); + var result = Deserializer.Deserialize(stream); - result.Should().Be("a scalar"); - } + result.Should().Be("a scalar"); + } - [Fact] - public void DeserializeScalarZero() - { - var result = Deserializer.Deserialize(UsingReaderFor("0")); + [Fact] + public void DeserializeScalarZero() + { + var result = Deserializer.Deserialize(UsingReaderFor("0")); - result.Should().Be(0); - } + result.Should().Be(0); + } - [Fact] - public void DeserializeScalarDecimal() - { - var result = Deserializer.Deserialize(UsingReaderFor("+1_234_567")); + [Fact] + public void DeserializeScalarDecimal() + { + var result = Deserializer.Deserialize(UsingReaderFor("+1_234_567")); - result.Should().Be(1234567); - } + result.Should().Be(1234567); + } - [Fact] - public void DeserializeScalarBinaryNumber() - { - var result = Deserializer.Deserialize(UsingReaderFor("-0b1_0010_1001_0010")); + [Fact] + public void DeserializeScalarBinaryNumber() + { + var result = Deserializer.Deserialize(UsingReaderFor("-0b1_0010_1001_0010")); - result.Should().Be(-4754); - } + result.Should().Be(-4754); + } - [Fact] - public void DeserializeScalarOctalNumber() - { - var result = Deserializer.Deserialize(UsingReaderFor("+071_352")); + [Fact] + public void DeserializeScalarOctalNumber() + { + var result = Deserializer.Deserialize(UsingReaderFor("+071_352")); - result.Should().Be(29418); - } + result.Should().Be(29418); + } - [Fact] - public void DeserializeScalarHexNumber() - { - var result = Deserializer.Deserialize(UsingReaderFor("-0x_0F_B9")); + [Fact] + public void DeserializeScalarHexNumber() + { + var result = Deserializer.Deserialize(UsingReaderFor("-0x_0F_B9")); - result.Should().Be(-0xFB9); - } + result.Should().Be(-0xFB9); + } - [Fact] - public void DeserializeScalarLongBase60Number() - { - var result = Deserializer.Deserialize(UsingReaderFor("99_:_58:47:3:6_2:10")); + [Fact] + public void DeserializeScalarLongBase60Number() + { + var result = Deserializer.Deserialize(UsingReaderFor("99_:_58:47:3:6_2:10")); - result.Should().Be(77744246530L); - } + result.Should().Be(77744246530L); + } - [Fact] - public void RoundtripEnums() - { - var flags = EnumExample.One | EnumExample.Two; + [Fact] + public void RoundtripEnums() + { + var flags = EnumExample.One | EnumExample.Two; - var result = DoRoundtripFromObjectTo(flags); + var result = DoRoundtripFromObjectTo(flags); - result.Should().Be(flags); - } + result.Should().Be(flags); + } - [Fact] - public void SerializeCircularReference() - { - var obj = new CircularReference(); - obj.Child1 = new CircularReference - { - Child1 = obj, - Child2 = obj - }; + [Fact] + public void SerializeCircularReference() + { + var obj = new CircularReference(); + obj.Child1 = new CircularReference + { + Child1 = obj, + Child2 = obj + }; - Action action = () => RoundtripSerializer.Serialize(new StringWriter(), obj, typeof(CircularReference)); + Action action = () => RoundtripSerializer.Serialize(new StringWriter(), obj, typeof(CircularReference)); - action.ShouldNotThrow(); - } + action.ShouldNotThrow(); + } - [Fact] - public void DeserializeCustomTags() - { - var stream = Yaml.StreamFrom("tags.yaml"); + [Fact] + public void DeserializeCustomTags() + { + var stream = Yaml.StreamFrom("tags.yaml"); - Deserializer.RegisterTagMapping("tag:yaml.org,2002:point", typeof(Point)); - var result = Deserializer.Deserialize(stream); + Deserializer.RegisterTagMapping("tag:yaml.org,2002:point", typeof(Point)); + var result = Deserializer.Deserialize(stream); - result.Should().BeOfType().And - .Subject.As() - .ShouldBeEquivalentTo(new { X = 10, Y = 20 }, o => o.ExcludingMissingMembers()); - } + result.Should().BeOfType().And + .Subject.As() + .ShouldBeEquivalentTo(new { X = 10, Y = 20 }, o => o.ExcludingMissingMembers()); + } - [Fact] - public void DeserializeExplicitType() - { - var text = Yaml.StreamFrom("explicit-type.template").TemplatedOn(); + [Fact] + public void DeserializeExplicitType() + { + var text = Yaml.StreamFrom("explicit-type.template").TemplatedOn(); - var result = Deserializer.Deserialize(UsingReaderFor(text)); + var result = Deserializer.Deserialize(UsingReaderFor(text)); - result.aaa.Should().Be("bbb"); - } + result.aaa.Should().Be("bbb"); + } - [Fact] - public void DeserializeConvertible() - { - var text = Yaml.StreamFrom("convertible.template").TemplatedOn(); + [Fact] + public void DeserializeConvertible() + { + var text = Yaml.StreamFrom("convertible.template").TemplatedOn(); - var result = Deserializer.Deserialize(UsingReaderFor(text)); + var result = Deserializer.Deserialize(UsingReaderFor(text)); - result.aaa.Should().Be("[hello, world]"); - } + result.aaa.Should().Be("[hello, world]"); + } - [Fact] - public void DeserializationOfObjectsHandlesForwardReferences() - { - var text = Lines( - "Nothing: *forward", - "MyString: &forward ForwardReference"); + [Fact] + public void DeserializationOfObjectsHandlesForwardReferences() + { + var text = Lines( + "Nothing: *forward", + "MyString: &forward ForwardReference"); - var result = Deserializer.Deserialize(UsingReaderFor(text)); + var result = Deserializer.Deserialize(UsingReaderFor(text)); - result.ShouldBeEquivalentTo( - new { Nothing = "ForwardReference", MyString = "ForwardReference" }, o => o.ExcludingMissingMembers()); - } + result.ShouldBeEquivalentTo( + new { Nothing = "ForwardReference", MyString = "ForwardReference" }, o => o.ExcludingMissingMembers()); + } - [Fact] - public void DeserializationFailsForUndefinedForwardReferences() - { - var text = Lines( - "Nothing: *forward", - "MyString: ForwardReference"); + [Fact] + public void DeserializationFailsForUndefinedForwardReferences() + { + var text = Lines( + "Nothing: *forward", + "MyString: ForwardReference"); - Action action = () => Deserializer.Deserialize(UsingReaderFor(text)); + Action action = () => Deserializer.Deserialize(UsingReaderFor(text)); - action.ShouldThrow(); - } - - [Fact] - public void RoundtripObject() - { - var obj = new Example(); - - var result = DoRoundtripFromObjectTo(obj, RoundtripSerializer); - - result.ShouldBeEquivalentTo(obj); - } - - [Fact] - public void RoundtripObjectWithDefaults() - { - var obj = new Example(); - - var result = DoRoundtripFromObjectTo(obj, RoundtripEmitDefaultsSerializer); - - result.ShouldBeEquivalentTo(obj); - } - - [Fact] - public void RoundtripAnonymousType() - { - var data = new { Key = 3 }; - - var result = DoRoundtripFromObjectTo>(data); - - result.Should().Equal(new Dictionary { - { "Key", "3" } - }); - } - - [Fact] - public void RoundtripWithYamlTypeConverter() - { - var obj = new MissingDefaultCtor("Yo"); + action.ShouldThrow(); + } + + [Fact] + public void RoundtripObject() + { + var obj = new Example(); + + var result = DoRoundtripFromObjectTo(obj, RoundtripSerializer); + + result.ShouldBeEquivalentTo(obj); + } + + [Fact] + public void RoundtripObjectWithDefaults() + { + var obj = new Example(); + + var result = DoRoundtripFromObjectTo(obj, RoundtripEmitDefaultsSerializer); + + result.ShouldBeEquivalentTo(obj); + } + + [Fact] + public void RoundtripAnonymousType() + { + var data = new { Key = 3 }; + + var result = DoRoundtripFromObjectTo>(data); + + result.Should().Equal(new Dictionary { + { "Key", "3" } + }); + } + + [Fact] + public void RoundtripWithYamlTypeConverter() + { + var obj = new MissingDefaultCtor("Yo"); - RoundtripSerializer.RegisterTypeConverter(new MissingDefaultCtorConverter()); - Deserializer.RegisterTypeConverter(new MissingDefaultCtorConverter()); - var result = DoRoundtripFromObjectTo(obj, RoundtripSerializer, Deserializer); + RoundtripSerializer.RegisterTypeConverter(new MissingDefaultCtorConverter()); + Deserializer.RegisterTypeConverter(new MissingDefaultCtorConverter()); + var result = DoRoundtripFromObjectTo(obj, RoundtripSerializer, Deserializer); - result.Value.Should().Be("Yo"); - } + result.Value.Should().Be("Yo"); + } - [Fact] - public void RoundtripAlias() - { - var writer = new StringWriter(); - var input = new NameConvention { AliasTest = "Fourth" }; + [Fact] + public void RoundtripAlias() + { + var writer = new StringWriter(); + var input = new NameConvention { AliasTest = "Fourth" }; - Serializer.Serialize(writer, input, input.GetType()); - var text = writer.ToString(); + Serializer.Serialize(writer, input, input.GetType()); + var text = writer.ToString(); - // Todo: use RegEx once FluentAssertions 2.2 is released - text.TrimEnd('\r', '\n').Should().Be("fourthTest: Fourth"); + // Todo: use RegEx once FluentAssertions 2.2 is released + text.TrimEnd('\r', '\n').Should().Be("fourthTest: Fourth"); - var output = Deserializer.Deserialize(UsingReaderFor(text)); + var output = Deserializer.Deserialize(UsingReaderFor(text)); - output.AliasTest.Should().Be(input.AliasTest); - } + output.AliasTest.Should().Be(input.AliasTest); + } - [Fact] - // Todo: is the assert on the string necessary? - public void RoundtripDerivedClass() - { - var obj = new InheritanceExample - { - SomeScalar = "Hello", - RegularBase = new Derived { BaseProperty = "foo", DerivedProperty = "bar" }, - }; + [Fact] + // Todo: is the assert on the string necessary? + public void RoundtripDerivedClass() + { + var obj = new InheritanceExample + { + SomeScalar = "Hello", + RegularBase = new Derived { BaseProperty = "foo", DerivedProperty = "bar" }, + }; - var result = DoRoundtripFromObjectTo(obj, RoundtripSerializer); + var result = DoRoundtripFromObjectTo(obj, RoundtripSerializer); - result.SomeScalar.Should().Be("Hello"); - result.RegularBase.Should().BeOfType().And - .Subject.As().ShouldBeEquivalentTo(new { ChildProp = "bar" }, o => o.ExcludingMissingMembers()); - } + result.SomeScalar.Should().Be("Hello"); + result.RegularBase.Should().BeOfType().And + .Subject.As().ShouldBeEquivalentTo(new { ChildProp = "bar" }, o => o.ExcludingMissingMembers()); + } - [Fact] - public void RoundtripDerivedClassWithSerializeAs() - { - var obj = new InheritanceExample - { - SomeScalar = "Hello", - BaseWithSerializeAs = new Derived { BaseProperty = "foo", DerivedProperty = "bar" }, - }; + [Fact] + public void RoundtripDerivedClassWithSerializeAs() + { + var obj = new InheritanceExample + { + SomeScalar = "Hello", + BaseWithSerializeAs = new Derived { BaseProperty = "foo", DerivedProperty = "bar" }, + }; - var result = DoRoundtripFromObjectTo(obj, RoundtripSerializer); + var result = DoRoundtripFromObjectTo(obj, RoundtripSerializer); - result.BaseWithSerializeAs.Should().BeOfType().And - .Subject.As().ShouldBeEquivalentTo(new { ParentProp = "foo" }, o => o.ExcludingMissingMembers()); - } + result.BaseWithSerializeAs.Should().BeOfType().And + .Subject.As().ShouldBeEquivalentTo(new { ParentProp = "foo" }, o => o.ExcludingMissingMembers()); + } - [Fact] - public void RoundtripInterfaceProperties() - { - AssumingDeserializerWith(new LambdaObjectFactory(t => - { - if (t == typeof(InterfaceExample)) { return new InterfaceExample(); } - else if (t == typeof(IDerived)) { return new Derived(); } - return null; - })); + [Fact] + public void RoundtripInterfaceProperties() + { + AssumingDeserializerWith(new LambdaObjectFactory(t => + { + if (t == typeof(InterfaceExample)) { return new InterfaceExample(); } + else if (t == typeof(IDerived)) { return new Derived(); } + return null; + })); - var obj = new InterfaceExample - { - Derived = new Derived { BaseProperty = "foo", DerivedProperty = "bar" } - }; + var obj = new InterfaceExample + { + Derived = new Derived { BaseProperty = "foo", DerivedProperty = "bar" } + }; - var result = DoRoundtripFromObjectTo(obj); + var result = DoRoundtripFromObjectTo(obj); - result.Derived.Should().BeOfType().And - .Subject.As().ShouldBeEquivalentTo(new { BaseProperty = "foo", DerivedProperty = "bar" }, o => o.ExcludingMissingMembers()); - } + result.Derived.Should().BeOfType().And + .Subject.As().ShouldBeEquivalentTo(new { BaseProperty = "foo", DerivedProperty = "bar" }, o => o.ExcludingMissingMembers()); + } - [Fact] - public void DeserializeGuid() - { - var stream = Yaml.StreamFrom("guid.yaml"); - var result = Deserializer.Deserialize(stream); + [Fact] + public void DeserializeGuid() + { + var stream = Yaml.StreamFrom("guid.yaml"); + var result = Deserializer.Deserialize(stream); - result.Should().Be(new Guid("9462790d5c44468985425e2dd38ebd98")); - } + result.Should().Be(new Guid("9462790d5c44468985425e2dd38ebd98")); + } - [Fact] - public void DeserializationOfOrderedProperties() - { - TextReader stream = Yaml.StreamFrom("ordered-properties.yaml"); + [Fact] + public void DeserializationOfOrderedProperties() + { + TextReader stream = Yaml.StreamFrom("ordered-properties.yaml"); - var orderExample = Deserializer.Deserialize(stream); + var orderExample = Deserializer.Deserialize(stream); - orderExample.Order1.Should().Be("Order1 value"); - orderExample.Order2.Should().Be("Order2 value"); - } + orderExample.Order1.Should().Be("Order1 value"); + orderExample.Order2.Should().Be("Order2 value"); + } - [Fact] - public void DeserializeEnumerable() - { - var obj = new[] { new Simple { aaa = "bbb" } }; + [Fact] + public void DeserializeEnumerable() + { + var obj = new[] { new Simple { aaa = "bbb" } }; - var result = DoRoundtripFromObjectTo>(obj); + var result = DoRoundtripFromObjectTo>(obj); - result.Should().ContainSingle(item => "bbb".Equals(item.aaa)); - } + result.Should().ContainSingle(item => "bbb".Equals(item.aaa)); + } - [Fact] - public void DeserializeArray() - { - var stream = Yaml.StreamFrom("list.yaml"); + [Fact] + public void DeserializeArray() + { + var stream = Yaml.StreamFrom("list.yaml"); - var result = Deserializer.Deserialize(stream); + var result = Deserializer.Deserialize(stream); - result.Should().Equal(new[] { "one", "two", "three" }); - } + result.Should().Equal(new[] { "one", "two", "three" }); + } - [Fact] - public void DeserializeList() - { - var stream = Yaml.StreamFrom("list.yaml"); - - var result = Deserializer.Deserialize(stream); - - result.Should().BeAssignableTo().And - .Subject.As().Should().Equal(new[] { "one", "two", "three" }); - } - - [Fact] - public void DeserializeExplicitList() - { - var stream = Yaml.StreamFrom("list-explicit.yaml"); - - var result = Deserializer.Deserialize(stream); - - result.Should().BeAssignableTo>().And - .Subject.As>().Should().Equal(3, 4, 5); - } - - [Fact] - public void DeserializationOfGenericListsHandlesForwardReferences() - { - var text = Lines( - "- *forward", - "- &forward ForwardReference"); - - var result = Deserializer.Deserialize(UsingReaderFor(text)); - - result.Should().Equal(new[] { "ForwardReference", "ForwardReference" }); - } - - [Fact] - public void DeserializationOfNonGenericListsHandlesForwardReferences() - { - var text = Lines( - "- *forward", - "- &forward ForwardReference"); - - var result = Deserializer.Deserialize(UsingReaderFor(text)); - - result.Should().Equal(new[] { "ForwardReference", "ForwardReference" }); - } - - [Fact] - public void RoundtripList() - { - var obj = new List { 2, 4, 6 }; - - var result = DoRoundtripOn>(obj, RoundtripSerializer); - - result.Should().Equal(obj); - } - - [Fact] - public void RoundtripArrayWithTypeConversion() - { - var obj = new object[] { 1, 2, "3" }; - - var result = DoRoundtripFromObjectTo(obj); - - result.Should().Equal(1, 2, 3); - } - - [Fact] - public void RoundtripArrayOfIdenticalObjects() - { - var z = new Simple { aaa = "bbb" }; - var obj = new[] { z, z, z }; - - var result = DoRoundtripOn(obj); - - result.Should().HaveCount(3).And.OnlyContain(x => z.aaa.Equals(x.aaa)); - result[0].Should().BeSameAs(result[1]).And.BeSameAs(result[2]); - } - - [Fact] - public void DeserializeDictionary() - { - var stream = Yaml.StreamFrom("dictionary.yaml"); - - var result = Deserializer.Deserialize(stream); - - result.Should().BeAssignableTo>().And.Subject - .As>().Should().Equal(new Dictionary { - { "key1", "value1" }, - { "key2", "value2" } - }); - } - - [Fact] - public void DeserializeExplicitDictionary() - { - var stream = Yaml.StreamFrom("dictionary-explicit.yaml"); - - var result = Deserializer.Deserialize(stream); - - result.Should().BeAssignableTo>().And.Subject - .As>().Should().Equal(new Dictionary { - { "key1", 1 }, - { "key2", 2 } - }); - } - - [Fact] - public void RoundtripDictionary() - { - var obj = new Dictionary { - { "key1", "value1" }, - { "key2", "value2" }, - { "key3", "value3" }, - }; - - var result = DoRoundtripFromObjectTo>(obj); - - result.Should().Equal(obj); - } - - [Fact] - public void DeserializationOfGenericDictionariesHandlesForwardReferences() - { - var text = Lines( - "key1: *forward", - "*forwardKey: ForwardKeyValue", - "*forward: *forward", - "key2: &forward ForwardReference", - "key3: &forwardKey key4"); - - var result = Deserializer.Deserialize>(UsingReaderFor(text)); - - result.Should().Equal(new Dictionary { - { "ForwardReference", "ForwardReference" }, - { "key1", "ForwardReference" }, - { "key2", "ForwardReference" }, - { "key4", "ForwardKeyValue" }, - { "key3", "key4" } - }); - } - - [Fact] - public void DeserializationOfNonGenericDictionariesHandlesForwardReferences() - { - var text = Lines( - "key1: *forward", - "*forwardKey: ForwardKeyValue", - "*forward: *forward", - "key2: &forward ForwardReference", - "key3: &forwardKey key4"); - - var result = Deserializer.Deserialize(UsingReaderFor(text)); - - result.Should().BeEquivalentTo( - Entry("ForwardReference", "ForwardReference"), - Entry("key1", "ForwardReference"), - Entry("key2", "ForwardReference"), - Entry("key4", "ForwardKeyValue"), - Entry("key3", "key4")); - } - - [Fact] - public void DeserializeListOfDictionaries() - { - var stream = Yaml.StreamFrom("list-of-dictionaries.yaml"); - - var result = Deserializer.Deserialize>>(stream); - - result.ShouldBeEquivalentTo(new[] { - new Dictionary { - { "connection", "conn1" }, - { "path", "path1" } - }, - new Dictionary { - { "connection", "conn2" }, - { "path", "path2" } - }}, opt => opt.WithStrictOrderingFor(root => root)); - } - - [Fact] - public void DeserializeTwoDocuments() - { - var reader = EventReaderFor(Lines( - "---", - "aaa: 111", - "---", - "aaa: 222", - "...")); - - reader.Expect(); - var one = Deserializer.Deserialize(reader); - var two = Deserializer.Deserialize(reader); - - one.ShouldBeEquivalentTo(new { aaa = "111" }); - two.ShouldBeEquivalentTo(new { aaa = "222" }); - } - - [Fact] - public void DeserializeThreeDocuments() - { - var reader = EventReaderFor(Lines( - "---", - "aaa: 111", - "---", - "aaa: 222", - "---", - "aaa: 333", - "...")); - - reader.Expect(); - var one = Deserializer.Deserialize(reader); - var two = Deserializer.Deserialize(reader); - var three = Deserializer.Deserialize(reader); - - reader.Accept().Should().BeTrue("reader should have reached StreamEnd"); - one.ShouldBeEquivalentTo(new { aaa = "111" }); - two.ShouldBeEquivalentTo(new { aaa = "222" }); - three.ShouldBeEquivalentTo(new { aaa = "333" }); - } - - [Fact] - public void SerializeGuid() - { - var guid = new Guid("{9462790D-5C44-4689-8542-5E2DD38EBD98}"); - - var writer = new StringWriter(); - - Serializer.Serialize(writer, guid); - var serialized = writer.ToString(); - Dump.WriteLine(writer.ToString()); - Regex.IsMatch(serialized, "^" + guid.ToString("D")).Should().BeTrue("serialized content should contain the guid"); - } - - [Fact] - public void SerializationOfNullInListsAreAlwaysEmittedWithoutUsingEmitDefaults() - { - var writer = new StringWriter(); - var obj = new[] { "foo", null, "bar" }; - - Serializer.Serialize(writer, obj); - var serialized = writer.ToString(); - Dump.WriteLine(serialized); - - Regex.Matches(serialized, "-").Count.Should().Be(3, "there should have been 3 elements"); - } - - [Fact] - public void SerializationOfNullInListsAreAlwaysEmittedWhenUsingEmitDefaults() - { - var writer = new StringWriter(); - var obj = new[] { "foo", null, "bar" }; - - EmitDefaultsSerializer.Serialize(writer, obj); - var serialized = writer.ToString(); - Dump.WriteLine(serialized); - - Regex.Matches(serialized, "-").Count.Should().Be(3, "there should have been 3 elements"); - } - - [Fact] - public void SerializationIncludesKeyWhenEmittingDefaults() - { - var writer = new StringWriter(); - var obj = new Example { MyString = null }; - - EmitDefaultsSerializer.Serialize(writer, obj, typeof(Example)); - Dump.WriteLine(writer); - - writer.ToString().Should().Contain("MyString"); - } - - [Fact] - [Trait("Motive", "Bug fix")] - public void SerializationIncludesKeyFromAnonymousTypeWhenEmittingDefaults() - { - var writer = new StringWriter(); - var obj = new { MyString = (string)null }; - - EmitDefaultsSerializer.Serialize(writer, obj, obj.GetType()); - Dump.WriteLine(writer); - - writer.ToString().Should().Contain("MyString"); - } - - [Fact] - public void SerializationDoesNotIncludeKeyWhenDisregardingDefaults() - { - var writer = new StringWriter(); - var obj = new Example { MyString = null }; - - Serializer.Serialize(writer, obj, typeof(Example)); - Dump.WriteLine(writer); - - writer.ToString().Should().NotContain("MyString"); - } - - [Fact] - public void SerializationOfDefaultsWorkInJson() - { - var writer = new StringWriter(); - var obj = new Example { MyString = null }; - - EmitDefaultsJsonCompatibleSerializer.Serialize(writer, obj, typeof(Example)); - Dump.WriteLine(writer); - - writer.ToString().Should().Contain("MyString"); - } - - [Fact] - // Todo: this is actualy roundtrip - public void DeserializationOfDefaultsWorkInJson() - { - var writer = new StringWriter(); - var obj = new Example { MyString = null }; - - RoundtripEmitDefaultsJsonCompatibleSerializer.Serialize(writer, obj, typeof(Example)); - Dump.WriteLine(writer); - var result = Deserializer.Deserialize(UsingReaderFor(writer)); - - result.MyString.Should().BeNull(); - } - - [Fact] - public void SerializationOfOrderedProperties() - { - var obj = new OrderExample(); - var writer = new StringWriter(); - - Serializer.Serialize(writer, obj); - var serialized = writer.ToString(); - Dump.WriteLine(serialized); - - serialized.Should() - .Be("Order1: Order1 value\r\nOrder2: Order2 value\r\n", "the properties should be in the right order"); - } - - [Fact] - public void SerializationRespectsYamlIgnoreAttribute() - { - - var writer = new StringWriter(); - var obj = new IgnoreExample(); - - Serializer.Serialize(writer, obj); - var serialized = writer.ToString(); - Dump.WriteLine(serialized); - - serialized.Should().NotContain("IgnoreMe"); - } - - [Fact] - public void SerializationRespectsScalarStyle() - { - var writer = new StringWriter(); - var obj = new ScalarStyleExample(); - - Serializer.Serialize(writer, obj); - var serialized = writer.ToString(); - Dump.WriteLine(serialized); - - serialized.Should() - .Be("LiteralString: |-\r\n Test\r\nDoubleQuotedString: \"Test\"\r\n", "the properties should be specifically styled"); - } - - [Fact] - public void SerializationSkipsPropertyWhenUsingDefaultValueAttribute() - { - var writer = new StringWriter(); - var obj = new DefaultsExample { Value = DefaultsExample.DefaultValue }; - - Serializer.Serialize(writer, obj); - var serialized = writer.ToString(); - Dump.WriteLine(serialized); - - serialized.Should().NotContain("Value"); - } - - [Fact] - public void SerializationEmitsPropertyWhenUsingEmitDefaultsAndDefaultValueAttribute() - { - var writer = new StringWriter(); - var obj = new DefaultsExample { Value = DefaultsExample.DefaultValue }; - - EmitDefaultsSerializer.Serialize(writer, obj); - var serialized = writer.ToString(); - Dump.WriteLine(serialized); - - serialized.Should().Contain("Value"); - } - - [Fact] - public void SerializationEmitsPropertyWhenValueDifferFromDefaultValueAttribute() - { - var writer = new StringWriter(); - var obj = new DefaultsExample { Value = "non-default" }; - - Serializer.Serialize(writer, obj); - var serialized = writer.ToString(); - Dump.WriteLine(serialized); - - serialized.Should().Contain("Value"); - } - - [Fact] - public void SerializingAGenericDictionaryShouldNotThrowTargetException() - { - var obj = new CustomGenericDictionary { - { "hello", "world" }, - }; - - Action action = () => Serializer.Serialize(new StringWriter(), obj); - - action.ShouldNotThrow(); - } - - [Fact] - public void SerializaionUtilizeNamingConventions() - { - var convention = A.Fake(); - A.CallTo(() => convention.Apply(A._)).ReturnsLazily((string x) => x); - var obj = new NameConvention { FirstTest = "1", SecondTest = "2" }; - - var serializer = new Serializer(namingConvention: convention); - serializer.Serialize(new StringWriter(), obj); - - A.CallTo(() => convention.Apply("FirstTest")).MustHaveHappened(); - A.CallTo(() => convention.Apply("SecondTest")).MustHaveHappened(); - } - - [Fact] - public void DeserializationUtilizeNamingConventions() - { - var convention = A.Fake(); - A.CallTo(() => convention.Apply(A._)).ReturnsLazily((string x) => x); - var text = Lines( - "FirstTest: 1", - "SecondTest: 2"); - - var deserializer = new Deserializer(namingConvention: convention); - deserializer.Deserialize(UsingReaderFor(text)); - - A.CallTo(() => convention.Apply("FirstTest")).MustHaveHappened(); - A.CallTo(() => convention.Apply("SecondTest")).MustHaveHappened(); - } - - [Fact] - public void TypeConverterIsUsedOnListItems() - { - var text = Lines( - "- !", - " Left: hello", - " Right: world") - .TemplatedOn(); - - var list = Deserializer.Deserialize>(UsingReaderFor(text)); - - list - .Should().NotBeNull() - .And.ContainSingle(c => c.Equals("[hello, world]")); - } - - [Fact] - public void BackreferencesAreMergedWithMappings() - { - var stream = Yaml.StreamFrom("backreference.yaml"); - - var parser = new MergingParser(new Parser(stream)); - var result = Deserializer.Deserialize>>(new EventReader(parser)); - - var alias = result["alias"]; - alias.Should() - .Contain("key1", "value1", "key1 should be inherited from the backreferenced mapping") - .And.Contain("key2", "Overriding key2", "key2 should be overriden by the actual mapping") - .And.Contain("key3", "value3", "key3 is defined in the actual mapping"); - } - - [Fact] - public void MergingDoesNotProduceDuplicateAnchors() - { - var parser = new MergingParser(Yaml.ParserForText(@" - anchor: &default - key1: &myValue value1 - key2: value2 - alias: - <<: *default - key2: Overriding key2 - key3: value3 - useMyValue: - key: *myValue - ")); - var result = Deserializer.Deserialize>>(new EventReader(parser)); - - var alias = result["alias"]; - alias.Should() - .Contain("key1", "value1", "key1 should be inherited from the backreferenced mapping") - .And.Contain("key2", "Overriding key2", "key2 should be overriden by the actual mapping") - .And.Contain("key3", "value3", "key3 is defined in the actual mapping"); - - result["useMyValue"].Should() - .Contain("key", "value1", "key should be copied"); - } - - [Fact] - public void ExampleFromSpecificationIsHandledCorrectly() - { - var parser = new MergingParser(Yaml.ParserForText(@" - obj: - - &CENTER { x: 1, y: 2 } - - &LEFT { x: 0, y: 2 } - - &BIG { r: 10 } - - &SMALL { r: 1 } - - # All the following maps are equal: - results: - - # Explicit keys - x: 1 - y: 2 - r: 10 - label: center/big - - - # Merge one map - << : *CENTER - r: 10 - label: center/big - - - # Merge multiple maps - << : [ *CENTER, *BIG ] - label: center/big - - - # Override - #<< : [ *BIG, *LEFT, *SMALL ] # This does not work because, in the current implementation, - # later keys override former keys. This could be fixed, but that - # is not trivial because the deserializer allows aliases to refer to - # an anchor that is defined later in the document, and the way it is - # implemented, the value is assigned later when the anchored value is - # deserialized. - << : [ *SMALL, *LEFT, *BIG ] - x: 1 - label: center/big - ")); - - var result = Deserializer.Deserialize>>>(new EventReader(parser)); - - int index = 0; - foreach (var mapping in result["results"]) - { - mapping.Should() - .Contain("x", "1", "'x' should be '1' in result #{0}", index) - .And.Contain("y", "2", "'y' should be '2' in result #{0}", index) - .And.Contain("r", "10", "'r' should be '10' in result #{0}", index) - .And.Contain("label", "center/big", "'label' should be 'center/big' in result #{0}", index); - - ++index; - } - } - - [Fact] - public void IgnoreExtraPropertiesIfWanted() - { - var text = Lines("aaa: hello", "bbb: world"); - var des = new Deserializer(ignoreUnmatched: true); - var actual = des.Deserialize(UsingReaderFor(text)); - actual.aaa.Should().Be("hello"); - } - - [Fact] - public void DontIgnoreExtraPropertiesIfWanted() - { - var text = Lines("aaa: hello", "bbb: world"); - var des = new Deserializer(ignoreUnmatched: false); - var actual = Record.Exception(() => des.Deserialize(UsingReaderFor(text))); - Assert.IsType(actual); - } - - [Fact] - public void IgnoreExtraPropertiesIfWantedBefore() - { - var text = Lines("bbb: [200,100]", "aaa: hello"); - var des = new Deserializer(ignoreUnmatched: true); - var actual = des.Deserialize(UsingReaderFor(text)); - actual.aaa.Should().Be("hello"); - } - - [Fact] - public void IgnoreExtraPropertiesIfWantedNamingScheme() - { - var text = Lines( - "scratch: 'scratcher'", - "deleteScratch: false", - "notScratch: 9443", - "notScratch: 192.168.1.30", - "mappedScratch:", - "- '/work/'" - ); - - var des = new Deserializer(namingConvention: new CamelCaseNamingConvention(), ignoreUnmatched: true); - var actual = des.Deserialize(UsingReaderFor(text)); - actual.Scratch.Should().Be("scratcher"); - actual.DeleteScratch.Should().Be(false); - actual.MappedScratch.Should().ContainInOrder(new[] { "/work/" }); - } - - [Fact] - public void InvalidTypeConversionsProduceProperExceptions() - { - var text = Lines("- 1", "- two", "- 3"); - - var sut = new Deserializer(); - var exception = Assert.Throws(() => sut.Deserialize>(UsingReaderFor(text))); - - Assert.Equal(2, exception.Start.Line); - Assert.Equal(3, exception.Start.Column); - } - - [Fact] - public void SerializeDynamicPropertyAndApplyNamingConvention() - { - dynamic obj = new ExpandoObject(); - obj.property_one = new ExpandoObject(); - ((IDictionary)obj.property_one).Add("new_key_here", "new_value"); - - var mockNamingConvention = A.Fake(); - A.CallTo(() => mockNamingConvention.Apply(A.Ignored)).Returns("xxx"); - - var serializer = new Serializer(namingConvention: mockNamingConvention); - var writer = new StringWriter(); - serializer.Serialize(writer, obj); - - writer.ToString().Should().Contain("xxx: new_value"); - } - - [Fact] - public void SerializeGenericDictionaryPropertyAndDoNotApplyNamingConvention() - { - var obj = new Dictionary(); - obj["property_one"] = new GenericTestDictionary(); - ((IDictionary)obj["property_one"]).Add("new_key_here", "new_value"); - - var mockNamingConvention = A.Fake(); - A.CallTo(() => mockNamingConvention.Apply(A.Ignored)).Returns("xxx"); - - var serializer = new Serializer(namingConvention: mockNamingConvention); - var writer = new StringWriter(); - serializer.Serialize(writer, obj); - - writer.ToString().Should().Contain("new_key_here: new_value"); - } - - [Fact] - public void SpecialFloatsAreDeserializedCorrectly() - { - var deserializer = new Deserializer(); - var doubles = deserializer.Deserialize>(Yaml.ReaderForText(@" - - .nan - - .inf - - -.inf - - 2.3e4 - - 1 - ")); - - Assert.Equal(new double[] - { - double.NaN, - double.PositiveInfinity, - double.NegativeInfinity, - 23000, - 1.0 - }, doubles); - } - - [Fact] - public void SpecialFloatsAreSerializedCorrectly() - { - var serializer = new Serializer(); - - var buffer = new StringWriter(); - serializer.Serialize(buffer, new double[] - { - double.NaN, - double.PositiveInfinity, - double.NegativeInfinity, - }); - - var text = buffer.ToString(); - - Assert.Contains("- .nan", text); - Assert.Contains("- .inf", text); - Assert.Contains("- -.inf", text); - } - - [Fact] - public void NegativeIntegersCanBeDeserialized() - { - var deserializer = new Deserializer(); - - var value = deserializer.Deserialize(Yaml.ReaderForText(@" - '-123' - ")); - Assert.Equal(-123, value); - } - - #region Test Dictionary that implements IDictionary<,>, but not IDictionary - public class GenericTestDictionary : IDictionary - { - private readonly Dictionary _dictionary; - public GenericTestDictionary() - { - _dictionary = new Dictionary(); - } - public void Add(TKey key, TValue value) - { - _dictionary.Add(key, value); - } - - public bool ContainsKey(TKey key) - { - return _dictionary.ContainsKey(key); - } - - public ICollection Keys - { - get { return _dictionary.Keys; } - } - - public bool Remove(TKey key) - { - return _dictionary.Remove(key); - } - - public bool TryGetValue(TKey key, out TValue value) - { - return _dictionary.TryGetValue(key, out value); - } - - public ICollection Values - { - get { return _dictionary.Values; } - } - - public TValue this[TKey key] - { - get { return _dictionary[key]; } - set { _dictionary[key] = value; } - } - - public void Add(KeyValuePair item) - { - ((IDictionary)_dictionary).Add(item); - } - - public void Clear() - { - _dictionary.Clear(); - } - - public bool Contains(KeyValuePair item) - { - return ((IDictionary)_dictionary).Contains(item); - } - - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - ((IDictionary)_dictionary).CopyTo(array, arrayIndex); - } - - public int Count - { - get { return _dictionary.Count; } - } - - public bool IsReadOnly - { - get { return false; } - } - - public bool Remove(KeyValuePair item) - { - return ((IDictionary)_dictionary).Remove(item); - } - - public IEnumerator> GetEnumerator() - { - return _dictionary.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _dictionary.GetEnumerator(); - } - } - #endregion - } + [Fact] + public void DeserializeList() + { + var stream = Yaml.StreamFrom("list.yaml"); + + var result = Deserializer.Deserialize(stream); + + result.Should().BeAssignableTo().And + .Subject.As().Should().Equal(new[] { "one", "two", "three" }); + } + + [Fact] + public void DeserializeExplicitList() + { + var stream = Yaml.StreamFrom("list-explicit.yaml"); + + var result = Deserializer.Deserialize(stream); + + result.Should().BeAssignableTo>().And + .Subject.As>().Should().Equal(3, 4, 5); + } + + [Fact] + public void DeserializationOfGenericListsHandlesForwardReferences() + { + var text = Lines( + "- *forward", + "- &forward ForwardReference"); + + var result = Deserializer.Deserialize(UsingReaderFor(text)); + + result.Should().Equal(new[] { "ForwardReference", "ForwardReference" }); + } + + [Fact] + public void DeserializationOfNonGenericListsHandlesForwardReferences() + { + var text = Lines( + "- *forward", + "- &forward ForwardReference"); + + var result = Deserializer.Deserialize(UsingReaderFor(text)); + + result.Should().Equal(new[] { "ForwardReference", "ForwardReference" }); + } + + [Fact] + public void RoundtripList() + { + var obj = new List { 2, 4, 6 }; + + var result = DoRoundtripOn>(obj, RoundtripSerializer); + + result.Should().Equal(obj); + } + + [Fact] + public void RoundtripArrayWithTypeConversion() + { + var obj = new object[] { 1, 2, "3" }; + + var result = DoRoundtripFromObjectTo(obj); + + result.Should().Equal(1, 2, 3); + } + + [Fact] + public void RoundtripArrayOfIdenticalObjects() + { + var z = new Simple { aaa = "bbb" }; + var obj = new[] { z, z, z }; + + var result = DoRoundtripOn(obj); + + result.Should().HaveCount(3).And.OnlyContain(x => z.aaa.Equals(x.aaa)); + result[0].Should().BeSameAs(result[1]).And.BeSameAs(result[2]); + } + + [Fact] + public void DeserializeDictionary() + { + var stream = Yaml.StreamFrom("dictionary.yaml"); + + var result = Deserializer.Deserialize(stream); + + result.Should().BeAssignableTo>().And.Subject + .As>().Should().Equal(new Dictionary { + { "key1", "value1" }, + { "key2", "value2" } + }); + } + + [Fact] + public void DeserializeExplicitDictionary() + { + var stream = Yaml.StreamFrom("dictionary-explicit.yaml"); + + var result = Deserializer.Deserialize(stream); + + result.Should().BeAssignableTo>().And.Subject + .As>().Should().Equal(new Dictionary { + { "key1", 1 }, + { "key2", 2 } + }); + } + + [Fact] + public void RoundtripDictionary() + { + var obj = new Dictionary { + { "key1", "value1" }, + { "key2", "value2" }, + { "key3", "value3" }, + }; + + var result = DoRoundtripFromObjectTo>(obj); + + result.Should().Equal(obj); + } + + [Fact] + public void DeserializationOfGenericDictionariesHandlesForwardReferences() + { + var text = Lines( + "key1: *forward", + "*forwardKey: ForwardKeyValue", + "*forward: *forward", + "key2: &forward ForwardReference", + "key3: &forwardKey key4"); + + var result = Deserializer.Deserialize>(UsingReaderFor(text)); + + result.Should().Equal(new Dictionary { + { "ForwardReference", "ForwardReference" }, + { "key1", "ForwardReference" }, + { "key2", "ForwardReference" }, + { "key4", "ForwardKeyValue" }, + { "key3", "key4" } + }); + } + + [Fact] + public void DeserializationOfNonGenericDictionariesHandlesForwardReferences() + { + var text = Lines( + "key1: *forward", + "*forwardKey: ForwardKeyValue", + "*forward: *forward", + "key2: &forward ForwardReference", + "key3: &forwardKey key4"); + + var result = Deserializer.Deserialize(UsingReaderFor(text)); + + result.Should().BeEquivalentTo( + Entry("ForwardReference", "ForwardReference"), + Entry("key1", "ForwardReference"), + Entry("key2", "ForwardReference"), + Entry("key4", "ForwardKeyValue"), + Entry("key3", "key4")); + } + + [Fact] + public void DeserializeListOfDictionaries() + { + var stream = Yaml.StreamFrom("list-of-dictionaries.yaml"); + + var result = Deserializer.Deserialize>>(stream); + + result.ShouldBeEquivalentTo(new[] { + new Dictionary { + { "connection", "conn1" }, + { "path", "path1" } + }, + new Dictionary { + { "connection", "conn2" }, + { "path", "path2" } + }}, opt => opt.WithStrictOrderingFor(root => root)); + } + + [Fact] + public void DeserializeTwoDocuments() + { + var reader = EventReaderFor(Lines( + "---", + "aaa: 111", + "---", + "aaa: 222", + "...")); + + reader.Expect(); + var one = Deserializer.Deserialize(reader); + var two = Deserializer.Deserialize(reader); + + one.ShouldBeEquivalentTo(new { aaa = "111" }); + two.ShouldBeEquivalentTo(new { aaa = "222" }); + } + + [Fact] + public void DeserializeThreeDocuments() + { + var reader = EventReaderFor(Lines( + "---", + "aaa: 111", + "---", + "aaa: 222", + "---", + "aaa: 333", + "...")); + + reader.Expect(); + var one = Deserializer.Deserialize(reader); + var two = Deserializer.Deserialize(reader); + var three = Deserializer.Deserialize(reader); + + reader.Accept().Should().BeTrue("reader should have reached StreamEnd"); + one.ShouldBeEquivalentTo(new { aaa = "111" }); + two.ShouldBeEquivalentTo(new { aaa = "222" }); + three.ShouldBeEquivalentTo(new { aaa = "333" }); + } + + [Fact] + public void SerializeGuid() + { + var guid = new Guid("{9462790D-5C44-4689-8542-5E2DD38EBD98}"); + + var writer = new StringWriter(); + + Serializer.Serialize(writer, guid); + var serialized = writer.ToString(); + Dump.WriteLine(writer.ToString()); + Regex.IsMatch(serialized, "^" + guid.ToString("D")).Should().BeTrue("serialized content should contain the guid"); + } + + [Fact] + public void SerializationOfNullInListsAreAlwaysEmittedWithoutUsingEmitDefaults() + { + var writer = new StringWriter(); + var obj = new[] { "foo", null, "bar" }; + + Serializer.Serialize(writer, obj); + var serialized = writer.ToString(); + Dump.WriteLine(serialized); + + Regex.Matches(serialized, "-").Count.Should().Be(3, "there should have been 3 elements"); + } + + [Fact] + public void SerializationOfNullInListsAreAlwaysEmittedWhenUsingEmitDefaults() + { + var writer = new StringWriter(); + var obj = new[] { "foo", null, "bar" }; + + EmitDefaultsSerializer.Serialize(writer, obj); + var serialized = writer.ToString(); + Dump.WriteLine(serialized); + + Regex.Matches(serialized, "-").Count.Should().Be(3, "there should have been 3 elements"); + } + + [Fact] + public void SerializationIncludesKeyWhenEmittingDefaults() + { + var writer = new StringWriter(); + var obj = new Example { MyString = null }; + + EmitDefaultsSerializer.Serialize(writer, obj, typeof(Example)); + Dump.WriteLine(writer); + + writer.ToString().Should().Contain("MyString"); + } + + [Fact] + [Trait("Motive", "Bug fix")] + public void SerializationIncludesKeyFromAnonymousTypeWhenEmittingDefaults() + { + var writer = new StringWriter(); + var obj = new { MyString = (string)null }; + + EmitDefaultsSerializer.Serialize(writer, obj, obj.GetType()); + Dump.WriteLine(writer); + + writer.ToString().Should().Contain("MyString"); + } + + [Fact] + public void SerializationDoesNotIncludeKeyWhenDisregardingDefaults() + { + var writer = new StringWriter(); + var obj = new Example { MyString = null }; + + Serializer.Serialize(writer, obj, typeof(Example)); + Dump.WriteLine(writer); + + writer.ToString().Should().NotContain("MyString"); + } + + [Fact] + public void SerializationOfDefaultsWorkInJson() + { + var writer = new StringWriter(); + var obj = new Example { MyString = null }; + + EmitDefaultsJsonCompatibleSerializer.Serialize(writer, obj, typeof(Example)); + Dump.WriteLine(writer); + + writer.ToString().Should().Contain("MyString"); + } + + [Fact] + // Todo: this is actualy roundtrip + public void DeserializationOfDefaultsWorkInJson() + { + var writer = new StringWriter(); + var obj = new Example { MyString = null }; + + RoundtripEmitDefaultsJsonCompatibleSerializer.Serialize(writer, obj, typeof(Example)); + Dump.WriteLine(writer); + var result = Deserializer.Deserialize(UsingReaderFor(writer)); + + result.MyString.Should().BeNull(); + } + + [Fact] + public void SerializationOfOrderedProperties() + { + var obj = new OrderExample(); + var writer = new StringWriter(); + + Serializer.Serialize(writer, obj); + var serialized = writer.ToString(); + Dump.WriteLine(serialized); + + serialized.Should() + .Be("Order1: Order1 value\r\nOrder2: Order2 value\r\n", "the properties should be in the right order"); + } + + [Fact] + public void SerializationRespectsYamlIgnoreAttribute() + { + + var writer = new StringWriter(); + var obj = new IgnoreExample(); + + Serializer.Serialize(writer, obj); + var serialized = writer.ToString(); + Dump.WriteLine(serialized); + + serialized.Should().NotContain("IgnoreMe"); + } + + [Fact] + public void SerializationRespectsScalarStyle() + { + var writer = new StringWriter(); + var obj = new ScalarStyleExample(); + + Serializer.Serialize(writer, obj); + var serialized = writer.ToString(); + Dump.WriteLine(serialized); + + serialized.Should() + .Be("LiteralString: |-\r\n Test\r\nDoubleQuotedString: \"Test\"\r\n", "the properties should be specifically styled"); + } + + [Fact] + public void SerializationSkipsPropertyWhenUsingDefaultValueAttribute() + { + var writer = new StringWriter(); + var obj = new DefaultsExample { Value = DefaultsExample.DefaultValue }; + + Serializer.Serialize(writer, obj); + var serialized = writer.ToString(); + Dump.WriteLine(serialized); + + serialized.Should().NotContain("Value"); + } + + [Fact] + public void SerializationEmitsPropertyWhenUsingEmitDefaultsAndDefaultValueAttribute() + { + var writer = new StringWriter(); + var obj = new DefaultsExample { Value = DefaultsExample.DefaultValue }; + + EmitDefaultsSerializer.Serialize(writer, obj); + var serialized = writer.ToString(); + Dump.WriteLine(serialized); + + serialized.Should().Contain("Value"); + } + + [Fact] + public void SerializationEmitsPropertyWhenValueDifferFromDefaultValueAttribute() + { + var writer = new StringWriter(); + var obj = new DefaultsExample { Value = "non-default" }; + + Serializer.Serialize(writer, obj); + var serialized = writer.ToString(); + Dump.WriteLine(serialized); + + serialized.Should().Contain("Value"); + } + + [Fact] + public void SerializingAGenericDictionaryShouldNotThrowTargetException() + { + var obj = new CustomGenericDictionary { + { "hello", "world" }, + }; + + Action action = () => Serializer.Serialize(new StringWriter(), obj); + + action.ShouldNotThrow(); + } + + [Fact] + public void SerializaionUtilizeNamingConventions() + { + var convention = A.Fake(); + A.CallTo(() => convention.Apply(A._)).ReturnsLazily((string x) => x); + var obj = new NameConvention { FirstTest = "1", SecondTest = "2" }; + + var serializer = new Serializer(namingConvention: convention); + serializer.Serialize(new StringWriter(), obj); + + A.CallTo(() => convention.Apply("FirstTest")).MustHaveHappened(); + A.CallTo(() => convention.Apply("SecondTest")).MustHaveHappened(); + } + + [Fact] + public void DeserializationUtilizeNamingConventions() + { + var convention = A.Fake(); + A.CallTo(() => convention.Apply(A._)).ReturnsLazily((string x) => x); + var text = Lines( + "FirstTest: 1", + "SecondTest: 2"); + + var deserializer = new Deserializer(namingConvention: convention); + deserializer.Deserialize(UsingReaderFor(text)); + + A.CallTo(() => convention.Apply("FirstTest")).MustHaveHappened(); + A.CallTo(() => convention.Apply("SecondTest")).MustHaveHappened(); + } + + [Fact] + public void TypeConverterIsUsedOnListItems() + { + var text = Lines( + "- !", + " Left: hello", + " Right: world") + .TemplatedOn(); + + var list = Deserializer.Deserialize>(UsingReaderFor(text)); + + list + .Should().NotBeNull() + .And.ContainSingle(c => c.Equals("[hello, world]")); + } + + [Fact] + public void BackreferencesAreMergedWithMappings() + { + var stream = Yaml.StreamFrom("backreference.yaml"); + + var parser = new MergingParser(new Parser(stream)); + var result = Deserializer.Deserialize>>(new EventReader(parser)); + + var alias = result["alias"]; + alias.Should() + .Contain("key1", "value1", "key1 should be inherited from the backreferenced mapping") + .And.Contain("key2", "Overriding key2", "key2 should be overriden by the actual mapping") + .And.Contain("key3", "value3", "key3 is defined in the actual mapping"); + } + + [Fact] + public void MergingDoesNotProduceDuplicateAnchors() + { + var parser = new MergingParser(Yaml.ParserForText(@" + anchor: &default + key1: &myValue value1 + key2: value2 + alias: + <<: *default + key2: Overriding key2 + key3: value3 + useMyValue: + key: *myValue + ")); + var result = Deserializer.Deserialize>>(new EventReader(parser)); + + var alias = result["alias"]; + alias.Should() + .Contain("key1", "value1", "key1 should be inherited from the backreferenced mapping") + .And.Contain("key2", "Overriding key2", "key2 should be overriden by the actual mapping") + .And.Contain("key3", "value3", "key3 is defined in the actual mapping"); + + result["useMyValue"].Should() + .Contain("key", "value1", "key should be copied"); + } + + [Fact] + public void ExampleFromSpecificationIsHandledCorrectly() + { + var parser = new MergingParser(Yaml.ParserForText(@" + obj: + - &CENTER { x: 1, y: 2 } + - &LEFT { x: 0, y: 2 } + - &BIG { r: 10 } + - &SMALL { r: 1 } + + # All the following maps are equal: + results: + - # Explicit keys + x: 1 + y: 2 + r: 10 + label: center/big + + - # Merge one map + << : *CENTER + r: 10 + label: center/big + + - # Merge multiple maps + << : [ *CENTER, *BIG ] + label: center/big + + - # Override + #<< : [ *BIG, *LEFT, *SMALL ] # This does not work because, in the current implementation, + # later keys override former keys. This could be fixed, but that + # is not trivial because the deserializer allows aliases to refer to + # an anchor that is defined later in the document, and the way it is + # implemented, the value is assigned later when the anchored value is + # deserialized. + << : [ *SMALL, *LEFT, *BIG ] + x: 1 + label: center/big + ")); + + var result = Deserializer.Deserialize>>>(new EventReader(parser)); + + int index = 0; + foreach (var mapping in result["results"]) + { + mapping.Should() + .Contain("x", "1", "'x' should be '1' in result #{0}", index) + .And.Contain("y", "2", "'y' should be '2' in result #{0}", index) + .And.Contain("r", "10", "'r' should be '10' in result #{0}", index) + .And.Contain("label", "center/big", "'label' should be 'center/big' in result #{0}", index); + + ++index; + } + } + + [Fact] + public void IgnoreExtraPropertiesIfWanted() + { + var text = Lines("aaa: hello", "bbb: world"); + var des = new Deserializer(ignoreUnmatched: true); + var actual = des.Deserialize(UsingReaderFor(text)); + actual.aaa.Should().Be("hello"); + } + + [Fact] + public void DontIgnoreExtraPropertiesIfWanted() + { + var text = Lines("aaa: hello", "bbb: world"); + var des = new Deserializer(ignoreUnmatched: false); + var actual = Record.Exception(() => des.Deserialize(UsingReaderFor(text))); + Assert.IsType(actual); + } + + [Fact] + public void IgnoreExtraPropertiesIfWantedBefore() + { + var text = Lines("bbb: [200,100]", "aaa: hello"); + var des = new Deserializer(ignoreUnmatched: true); + var actual = des.Deserialize(UsingReaderFor(text)); + actual.aaa.Should().Be("hello"); + } + + [Fact] + public void IgnoreExtraPropertiesIfWantedNamingScheme() + { + var text = Lines( + "scratch: 'scratcher'", + "deleteScratch: false", + "notScratch: 9443", + "notScratch: 192.168.1.30", + "mappedScratch:", + "- '/work/'" + ); + + var des = new Deserializer(namingConvention: new CamelCaseNamingConvention(), ignoreUnmatched: true); + var actual = des.Deserialize(UsingReaderFor(text)); + actual.Scratch.Should().Be("scratcher"); + actual.DeleteScratch.Should().Be(false); + actual.MappedScratch.Should().ContainInOrder(new[] { "/work/" }); + } + + [Fact] + public void InvalidTypeConversionsProduceProperExceptions() + { + var text = Lines("- 1", "- two", "- 3"); + + var sut = new Deserializer(); + var exception = Assert.Throws(() => sut.Deserialize>(UsingReaderFor(text))); + + Assert.Equal(2, exception.Start.Line); + Assert.Equal(3, exception.Start.Column); + } + + [Fact] + public void SerializeDynamicPropertyAndApplyNamingConvention() + { + dynamic obj = new ExpandoObject(); + obj.property_one = new ExpandoObject(); + ((IDictionary)obj.property_one).Add("new_key_here", "new_value"); + + var mockNamingConvention = A.Fake(); + A.CallTo(() => mockNamingConvention.Apply(A.Ignored)).Returns("xxx"); + + var serializer = new Serializer(namingConvention: mockNamingConvention); + var writer = new StringWriter(); + serializer.Serialize(writer, obj); + + writer.ToString().Should().Contain("xxx: new_value"); + } + + [Fact] + public void SerializeGenericDictionaryPropertyAndDoNotApplyNamingConvention() + { + var obj = new Dictionary(); + obj["property_one"] = new GenericTestDictionary(); + ((IDictionary)obj["property_one"]).Add("new_key_here", "new_value"); + + var mockNamingConvention = A.Fake(); + A.CallTo(() => mockNamingConvention.Apply(A.Ignored)).Returns("xxx"); + + var serializer = new Serializer(namingConvention: mockNamingConvention); + var writer = new StringWriter(); + serializer.Serialize(writer, obj); + + writer.ToString().Should().Contain("new_key_here: new_value"); + } + + [Fact] + public void SpecialFloatsAreDeserializedCorrectly() + { + var deserializer = new Deserializer(); + var doubles = deserializer.Deserialize>(Yaml.ReaderForText(@" + - .nan + - .inf + - -.inf + - 2.3e4 + - 1 + ")); + + Assert.Equal(new double[] + { + double.NaN, + double.PositiveInfinity, + double.NegativeInfinity, + 23000, + 1.0 + }, doubles); + } + + [Fact] + public void SpecialFloatsAreSerializedCorrectly() + { + var serializer = new Serializer(); + + var buffer = new StringWriter(); + serializer.Serialize(buffer, new double[] + { + double.NaN, + double.PositiveInfinity, + double.NegativeInfinity, + }); + + var text = buffer.ToString(); + + Assert.Contains("- .nan", text); + Assert.Contains("- .inf", text); + Assert.Contains("- -.inf", text); + } + + [Fact] + public void NegativeIntegersCanBeDeserialized() + { + var deserializer = new Deserializer(); + + var value = deserializer.Deserialize(Yaml.ReaderForText(@" + '-123' + ")); + Assert.Equal(-123, value); + } + + #region Test Dictionary that implements IDictionary<,>, but not IDictionary + public class GenericTestDictionary : IDictionary + { + private readonly Dictionary _dictionary; + public GenericTestDictionary() + { + _dictionary = new Dictionary(); + } + public void Add(TKey key, TValue value) + { + _dictionary.Add(key, value); + } + + public bool ContainsKey(TKey key) + { + return _dictionary.ContainsKey(key); + } + + public ICollection Keys + { + get { return _dictionary.Keys; } + } + + public bool Remove(TKey key) + { + return _dictionary.Remove(key); + } + + public bool TryGetValue(TKey key, out TValue value) + { + return _dictionary.TryGetValue(key, out value); + } + + public ICollection Values + { + get { return _dictionary.Values; } + } + + public TValue this[TKey key] + { + get { return _dictionary[key]; } + set { _dictionary[key] = value; } + } + + public void Add(KeyValuePair item) + { + ((IDictionary)_dictionary).Add(item); + } + + public void Clear() + { + _dictionary.Clear(); + } + + public bool Contains(KeyValuePair item) + { + return ((IDictionary)_dictionary).Contains(item); + } + + public void CopyTo(KeyValuePair[] array, int arrayIndex) + { + ((IDictionary)_dictionary).CopyTo(array, arrayIndex); + } + + public int Count + { + get { return _dictionary.Count; } + } + + public bool IsReadOnly + { + get { return false; } + } + + public bool Remove(KeyValuePair item) + { + return ((IDictionary)_dictionary).Remove(item); + } + + public IEnumerator> GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _dictionary.GetEnumerator(); + } + } + #endregion + } } diff --git a/YamlDotNet.Test/Yaml.cs b/YamlDotNet.Test/Yaml.cs index 5bdea1bbc..9d4845b37 100644 --- a/YamlDotNet.Test/Yaml.cs +++ b/YamlDotNet.Test/Yaml.cs @@ -28,82 +28,82 @@ namespace YamlDotNet.Test { - public static class Yaml - { - public static TextReader StreamFrom(string name) - { - var fromType = typeof(Yaml); - var assembly = Assembly.GetAssembly(fromType); - var stream = assembly.GetManifestResourceStream(name) ?? - assembly.GetManifestResourceStream(fromType.Namespace + ".files." + name); - return new StreamReader(stream); - } + public static class Yaml + { + public static TextReader StreamFrom(string name) + { + var fromType = typeof(Yaml); + var assembly = Assembly.GetAssembly(fromType); + var stream = assembly.GetManifestResourceStream(name) ?? + assembly.GetManifestResourceStream(fromType.Namespace + ".files." + name); + return new StreamReader(stream); + } - public static string TemplatedOn(this TextReader reader) - { - var text = reader.ReadToEnd(); - return text.TemplatedOn(); - } + public static string TemplatedOn(this TextReader reader) + { + var text = reader.ReadToEnd(); + return text.TemplatedOn(); + } - public static string TemplatedOn(this string text) - { - return Regex.Replace(text, @"{type}", match => - Uri.EscapeDataString(String.Format("{0}, {1}", typeof(T).FullName, typeof(T).Assembly.FullName))); - } + public static string TemplatedOn(this string text) + { + return Regex.Replace(text, @"{type}", match => + Uri.EscapeDataString(String.Format("{0}, {1}", typeof(T).FullName, typeof(T).Assembly.FullName))); + } - public static IParser ParserForEmptyContent() - { - return new Parser(new StringReader(string.Empty)); - } + public static IParser ParserForEmptyContent() + { + return new Parser(new StringReader(string.Empty)); + } - public static IParser ParserForResource(string name) - { - return new Parser(Yaml.StreamFrom(name)); - } + public static IParser ParserForResource(string name) + { + return new Parser(Yaml.StreamFrom(name)); + } - public static IParser ParserForText(string yamlText) - { - return new Parser(ReaderForText(yamlText)); - } + public static IParser ParserForText(string yamlText) + { + return new Parser(ReaderForText(yamlText)); + } - public static Scanner ScannerForResource(string name) - { - return new Scanner(Yaml.StreamFrom(name)); - } + public static Scanner ScannerForResource(string name) + { + return new Scanner(Yaml.StreamFrom(name)); + } - public static Scanner ScannerForText(string yamlText) - { - return new Scanner(ReaderForText(yamlText)); - } + public static Scanner ScannerForText(string yamlText) + { + return new Scanner(ReaderForText(yamlText)); + } - public static StringReader ReaderForText(string yamlText) - { - var lines = yamlText - .Split('\n') - .Select(l => l.TrimEnd('\r', '\n')) - .SkipWhile(l => l.Trim(' ', '\t').Length == 0) - .ToList(); + public static StringReader ReaderForText(string yamlText) + { + var lines = yamlText + .Split('\n') + .Select(l => l.TrimEnd('\r', '\n')) + .SkipWhile(l => l.Trim(' ', '\t').Length == 0) + .ToList(); - while (lines.Count > 0 && lines[lines.Count - 1].Trim(' ', '\t').Length == 0) - { - lines.RemoveAt(lines.Count - 1); - } + while (lines.Count > 0 && lines[lines.Count - 1].Trim(' ', '\t').Length == 0) + { + lines.RemoveAt(lines.Count - 1); + } - if (lines.Count > 0) - { - var indent = Regex.Match(lines[0], @"^(\t+)"); - if (!indent.Success) - { - throw new ArgumentException("Invalid indentation"); - } + if (lines.Count > 0) + { + var indent = Regex.Match(lines[0], @"^(\s+)"); + if (!indent.Success) + { + throw new ArgumentException("Invalid indentation"); + } - lines = lines - .Select(l => l.Substring(indent.Groups[1].Length)) - .ToList(); - } + lines = lines + .Select(l => l.Substring(indent.Groups[1].Length)) + .ToList(); + } - var reader = new StringReader(string.Join("\n", lines.ToArray())); - return reader; - } - } + var reader = new StringReader(string.Join("\n", lines.ToArray())); + return reader; + } + } } \ No newline at end of file diff --git a/YamlDotNet.Test/files/09-flow-mapping.yaml b/YamlDotNet.Test/files/09-flow-mapping.yaml index 2020cb265..1ae8486f4 100644 --- a/YamlDotNet.Test/files/09-flow-mapping.yaml +++ b/YamlDotNet.Test/files/09-flow-mapping.yaml @@ -1,4 +1,4 @@ { - a simple key: a value, # Note that the KEY token is produced. - ? a complex key: another value, + a simple key: a value, # Note that the KEY token is produced. + ? a complex key: another value, } \ No newline at end of file diff --git a/YamlDotNet.Test/files/dictionary-explicit.yaml b/YamlDotNet.Test/files/dictionary-explicit.yaml index 82a2f1867..179db5709 100644 --- a/YamlDotNet.Test/files/dictionary-explicit.yaml +++ b/YamlDotNet.Test/files/dictionary-explicit.yaml @@ -1,4 +1,4 @@ ! { - key1: 1, - key2: 2 + key1: 1, + key2: 2 } \ No newline at end of file diff --git a/YamlDotNet.Test/files/dictionary.yaml b/YamlDotNet.Test/files/dictionary.yaml index 14e7ecfab..7d8b593f9 100644 --- a/YamlDotNet.Test/files/dictionary.yaml +++ b/YamlDotNet.Test/files/dictionary.yaml @@ -1,4 +1,4 @@ !!map { - key1: value1, - key2: value2 + key1: value1, + key2: value2 } \ No newline at end of file diff --git a/YamlDotNet.Test/files/explicit-type.template b/YamlDotNet.Test/files/explicit-type.template index 7361f6ded..d0669839b 100644 --- a/YamlDotNet.Test/files/explicit-type.template +++ b/YamlDotNet.Test/files/explicit-type.template @@ -1,3 +1,3 @@ ! { - aaa: bbb + aaa: bbb } \ No newline at end of file diff --git a/YamlDotNet.sln b/YamlDotNet.sln index 2b3293a91..7ed01c2ad 100644 --- a/YamlDotNet.sln +++ b/YamlDotNet.sln @@ -8,6 +8,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .gitignore = .gitignore appveyor.yml = appveyor.yml build.ps1 = build.ps1 + CONTRIBUTING.md = CONTRIBUTING.md LICENSE = LICENSE prebuild.ps1 = prebuild.ps1 README.md = README.md diff --git a/YamlDotNet/Core/AnchorNotFoundException.cs b/YamlDotNet/Core/AnchorNotFoundException.cs index d29b37475..7e8585248 100644 --- a/YamlDotNet/Core/AnchorNotFoundException.cs +++ b/YamlDotNet/Core/AnchorNotFoundException.cs @@ -24,58 +24,58 @@ namespace YamlDotNet.Core { - /// - /// The exception that is thrown when an alias references an anchor that does not exist. - /// - [Serializable] - public class AnchorNotFoundException : YamlException - { - /// - /// Initializes a new instance of the class. - /// - public AnchorNotFoundException() - { - } + /// + /// The exception that is thrown when an alias references an anchor that does not exist. + /// + [Serializable] + public class AnchorNotFoundException : YamlException + { + /// + /// Initializes a new instance of the class. + /// + public AnchorNotFoundException() + { + } - /// - /// Initializes a new instance of the class. - /// - /// The message. - public AnchorNotFoundException(string message) - : base(message) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The message. + public AnchorNotFoundException(string message) + : base(message) + { + } - /// - /// Initializes a new instance of the class. - /// - public AnchorNotFoundException(Mark start, Mark end, string message) - : base(start, end, message) - { - } + /// + /// Initializes a new instance of the class. + /// + public AnchorNotFoundException(Mark start, Mark end, string message) + : base(start, end, message) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The message. - /// The inner. - public AnchorNotFoundException(string message, Exception inner) - : base(message, inner) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The message. + /// The inner. + public AnchorNotFoundException(string message, Exception inner) + : base(message, inner) + { + } #if !(PORTABLE || UNITY) - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is null. - /// The class name is null or is zero (0). - protected AnchorNotFoundException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is null. + /// The class name is null or is zero (0). + protected AnchorNotFoundException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } #endif - } + } } diff --git a/YamlDotNet/Core/CharacterAnalyzer.cs b/YamlDotNet/Core/CharacterAnalyzer.cs index 4df6e3bb9..05a93996a 100644 --- a/YamlDotNet/Core/CharacterAnalyzer.cs +++ b/YamlDotNet/Core/CharacterAnalyzer.cs @@ -25,154 +25,154 @@ namespace YamlDotNet.Core { - [Serializable] - internal class CharacterAnalyzer where TBuffer : ILookAheadBuffer - { - private readonly TBuffer buffer; - - public CharacterAnalyzer(TBuffer buffer) - { - this.buffer = buffer; - } - - public TBuffer Buffer { - get { - return buffer; - } - } - - public bool EndOfInput { - get { - return buffer.EndOfInput; - } - } - - public char Peek(int offset) - { - return buffer.Peek(offset); - } - - public void Skip(int length) - { - buffer.Skip(length); - } - - public bool IsAlphaNumericDashOrUnderscore(int offset = 0) - { - var character = buffer.Peek(offset); - return - (character >= '0' && character <= '9') || - (character >= 'A' && character <= 'Z') || - (character >= 'a' && character <= 'z') || - character == '_' || - character == '-'; - } - - public bool IsAscii(int offset = 0) - { - return buffer.Peek(offset) <= '\x7F'; - } - - public bool IsPrintable(int offset = 0) - { - var character = buffer.Peek(offset); - return - character == '\x9' || - character == '\xA' || - character == '\xD' || - (character >= '\x20' && character <= '\x7E') || - character == '\x85' || - (character >= '\xA0' && character <= '\xD7FF') || - (character >= '\xE000' && character <= '\xFFFD'); - } - - public bool IsDigit(int offset = 0) - { - var character = buffer.Peek(offset); - return character >= '0' && character <= '9'; - } - - public int AsDigit(int offset = 0) - { - return buffer.Peek(offset) - '0'; - } - - public bool IsHex(int offset) - { - var character = buffer.Peek(offset); - return - (character >= '0' && character <= '9') || - (character >= 'A' && character <= 'F') || - (character >= 'a' && character <= 'f'); - } - - public int AsHex(int offset) - { - var character = buffer.Peek(offset); - - if (character <= '9') - { - return character - '0'; - } - if (character <= 'F') - { - return character - 'A' + 10; - } - return character - 'a' + 10; - } - - public bool IsSpace(int offset = 0) - { - return Check(' ', offset); - } - - public bool IsZero(int offset = 0) - { - return Check('\0', offset); - } - - public bool IsTab(int offset = 0) - { - return Check('\t', offset); - } - - public bool IsWhite(int offset = 0) - { - return IsSpace(offset) || IsTab(offset); - } - - public bool IsBreak(int offset = 0) - { - return Check("\r\n\x85\x2028\x2029", offset); - } - - public bool IsCrLf(int offset = 0) - { - return Check('\r', offset) && Check('\n', offset + 1); - } - - public bool IsBreakOrZero(int offset = 0) - { - return IsBreak(offset) || IsZero(offset); - } - - public bool IsWhiteBreakOrZero(int offset = 0) - { - return IsWhite(offset) || IsBreakOrZero(offset); - } - - public bool Check(char expected, int offset = 0) - { - return buffer.Peek(offset) == expected; - } - - public bool Check(string expectedCharacters, int offset = 0) - { - // Todo: using it this way doesn't break anything, it's not realy wrong... - Debug.Assert(expectedCharacters.Length > 1, "Use Check(char, int) instead."); - - var character = buffer.Peek(offset); - return expectedCharacters.IndexOf(character) != -1; - } - } + [Serializable] + internal class CharacterAnalyzer where TBuffer : ILookAheadBuffer + { + private readonly TBuffer buffer; + + public CharacterAnalyzer(TBuffer buffer) + { + this.buffer = buffer; + } + + public TBuffer Buffer { + get { + return buffer; + } + } + + public bool EndOfInput { + get { + return buffer.EndOfInput; + } + } + + public char Peek(int offset) + { + return buffer.Peek(offset); + } + + public void Skip(int length) + { + buffer.Skip(length); + } + + public bool IsAlphaNumericDashOrUnderscore(int offset = 0) + { + var character = buffer.Peek(offset); + return + (character >= '0' && character <= '9') || + (character >= 'A' && character <= 'Z') || + (character >= 'a' && character <= 'z') || + character == '_' || + character == '-'; + } + + public bool IsAscii(int offset = 0) + { + return buffer.Peek(offset) <= '\x7F'; + } + + public bool IsPrintable(int offset = 0) + { + var character = buffer.Peek(offset); + return + character == '\x9' || + character == '\xA' || + character == '\xD' || + (character >= '\x20' && character <= '\x7E') || + character == '\x85' || + (character >= '\xA0' && character <= '\xD7FF') || + (character >= '\xE000' && character <= '\xFFFD'); + } + + public bool IsDigit(int offset = 0) + { + var character = buffer.Peek(offset); + return character >= '0' && character <= '9'; + } + + public int AsDigit(int offset = 0) + { + return buffer.Peek(offset) - '0'; + } + + public bool IsHex(int offset) + { + var character = buffer.Peek(offset); + return + (character >= '0' && character <= '9') || + (character >= 'A' && character <= 'F') || + (character >= 'a' && character <= 'f'); + } + + public int AsHex(int offset) + { + var character = buffer.Peek(offset); + + if (character <= '9') + { + return character - '0'; + } + if (character <= 'F') + { + return character - 'A' + 10; + } + return character - 'a' + 10; + } + + public bool IsSpace(int offset = 0) + { + return Check(' ', offset); + } + + public bool IsZero(int offset = 0) + { + return Check('\0', offset); + } + + public bool IsTab(int offset = 0) + { + return Check('\t', offset); + } + + public bool IsWhite(int offset = 0) + { + return IsSpace(offset) || IsTab(offset); + } + + public bool IsBreak(int offset = 0) + { + return Check("\r\n\x85\x2028\x2029", offset); + } + + public bool IsCrLf(int offset = 0) + { + return Check('\r', offset) && Check('\n', offset + 1); + } + + public bool IsBreakOrZero(int offset = 0) + { + return IsBreak(offset) || IsZero(offset); + } + + public bool IsWhiteBreakOrZero(int offset = 0) + { + return IsWhite(offset) || IsBreakOrZero(offset); + } + + public bool Check(char expected, int offset = 0) + { + return buffer.Peek(offset) == expected; + } + + public bool Check(string expectedCharacters, int offset = 0) + { + // Todo: using it this way doesn't break anything, it's not realy wrong... + Debug.Assert(expectedCharacters.Length > 1, "Use Check(char, int) instead."); + + var character = buffer.Peek(offset); + return expectedCharacters.IndexOf(character) != -1; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Constants.cs b/YamlDotNet/Core/Constants.cs index c1f7934d8..c4b055e40 100644 --- a/YamlDotNet/Core/Constants.cs +++ b/YamlDotNet/Core/Constants.cs @@ -24,21 +24,21 @@ 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 = "!"; - } + /// + /// 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/Cursor.cs b/YamlDotNet/Core/Cursor.cs index 4029e927d..5060256a6 100644 --- a/YamlDotNet/Core/Cursor.cs +++ b/YamlDotNet/Core/Cursor.cs @@ -23,50 +23,50 @@ namespace YamlDotNet.Core { - [Serializable] - internal class Cursor - { - public int Index { get; set; } - public int Line { get; set; } - public int LineOffset { get; set; } + [Serializable] + internal class Cursor + { + public int Index { get; set; } + public int Line { get; set; } + public int LineOffset { get; set; } - public Cursor() - { - Line = 1; - } + public Cursor() + { + Line = 1; + } - public Cursor(Cursor cursor) - { - Index = cursor.Index; - Line = cursor.Line; - LineOffset = cursor.LineOffset; - } + public Cursor(Cursor cursor) + { + Index = cursor.Index; + Line = cursor.Line; + LineOffset = cursor.LineOffset; + } - public Mark Mark() - { - return new Mark(Index, Line, LineOffset + 1); - } + public Mark Mark() + { + return new Mark(Index, Line, LineOffset + 1); + } - public void Skip() - { - Index++; - LineOffset++; - } - - public void SkipLineByOffset(int offset) - { - Index += offset; - Line++; - LineOffset = 0; - } + public void Skip() + { + Index++; + LineOffset++; + } + + public void SkipLineByOffset(int offset) + { + Index += offset; + Line++; + LineOffset = 0; + } - public void ForceSkipLineAfterNonBreak() - { - if (LineOffset != 0) - { - Line++; - LineOffset = 0; - } - } - } + public void ForceSkipLineAfterNonBreak() + { + if (LineOffset != 0) + { + Line++; + LineOffset = 0; + } + } + } } diff --git a/YamlDotNet/Core/DuplicateAnchorException.cs b/YamlDotNet/Core/DuplicateAnchorException.cs index 7268103be..0ff1dc214 100644 --- a/YamlDotNet/Core/DuplicateAnchorException.cs +++ b/YamlDotNet/Core/DuplicateAnchorException.cs @@ -24,58 +24,58 @@ namespace YamlDotNet.Core { - /// - /// The exception that is thrown when a duplicate anchor is detected. - /// - [Serializable] - public class DuplicateAnchorException : YamlException - { - /// - /// Initializes a new instance of the class. - /// - public DuplicateAnchorException() - { - } + /// + /// The exception that is thrown when a duplicate anchor is detected. + /// + [Serializable] + public class DuplicateAnchorException : YamlException + { + /// + /// Initializes a new instance of the class. + /// + public DuplicateAnchorException() + { + } - /// - /// Initializes a new instance of the class. - /// - /// The message. - public DuplicateAnchorException(string message) - : base(message) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The message. + public DuplicateAnchorException(string message) + : base(message) + { + } - /// - /// Initializes a new instance of the class. - /// - public DuplicateAnchorException(Mark start, Mark end, string message) - : base(start, end, message) - { - } + /// + /// Initializes a new instance of the class. + /// + public DuplicateAnchorException(Mark start, Mark end, string message) + : base(start, end, message) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The message. - /// The inner. - public DuplicateAnchorException(string message, Exception inner) - : base(message, inner) - { + /// + /// Initializes a new instance of the class. + /// + /// The message. + /// The inner. + public DuplicateAnchorException(string message, Exception inner) + : base(message, inner) + { } #if !(PORTABLE || UNITY) - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is null. - /// The class name is null or is zero (0). - protected DuplicateAnchorException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is null. + /// The class name is null or is zero (0). + protected DuplicateAnchorException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } #endif } } diff --git a/YamlDotNet/Core/Emitter.cs b/YamlDotNet/Core/Emitter.cs index e6a32bc5a..566cac9e4 100644 --- a/YamlDotNet/Core/Emitter.cs +++ b/YamlDotNet/Core/Emitter.cs @@ -32,264 +32,264 @@ namespace YamlDotNet.Core { - /// - /// Emits YAML streams. - /// - public class Emitter : IEmitter - { - private const int MinBestIndent = 2; - private const int MaxBestIndent = 9; - private const int MaxAliasLength = 128; - - private static readonly Regex uriReplacer = new Regex(@"[^0-9A-Za-z_\-;?@=$~\\\)\]/:&+,\.\*\(\[!]", - StandardRegexOptions.Compiled | RegexOptions.Singleline); - - private readonly TextWriter output; + /// + /// Emits YAML streams. + /// + public class Emitter : IEmitter + { + private const int MinBestIndent = 2; + private const int MaxBestIndent = 9; + private const int MaxAliasLength = 128; + + private static readonly Regex uriReplacer = new Regex(@"[^0-9A-Za-z_\-;?@=$~\\\)\]/:&+,\.\*\(\[!]", + StandardRegexOptions.Compiled | RegexOptions.Singleline); + + private readonly TextWriter output; private readonly bool outputUsesUnicodeEncoding; - private readonly bool isCanonical; - private readonly int bestIndent; - private readonly int bestWidth; - private EmitterState state; - - private readonly Stack states = new Stack(); - private readonly Queue events = new Queue(); - private readonly Stack indents = new Stack(); - private readonly TagDirectiveCollection tagDirectives = new TagDirectiveCollection(); - private int indent; - private int flowLevel; - private bool isMappingContext; - private bool isSimpleKeyContext; - private bool isRootContext; - - private int column; - private bool isWhitespace; - private bool isIndentation; - - private bool isOpenEnded; - private bool isDocumentEndWritten; - - private readonly AnchorData anchorData = new AnchorData(); - private readonly TagData tagData = new TagData(); - private readonly ScalarData scalarData = new ScalarData(); - - private class AnchorData - { - public string anchor; - public bool isAlias; - } - - private class TagData - { - public string handle; - public string suffix; - } - - private class ScalarData - { - public string value; - public bool isMultiline; - public bool isFlowPlainAllowed; - public bool isBlockPlainAllowed; - public bool isSingleQuotedAllowed; - public bool isBlockAllowed; - public ScalarStyle style; - } - - /// - /// Initializes a new instance of the class. - /// - /// The where the emitter will write. - public Emitter(TextWriter output) - : this(output, MinBestIndent) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The where the emitter will write. - /// The preferred indentation. - public Emitter(TextWriter output, int bestIndent) - : this(output, bestIndent, int.MaxValue) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The where the emitter will write. - /// The preferred indentation. - /// The preferred text width. - public Emitter(TextWriter output, int bestIndent, int bestWidth) - : this(output, bestIndent, bestWidth, false) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The where the emitter will write. - /// The preferred indentation. - /// The preferred text width. - /// If true, write the output in canonical form. - public Emitter(TextWriter output, int bestIndent, int bestWidth, bool isCanonical) - { - if (bestIndent < MinBestIndent || bestIndent > MaxBestIndent) - { - throw new ArgumentOutOfRangeException("bestIndent", string.Format(CultureInfo.InvariantCulture, - "The bestIndent parameter must be between {0} and {1}.", MinBestIndent, MaxBestIndent)); - } - - this.bestIndent = bestIndent; - - if (bestWidth <= bestIndent * 2) - { - throw new ArgumentOutOfRangeException("bestWidth", "The bestWidth parameter must be greater than bestIndent * 2."); - } - - this.bestWidth = bestWidth; - - this.isCanonical = isCanonical; - - this.output = output; + private readonly bool isCanonical; + private readonly int bestIndent; + private readonly int bestWidth; + private EmitterState state; + + private readonly Stack states = new Stack(); + private readonly Queue events = new Queue(); + private readonly Stack indents = new Stack(); + private readonly TagDirectiveCollection tagDirectives = new TagDirectiveCollection(); + private int indent; + private int flowLevel; + private bool isMappingContext; + private bool isSimpleKeyContext; + private bool isRootContext; + + private int column; + private bool isWhitespace; + private bool isIndentation; + + private bool isOpenEnded; + private bool isDocumentEndWritten; + + private readonly AnchorData anchorData = new AnchorData(); + private readonly TagData tagData = new TagData(); + private readonly ScalarData scalarData = new ScalarData(); + + private class AnchorData + { + public string anchor; + public bool isAlias; + } + + private class TagData + { + public string handle; + public string suffix; + } + + private class ScalarData + { + public string value; + public bool isMultiline; + public bool isFlowPlainAllowed; + public bool isBlockPlainAllowed; + public bool isSingleQuotedAllowed; + public bool isBlockAllowed; + public ScalarStyle style; + } + + /// + /// Initializes a new instance of the class. + /// + /// The where the emitter will write. + public Emitter(TextWriter output) + : this(output, MinBestIndent) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The where the emitter will write. + /// The preferred indentation. + public Emitter(TextWriter output, int bestIndent) + : this(output, bestIndent, int.MaxValue) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The where the emitter will write. + /// The preferred indentation. + /// The preferred text width. + public Emitter(TextWriter output, int bestIndent, int bestWidth) + : this(output, bestIndent, bestWidth, false) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The where the emitter will write. + /// The preferred indentation. + /// The preferred text width. + /// If true, write the output in canonical form. + public Emitter(TextWriter output, int bestIndent, int bestWidth, bool isCanonical) + { + if (bestIndent < MinBestIndent || bestIndent > MaxBestIndent) + { + throw new ArgumentOutOfRangeException("bestIndent", string.Format(CultureInfo.InvariantCulture, + "The bestIndent parameter must be between {0} and {1}.", MinBestIndent, MaxBestIndent)); + } + + this.bestIndent = bestIndent; + + if (bestWidth <= bestIndent * 2) + { + throw new ArgumentOutOfRangeException("bestWidth", "The bestWidth parameter must be greater than bestIndent * 2."); + } + + this.bestWidth = bestWidth; + + this.isCanonical = isCanonical; + + this.output = output; this.outputUsesUnicodeEncoding = IsUnicode(output.Encoding); - } - - /// - /// Emit an evt. - /// - public void Emit(ParsingEvent @event) - { - events.Enqueue(@event); - - while (!NeedMoreEvents()) - { - var current = events.Peek(); - try - { - - AnalyzeEvent(current); - StateMachine(current); - } - finally - { - // Only dequeue after calling state_machine because it checks how many events are in the queue. - // Todo: well, move into StateMachine() then - events.Dequeue(); - } - } - } - - /// - /// Check if we need to accumulate more events before emitting. - /// - /// We accumulate extra - /// - 1 event for DOCUMENT-START - /// - 2 events for SEQUENCE-START - /// - 3 events for MAPPING-START - /// - private bool NeedMoreEvents() - { - if (events.Count == 0) - { - return true; - } - - int accumulate; - switch (events.Peek().Type) - { - case EventType.DocumentStart: - accumulate = 1; - break; - - case EventType.SequenceStart: - accumulate = 2; - break; - - case EventType.MappingStart: - accumulate = 3; - break; - - default: - return false; - } - - if (events.Count > accumulate) - { - return false; - } - - var level = 0; - foreach (var evt in events) - { - switch (evt.Type) - { - case EventType.DocumentStart: - case EventType.SequenceStart: - case EventType.MappingStart: - ++level; - break; - - case EventType.DocumentEnd: - case EventType.SequenceEnd: - case EventType.MappingEnd: - --level; - break; - } - if (level == 0) - { - return false; - } - } - - return true; - } - - private void AnalyzeEvent(ParsingEvent evt) - { - anchorData.anchor = null; - tagData.handle = null; - tagData.suffix = null; - - var alias = evt as AnchorAlias; - if (alias != null) - { - AnalyzeAnchor(alias.Value, true); - return; - } - - var nodeEvent = evt as NodeEvent; - if (nodeEvent != null) - { - var scalar = evt as Scalar; - if (scalar != null) - { - AnalyzeScalar(scalar); - } - - AnalyzeAnchor(nodeEvent.Anchor, false); - - if (!string.IsNullOrEmpty(nodeEvent.Tag) && (isCanonical || nodeEvent.IsCanonical)) - { - AnalyzeTag(nodeEvent.Tag); - } - } - } - - private void AnalyzeAnchor(string anchor, bool isAlias) - { - anchorData.anchor = anchor; - anchorData.isAlias = isAlias; - } + } + + /// + /// Emit an evt. + /// + public void Emit(ParsingEvent @event) + { + events.Enqueue(@event); + + while (!NeedMoreEvents()) + { + var current = events.Peek(); + try + { + + AnalyzeEvent(current); + StateMachine(current); + } + finally + { + // Only dequeue after calling state_machine because it checks how many events are in the queue. + // Todo: well, move into StateMachine() then + events.Dequeue(); + } + } + } + + /// + /// Check if we need to accumulate more events before emitting. + /// + /// We accumulate extra + /// - 1 event for DOCUMENT-START + /// - 2 events for SEQUENCE-START + /// - 3 events for MAPPING-START + /// + private bool NeedMoreEvents() + { + if (events.Count == 0) + { + return true; + } + + int accumulate; + switch (events.Peek().Type) + { + case EventType.DocumentStart: + accumulate = 1; + break; + + case EventType.SequenceStart: + accumulate = 2; + break; + + case EventType.MappingStart: + accumulate = 3; + break; + + default: + return false; + } + + if (events.Count > accumulate) + { + return false; + } + + var level = 0; + foreach (var evt in events) + { + switch (evt.Type) + { + case EventType.DocumentStart: + case EventType.SequenceStart: + case EventType.MappingStart: + ++level; + break; + + case EventType.DocumentEnd: + case EventType.SequenceEnd: + case EventType.MappingEnd: + --level; + break; + } + if (level == 0) + { + return false; + } + } + + return true; + } + + private void AnalyzeEvent(ParsingEvent evt) + { + anchorData.anchor = null; + tagData.handle = null; + tagData.suffix = null; + + var alias = evt as AnchorAlias; + if (alias != null) + { + AnalyzeAnchor(alias.Value, true); + return; + } + + var nodeEvent = evt as NodeEvent; + if (nodeEvent != null) + { + var scalar = evt as Scalar; + if (scalar != null) + { + AnalyzeScalar(scalar); + } + + AnalyzeAnchor(nodeEvent.Anchor, false); + + if (!string.IsNullOrEmpty(nodeEvent.Tag) && (isCanonical || nodeEvent.IsCanonical)) + { + AnalyzeTag(nodeEvent.Tag); + } + } + } + + private void AnalyzeAnchor(string anchor, bool isAlias) + { + anchorData.anchor = anchor; + anchorData.isAlias = isAlias; + } private void AnalyzeScalar(Scalar scalar) - { + { var value = scalar.Value; - scalarData.value = value; + scalarData.value = value; - if (value.Length == 0) - { + if (value.Length == 0) + { if (scalar.Tag == "tag:yaml.org,2002:null") { scalarData.isMultiline = false; @@ -306,77 +306,77 @@ private void AnalyzeScalar(Scalar scalar) scalarData.isSingleQuotedAllowed = true; scalarData.isBlockAllowed = false; } - return; - } + return; + } - var flowIndicators = false; - var blockIndicators = false; - if (value.StartsWith("---", StringComparison.Ordinal) || value.StartsWith("...", StringComparison.Ordinal)) - { - flowIndicators = true; - blockIndicators = true; - } + var flowIndicators = false; + var blockIndicators = false; + if (value.StartsWith("---", StringComparison.Ordinal) || value.StartsWith("...", StringComparison.Ordinal)) + { + flowIndicators = true; + blockIndicators = true; + } - var buffer = new CharacterAnalyzer(new StringLookAheadBuffer(value)); - var preceededByWhitespace = true; - var followedByWhitespace = buffer.IsWhiteBreakOrZero(1); + var buffer = new CharacterAnalyzer(new StringLookAheadBuffer(value)); + var preceededByWhitespace = true; + var followedByWhitespace = buffer.IsWhiteBreakOrZero(1); - var leadingSpace = false; - var leadingBreak = false; - var trailingSpace = false; - var trailingBreak = false; + var leadingSpace = false; + var leadingBreak = false; + var trailingSpace = false; + var trailingBreak = false; - var breakSpace = false; - var spaceBreak = false; - var previousSpace = false; - var previousBreak = false; + var breakSpace = false; + var spaceBreak = false; + var previousSpace = false; + var previousBreak = false; - var lineBreaks = false; + var lineBreaks = false; var specialCharacters = !ValueIsRepresentableInOutputEncoding(value); - var isFirst = true; - while (!buffer.EndOfInput) - { - if (isFirst) - { - if (buffer.Check(@"#,[]{}&*!|>\""%@`")) - { - flowIndicators = true; - blockIndicators = true; - } - - if (buffer.Check("?:")) - { - flowIndicators = true; - if (followedByWhitespace) - blockIndicators = true; - } - - if (buffer.Check('-') && followedByWhitespace) - { - flowIndicators = true; - blockIndicators = true; - } - } - else - { - if (buffer.Check(",?[]{}")) - flowIndicators = true; - - if (buffer.Check(':')) - { - flowIndicators = true; - if (followedByWhitespace) - blockIndicators = true; - } - - if (buffer.Check('#') && preceededByWhitespace) - { - flowIndicators = true; - blockIndicators = true; - } - } + var isFirst = true; + while (!buffer.EndOfInput) + { + if (isFirst) + { + if (buffer.Check(@"#,[]{}&*!|>\""%@`")) + { + flowIndicators = true; + blockIndicators = true; + } + + if (buffer.Check("?:")) + { + flowIndicators = true; + if (followedByWhitespace) + blockIndicators = true; + } + + if (buffer.Check('-') && followedByWhitespace) + { + flowIndicators = true; + blockIndicators = true; + } + } + else + { + if (buffer.Check(",?[]{}")) + flowIndicators = true; + + if (buffer.Check(':')) + { + flowIndicators = true; + if (followedByWhitespace) + blockIndicators = true; + } + + if (buffer.Check('#') && preceededByWhitespace) + { + flowIndicators = true; + blockIndicators = true; + } + } if (!specialCharacters && !buffer.IsPrintable()) { @@ -388,90 +388,90 @@ private void AnalyzeScalar(Scalar scalar) lineBreaks = true; } - if (buffer.IsSpace()) - { - if (isFirst) - leadingSpace = true; - - if (buffer.Buffer.Position >= buffer.Buffer.Length - 1) - trailingSpace = true; - - if (previousBreak) - breakSpace = true; - - previousSpace = true; - previousBreak = false; - } - else if (buffer.IsBreak()) - { - if (isFirst) - leadingBreak = true; - - if (buffer.Buffer.Position >= buffer.Buffer.Length - 1) - trailingBreak = true; - - if (previousSpace) - spaceBreak = true; - - previousSpace = false; - previousBreak = true; - } - else - { - previousSpace = false; - previousBreak = false; - } - - preceededByWhitespace = buffer.IsWhiteBreakOrZero(); - buffer.Skip(1); - if (!buffer.EndOfInput) - followedByWhitespace = buffer.IsWhiteBreakOrZero(1); - - isFirst = false; - } - - scalarData.isFlowPlainAllowed = true; - scalarData.isBlockPlainAllowed = true; - scalarData.isSingleQuotedAllowed = true; - scalarData.isBlockAllowed = true; - - if (leadingSpace || leadingBreak || trailingSpace || trailingBreak) - { - scalarData.isFlowPlainAllowed = false; - scalarData.isBlockPlainAllowed = false; - } - - if (trailingSpace) - scalarData.isBlockAllowed = false; - - if (breakSpace) - { - scalarData.isFlowPlainAllowed = false; - scalarData.isBlockPlainAllowed = false; - scalarData.isSingleQuotedAllowed = false; - } - - if (spaceBreak || specialCharacters) - { - scalarData.isFlowPlainAllowed = false; - scalarData.isBlockPlainAllowed = false; - scalarData.isSingleQuotedAllowed = false; - scalarData.isBlockAllowed = false; - } - - scalarData.isMultiline = lineBreaks; - if (lineBreaks) - { - scalarData.isFlowPlainAllowed = false; - scalarData.isBlockPlainAllowed = false; - } - - if (flowIndicators) - scalarData.isFlowPlainAllowed = false; - - if (blockIndicators) - scalarData.isBlockPlainAllowed = false; - } + if (buffer.IsSpace()) + { + if (isFirst) + leadingSpace = true; + + if (buffer.Buffer.Position >= buffer.Buffer.Length - 1) + trailingSpace = true; + + if (previousBreak) + breakSpace = true; + + previousSpace = true; + previousBreak = false; + } + else if (buffer.IsBreak()) + { + if (isFirst) + leadingBreak = true; + + if (buffer.Buffer.Position >= buffer.Buffer.Length - 1) + trailingBreak = true; + + if (previousSpace) + spaceBreak = true; + + previousSpace = false; + previousBreak = true; + } + else + { + previousSpace = false; + previousBreak = false; + } + + preceededByWhitespace = buffer.IsWhiteBreakOrZero(); + buffer.Skip(1); + if (!buffer.EndOfInput) + followedByWhitespace = buffer.IsWhiteBreakOrZero(1); + + isFirst = false; + } + + scalarData.isFlowPlainAllowed = true; + scalarData.isBlockPlainAllowed = true; + scalarData.isSingleQuotedAllowed = true; + scalarData.isBlockAllowed = true; + + if (leadingSpace || leadingBreak || trailingSpace || trailingBreak) + { + scalarData.isFlowPlainAllowed = false; + scalarData.isBlockPlainAllowed = false; + } + + if (trailingSpace) + scalarData.isBlockAllowed = false; + + if (breakSpace) + { + scalarData.isFlowPlainAllowed = false; + scalarData.isBlockPlainAllowed = false; + scalarData.isSingleQuotedAllowed = false; + } + + if (spaceBreak || specialCharacters) + { + scalarData.isFlowPlainAllowed = false; + scalarData.isBlockPlainAllowed = false; + scalarData.isSingleQuotedAllowed = false; + scalarData.isBlockAllowed = false; + } + + scalarData.isMultiline = lineBreaks; + if (lineBreaks) + { + scalarData.isFlowPlainAllowed = false; + scalarData.isBlockPlainAllowed = false; + } + + if (flowIndicators) + scalarData.isFlowPlainAllowed = false; + + if (blockIndicators) + scalarData.isBlockPlainAllowed = false; + } private bool ValueIsRepresentableInOutputEncoding(string value) { @@ -497,1330 +497,1330 @@ private bool ValueIsRepresentableInOutputEncoding(string value) } private bool IsUnicode(Encoding encoding) - { - return encoding is UTF8Encoding || - encoding is UnicodeEncoding || - encoding is UTF7Encoding || - encoding is UTF8Encoding; - } - - private void AnalyzeTag(string tag) - { - tagData.handle = tag; - foreach (var tagDirective in tagDirectives) - { - if (tag.StartsWith(tagDirective.Prefix, StringComparison.Ordinal)) - { - tagData.handle = tagDirective.Handle; - tagData.suffix = tag.Substring(tagDirective.Prefix.Length); - break; - } - } - } - - private void StateMachine(ParsingEvent evt) - { - var comment = evt as Comment; - if (comment != null) - { - EmitComment(comment); - return; - } - - switch (state) - { - case EmitterState.StreamStart: - EmitStreamStart(evt); - break; - - case EmitterState.FirstDocumentStart: - EmitDocumentStart(evt, true); - break; - - case EmitterState.DocumentStart: - EmitDocumentStart(evt, false); - break; - - case EmitterState.DocumentContent: - EmitDocumentContent(evt); - break; - - case EmitterState.DocumentEnd: - EmitDocumentEnd(evt); - break; - - case EmitterState.FlowSequenceFirstItem: - EmitFlowSequenceItem(evt, true); - break; - - case EmitterState.FlowSequenceItem: - EmitFlowSequenceItem(evt, false); - break; - - case EmitterState.FlowMappingFirstKey: - EmitFlowMappingKey(evt, true); - break; - - case EmitterState.FlowMappingKey: - EmitFlowMappingKey(evt, false); - break; - - case EmitterState.FlowMappingSimpleValue: - EmitFlowMappingValue(evt, true); - break; - - case EmitterState.FlowMappingValue: - EmitFlowMappingValue(evt, false); - break; - - case EmitterState.BlockSequenceFirstItem: - EmitBlockSequenceItem(evt, true); - break; - - case EmitterState.BlockSequenceItem: - EmitBlockSequenceItem(evt, false); - break; - - case EmitterState.BlockMappingFirstKey: - EmitBlockMappingKey(evt, true); - break; - - case EmitterState.BlockMappingKey: - EmitBlockMappingKey(evt, false); - break; - - case EmitterState.BlockMappingSimpleValue: - EmitBlockMappingValue(evt, true); - break; - - case EmitterState.BlockMappingValue: - EmitBlockMappingValue(evt, false); - break; - - case EmitterState.StreamEnd: - throw new YamlException("Expected nothing after STREAM-END"); - - default: - throw new InvalidOperationException(); - } - } - - private void EmitComment(Comment comment) - { - if (comment.IsInline) - { - Write(' '); - } - else - { - WriteBreak(); - } - - Write("# "); - Write(comment.Value); - - isIndentation = true; - } - - /// - /// Expect STREAM-START. - /// - private void EmitStreamStart(ParsingEvent evt) - { - if (!(evt is StreamStart)) - { - throw new ArgumentException("Expected STREAM-START.", "evt"); - } - - indent = -1; - column = 0; - isWhitespace = true; - isIndentation = true; - - state = EmitterState.FirstDocumentStart; - } - - /// - /// Expect DOCUMENT-START or STREAM-END. - /// - private void EmitDocumentStart(ParsingEvent evt, bool isFirst) - { - var documentStart = evt as DocumentStart; - if (documentStart != null) - { - var isImplicit = documentStart.IsImplicit && isFirst && !isCanonical; - - var documentTagDirectives = NonDefaultTagsAmong(documentStart.Tags); - - if (!isFirst && !isDocumentEndWritten && (documentStart.Version != null || documentTagDirectives.Count > 0)) - { - isDocumentEndWritten = false; - WriteIndicator("...", true, false, false); - WriteIndent(); - } - - if (documentStart.Version != null) - { - AnalyzeVersionDirective(documentStart.Version); - - isImplicit = false; - WriteIndicator("%YAML", true, false, false); - WriteIndicator(string.Format(CultureInfo.InvariantCulture, - "{0}.{1}", Constants.MajorVersion, Constants.MinorVersion), - true, false, false); - WriteIndent(); - } - - foreach (var tagDirective in documentTagDirectives) - { - AppendTagDirectiveTo(tagDirective, false, tagDirectives); - } - - foreach (var tagDirective in Constants.DefaultTagDirectives) - { - AppendTagDirectiveTo(tagDirective, true, tagDirectives); - } - - if (documentTagDirectives.Count > 0) - { - isImplicit = false; - foreach (var tagDirective in Constants.DefaultTagDirectives) - { - AppendTagDirectiveTo(tagDirective, true, documentTagDirectives); - } - - foreach (var tagDirective in documentTagDirectives) - { - WriteIndicator("%TAG", true, false, false); - WriteTagHandle(tagDirective.Handle); - WriteTagContent(tagDirective.Prefix, true); - WriteIndent(); - } - } - - if (CheckEmptyDocument()) - { - isImplicit = false; - } - - if (!isImplicit) - { - WriteIndent(); - WriteIndicator("---", true, false, false); - if (isCanonical) - { - WriteIndent(); - } - } - - state = EmitterState.DocumentContent; - } - - else if (evt is StreamEnd) - { - if (isOpenEnded) - { - WriteIndicator("...", true, false, false); - WriteIndent(); - } - - state = EmitterState.StreamEnd; - } - else - { - throw new YamlException("Expected DOCUMENT-START or STREAM-END"); - } - } - - private TagDirectiveCollection NonDefaultTagsAmong(IEnumerable tagCollection) - { - var directives = new TagDirectiveCollection(); - if (tagCollection == null) - return directives; - - foreach (var tagDirective in tagCollection) - { - AppendTagDirectiveTo(tagDirective, false, directives); - } - foreach (var tagDirective in Constants.DefaultTagDirectives) - { - directives.Remove(tagDirective); - } - return directives; - } - - // ReSharper disable UnusedParameter.Local - private void AnalyzeVersionDirective(VersionDirective versionDirective) - { - if (versionDirective.Version.Major != Constants.MajorVersion || versionDirective.Version.Minor != Constants.MinorVersion) - { - throw new YamlException("Incompatible %YAML directive"); - } - } - // ReSharper restore UnusedParameter.Local - - private void AppendTagDirectiveTo(TagDirective value, bool allowDuplicates, TagDirectiveCollection tagDirectives) - { - if (tagDirectives.Contains(value)) - { - if (!allowDuplicates) - { - throw new YamlException("Duplicate %TAG directive."); - } - } - else - { - tagDirectives.Add(value); - } - } - - /// - /// Expect the root node. - /// - private void EmitDocumentContent(ParsingEvent evt) - { - states.Push(EmitterState.DocumentEnd); - EmitNode(evt, true, false, false); - } - - /// - /// Expect a node. - /// - private void EmitNode(ParsingEvent evt, bool isRoot, bool isMapping, bool isSimpleKey) - { - isRootContext = isRoot; - isMappingContext = isMapping; - isSimpleKeyContext = isSimpleKey; - - switch (evt.Type) - { - case EventType.Alias: - EmitAlias(); - break; - - case EventType.Scalar: - EmitScalar(evt); - break; - - case EventType.SequenceStart: - EmitSequenceStart(evt); - break; - - case EventType.MappingStart: - EmitMappingStart(evt); - break; - - default: - throw new YamlException(string.Format("Expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, got {0}", evt.Type)); - } - } - - /// - /// Expect ALIAS. - /// - private void EmitAlias() - { - ProcessAnchor(); - state = states.Pop(); - } - - /// - /// Expect SCALAR. - /// - private void EmitScalar(ParsingEvent evt) - { - SelectScalarStyle(evt); - ProcessAnchor(); - ProcessTag(); - IncreaseIndent(true, false); - ProcessScalar(); - - indent = indents.Pop(); - state = states.Pop(); - } - - private void SelectScalarStyle(ParsingEvent evt) - { - var scalar = (Scalar)evt; - - var style = scalar.Style; - var noTag = tagData.handle == null && tagData.suffix == null; - - if (noTag && !scalar.IsPlainImplicit && !scalar.IsQuotedImplicit) - { - throw new YamlException("Neither tag nor isImplicit flags are specified."); - } - - if (style == ScalarStyle.Any) - { - style = scalarData.isMultiline ? ScalarStyle.Folded : ScalarStyle.Plain; - } - - if (isCanonical) - { - style = ScalarStyle.DoubleQuoted; - } - - if (isSimpleKeyContext && scalarData.isMultiline) - { - style = ScalarStyle.DoubleQuoted; - } - - if (style == ScalarStyle.Plain) - { - if ((flowLevel != 0 && !scalarData.isFlowPlainAllowed) || (flowLevel == 0 && !scalarData.isBlockPlainAllowed)) - { - style = ScalarStyle.SingleQuoted; - } - if (string.IsNullOrEmpty(scalarData.value) && (flowLevel != 0 || isSimpleKeyContext)) - { - style = ScalarStyle.SingleQuoted; - } - if (noTag && !scalar.IsPlainImplicit) - { - style = ScalarStyle.SingleQuoted; - } - } - - if (style == ScalarStyle.SingleQuoted) - { - if (!scalarData.isSingleQuotedAllowed) - { - style = ScalarStyle.DoubleQuoted; - } - } - - if (style == ScalarStyle.Literal || style == ScalarStyle.Folded) - { - if (!scalarData.isBlockAllowed || flowLevel != 0 || isSimpleKeyContext) - { - style = ScalarStyle.DoubleQuoted; - } - } - - scalarData.style = style; - } - - private void ProcessScalar() - { - switch (scalarData.style) - { - case ScalarStyle.Plain: - WritePlainScalar(scalarData.value, !isSimpleKeyContext); - break; - - case ScalarStyle.SingleQuoted: - WriteSingleQuotedScalar(scalarData.value, !isSimpleKeyContext); - break; - - case ScalarStyle.DoubleQuoted: - WriteDoubleQuotedScalar(scalarData.value, !isSimpleKeyContext); - break; - - case ScalarStyle.Literal: - WriteLiteralScalar(scalarData.value); - break; - - case ScalarStyle.Folded: - WriteFoldedScalar(scalarData.value); - break; - - default: - throw new InvalidOperationException(); - } - } - - #region Write scalar Methods - - private void WritePlainScalar(string value, bool allowBreaks) - { - if (!isWhitespace) - { - Write(' '); - } - - var previousSpace = false; - var previousBreak = false; - for (var index = 0; index < value.Length; ++index) - { - var character = value[index]; - - if (IsSpace(character)) - { - if (allowBreaks && !previousSpace && column > bestWidth && index + 1 < value.Length && value[index + 1] != ' ') - { - WriteIndent(); - } - else - { - Write(character); - } - previousSpace = true; - } - else if (IsBreak(character)) - { - if (!previousBreak && character == '\n') - { - WriteBreak(); - } - WriteBreak(); - isIndentation = true; - previousBreak = true; - } - else - { - if (previousBreak) - { - WriteIndent(); - } - Write(character); - isIndentation = false; - previousSpace = false; - previousBreak = false; - } - } - - isWhitespace = false; - isIndentation = false; - - if (isRootContext) - { - isOpenEnded = true; - } - } - - private void WriteSingleQuotedScalar(string value, bool allowBreaks) - { - WriteIndicator("'", true, false, false); - - var previousSpace = false; - var previousBreak = false; - - for (var index = 0; index < value.Length; ++index) - { - var character = value[index]; - - if (character == ' ') - { - if (allowBreaks && !previousSpace && column > bestWidth && index != 0 && index + 1 < value.Length && - value[index + 1] != ' ') - { - WriteIndent(); - } - else - { - Write(character); - } - previousSpace = true; - } - else if (IsBreak(character)) - { - if (!previousBreak && character == '\n') - { - WriteBreak(); - } - WriteBreak(); - isIndentation = true; - previousBreak = true; - } - else - { - if (previousBreak) - { - WriteIndent(); - } - if (character == '\'') - { - Write(character); - } - Write(character); - isIndentation = false; - previousSpace = false; - previousBreak = false; - } - } - - WriteIndicator("'", false, false, false); - - isWhitespace = false; - isIndentation = false; - } - - private void WriteDoubleQuotedScalar(string value, bool allowBreaks) - { - WriteIndicator("\"", true, false, false); - - var previousSpace = false; - for (var index = 0; index < value.Length; ++index) - { - var character = value[index]; - - if (!IsPrintable(character) || IsBreak(character) || character == '"' || character == '\\') - { - Write('\\'); - - switch (character) - { - case '\0': - Write('0'); - break; - - case '\x7': - Write('a'); - break; - - case '\x8': - Write('b'); - break; - - case '\x9': - Write('t'); - break; - - case '\xA': - Write('n'); - break; - - case '\xB': - Write('v'); - break; - - case '\xC': - Write('f'); - break; - - case '\xD': - Write('r'); - break; - - case '\x1B': - Write('e'); - break; - - case '\x22': - Write('"'); - break; - - case '\x5C': - Write('\\'); - break; - - case '\x85': - Write('N'); - break; - - case '\xA0': - Write('_'); - break; - - case '\x2028': - Write('L'); - break; - - case '\x2029': - Write('P'); - break; - - default: - var code = (short) character; - if (code <= 0xFF) - { - Write('x'); - Write(code.ToString("X02", CultureInfo.InvariantCulture)); - } - else - { - Write('u'); - Write(code.ToString("X04", CultureInfo.InvariantCulture)); - } - break; - } - previousSpace = false; - } - else if (character == ' ') - { - if (allowBreaks && !previousSpace && column > bestWidth && index > 0 && index + 1 < value.Length) - { - WriteIndent(); - if (value[index + 1] == ' ') - { - Write('\\'); - } - } - else - { - Write(character); - } - previousSpace = true; - } - else - { - Write(character); - previousSpace = false; - } - } - - WriteIndicator("\"", false, false, false); - - isWhitespace = false; - isIndentation = false; - } - - private void WriteLiteralScalar(string value) - { - var previousBreak = true; - - WriteIndicator("|", true, false, false); - WriteBlockScalarHints(value); - WriteBreak(); - - isIndentation = true; - isWhitespace = true; - - foreach (var character in value) - { - if (IsBreak(character)) - { - WriteBreak(); - isIndentation = true; - previousBreak = true; - } - else - { - if (previousBreak) - { - WriteIndent(); - } - Write(character); - isIndentation = false; - previousBreak = false; - } - } - } - - private void WriteFoldedScalar(string value) - { - var previousBreak = true; - var leadingSpaces = true; - - WriteIndicator(">", true, false, false); - WriteBlockScalarHints(value); - WriteBreak(); - - isIndentation = true; - isWhitespace = true; - - for (var i = 0; i < value.Length; ++i) - { - var character = value[i]; - if (IsBreak(character)) - { - if (!previousBreak && !leadingSpaces && character == '\n') - { - var k = 0; - while (i + k < value.Length && IsBreak(value[i + k])) - { - ++k; - } - if (i + k < value.Length && !(IsBlank(value[i + k]) || IsBreak(value[i + k]))) - { - WriteBreak(); - } - } - WriteBreak(); - isIndentation = true; - previousBreak = true; - } - else - { - if (previousBreak) - { - WriteIndent(); - leadingSpaces = IsBlank(character); - } - if (!previousBreak && character == ' ' && i + 1 < value.Length && value[i + 1] != ' ' && column > bestWidth) - { - WriteIndent(); - } - else - { - Write(character); - } - isIndentation = false; - previousBreak = false; - } - } - } - - // Todo: isn't this what CharacterAnalyser is for? - private static bool IsSpace(char character) - { - return character == ' '; - } - - private static bool IsBreak(char character) - { - return character == '\r' || character == '\n' || character == '\x85' || character == '\x2028' || - character == '\x2029'; - } - - private static bool IsBlank(char character) - { - return character == ' ' || character == '\t'; - } - - private static bool IsPrintable(char character) - { - return - character == '\x9' || - character == '\xA' || - character == '\xD' || - (character >= '\x20' && character <= '\x7E') || - character == '\x85' || - (character >= '\xA0' && character <= '\xD7FF') || - (character >= '\xE000' && character <= '\xFFFD'); - } - - #endregion - - /// - /// Expect SEQUENCE-START. - /// - private void EmitSequenceStart(ParsingEvent evt) - { - ProcessAnchor(); - ProcessTag(); - - var sequenceStart = (SequenceStart) evt; - - if (flowLevel != 0 || isCanonical || sequenceStart.Style == SequenceStyle.Flow || CheckEmptySequence()) - { - state = EmitterState.FlowSequenceFirstItem; - } - else - { - state = EmitterState.BlockSequenceFirstItem; - } - } - - /// - /// Expect MAPPING-START. - /// - private void EmitMappingStart(ParsingEvent evt) - { - ProcessAnchor(); - ProcessTag(); - - var mappingStart = (MappingStart) evt; - - if (flowLevel != 0 || isCanonical || mappingStart.Style == MappingStyle.Flow || CheckEmptyMapping()) - { - state = EmitterState.FlowMappingFirstKey; - } - else - { - state = EmitterState.BlockMappingFirstKey; - } - } - - private void ProcessAnchor() - { - if (anchorData.anchor != null) - { - WriteIndicator(anchorData.isAlias ? "*" : "&", true, false, false); - WriteAnchor(anchorData.anchor); - } - } - - private void ProcessTag() - { - if (tagData.handle == null && tagData.suffix == null) - { - return; - } - - if (tagData.handle != null) - { - WriteTagHandle(tagData.handle); - if (tagData.suffix != null) - { - WriteTagContent(tagData.suffix, false); - } - } - else - { - WriteIndicator("!<", true, false, false); - WriteTagContent(tagData.suffix, false); - WriteIndicator(">", false, false, false); - } - } - - /// - /// Expect DOCUMENT-END. - /// - private void EmitDocumentEnd(ParsingEvent evt) - { - var documentEnd = evt as DocumentEnd; - if (documentEnd != null) - { - WriteIndent(); - if (!documentEnd.IsImplicit) - { - WriteIndicator("...", true, false, false); - WriteIndent(); - isDocumentEndWritten = true; - } - - state = EmitterState.DocumentStart; - - tagDirectives.Clear(); - } - else - { - throw new YamlException("Expected DOCUMENT-END."); - } - } - - /// - /// Expect a flow item node. - /// - private void EmitFlowSequenceItem(ParsingEvent evt, bool isFirst) - { - if (isFirst) - { - WriteIndicator("[", true, true, false); - IncreaseIndent(true, false); - ++flowLevel; - } - - if (evt is SequenceEnd) - { - --flowLevel; - indent = indents.Pop(); - if (isCanonical && !isFirst) - { - WriteIndicator(",", false, false, false); - WriteIndent(); - } - WriteIndicator("]", false, false, false); - state = states.Pop(); - return; - } - - if (!isFirst) - { - WriteIndicator(",", false, false, false); - } - - if (isCanonical || column > bestWidth) - { - WriteIndent(); - } - - states.Push(EmitterState.FlowSequenceItem); - - EmitNode(evt, false, false, false); - } - - /// - /// Expect a flow key node. - /// - private void EmitFlowMappingKey(ParsingEvent evt, bool isFirst) - { - if (isFirst) - { - WriteIndicator("{", true, true, false); - IncreaseIndent(true, false); - ++flowLevel; - } - - if (evt is MappingEnd) - { - --flowLevel; - indent = indents.Pop(); - if (isCanonical && !isFirst) - { - WriteIndicator(",", false, false, false); - WriteIndent(); - } - WriteIndicator("}", false, false, false); - state = states.Pop(); - return; - } - - if (!isFirst) - { - WriteIndicator(",", false, false, false); - } - if (isCanonical || column > bestWidth) - { - WriteIndent(); - } - - if (!isCanonical && CheckSimpleKey()) - { - states.Push(EmitterState.FlowMappingSimpleValue); - EmitNode(evt, false, true, true); - } - else - { - WriteIndicator("?", true, false, false); - states.Push(EmitterState.FlowMappingValue); - EmitNode(evt, false, true, false); - } - } - - /// - /// Expect a flow value node. - /// - private void EmitFlowMappingValue(ParsingEvent evt, bool isSimple) - { - if (isSimple) - { - WriteIndicator(":", false, false, false); - } - else - { - if (isCanonical || column > bestWidth) - { - WriteIndent(); - } - WriteIndicator(":", true, false, false); - } - states.Push(EmitterState.FlowMappingKey); - EmitNode(evt, false, true, false); - } - - /// - /// Expect a block item node. - /// - private void EmitBlockSequenceItem(ParsingEvent evt, bool isFirst) - { - if (isFirst) - { - IncreaseIndent(false, (isMappingContext && !isIndentation)); - } - - if (evt is SequenceEnd) - { - indent = indents.Pop(); - state = states.Pop(); - return; - } - - WriteIndent(); - WriteIndicator("-", true, false, true); - states.Push(EmitterState.BlockSequenceItem); - - EmitNode(evt, false, false, false); - } - - /// - /// Expect a block key node. - /// - private void EmitBlockMappingKey(ParsingEvent evt, bool isFirst) - { - if (isFirst) - { - IncreaseIndent(false, false); - } - - if (evt is MappingEnd) - { - indent = indents.Pop(); - state = states.Pop(); - return; - } - - WriteIndent(); - - if (CheckSimpleKey()) - { - states.Push(EmitterState.BlockMappingSimpleValue); - EmitNode(evt, false, true, true); - } - else - { - WriteIndicator("?", true, false, true); - states.Push(EmitterState.BlockMappingValue); - EmitNode(evt, false, true, false); - } - } - - /// - /// Expect a block value node. - /// - private void EmitBlockMappingValue(ParsingEvent evt, bool isSimple) - { - if (isSimple) - { - WriteIndicator(":", false, false, false); - } - else - { - WriteIndent(); - WriteIndicator(":", true, false, true); - } - states.Push(EmitterState.BlockMappingKey); - EmitNode(evt, false, true, false); - } - - private void IncreaseIndent(bool isFlow, bool isIndentless) - { - indents.Push(indent); - - if (indent < 0) - { - indent = isFlow ? bestIndent : 0; - } - else if (!isIndentless) - { - indent += bestIndent; - } - } - - #region Check Methods - - /// - /// Check if the document content is an empty scalar. - /// - private bool CheckEmptyDocument() - { - var index = 0; - foreach (var parsingEvent in events) - { - index++; - if (index == 2) - { - var scalar = parsingEvent as Scalar; - if (scalar != null) - { - return string.IsNullOrEmpty(scalar.Value); - } - break; - } - } - - return false; - } - - /// - /// Check if the next node can be expressed as a simple key. - /// - private bool CheckSimpleKey() - { - if (events.Count < 1) - { - return false; - } - - int length; - switch (events.Peek().Type) - { - case EventType.Alias: - length = SafeStringLength(anchorData.anchor); - break; - - case EventType.Scalar: - if (scalarData.isMultiline) - { - return false; - } - - length = - SafeStringLength(anchorData.anchor) + - SafeStringLength(tagData.handle) + - SafeStringLength(tagData.suffix) + - SafeStringLength(scalarData.value); - break; - - case EventType.SequenceStart: - if (!CheckEmptySequence()) - { - return false; - } - length = - SafeStringLength(anchorData.anchor) + - SafeStringLength(tagData.handle) + - SafeStringLength(tagData.suffix); - break; - - case EventType.MappingStart: - if (!CheckEmptySequence()) - { - return false; - } - length = - SafeStringLength(anchorData.anchor) + - SafeStringLength(tagData.handle) + - SafeStringLength(tagData.suffix); - break; - - default: - return false; - } - - return length <= MaxAliasLength; - } - - private int SafeStringLength(string value) - { - return value == null? 0: value.Length; - } - - private bool CheckEmptySequence() - { - if (events.Count < 2) - { - return false; - } - - // Todo: must be something better than this FakeList - var eventList = new FakeList(events); - return eventList[0] is SequenceStart && eventList[1] is SequenceEnd; - } - - private bool CheckEmptyMapping() - { - if (events.Count < 2) - { - return false; - } - - // Todo: must be something better than this FakeList - var eventList = new FakeList(events); - return eventList[0] is MappingStart && eventList[1] is MappingEnd; - } - - #endregion - - #region Write Methods - - private void WriteBlockScalarHints(string value) - { - var analyzer = new CharacterAnalyzer(new StringLookAheadBuffer(value)); - - if (analyzer.IsSpace() || analyzer.IsBreak()) - { - var indentHint = string.Format(CultureInfo.InvariantCulture, "{0}\0", bestIndent); - WriteIndicator(indentHint, false, false, false); - } - - isOpenEnded = false; - - string chompHint = null; - if (value.Length == 0 || !analyzer.IsBreak(value.Length - 1)) - { - chompHint = "-"; - } - else if (value.Length >= 2 && analyzer.IsBreak(value.Length - 2)) - { - chompHint = "+"; - isOpenEnded = true; - } - - if (chompHint != null) - { - WriteIndicator(chompHint, false, false, false); - } - } - - private void WriteIndicator(string indicator, bool needWhitespace, bool whitespace, bool indentation) - { - if (needWhitespace && !isWhitespace) - { - Write(' '); - } - - Write(indicator); - - isWhitespace = whitespace; - isIndentation &= indentation; - isOpenEnded = false; - } - - private void WriteIndent() - { - var currentIndent = Math.Max(indent, 0); - - if (!isIndentation || column > currentIndent || (column == currentIndent && !isWhitespace)) - { - WriteBreak(); - } - - while (column < currentIndent) - { - Write(' '); - } - - isWhitespace = true; - isIndentation = true; - } - - private void WriteAnchor(string value) - { - Write(value); - - isWhitespace = false; - isIndentation = false; - } - - private void WriteTagHandle(string value) - { - if (!isWhitespace) - { - Write(' '); - } - - Write(value); - - isWhitespace = false; - isIndentation = false; - } - - private void WriteTagContent(string value, bool needsWhitespace) - { - if (needsWhitespace && !isWhitespace) - { - Write(' '); - } - - Write(UrlEncode(value)); - - isWhitespace = false; - isIndentation = false; - } - - private string UrlEncode(string text) - { - return uriReplacer.Replace(text, delegate(Match match) { - var buffer = new StringBuilder(); - foreach (var toEncode in Encoding.UTF8.GetBytes(match.Value)) - { - buffer.AppendFormat("%{0:X02}", toEncode); - } - return buffer.ToString(); - }); - } - - private void Write(char value) - { - output.Write(value); - ++column; - } - - private void Write(string value) - { - output.Write(value); - column += value.Length; - } - - private void WriteBreak() - { - output.WriteLine(); - column = 0; - } - - #endregion - } + { + return encoding is UTF8Encoding || + encoding is UnicodeEncoding || + encoding is UTF7Encoding || + encoding is UTF8Encoding; + } + + private void AnalyzeTag(string tag) + { + tagData.handle = tag; + foreach (var tagDirective in tagDirectives) + { + if (tag.StartsWith(tagDirective.Prefix, StringComparison.Ordinal)) + { + tagData.handle = tagDirective.Handle; + tagData.suffix = tag.Substring(tagDirective.Prefix.Length); + break; + } + } + } + + private void StateMachine(ParsingEvent evt) + { + var comment = evt as Comment; + if (comment != null) + { + EmitComment(comment); + return; + } + + switch (state) + { + case EmitterState.StreamStart: + EmitStreamStart(evt); + break; + + case EmitterState.FirstDocumentStart: + EmitDocumentStart(evt, true); + break; + + case EmitterState.DocumentStart: + EmitDocumentStart(evt, false); + break; + + case EmitterState.DocumentContent: + EmitDocumentContent(evt); + break; + + case EmitterState.DocumentEnd: + EmitDocumentEnd(evt); + break; + + case EmitterState.FlowSequenceFirstItem: + EmitFlowSequenceItem(evt, true); + break; + + case EmitterState.FlowSequenceItem: + EmitFlowSequenceItem(evt, false); + break; + + case EmitterState.FlowMappingFirstKey: + EmitFlowMappingKey(evt, true); + break; + + case EmitterState.FlowMappingKey: + EmitFlowMappingKey(evt, false); + break; + + case EmitterState.FlowMappingSimpleValue: + EmitFlowMappingValue(evt, true); + break; + + case EmitterState.FlowMappingValue: + EmitFlowMappingValue(evt, false); + break; + + case EmitterState.BlockSequenceFirstItem: + EmitBlockSequenceItem(evt, true); + break; + + case EmitterState.BlockSequenceItem: + EmitBlockSequenceItem(evt, false); + break; + + case EmitterState.BlockMappingFirstKey: + EmitBlockMappingKey(evt, true); + break; + + case EmitterState.BlockMappingKey: + EmitBlockMappingKey(evt, false); + break; + + case EmitterState.BlockMappingSimpleValue: + EmitBlockMappingValue(evt, true); + break; + + case EmitterState.BlockMappingValue: + EmitBlockMappingValue(evt, false); + break; + + case EmitterState.StreamEnd: + throw new YamlException("Expected nothing after STREAM-END"); + + default: + throw new InvalidOperationException(); + } + } + + private void EmitComment(Comment comment) + { + if (comment.IsInline) + { + Write(' '); + } + else + { + WriteBreak(); + } + + Write("# "); + Write(comment.Value); + + isIndentation = true; + } + + /// + /// Expect STREAM-START. + /// + private void EmitStreamStart(ParsingEvent evt) + { + if (!(evt is StreamStart)) + { + throw new ArgumentException("Expected STREAM-START.", "evt"); + } + + indent = -1; + column = 0; + isWhitespace = true; + isIndentation = true; + + state = EmitterState.FirstDocumentStart; + } + + /// + /// Expect DOCUMENT-START or STREAM-END. + /// + private void EmitDocumentStart(ParsingEvent evt, bool isFirst) + { + var documentStart = evt as DocumentStart; + if (documentStart != null) + { + var isImplicit = documentStart.IsImplicit && isFirst && !isCanonical; + + var documentTagDirectives = NonDefaultTagsAmong(documentStart.Tags); + + if (!isFirst && !isDocumentEndWritten && (documentStart.Version != null || documentTagDirectives.Count > 0)) + { + isDocumentEndWritten = false; + WriteIndicator("...", true, false, false); + WriteIndent(); + } + + if (documentStart.Version != null) + { + AnalyzeVersionDirective(documentStart.Version); + + isImplicit = false; + WriteIndicator("%YAML", true, false, false); + WriteIndicator(string.Format(CultureInfo.InvariantCulture, + "{0}.{1}", Constants.MajorVersion, Constants.MinorVersion), + true, false, false); + WriteIndent(); + } + + foreach (var tagDirective in documentTagDirectives) + { + AppendTagDirectiveTo(tagDirective, false, tagDirectives); + } + + foreach (var tagDirective in Constants.DefaultTagDirectives) + { + AppendTagDirectiveTo(tagDirective, true, tagDirectives); + } + + if (documentTagDirectives.Count > 0) + { + isImplicit = false; + foreach (var tagDirective in Constants.DefaultTagDirectives) + { + AppendTagDirectiveTo(tagDirective, true, documentTagDirectives); + } + + foreach (var tagDirective in documentTagDirectives) + { + WriteIndicator("%TAG", true, false, false); + WriteTagHandle(tagDirective.Handle); + WriteTagContent(tagDirective.Prefix, true); + WriteIndent(); + } + } + + if (CheckEmptyDocument()) + { + isImplicit = false; + } + + if (!isImplicit) + { + WriteIndent(); + WriteIndicator("---", true, false, false); + if (isCanonical) + { + WriteIndent(); + } + } + + state = EmitterState.DocumentContent; + } + + else if (evt is StreamEnd) + { + if (isOpenEnded) + { + WriteIndicator("...", true, false, false); + WriteIndent(); + } + + state = EmitterState.StreamEnd; + } + else + { + throw new YamlException("Expected DOCUMENT-START or STREAM-END"); + } + } + + private TagDirectiveCollection NonDefaultTagsAmong(IEnumerable tagCollection) + { + var directives = new TagDirectiveCollection(); + if (tagCollection == null) + return directives; + + foreach (var tagDirective in tagCollection) + { + AppendTagDirectiveTo(tagDirective, false, directives); + } + foreach (var tagDirective in Constants.DefaultTagDirectives) + { + directives.Remove(tagDirective); + } + return directives; + } + + // ReSharper disable UnusedParameter.Local + private void AnalyzeVersionDirective(VersionDirective versionDirective) + { + if (versionDirective.Version.Major != Constants.MajorVersion || versionDirective.Version.Minor != Constants.MinorVersion) + { + throw new YamlException("Incompatible %YAML directive"); + } + } + // ReSharper restore UnusedParameter.Local + + private void AppendTagDirectiveTo(TagDirective value, bool allowDuplicates, TagDirectiveCollection tagDirectives) + { + if (tagDirectives.Contains(value)) + { + if (!allowDuplicates) + { + throw new YamlException("Duplicate %TAG directive."); + } + } + else + { + tagDirectives.Add(value); + } + } + + /// + /// Expect the root node. + /// + private void EmitDocumentContent(ParsingEvent evt) + { + states.Push(EmitterState.DocumentEnd); + EmitNode(evt, true, false, false); + } + + /// + /// Expect a node. + /// + private void EmitNode(ParsingEvent evt, bool isRoot, bool isMapping, bool isSimpleKey) + { + isRootContext = isRoot; + isMappingContext = isMapping; + isSimpleKeyContext = isSimpleKey; + + switch (evt.Type) + { + case EventType.Alias: + EmitAlias(); + break; + + case EventType.Scalar: + EmitScalar(evt); + break; + + case EventType.SequenceStart: + EmitSequenceStart(evt); + break; + + case EventType.MappingStart: + EmitMappingStart(evt); + break; + + default: + throw new YamlException(string.Format("Expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, got {0}", evt.Type)); + } + } + + /// + /// Expect ALIAS. + /// + private void EmitAlias() + { + ProcessAnchor(); + state = states.Pop(); + } + + /// + /// Expect SCALAR. + /// + private void EmitScalar(ParsingEvent evt) + { + SelectScalarStyle(evt); + ProcessAnchor(); + ProcessTag(); + IncreaseIndent(true, false); + ProcessScalar(); + + indent = indents.Pop(); + state = states.Pop(); + } + + private void SelectScalarStyle(ParsingEvent evt) + { + var scalar = (Scalar)evt; + + var style = scalar.Style; + var noTag = tagData.handle == null && tagData.suffix == null; + + if (noTag && !scalar.IsPlainImplicit && !scalar.IsQuotedImplicit) + { + throw new YamlException("Neither tag nor isImplicit flags are specified."); + } + + if (style == ScalarStyle.Any) + { + style = scalarData.isMultiline ? ScalarStyle.Folded : ScalarStyle.Plain; + } + + if (isCanonical) + { + style = ScalarStyle.DoubleQuoted; + } + + if (isSimpleKeyContext && scalarData.isMultiline) + { + style = ScalarStyle.DoubleQuoted; + } + + if (style == ScalarStyle.Plain) + { + if ((flowLevel != 0 && !scalarData.isFlowPlainAllowed) || (flowLevel == 0 && !scalarData.isBlockPlainAllowed)) + { + style = ScalarStyle.SingleQuoted; + } + if (string.IsNullOrEmpty(scalarData.value) && (flowLevel != 0 || isSimpleKeyContext)) + { + style = ScalarStyle.SingleQuoted; + } + if (noTag && !scalar.IsPlainImplicit) + { + style = ScalarStyle.SingleQuoted; + } + } + + if (style == ScalarStyle.SingleQuoted) + { + if (!scalarData.isSingleQuotedAllowed) + { + style = ScalarStyle.DoubleQuoted; + } + } + + if (style == ScalarStyle.Literal || style == ScalarStyle.Folded) + { + if (!scalarData.isBlockAllowed || flowLevel != 0 || isSimpleKeyContext) + { + style = ScalarStyle.DoubleQuoted; + } + } + + scalarData.style = style; + } + + private void ProcessScalar() + { + switch (scalarData.style) + { + case ScalarStyle.Plain: + WritePlainScalar(scalarData.value, !isSimpleKeyContext); + break; + + case ScalarStyle.SingleQuoted: + WriteSingleQuotedScalar(scalarData.value, !isSimpleKeyContext); + break; + + case ScalarStyle.DoubleQuoted: + WriteDoubleQuotedScalar(scalarData.value, !isSimpleKeyContext); + break; + + case ScalarStyle.Literal: + WriteLiteralScalar(scalarData.value); + break; + + case ScalarStyle.Folded: + WriteFoldedScalar(scalarData.value); + break; + + default: + throw new InvalidOperationException(); + } + } + + #region Write scalar Methods + + private void WritePlainScalar(string value, bool allowBreaks) + { + if (!isWhitespace) + { + Write(' '); + } + + var previousSpace = false; + var previousBreak = false; + for (var index = 0; index < value.Length; ++index) + { + var character = value[index]; + + if (IsSpace(character)) + { + if (allowBreaks && !previousSpace && column > bestWidth && index + 1 < value.Length && value[index + 1] != ' ') + { + WriteIndent(); + } + else + { + Write(character); + } + previousSpace = true; + } + else if (IsBreak(character)) + { + if (!previousBreak && character == '\n') + { + WriteBreak(); + } + WriteBreak(); + isIndentation = true; + previousBreak = true; + } + else + { + if (previousBreak) + { + WriteIndent(); + } + Write(character); + isIndentation = false; + previousSpace = false; + previousBreak = false; + } + } + + isWhitespace = false; + isIndentation = false; + + if (isRootContext) + { + isOpenEnded = true; + } + } + + private void WriteSingleQuotedScalar(string value, bool allowBreaks) + { + WriteIndicator("'", true, false, false); + + var previousSpace = false; + var previousBreak = false; + + for (var index = 0; index < value.Length; ++index) + { + var character = value[index]; + + if (character == ' ') + { + if (allowBreaks && !previousSpace && column > bestWidth && index != 0 && index + 1 < value.Length && + value[index + 1] != ' ') + { + WriteIndent(); + } + else + { + Write(character); + } + previousSpace = true; + } + else if (IsBreak(character)) + { + if (!previousBreak && character == '\n') + { + WriteBreak(); + } + WriteBreak(); + isIndentation = true; + previousBreak = true; + } + else + { + if (previousBreak) + { + WriteIndent(); + } + if (character == '\'') + { + Write(character); + } + Write(character); + isIndentation = false; + previousSpace = false; + previousBreak = false; + } + } + + WriteIndicator("'", false, false, false); + + isWhitespace = false; + isIndentation = false; + } + + private void WriteDoubleQuotedScalar(string value, bool allowBreaks) + { + WriteIndicator("\"", true, false, false); + + var previousSpace = false; + for (var index = 0; index < value.Length; ++index) + { + var character = value[index]; + + if (!IsPrintable(character) || IsBreak(character) || character == '"' || character == '\\') + { + Write('\\'); + + switch (character) + { + case '\0': + Write('0'); + break; + + case '\x7': + Write('a'); + break; + + case '\x8': + Write('b'); + break; + + case '\x9': + Write('t'); + break; + + case '\xA': + Write('n'); + break; + + case '\xB': + Write('v'); + break; + + case '\xC': + Write('f'); + break; + + case '\xD': + Write('r'); + break; + + case '\x1B': + Write('e'); + break; + + case '\x22': + Write('"'); + break; + + case '\x5C': + Write('\\'); + break; + + case '\x85': + Write('N'); + break; + + case '\xA0': + Write('_'); + break; + + case '\x2028': + Write('L'); + break; + + case '\x2029': + Write('P'); + break; + + default: + var code = (short) character; + if (code <= 0xFF) + { + Write('x'); + Write(code.ToString("X02", CultureInfo.InvariantCulture)); + } + else + { + Write('u'); + Write(code.ToString("X04", CultureInfo.InvariantCulture)); + } + break; + } + previousSpace = false; + } + else if (character == ' ') + { + if (allowBreaks && !previousSpace && column > bestWidth && index > 0 && index + 1 < value.Length) + { + WriteIndent(); + if (value[index + 1] == ' ') + { + Write('\\'); + } + } + else + { + Write(character); + } + previousSpace = true; + } + else + { + Write(character); + previousSpace = false; + } + } + + WriteIndicator("\"", false, false, false); + + isWhitespace = false; + isIndentation = false; + } + + private void WriteLiteralScalar(string value) + { + var previousBreak = true; + + WriteIndicator("|", true, false, false); + WriteBlockScalarHints(value); + WriteBreak(); + + isIndentation = true; + isWhitespace = true; + + foreach (var character in value) + { + if (IsBreak(character)) + { + WriteBreak(); + isIndentation = true; + previousBreak = true; + } + else + { + if (previousBreak) + { + WriteIndent(); + } + Write(character); + isIndentation = false; + previousBreak = false; + } + } + } + + private void WriteFoldedScalar(string value) + { + var previousBreak = true; + var leadingSpaces = true; + + WriteIndicator(">", true, false, false); + WriteBlockScalarHints(value); + WriteBreak(); + + isIndentation = true; + isWhitespace = true; + + for (var i = 0; i < value.Length; ++i) + { + var character = value[i]; + if (IsBreak(character)) + { + if (!previousBreak && !leadingSpaces && character == '\n') + { + var k = 0; + while (i + k < value.Length && IsBreak(value[i + k])) + { + ++k; + } + if (i + k < value.Length && !(IsBlank(value[i + k]) || IsBreak(value[i + k]))) + { + WriteBreak(); + } + } + WriteBreak(); + isIndentation = true; + previousBreak = true; + } + else + { + if (previousBreak) + { + WriteIndent(); + leadingSpaces = IsBlank(character); + } + if (!previousBreak && character == ' ' && i + 1 < value.Length && value[i + 1] != ' ' && column > bestWidth) + { + WriteIndent(); + } + else + { + Write(character); + } + isIndentation = false; + previousBreak = false; + } + } + } + + // Todo: isn't this what CharacterAnalyser is for? + private static bool IsSpace(char character) + { + return character == ' '; + } + + private static bool IsBreak(char character) + { + return character == '\r' || character == '\n' || character == '\x85' || character == '\x2028' || + character == '\x2029'; + } + + private static bool IsBlank(char character) + { + return character == ' ' || character == '\t'; + } + + private static bool IsPrintable(char character) + { + return + character == '\x9' || + character == '\xA' || + character == '\xD' || + (character >= '\x20' && character <= '\x7E') || + character == '\x85' || + (character >= '\xA0' && character <= '\xD7FF') || + (character >= '\xE000' && character <= '\xFFFD'); + } + + #endregion + + /// + /// Expect SEQUENCE-START. + /// + private void EmitSequenceStart(ParsingEvent evt) + { + ProcessAnchor(); + ProcessTag(); + + var sequenceStart = (SequenceStart) evt; + + if (flowLevel != 0 || isCanonical || sequenceStart.Style == SequenceStyle.Flow || CheckEmptySequence()) + { + state = EmitterState.FlowSequenceFirstItem; + } + else + { + state = EmitterState.BlockSequenceFirstItem; + } + } + + /// + /// Expect MAPPING-START. + /// + private void EmitMappingStart(ParsingEvent evt) + { + ProcessAnchor(); + ProcessTag(); + + var mappingStart = (MappingStart) evt; + + if (flowLevel != 0 || isCanonical || mappingStart.Style == MappingStyle.Flow || CheckEmptyMapping()) + { + state = EmitterState.FlowMappingFirstKey; + } + else + { + state = EmitterState.BlockMappingFirstKey; + } + } + + private void ProcessAnchor() + { + if (anchorData.anchor != null) + { + WriteIndicator(anchorData.isAlias ? "*" : "&", true, false, false); + WriteAnchor(anchorData.anchor); + } + } + + private void ProcessTag() + { + if (tagData.handle == null && tagData.suffix == null) + { + return; + } + + if (tagData.handle != null) + { + WriteTagHandle(tagData.handle); + if (tagData.suffix != null) + { + WriteTagContent(tagData.suffix, false); + } + } + else + { + WriteIndicator("!<", true, false, false); + WriteTagContent(tagData.suffix, false); + WriteIndicator(">", false, false, false); + } + } + + /// + /// Expect DOCUMENT-END. + /// + private void EmitDocumentEnd(ParsingEvent evt) + { + var documentEnd = evt as DocumentEnd; + if (documentEnd != null) + { + WriteIndent(); + if (!documentEnd.IsImplicit) + { + WriteIndicator("...", true, false, false); + WriteIndent(); + isDocumentEndWritten = true; + } + + state = EmitterState.DocumentStart; + + tagDirectives.Clear(); + } + else + { + throw new YamlException("Expected DOCUMENT-END."); + } + } + + /// + /// Expect a flow item node. + /// + private void EmitFlowSequenceItem(ParsingEvent evt, bool isFirst) + { + if (isFirst) + { + WriteIndicator("[", true, true, false); + IncreaseIndent(true, false); + ++flowLevel; + } + + if (evt is SequenceEnd) + { + --flowLevel; + indent = indents.Pop(); + if (isCanonical && !isFirst) + { + WriteIndicator(",", false, false, false); + WriteIndent(); + } + WriteIndicator("]", false, false, false); + state = states.Pop(); + return; + } + + if (!isFirst) + { + WriteIndicator(",", false, false, false); + } + + if (isCanonical || column > bestWidth) + { + WriteIndent(); + } + + states.Push(EmitterState.FlowSequenceItem); + + EmitNode(evt, false, false, false); + } + + /// + /// Expect a flow key node. + /// + private void EmitFlowMappingKey(ParsingEvent evt, bool isFirst) + { + if (isFirst) + { + WriteIndicator("{", true, true, false); + IncreaseIndent(true, false); + ++flowLevel; + } + + if (evt is MappingEnd) + { + --flowLevel; + indent = indents.Pop(); + if (isCanonical && !isFirst) + { + WriteIndicator(",", false, false, false); + WriteIndent(); + } + WriteIndicator("}", false, false, false); + state = states.Pop(); + return; + } + + if (!isFirst) + { + WriteIndicator(",", false, false, false); + } + if (isCanonical || column > bestWidth) + { + WriteIndent(); + } + + if (!isCanonical && CheckSimpleKey()) + { + states.Push(EmitterState.FlowMappingSimpleValue); + EmitNode(evt, false, true, true); + } + else + { + WriteIndicator("?", true, false, false); + states.Push(EmitterState.FlowMappingValue); + EmitNode(evt, false, true, false); + } + } + + /// + /// Expect a flow value node. + /// + private void EmitFlowMappingValue(ParsingEvent evt, bool isSimple) + { + if (isSimple) + { + WriteIndicator(":", false, false, false); + } + else + { + if (isCanonical || column > bestWidth) + { + WriteIndent(); + } + WriteIndicator(":", true, false, false); + } + states.Push(EmitterState.FlowMappingKey); + EmitNode(evt, false, true, false); + } + + /// + /// Expect a block item node. + /// + private void EmitBlockSequenceItem(ParsingEvent evt, bool isFirst) + { + if (isFirst) + { + IncreaseIndent(false, (isMappingContext && !isIndentation)); + } + + if (evt is SequenceEnd) + { + indent = indents.Pop(); + state = states.Pop(); + return; + } + + WriteIndent(); + WriteIndicator("-", true, false, true); + states.Push(EmitterState.BlockSequenceItem); + + EmitNode(evt, false, false, false); + } + + /// + /// Expect a block key node. + /// + private void EmitBlockMappingKey(ParsingEvent evt, bool isFirst) + { + if (isFirst) + { + IncreaseIndent(false, false); + } + + if (evt is MappingEnd) + { + indent = indents.Pop(); + state = states.Pop(); + return; + } + + WriteIndent(); + + if (CheckSimpleKey()) + { + states.Push(EmitterState.BlockMappingSimpleValue); + EmitNode(evt, false, true, true); + } + else + { + WriteIndicator("?", true, false, true); + states.Push(EmitterState.BlockMappingValue); + EmitNode(evt, false, true, false); + } + } + + /// + /// Expect a block value node. + /// + private void EmitBlockMappingValue(ParsingEvent evt, bool isSimple) + { + if (isSimple) + { + WriteIndicator(":", false, false, false); + } + else + { + WriteIndent(); + WriteIndicator(":", true, false, true); + } + states.Push(EmitterState.BlockMappingKey); + EmitNode(evt, false, true, false); + } + + private void IncreaseIndent(bool isFlow, bool isIndentless) + { + indents.Push(indent); + + if (indent < 0) + { + indent = isFlow ? bestIndent : 0; + } + else if (!isIndentless) + { + indent += bestIndent; + } + } + + #region Check Methods + + /// + /// Check if the document content is an empty scalar. + /// + private bool CheckEmptyDocument() + { + var index = 0; + foreach (var parsingEvent in events) + { + index++; + if (index == 2) + { + var scalar = parsingEvent as Scalar; + if (scalar != null) + { + return string.IsNullOrEmpty(scalar.Value); + } + break; + } + } + + return false; + } + + /// + /// Check if the next node can be expressed as a simple key. + /// + private bool CheckSimpleKey() + { + if (events.Count < 1) + { + return false; + } + + int length; + switch (events.Peek().Type) + { + case EventType.Alias: + length = SafeStringLength(anchorData.anchor); + break; + + case EventType.Scalar: + if (scalarData.isMultiline) + { + return false; + } + + length = + SafeStringLength(anchorData.anchor) + + SafeStringLength(tagData.handle) + + SafeStringLength(tagData.suffix) + + SafeStringLength(scalarData.value); + break; + + case EventType.SequenceStart: + if (!CheckEmptySequence()) + { + return false; + } + length = + SafeStringLength(anchorData.anchor) + + SafeStringLength(tagData.handle) + + SafeStringLength(tagData.suffix); + break; + + case EventType.MappingStart: + if (!CheckEmptySequence()) + { + return false; + } + length = + SafeStringLength(anchorData.anchor) + + SafeStringLength(tagData.handle) + + SafeStringLength(tagData.suffix); + break; + + default: + return false; + } + + return length <= MaxAliasLength; + } + + private int SafeStringLength(string value) + { + return value == null? 0: value.Length; + } + + private bool CheckEmptySequence() + { + if (events.Count < 2) + { + return false; + } + + // Todo: must be something better than this FakeList + var eventList = new FakeList(events); + return eventList[0] is SequenceStart && eventList[1] is SequenceEnd; + } + + private bool CheckEmptyMapping() + { + if (events.Count < 2) + { + return false; + } + + // Todo: must be something better than this FakeList + var eventList = new FakeList(events); + return eventList[0] is MappingStart && eventList[1] is MappingEnd; + } + + #endregion + + #region Write Methods + + private void WriteBlockScalarHints(string value) + { + var analyzer = new CharacterAnalyzer(new StringLookAheadBuffer(value)); + + if (analyzer.IsSpace() || analyzer.IsBreak()) + { + var indentHint = string.Format(CultureInfo.InvariantCulture, "{0}\0", bestIndent); + WriteIndicator(indentHint, false, false, false); + } + + isOpenEnded = false; + + string chompHint = null; + if (value.Length == 0 || !analyzer.IsBreak(value.Length - 1)) + { + chompHint = "-"; + } + else if (value.Length >= 2 && analyzer.IsBreak(value.Length - 2)) + { + chompHint = "+"; + isOpenEnded = true; + } + + if (chompHint != null) + { + WriteIndicator(chompHint, false, false, false); + } + } + + private void WriteIndicator(string indicator, bool needWhitespace, bool whitespace, bool indentation) + { + if (needWhitespace && !isWhitespace) + { + Write(' '); + } + + Write(indicator); + + isWhitespace = whitespace; + isIndentation &= indentation; + isOpenEnded = false; + } + + private void WriteIndent() + { + var currentIndent = Math.Max(indent, 0); + + if (!isIndentation || column > currentIndent || (column == currentIndent && !isWhitespace)) + { + WriteBreak(); + } + + while (column < currentIndent) + { + Write(' '); + } + + isWhitespace = true; + isIndentation = true; + } + + private void WriteAnchor(string value) + { + Write(value); + + isWhitespace = false; + isIndentation = false; + } + + private void WriteTagHandle(string value) + { + if (!isWhitespace) + { + Write(' '); + } + + Write(value); + + isWhitespace = false; + isIndentation = false; + } + + private void WriteTagContent(string value, bool needsWhitespace) + { + if (needsWhitespace && !isWhitespace) + { + Write(' '); + } + + Write(UrlEncode(value)); + + isWhitespace = false; + isIndentation = false; + } + + private string UrlEncode(string text) + { + return uriReplacer.Replace(text, delegate(Match match) { + var buffer = new StringBuilder(); + foreach (var toEncode in Encoding.UTF8.GetBytes(match.Value)) + { + buffer.AppendFormat("%{0:X02}", toEncode); + } + return buffer.ToString(); + }); + } + + private void Write(char value) + { + output.Write(value); + ++column; + } + + private void Write(string value) + { + output.Write(value); + column += value.Length; + } + + private void WriteBreak() + { + output.WriteLine(); + column = 0; + } + + #endregion + } } diff --git a/YamlDotNet/Core/EmitterState.cs b/YamlDotNet/Core/EmitterState.cs index 97b5a79fc..bad24b6da 100644 --- a/YamlDotNet/Core/EmitterState.cs +++ b/YamlDotNet/Core/EmitterState.cs @@ -21,25 +21,25 @@ namespace YamlDotNet.Core { - internal enum EmitterState - { - StreamStart, - StreamEnd, - FirstDocumentStart, - DocumentStart, - DocumentContent, - DocumentEnd, - FlowSequenceFirstItem, - FlowSequenceItem, - FlowMappingFirstKey, - FlowMappingKey, - FlowMappingSimpleValue, - FlowMappingValue, - BlockSequenceFirstItem, - BlockSequenceItem, - BlockMappingFirstKey, - BlockMappingKey, - BlockMappingSimpleValue, - BlockMappingValue - } + internal enum EmitterState + { + StreamStart, + StreamEnd, + FirstDocumentStart, + DocumentStart, + DocumentContent, + DocumentEnd, + FlowSequenceFirstItem, + FlowSequenceItem, + FlowMappingFirstKey, + FlowMappingKey, + FlowMappingSimpleValue, + FlowMappingValue, + BlockSequenceFirstItem, + BlockSequenceItem, + BlockMappingFirstKey, + BlockMappingKey, + BlockMappingSimpleValue, + BlockMappingValue + } } \ No newline at end of file diff --git a/YamlDotNet/Core/EventReader.cs b/YamlDotNet/Core/EventReader.cs index 6a773b181..e1626fbf3 100644 --- a/YamlDotNet/Core/EventReader.cs +++ b/YamlDotNet/Core/EventReader.cs @@ -25,123 +25,123 @@ namespace YamlDotNet.Core { - /// - /// Reads events from a sequence of . - /// - public class EventReader - { - private readonly IParser parser; - private bool endOfStream; + /// + /// Reads events from a sequence of . + /// + public class EventReader + { + private readonly IParser parser; + private bool endOfStream; - /// - /// Initializes a new instance of the class. - /// - /// The parser that provides the events. - public EventReader(IParser parser) - { - this.parser = parser; - MoveNext(); - } + /// + /// Initializes a new instance of the class. + /// + /// The parser that provides the events. + public EventReader(IParser parser) + { + this.parser = parser; + MoveNext(); + } - /// - /// Gets the underlying parser. - /// - /// The parser. - public IParser Parser - { - get - { - return parser; - } - } + /// + /// Gets the underlying parser. + /// + /// The parser. + public IParser Parser + { + get + { + return parser; + } + } - /// - /// Ensures that the current event is of the specified type, returns it and moves to the next event. - /// - /// Type of the . - /// Returns the current event. - /// If the current event is not of the specified type. - public T Expect() where T : ParsingEvent - { - var expectedEvent = Allow(); - if (expectedEvent == null) - { - // TODO: Throw a better exception - var @event = parser.Current; - throw new YamlException(@event.Start, @event.End, string.Format(CultureInfo.InvariantCulture, - "Expected '{0}', got '{1}' (at {2}).", typeof(T).Name, @event.GetType().Name, @event.Start)); - } - return expectedEvent; - } + /// + /// Ensures that the current event is of the specified type, returns it and moves to the next event. + /// + /// Type of the . + /// Returns the current event. + /// If the current event is not of the specified type. + public T Expect() where T : ParsingEvent + { + var expectedEvent = Allow(); + if (expectedEvent == null) + { + // TODO: Throw a better exception + var @event = parser.Current; + throw new YamlException(@event.Start, @event.End, string.Format(CultureInfo.InvariantCulture, + "Expected '{0}', got '{1}' (at {2}).", typeof(T).Name, @event.GetType().Name, @event.Start)); + } + return expectedEvent; + } - /// - /// Checks whether the current event is of the specified type. - /// - /// Type of the event. - /// Returns true if the current event is of type . Otherwise returns false. - public bool Accept() where T : ParsingEvent - { - ThrowIfAtEndOfStream(); - return parser.Current is T; - } + /// + /// Checks whether the current event is of the specified type. + /// + /// Type of the event. + /// Returns true if the current event is of type . Otherwise returns false. + public bool Accept() where T : ParsingEvent + { + ThrowIfAtEndOfStream(); + return parser.Current is T; + } - private void ThrowIfAtEndOfStream() - { - if (endOfStream) - { - throw new EndOfStreamException(); - } - } + private void ThrowIfAtEndOfStream() + { + if (endOfStream) + { + throw new EndOfStreamException(); + } + } - /// - /// Checks whether the current event is of the specified type. - /// If the event is of the specified type, returns it and moves to the next event. - /// Otherwise retruns null. - /// - /// Type of the . - /// Returns the current event if it is of type T; otherwise returns null. - public T Allow() where T : ParsingEvent - { - if (!Accept()) - { - return null; - } - var @event = (T) parser.Current; - MoveNext(); - return @event; - } + /// + /// Checks whether the current event is of the specified type. + /// If the event is of the specified type, returns it and moves to the next event. + /// Otherwise retruns null. + /// + /// Type of the . + /// Returns the current event if it is of type T; otherwise returns null. + public T Allow() where T : ParsingEvent + { + if (!Accept()) + { + return null; + } + var @event = (T) parser.Current; + MoveNext(); + return @event; + } - /// - /// Gets the next event without consuming it. - /// - /// Type of the . - /// Returns the current event if it is of type T; otherwise returns null. - public T Peek() where T : ParsingEvent - { - if (!Accept()) - { - return null; - } - return (T) parser.Current; - } + /// + /// Gets the next event without consuming it. + /// + /// Type of the . + /// Returns the current event if it is of type T; otherwise returns null. + public T Peek() where T : ParsingEvent + { + if (!Accept()) + { + return null; + } + return (T) parser.Current; + } - /// - /// Skips the current event and any nested event. - /// - public void SkipThisAndNestedEvents() - { - var depth = 0; - do - { - depth += Peek().NestingIncrease; - MoveNext(); - } - while(depth > 0); - } + /// + /// Skips the current event and any nested event. + /// + public void SkipThisAndNestedEvents() + { + var depth = 0; + do + { + depth += Peek().NestingIncrease; + MoveNext(); + } + while(depth > 0); + } - private void MoveNext() - { - endOfStream = !parser.MoveNext(); - } - } + private void MoveNext() + { + endOfStream = !parser.MoveNext(); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Events/AnchorAlias.cs b/YamlDotNet/Core/Events/AnchorAlias.cs index 65a7e64f3..aa1f61f24 100644 --- a/YamlDotNet/Core/Events/AnchorAlias.cs +++ b/YamlDotNet/Core/Events/AnchorAlias.cs @@ -23,80 +23,80 @@ namespace YamlDotNet.Core.Events { - /// - /// Represents an alias event. - /// - public class AnchorAlias : ParsingEvent - { - /// - /// Gets the event type, which allows for simpler type comparisons. - /// - internal override EventType Type { - get { - return EventType.Alias; - } - } - - private readonly string value; + /// + /// Represents an alias event. + /// + public class AnchorAlias : ParsingEvent + { + /// + /// Gets the event type, which allows for simpler type comparisons. + /// + internal override EventType Type { + get { + return EventType.Alias; + } + } + + private readonly string value; - /// - /// Gets the value of the alias. - /// - public string Value - { - get - { - return value; - } - } + /// + /// Gets the value of the alias. + /// + public string Value + { + get + { + return value; + } + } - /// - /// Initializes a new instance of the class. - /// - /// The value of the alias. - /// The start position of the event. - /// The end position of the event. - public AnchorAlias(string value, Mark start, Mark end) - : base(start, end) - { - if(string.IsNullOrEmpty(value)) { - throw new YamlException(start, end, "Anchor value must not be empty."); - } + /// + /// Initializes a new instance of the class. + /// + /// The value of the alias. + /// The start position of the event. + /// The end position of the event. + public AnchorAlias(string value, Mark start, Mark end) + : base(start, end) + { + if(string.IsNullOrEmpty(value)) { + throw new YamlException(start, end, "Anchor value must not be empty."); + } - if(!NodeEvent.anchorValidator.IsMatch(value)) { - throw new YamlException(start, end, "Anchor value must contain alphanumerical characters only."); - } - - this.value = value; - } + if(!NodeEvent.anchorValidator.IsMatch(value)) { + throw new YamlException(start, end, "Anchor value must contain alphanumerical characters only."); + } + + this.value = value; + } - /// - /// Initializes a new instance of the class. - /// - /// The value of the alias. - public AnchorAlias(string value) - : this(value, Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The value of the alias. + public AnchorAlias(string value) + : this(value, Mark.Empty, Mark.Empty) + { + } - /// - /// Returns a that represents the current . - /// - /// - /// A that represents the current . - /// - public override string ToString() - { - return string.Format(CultureInfo.InvariantCulture, "Alias [value = {0}]", value); - } + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, "Alias [value = {0}]", value); + } - /// - /// Invokes run-time type specific Visit() method of the specified visitor. - /// - /// visitor, may not be null. - public override void Accept(IParsingEventVisitor visitor) - { - visitor.Visit(this); - } - } + /// + /// Invokes run-time type specific Visit() method of the specified visitor. + /// + /// visitor, may not be null. + public override void Accept(IParsingEventVisitor visitor) + { + visitor.Visit(this); + } + } } diff --git a/YamlDotNet/Core/Events/Comment.cs b/YamlDotNet/Core/Events/Comment.cs index cc442dc77..01801cae2 100644 --- a/YamlDotNet/Core/Events/Comment.cs +++ b/YamlDotNet/Core/Events/Comment.cs @@ -22,31 +22,31 @@ namespace YamlDotNet.Core.Events { - public class Comment : ParsingEvent - { - public string Value { get; private set; } - public bool IsInline { get; private set; } - - public Comment(string value, bool isInline) - : this(value, isInline, Mark.Empty, Mark.Empty) - { - } - - public Comment(string value, bool isInline, Mark start, Mark end) - : base(start, end) - { - Value = value; - IsInline = isInline; - } - - internal override EventType Type - { - get { return EventType.Comment; } - } - - public override void Accept(IParsingEventVisitor visitor) - { - visitor.Visit(this); - } - } + public class Comment : ParsingEvent + { + public string Value { get; private set; } + public bool IsInline { get; private set; } + + public Comment(string value, bool isInline) + : this(value, isInline, Mark.Empty, Mark.Empty) + { + } + + public Comment(string value, bool isInline, Mark start, Mark end) + : base(start, end) + { + Value = value; + IsInline = isInline; + } + + internal override EventType Type + { + get { return EventType.Comment; } + } + + public override void Accept(IParsingEventVisitor visitor) + { + visitor.Visit(this); + } + } } diff --git a/YamlDotNet/Core/Events/DocumentEnd.cs b/YamlDotNet/Core/Events/DocumentEnd.cs index dd96402f2..888ef7bb6 100644 --- a/YamlDotNet/Core/Events/DocumentEnd.cs +++ b/YamlDotNet/Core/Events/DocumentEnd.cs @@ -23,90 +23,90 @@ namespace YamlDotNet.Core.Events { - /// - /// Represents a document end event. - /// - public class DocumentEnd : ParsingEvent - { - /// - /// 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. - /// - public override int NestingIncrease { - get { - return -1; - } - } + /// + /// Represents a document end event. + /// + public class DocumentEnd : ParsingEvent + { + /// + /// 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. + /// + public override int NestingIncrease { + get { + return -1; + } + } - /// - /// Gets the event type, which allows for simpler type comparisons. - /// - internal override EventType Type { - get { - return EventType.DocumentEnd; - } - } - - private readonly bool isImplicit; + /// + /// Gets the event type, which allows for simpler type comparisons. + /// + internal override EventType Type { + get { + return EventType.DocumentEnd; + } + } + + private readonly bool isImplicit; - /// - /// Gets a value indicating whether this instance is implicit. - /// - /// - /// true if this instance is implicit; otherwise, false. - /// - public bool IsImplicit - { - get - { - return isImplicit; - } - } + /// + /// Gets a value indicating whether this instance is implicit. + /// + /// + /// true if this instance is implicit; otherwise, false. + /// + public bool IsImplicit + { + get + { + return isImplicit; + } + } - /// - /// Initializes a new instance of the class. - /// - /// Indicates whether the event is implicit. - /// The start position of the event. - /// The end position of the event. - public DocumentEnd(bool isImplicit, Mark start, Mark end) - : base(start, end) - { - this.isImplicit = isImplicit; - } + /// + /// Initializes a new instance of the class. + /// + /// Indicates whether the event is implicit. + /// The start position of the event. + /// The end position of the event. + public DocumentEnd(bool isImplicit, Mark start, Mark end) + : base(start, end) + { + this.isImplicit = isImplicit; + } - /// - /// Initializes a new instance of the class. - /// - /// Indicates whether the event is implicit. - public DocumentEnd(bool isImplicit) - : this(isImplicit, Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + /// Indicates whether the event is implicit. + public DocumentEnd(bool isImplicit) + : this(isImplicit, Mark.Empty, Mark.Empty) + { + } - /// - /// Returns a that represents the current . - /// - /// - /// A that represents the current . - /// - public override string ToString() - { - return string.Format( - CultureInfo.InvariantCulture, - "Document end [isImplicit = {0}]", - isImplicit - ); - } + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + return string.Format( + CultureInfo.InvariantCulture, + "Document end [isImplicit = {0}]", + isImplicit + ); + } - /// - /// Invokes run-time type specific Visit() method of the specified visitor. - /// - /// visitor, may not be null. - public override void Accept(IParsingEventVisitor visitor) - { - visitor.Visit(this); - } - } + /// + /// Invokes run-time type specific Visit() method of the specified visitor. + /// + /// visitor, may not be null. + public override void Accept(IParsingEventVisitor visitor) + { + visitor.Visit(this); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Events/DocumentStart.cs b/YamlDotNet/Core/Events/DocumentStart.cs index ace3bb22e..be9e476ef 100644 --- a/YamlDotNet/Core/Events/DocumentStart.cs +++ b/YamlDotNet/Core/Events/DocumentStart.cs @@ -24,141 +24,141 @@ namespace YamlDotNet.Core.Events { - /// - /// Represents a document start event. - /// - public class DocumentStart : ParsingEvent - { - /// - /// 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. - /// - public override int NestingIncrease { - get { - return 1; - } - } + /// + /// Represents a document start event. + /// + public class DocumentStart : ParsingEvent + { + /// + /// 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. + /// + public override int NestingIncrease { + get { + return 1; + } + } - /// - /// Gets the event type, which allows for simpler type comparisons. - /// - internal override EventType Type { - get { - return EventType.DocumentStart; - } - } - - private readonly TagDirectiveCollection tags; - private readonly VersionDirective version; + /// + /// Gets the event type, which allows for simpler type comparisons. + /// + internal override EventType Type { + get { + return EventType.DocumentStart; + } + } + + private readonly TagDirectiveCollection tags; + private readonly VersionDirective version; - /// - /// Gets the tags. - /// - /// The tags. - public TagDirectiveCollection Tags - { - get - { - return tags; - } - } + /// + /// Gets the tags. + /// + /// The tags. + public TagDirectiveCollection Tags + { + get + { + return tags; + } + } - /// - /// Gets the version. - /// - /// The version. - public VersionDirective Version - { - get - { - return version; - } - } + /// + /// Gets the version. + /// + /// The version. + public VersionDirective Version + { + get + { + return version; + } + } - private readonly bool isImplicit; + private readonly bool isImplicit; - /// - /// Gets a value indicating whether this instance is implicit. - /// - /// - /// true if this instance is implicit; otherwise, false. - /// - public bool IsImplicit - { - get - { - return isImplicit; - } - } + /// + /// Gets a value indicating whether this instance is implicit. + /// + /// + /// true if this instance is implicit; otherwise, false. + /// + public bool IsImplicit + { + get + { + return isImplicit; + } + } - /// - /// Initializes a new instance of the class. - /// - /// The version. - /// The tags. - /// Indicates whether the event is implicit. - /// The start position of the event. - /// The end position of the event. - public DocumentStart(VersionDirective version, TagDirectiveCollection tags, bool isImplicit, Mark start, Mark end) - : base(start, end) - { - this.version = version; - this.tags = tags; - this.isImplicit = isImplicit; - } + /// + /// Initializes a new instance of the class. + /// + /// The version. + /// The tags. + /// Indicates whether the event is implicit. + /// The start position of the event. + /// The end position of the event. + public DocumentStart(VersionDirective version, TagDirectiveCollection tags, bool isImplicit, Mark start, Mark end) + : base(start, end) + { + this.version = version; + this.tags = tags; + this.isImplicit = isImplicit; + } - /// - /// Initializes a new instance of the class. - /// - /// The version. - /// The tags. - /// Indicates whether the event is implicit. - public DocumentStart(VersionDirective version, TagDirectiveCollection tags, bool isImplicit) - : this(version, tags, isImplicit, Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The version. + /// The tags. + /// Indicates whether the event is implicit. + public DocumentStart(VersionDirective version, TagDirectiveCollection tags, bool isImplicit) + : this(version, tags, isImplicit, Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the event. - /// The end position of the event. - public DocumentStart(Mark start, Mark end) - : this(null, null, true, start, end) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the event. + /// The end position of the event. + public DocumentStart(Mark start, Mark end) + : this(null, null, true, start, end) + { + } - /// - /// Initializes a new instance of the class. - /// - public DocumentStart() - : this(null, null, true, Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + public DocumentStart() + : this(null, null, true, Mark.Empty, Mark.Empty) + { + } - /// - /// Returns a that represents the current . - /// - /// - /// A that represents the current . - /// - public override string ToString() - { - return string.Format( - CultureInfo.InvariantCulture, - "Document start [isImplicit = {0}]", - isImplicit - ); - } + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + return string.Format( + CultureInfo.InvariantCulture, + "Document start [isImplicit = {0}]", + isImplicit + ); + } - /// - /// Invokes run-time type specific Visit() method of the specified visitor. - /// - /// visitor, may not be null. - public override void Accept(IParsingEventVisitor visitor) - { - visitor.Visit(this); - } - } + /// + /// Invokes run-time type specific Visit() method of the specified visitor. + /// + /// visitor, may not be null. + public override void Accept(IParsingEventVisitor visitor) + { + visitor.Visit(this); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Events/EventType.cs b/YamlDotNet/Core/Events/EventType.cs index 2c10ecaa4..6a34cdea5 100644 --- a/YamlDotNet/Core/Events/EventType.cs +++ b/YamlDotNet/Core/Events/EventType.cs @@ -21,19 +21,19 @@ namespace YamlDotNet.Core.Events { - internal enum EventType - { - None, - StreamStart, - StreamEnd, - DocumentStart, - DocumentEnd, - Alias, - Scalar, - SequenceStart, - SequenceEnd, - MappingStart, - MappingEnd, - Comment, - } + internal enum EventType + { + None, + StreamStart, + StreamEnd, + DocumentStart, + DocumentEnd, + Alias, + Scalar, + SequenceStart, + SequenceEnd, + MappingStart, + MappingEnd, + Comment, + } } diff --git a/YamlDotNet/Core/Events/IParsingEventVisitor.cs b/YamlDotNet/Core/Events/IParsingEventVisitor.cs index 6cbc6c301..c80a4a606 100644 --- a/YamlDotNet/Core/Events/IParsingEventVisitor.cs +++ b/YamlDotNet/Core/Events/IParsingEventVisitor.cs @@ -22,21 +22,21 @@ namespace YamlDotNet.Core.Events { - /// - /// Callback interface for external event Visitor. - /// - public interface IParsingEventVisitor - { - void Visit(AnchorAlias e); - void Visit(StreamStart e); - void Visit(StreamEnd e); - void Visit(DocumentStart e); - void Visit(DocumentEnd e); - void Visit(Scalar e); - void Visit(SequenceStart e); - void Visit(SequenceEnd e); - void Visit(MappingStart e); - void Visit(MappingEnd e); - void Visit(Comment e); - } + /// + /// Callback interface for external event Visitor. + /// + public interface IParsingEventVisitor + { + void Visit(AnchorAlias e); + void Visit(StreamStart e); + void Visit(StreamEnd e); + void Visit(DocumentStart e); + void Visit(DocumentEnd e); + void Visit(Scalar e); + void Visit(SequenceStart e); + void Visit(SequenceEnd e); + void Visit(MappingStart e); + void Visit(MappingEnd e); + void Visit(Comment e); + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Events/MappingEnd.cs b/YamlDotNet/Core/Events/MappingEnd.cs index 7028bf5cc..2f91c4b9c 100644 --- a/YamlDotNet/Core/Events/MappingEnd.cs +++ b/YamlDotNet/Core/Events/MappingEnd.cs @@ -21,67 +21,67 @@ namespace YamlDotNet.Core.Events { - /// - /// Represents a mapping end event. - /// - public class MappingEnd : ParsingEvent - { - /// - /// 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. - /// - public override int NestingIncrease { - get { - return -1; - } - } + /// + /// Represents a mapping end event. + /// + public class MappingEnd : ParsingEvent + { + /// + /// 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. + /// + public override int NestingIncrease { + get { + return -1; + } + } - /// - /// Gets the event type, which allows for simpler type comparisons. - /// - internal override EventType Type { - get { - return EventType.MappingEnd; - } - } - - /// - /// Initializes a new instance of the class. - /// - /// The start position of the event. - /// The end position of the event. - public MappingEnd(Mark start, Mark end) - : base(start, end) - { - } + /// + /// Gets the event type, which allows for simpler type comparisons. + /// + internal override EventType Type { + get { + return EventType.MappingEnd; + } + } + + /// + /// Initializes a new instance of the class. + /// + /// The start position of the event. + /// The end position of the event. + public MappingEnd(Mark start, Mark end) + : base(start, end) + { + } - /// - /// Initializes a new instance of the class. - /// - public MappingEnd() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + public MappingEnd() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Returns a that represents the current . - /// - /// - /// A that represents the current . - /// - public override string ToString() - { - return "Mapping end"; - } + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + return "Mapping end"; + } - /// - /// Invokes run-time type specific Visit() method of the specified visitor. - /// - /// visitor, may not be null. - public override void Accept(IParsingEventVisitor visitor) - { - visitor.Visit(this); - } - } + /// + /// Invokes run-time type specific Visit() method of the specified visitor. + /// + /// visitor, may not be null. + public override void Accept(IParsingEventVisitor visitor) + { + visitor.Visit(this); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Events/MappingStart.cs b/YamlDotNet/Core/Events/MappingStart.cs index cff7aab01..fae1aacaf 100644 --- a/YamlDotNet/Core/Events/MappingStart.cs +++ b/YamlDotNet/Core/Events/MappingStart.cs @@ -23,131 +23,131 @@ namespace YamlDotNet.Core.Events { - /// - /// Represents a mapping start event. - /// - public class MappingStart : NodeEvent - { - /// - /// 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. - /// - public override int NestingIncrease { - get { - return 1; - } - } + /// + /// Represents a mapping start event. + /// + public class MappingStart : NodeEvent + { + /// + /// 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. + /// + public override int NestingIncrease { + get { + return 1; + } + } - /// - /// Gets the event type, which allows for simpler type comparisons. - /// - internal override EventType Type { - get { - return EventType.MappingStart; - } - } + /// + /// Gets the event type, which allows for simpler type comparisons. + /// + internal override EventType Type { + get { + return EventType.MappingStart; + } + } - private readonly bool isImplicit; + private readonly bool isImplicit; - /// - /// Gets a value indicating whether this instance is implicit. - /// - /// - /// true if this instance is implicit; otherwise, false. - /// - public bool IsImplicit - { - get - { - return isImplicit; - } - } + /// + /// Gets a value indicating whether this instance is implicit. + /// + /// + /// true if this instance is implicit; otherwise, false. + /// + public bool IsImplicit + { + get + { + return isImplicit; + } + } - /// - /// Gets a value indicating whether this instance is canonical. - /// - /// - public override bool IsCanonical { - get { - return !isImplicit; - } - } + /// + /// Gets a value indicating whether this instance is canonical. + /// + /// + public override bool IsCanonical { + get { + return !isImplicit; + } + } - private readonly MappingStyle style; + private readonly MappingStyle style; - /// - /// Gets the style of the mapping. - /// - public MappingStyle Style - { - get - { - return style; - } - } + /// + /// Gets the style of the mapping. + /// + public MappingStyle Style + { + get + { + return style; + } + } - /// - /// Initializes a new instance of the class. - /// - /// The anchor. - /// The tag. - /// Indicates whether the event is implicit. - /// The style of the mapping. - /// The start position of the event. - /// The end position of the event. - public MappingStart(string anchor, string tag, bool isImplicit, MappingStyle style, Mark start, Mark end) - : base(anchor, tag, start, end) - { - this.isImplicit = isImplicit; - this.style = style; - } + /// + /// Initializes a new instance of the class. + /// + /// The anchor. + /// The tag. + /// Indicates whether the event is implicit. + /// The style of the mapping. + /// The start position of the event. + /// The end position of the event. + public MappingStart(string anchor, string tag, bool isImplicit, MappingStyle style, Mark start, Mark end) + : base(anchor, tag, start, end) + { + this.isImplicit = isImplicit; + this.style = style; + } - /// - /// Initializes a new instance of the class. - /// - /// The anchor. - /// The tag. - /// Indicates whether the event is implicit. - /// The style of the mapping. - public MappingStart(string anchor, string tag, bool isImplicit, MappingStyle style) - : this(anchor, tag, isImplicit, style, Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The anchor. + /// The tag. + /// Indicates whether the event is implicit. + /// The style of the mapping. + public MappingStart(string anchor, string tag, bool isImplicit, MappingStyle style) + : this(anchor, tag, isImplicit, style, Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - public MappingStart() - : this(null, null, true, MappingStyle.Any, Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + public MappingStart() + : this(null, null, true, MappingStyle.Any, Mark.Empty, Mark.Empty) + { + } - /// - /// Returns a that represents the current . - /// - /// - /// A that represents the current . - /// - public override string ToString() - { - return string.Format( - CultureInfo.InvariantCulture, - "Mapping start [anchor = {0}, tag = {1}, isImplicit = {2}, style = {3}]", - Anchor, - Tag, - isImplicit, - style - ); - } + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + return string.Format( + CultureInfo.InvariantCulture, + "Mapping start [anchor = {0}, tag = {1}, isImplicit = {2}, style = {3}]", + Anchor, + Tag, + isImplicit, + style + ); + } - /// - /// Invokes run-time type specific Visit() method of the specified visitor. - /// - /// visitor, may not be null. - public override void Accept(IParsingEventVisitor visitor) - { - visitor.Visit(this); - } - } + /// + /// Invokes run-time type specific Visit() method of the specified visitor. + /// + /// visitor, may not be null. + public override void Accept(IParsingEventVisitor visitor) + { + visitor.Visit(this); + } + } } diff --git a/YamlDotNet/Core/Events/MappingStyle.cs b/YamlDotNet/Core/Events/MappingStyle.cs index 72fb086ce..b0ae911d7 100644 --- a/YamlDotNet/Core/Events/MappingStyle.cs +++ b/YamlDotNet/Core/Events/MappingStyle.cs @@ -21,24 +21,24 @@ namespace YamlDotNet.Core.Events { - /// - /// Specifies the style of a mapping. - /// - public enum MappingStyle - { - /// - /// Let the emitter choose the style. - /// - Any, + /// + /// Specifies the style of a mapping. + /// + public enum MappingStyle + { + /// + /// Let the emitter choose the style. + /// + Any, - /// - /// The block mapping style. - /// - Block, + /// + /// The block mapping style. + /// + Block, - /// - /// The flow mapping style. - /// - Flow - } + /// + /// The flow mapping style. + /// + Flow + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Events/NodeEvent.cs b/YamlDotNet/Core/Events/NodeEvent.cs index 34b775c77..cfbf05846 100644 --- a/YamlDotNet/Core/Events/NodeEvent.cs +++ b/YamlDotNet/Core/Events/NodeEvent.cs @@ -24,83 +24,83 @@ namespace YamlDotNet.Core.Events { - /// - /// Contains the behavior that is common between node events. - /// - public abstract class NodeEvent : ParsingEvent - { - internal static readonly Regex anchorValidator = new Regex(@"^[0-9a-zA-Z_\-]+$", StandardRegexOptions.Compiled); + /// + /// Contains the behavior that is common between node events. + /// + public abstract class NodeEvent : ParsingEvent + { + internal static readonly Regex anchorValidator = new Regex(@"^[0-9a-zA-Z_\-]+$", StandardRegexOptions.Compiled); - private readonly string anchor; + private readonly string anchor; - /// - /// Gets the anchor. - /// - /// - public string Anchor - { - get - { - return anchor; - } - } + /// + /// Gets the anchor. + /// + /// + public string Anchor + { + get + { + return anchor; + } + } - private readonly string tag; + private readonly string tag; - /// - /// Gets the tag. - /// - /// - public string Tag - { - get - { - return tag; - } - } + /// + /// Gets the tag. + /// + /// + public string Tag + { + get + { + return tag; + } + } - /// - /// Gets a value indicating whether this instance is canonical. - /// - /// - public abstract bool IsCanonical { - get; - } + /// + /// Gets a value indicating whether this instance is canonical. + /// + /// + public abstract bool IsCanonical { + get; + } - /// - /// Initializes a new instance of the class. - /// - /// The anchor. - /// The tag. - /// The start position of the event. - /// The end position of the event. - protected NodeEvent(string anchor, string tag, Mark start, Mark end) - : base(start, end) - { - if(anchor != null) { - if(anchor.Length == 0) { - throw new ArgumentException("Anchor value must not be empty.", "anchor"); - } + /// + /// Initializes a new instance of the class. + /// + /// The anchor. + /// The tag. + /// The start position of the event. + /// The end position of the event. + protected NodeEvent(string anchor, string tag, Mark start, Mark end) + : base(start, end) + { + if(anchor != null) { + if(anchor.Length == 0) { + throw new ArgumentException("Anchor value must not be empty.", "anchor"); + } - if(!anchorValidator.IsMatch(anchor)) { - throw new ArgumentException("Anchor value must contain alphanumerical characters only.", "anchor"); - } - } - - if(tag != null && tag.Length == 0) { - throw new ArgumentException("Tag value must not be empty.", "tag"); - } - - this.anchor = anchor; - this.tag = tag; - } + if(!anchorValidator.IsMatch(anchor)) { + throw new ArgumentException("Anchor value must contain alphanumerical characters only.", "anchor"); + } + } + + if(tag != null && tag.Length == 0) { + throw new ArgumentException("Tag value must not be empty.", "tag"); + } + + this.anchor = anchor; + this.tag = tag; + } - /// - /// Initializes a new instance of the class. - /// - protected NodeEvent(string anchor, string tag) - : this(anchor, tag, Mark.Empty, Mark.Empty) - { - } - } + /// + /// Initializes a new instance of the class. + /// + protected NodeEvent(string anchor, string tag) + : this(anchor, tag, Mark.Empty, Mark.Empty) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Events/ParsingEvent.cs b/YamlDotNet/Core/Events/ParsingEvent.cs index 863da2a7a..89ebd652c 100644 --- a/YamlDotNet/Core/Events/ParsingEvent.cs +++ b/YamlDotNet/Core/Events/ParsingEvent.cs @@ -21,68 +21,68 @@ namespace YamlDotNet.Core.Events { - /// - /// Base class for parsing events. - /// - public abstract class ParsingEvent - { - /// - /// 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. - /// - public virtual int NestingIncrease { - get { return 0; } - } + /// + /// Base class for parsing events. + /// + public abstract class ParsingEvent + { + /// + /// 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. + /// + public virtual int NestingIncrease { + get { return 0; } + } - /// - /// Gets the event type, which allows for simpler type comparisons. - /// - internal abstract EventType Type { - get; - } - - private readonly Mark start; + /// + /// 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; - } - } + /// + /// Gets the position in the input stream where the event starts. + /// + public Mark Start + { + get + { + return start; + } + } - private readonly Mark end; + private readonly Mark end; - /// - /// Gets the position in the input stream where the event ends. - /// - public Mark End - { - get - { - return end; - } - } + /// + /// Gets the position in the input stream where the event ends. + /// + public Mark End + { + get + { + return end; + } + } - /// - /// Accepts the specified visitor. - /// - /// Visitor to accept, may not be null - public abstract void Accept(IParsingEventVisitor visitor); + /// + /// Accepts the specified visitor. + /// + /// Visitor to accept, may not be null + public abstract void Accept(IParsingEventVisitor visitor); - /// - /// 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; - } - } + /// + /// 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 586e0c3dc..e78d0b9eb 100644 --- a/YamlDotNet/Core/Events/Scalar.cs +++ b/YamlDotNet/Core/Events/Scalar.cs @@ -23,172 +23,172 @@ namespace YamlDotNet.Core.Events { - /// - /// Represents a scalar event. - /// - public class Scalar : NodeEvent - { - /// - /// Gets the event type, which allows for simpler type comparisons. - /// - internal override EventType Type { - get { - return EventType.Scalar; - } - } - - private readonly string value; - - /// - /// Gets the value. - /// - /// The value. - public string Value - { - get - { - return value; - } - } - - private readonly ScalarStyle style; - - /// - /// Gets the style of the scalar. - /// - /// The style. - public ScalarStyle Style - { - get - { - return style; - } - } - - private readonly bool isPlainImplicit; - - /// - /// Gets a value indicating whether the tag is optional for the plain style. - /// - public bool IsPlainImplicit - { - get - { - return isPlainImplicit; - } - } - - private readonly bool isQuotedImplicit; - - /// - /// Gets a value indicating whether the tag is optional for any non-plain style. - /// - public bool IsQuotedImplicit - { - get - { - return isQuotedImplicit; - } - } - - /// - /// Gets a value indicating whether this instance is canonical. - /// - /// - public override bool IsCanonical { - get { - return !isPlainImplicit && !isQuotedImplicit; - } - } - - /// - /// Initializes a new instance of the class. - /// - /// The anchor. - /// The tag. - /// The value. - /// The style. - /// . - /// . - /// The start position of the event. - /// The end position of the event. - public Scalar(string anchor, string tag, string value, ScalarStyle style, bool isPlainImplicit, bool isQuotedImplicit, Mark start, Mark end) - : base(anchor, tag, start, end) - { - this.value = value; - this.style = style; - this.isPlainImplicit = isPlainImplicit; - this.isQuotedImplicit = isQuotedImplicit; - } - - /// - /// Initializes a new instance of the class. - /// - /// The anchor. - /// The tag. - /// The value. - /// The style. - /// . - /// . - public Scalar(string anchor, string tag, string value, ScalarStyle style, bool isPlainImplicit, bool isQuotedImplicit) - : this(anchor, tag, value, style, isPlainImplicit, isQuotedImplicit, Mark.Empty, Mark.Empty) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - public Scalar(string value) - : this(null, null, value, ScalarStyle.Any, true, true, Mark.Empty, Mark.Empty) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The tag. - /// The value. - public Scalar(string tag, string value) - : this(null, tag, value, ScalarStyle.Any, true, true, Mark.Empty, Mark.Empty) - { - } - - /// - /// Initializes a new instance of the class. - /// - public Scalar(string anchor, string tag, string value) - : this(anchor, tag, value, ScalarStyle.Any, true, true, Mark.Empty, Mark.Empty) - { - } - - /// - /// Returns a that represents the current . - /// - /// - /// A that represents the current . - /// - public override string ToString() - { - return string.Format( - CultureInfo.InvariantCulture, - "Scalar [anchor = {0}, tag = {1}, value = {2}, style = {3}, isPlainImplicit = {4}, isQuotedImplicit = {5}]", - Anchor, - Tag, - value, - style, - isPlainImplicit, - isQuotedImplicit - ); - } - - /// - /// Invokes run-time type specific Visit() method of the specified visitor. - /// - /// visitor, may not be null. - public override void Accept(IParsingEventVisitor visitor) - { - visitor.Visit(this); - } - } + /// + /// Represents a scalar event. + /// + public class Scalar : NodeEvent + { + /// + /// Gets the event type, which allows for simpler type comparisons. + /// + internal override EventType Type { + get { + return EventType.Scalar; + } + } + + private readonly string value; + + /// + /// Gets the value. + /// + /// The value. + public string Value + { + get + { + return value; + } + } + + private readonly ScalarStyle style; + + /// + /// Gets the style of the scalar. + /// + /// The style. + public ScalarStyle Style + { + get + { + return style; + } + } + + private readonly bool isPlainImplicit; + + /// + /// Gets a value indicating whether the tag is optional for the plain style. + /// + public bool IsPlainImplicit + { + get + { + return isPlainImplicit; + } + } + + private readonly bool isQuotedImplicit; + + /// + /// Gets a value indicating whether the tag is optional for any non-plain style. + /// + public bool IsQuotedImplicit + { + get + { + return isQuotedImplicit; + } + } + + /// + /// Gets a value indicating whether this instance is canonical. + /// + /// + public override bool IsCanonical { + get { + return !isPlainImplicit && !isQuotedImplicit; + } + } + + /// + /// Initializes a new instance of the class. + /// + /// The anchor. + /// The tag. + /// The value. + /// The style. + /// . + /// . + /// The start position of the event. + /// The end position of the event. + public Scalar(string anchor, string tag, string value, ScalarStyle style, bool isPlainImplicit, bool isQuotedImplicit, Mark start, Mark end) + : base(anchor, tag, start, end) + { + this.value = value; + this.style = style; + this.isPlainImplicit = isPlainImplicit; + this.isQuotedImplicit = isQuotedImplicit; + } + + /// + /// Initializes a new instance of the class. + /// + /// The anchor. + /// The tag. + /// The value. + /// The style. + /// . + /// . + public Scalar(string anchor, string tag, string value, ScalarStyle style, bool isPlainImplicit, bool isQuotedImplicit) + : this(anchor, tag, value, style, isPlainImplicit, isQuotedImplicit, Mark.Empty, Mark.Empty) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + public Scalar(string value) + : this(null, null, value, ScalarStyle.Any, true, true, Mark.Empty, Mark.Empty) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The tag. + /// The value. + public Scalar(string tag, string value) + : this(null, tag, value, ScalarStyle.Any, true, true, Mark.Empty, Mark.Empty) + { + } + + /// + /// Initializes a new instance of the class. + /// + public Scalar(string anchor, string tag, string value) + : this(anchor, tag, value, ScalarStyle.Any, true, true, Mark.Empty, Mark.Empty) + { + } + + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + return string.Format( + CultureInfo.InvariantCulture, + "Scalar [anchor = {0}, tag = {1}, value = {2}, style = {3}, isPlainImplicit = {4}, isQuotedImplicit = {5}]", + Anchor, + Tag, + value, + style, + isPlainImplicit, + isQuotedImplicit + ); + } + + /// + /// Invokes run-time type specific Visit() method of the specified visitor. + /// + /// visitor, may not be null. + public override void Accept(IParsingEventVisitor visitor) + { + visitor.Visit(this); + } + } } diff --git a/YamlDotNet/Core/Events/SequenceEnd.cs b/YamlDotNet/Core/Events/SequenceEnd.cs index 595eaafb5..18f8c5fa7 100644 --- a/YamlDotNet/Core/Events/SequenceEnd.cs +++ b/YamlDotNet/Core/Events/SequenceEnd.cs @@ -21,67 +21,67 @@ namespace YamlDotNet.Core.Events { - /// - /// Represents a sequence end event. - /// - public class SequenceEnd : ParsingEvent - { - /// - /// 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. - /// - public override int NestingIncrease { - get { - return -1; - } - } + /// + /// Represents a sequence end event. + /// + public class SequenceEnd : ParsingEvent + { + /// + /// 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. + /// + public override int NestingIncrease { + get { + return -1; + } + } - /// - /// Gets the event type, which allows for simpler type comparisons. - /// - internal override EventType Type { - get { - return EventType.SequenceEnd; - } - } - - /// - /// Initializes a new instance of the class. - /// - /// The start position of the event. - /// The end position of the event. - public SequenceEnd(Mark start, Mark end) - : base(start, end) - { - } + /// + /// Gets the event type, which allows for simpler type comparisons. + /// + internal override EventType Type { + get { + return EventType.SequenceEnd; + } + } + + /// + /// Initializes a new instance of the class. + /// + /// The start position of the event. + /// The end position of the event. + public SequenceEnd(Mark start, Mark end) + : base(start, end) + { + } - /// - /// Initializes a new instance of the class. - /// - public SequenceEnd() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + public SequenceEnd() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Returns a that represents the current . - /// - /// - /// A that represents the current . - /// - public override string ToString() - { - return "Sequence end"; - } + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + return "Sequence end"; + } - /// - /// Invokes run-time type specific Visit() method of the specified visitor. - /// - /// visitor, may not be null. - public override void Accept(IParsingEventVisitor visitor) - { - visitor.Visit(this); - } - } + /// + /// Invokes run-time type specific Visit() method of the specified visitor. + /// + /// visitor, may not be null. + public override void Accept(IParsingEventVisitor visitor) + { + visitor.Visit(this); + } + } } diff --git a/YamlDotNet/Core/Events/SequenceStart.cs b/YamlDotNet/Core/Events/SequenceStart.cs index c18450f9d..a260d0da5 100644 --- a/YamlDotNet/Core/Events/SequenceStart.cs +++ b/YamlDotNet/Core/Events/SequenceStart.cs @@ -23,120 +23,120 @@ namespace YamlDotNet.Core.Events { - /// - /// Represents a sequence start event. - /// - public class SequenceStart : NodeEvent - { - /// - /// 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. - /// - public override int NestingIncrease { - get { - return 1; - } - } + /// + /// Represents a sequence start event. + /// + public class SequenceStart : NodeEvent + { + /// + /// 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. + /// + public override int NestingIncrease { + get { + return 1; + } + } - /// - /// Gets the event type, which allows for simpler type comparisons. - /// - internal override EventType Type { - get { - return EventType.SequenceStart; - } - } + /// + /// Gets the event type, which allows for simpler type comparisons. + /// + internal override EventType Type { + get { + return EventType.SequenceStart; + } + } - private readonly bool isImplicit; + private readonly bool isImplicit; - /// - /// Gets a value indicating whether this instance is implicit. - /// - /// - /// true if this instance is implicit; otherwise, false. - /// - public bool IsImplicit - { - get - { - return isImplicit; - } - } + /// + /// Gets a value indicating whether this instance is implicit. + /// + /// + /// true if this instance is implicit; otherwise, false. + /// + public bool IsImplicit + { + get + { + return isImplicit; + } + } - /// - /// Gets a value indicating whether this instance is canonical. - /// - /// - public override bool IsCanonical { - get { - return !isImplicit; - } - } + /// + /// Gets a value indicating whether this instance is canonical. + /// + /// + public override bool IsCanonical { + get { + return !isImplicit; + } + } - private readonly SequenceStyle style; + private readonly SequenceStyle style; - /// - /// Gets the style. - /// - /// The style. - public SequenceStyle Style - { - get - { - return style; - } - } + /// + /// Gets the style. + /// + /// The style. + public SequenceStyle Style + { + get + { + return style; + } + } - /// - /// Initializes a new instance of the class. - /// - /// The anchor. - /// The tag. - /// if set to true [is implicit]. - /// The style. - /// The start position of the event. - /// The end position of the event. - public SequenceStart(string anchor, string tag, bool isImplicit, SequenceStyle style, Mark start, Mark end) - : base(anchor, tag, start, end) - { - this.isImplicit = isImplicit; - this.style = style; - } + /// + /// Initializes a new instance of the class. + /// + /// The anchor. + /// The tag. + /// if set to true [is implicit]. + /// The style. + /// The start position of the event. + /// The end position of the event. + public SequenceStart(string anchor, string tag, bool isImplicit, SequenceStyle style, Mark start, Mark end) + : base(anchor, tag, start, end) + { + this.isImplicit = isImplicit; + this.style = style; + } - /// - /// Initializes a new instance of the class. - /// - public SequenceStart(string anchor, string tag, bool isImplicit, SequenceStyle style) - : this(anchor, tag, isImplicit, style, Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + public SequenceStart(string anchor, string tag, bool isImplicit, SequenceStyle style) + : this(anchor, tag, isImplicit, style, Mark.Empty, Mark.Empty) + { + } - /// - /// Returns a that represents the current . - /// - /// - /// A that represents the current . - /// - public override string ToString() - { - return string.Format( - CultureInfo.InvariantCulture, - "Sequence start [anchor = {0}, tag = {1}, isImplicit = {2}, style = {3}]", - Anchor, - Tag, - isImplicit, - style - ); - } + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + return string.Format( + CultureInfo.InvariantCulture, + "Sequence start [anchor = {0}, tag = {1}, isImplicit = {2}, style = {3}]", + Anchor, + Tag, + isImplicit, + style + ); + } - /// - /// Invokes run-time type specific Visit() method of the specified visitor. - /// - /// visitor, may not be null. - public override void Accept(IParsingEventVisitor visitor) - { - visitor.Visit(this); - } - } + /// + /// Invokes run-time type specific Visit() method of the specified visitor. + /// + /// visitor, may not be null. + public override void Accept(IParsingEventVisitor visitor) + { + visitor.Visit(this); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Events/SequenceStyle.cs b/YamlDotNet/Core/Events/SequenceStyle.cs index 364e7d0ac..d10ca3ba6 100644 --- a/YamlDotNet/Core/Events/SequenceStyle.cs +++ b/YamlDotNet/Core/Events/SequenceStyle.cs @@ -21,24 +21,24 @@ namespace YamlDotNet.Core.Events { - /// - /// Specifies the style of a sequence. - /// - public enum SequenceStyle - { - /// - /// Let the emitter choose the style. - /// - Any, + /// + /// Specifies the style of a sequence. + /// + public enum SequenceStyle + { + /// + /// Let the emitter choose the style. + /// + Any, - /// - /// The block sequence style. - /// - Block, + /// + /// The block sequence style. + /// + Block, - /// - /// The flow sequence style. - /// - Flow - } + /// + /// 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 f243a4e05..2f50fc2b6 100644 --- a/YamlDotNet/Core/Events/StreamEnd.cs +++ b/YamlDotNet/Core/Events/StreamEnd.cs @@ -21,67 +21,67 @@ namespace YamlDotNet.Core.Events { - /// - /// Represents a stream end event. - /// - public class StreamEnd : ParsingEvent - { - /// - /// 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. - /// - public override int NestingIncrease { - get { - return -1; - } - } + /// + /// Represents a stream end event. + /// + public class StreamEnd : ParsingEvent + { + /// + /// 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. + /// + public override int NestingIncrease { + get { + return -1; + } + } - /// - /// Gets the event type, which allows for simpler type comparisons. - /// - internal override EventType Type { - get { - return EventType.StreamEnd; - } - } - - /// - /// Initializes a new instance of the class. - /// - /// The start position of the event. - /// The end position of the event. - public StreamEnd(Mark start, Mark end) - : base(start, end) - { - } + /// + /// Gets the event type, which allows for simpler type comparisons. + /// + internal override EventType Type { + get { + return EventType.StreamEnd; + } + } + + /// + /// Initializes a new instance of the class. + /// + /// The start position of the event. + /// The end position of the event. + public StreamEnd(Mark start, Mark end) + : base(start, end) + { + } - /// - /// Initializes a new instance of the class. - /// - public StreamEnd() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + public StreamEnd() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Returns a that represents the current . - /// - /// - /// A that represents the current . - /// - public override string ToString() - { - return "Stream end"; - } + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + return "Stream end"; + } - /// - /// Invokes run-time type specific Visit() method of the specified visitor. - /// - /// visitor, may not be null. - public override void Accept(IParsingEventVisitor visitor) - { - visitor.Visit(this); - } - } + /// + /// Invokes run-time type specific Visit() method of the specified visitor. + /// + /// visitor, may not be null. + public override void Accept(IParsingEventVisitor visitor) + { + visitor.Visit(this); + } + } } diff --git a/YamlDotNet/Core/Events/StreamStart.cs b/YamlDotNet/Core/Events/StreamStart.cs index 70d21fdb7..377639e3f 100644 --- a/YamlDotNet/Core/Events/StreamStart.cs +++ b/YamlDotNet/Core/Events/StreamStart.cs @@ -21,67 +21,67 @@ namespace YamlDotNet.Core.Events { - /// - /// Represents a stream start event. - /// - public class StreamStart : ParsingEvent - { - /// - /// 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. - /// - public override int NestingIncrease { - get { - return 1; - } - } + /// + /// Represents a stream start event. + /// + public class StreamStart : ParsingEvent + { + /// + /// 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. + /// + public override int NestingIncrease { + get { + return 1; + } + } - /// - /// Gets the event type, which allows for simpler type comparisons. - /// - internal override EventType Type { - get { - return EventType.StreamStart; - } - } - - /// - /// Initializes a new instance of the class. - /// - public StreamStart() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Gets the event type, which allows for simpler type comparisons. + /// + internal override EventType Type { + get { + return EventType.StreamStart; + } + } + + /// + /// Initializes a new instance of the class. + /// + public StreamStart() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the event. - /// The end position of the event. - public StreamStart(Mark start, Mark end) - : base(start, end) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the event. + /// The end position of the event. + public StreamStart(Mark start, Mark end) + : base(start, end) + { + } - /// - /// Returns a that represents the current . - /// - /// - /// A that represents the current . - /// - public override string ToString() - { - return "Stream start"; - } + /// + /// Returns a that represents the current . + /// + /// + /// A that represents the current . + /// + public override string ToString() + { + return "Stream start"; + } - /// - /// Invokes run-time type specific Visit() method of the specified visitor. - /// - /// visitor, may not be null. - public override void Accept(IParsingEventVisitor visitor) - { - visitor.Visit(this); - } - } + /// + /// Invokes run-time type specific Visit() method of the specified visitor. + /// + /// visitor, may not be null. + public override void Accept(IParsingEventVisitor visitor) + { + visitor.Visit(this); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/FakeList.cs b/YamlDotNet/Core/FakeList.cs index 7cf64210c..69d607680 100644 --- a/YamlDotNet/Core/FakeList.cs +++ b/YamlDotNet/Core/FakeList.cs @@ -24,55 +24,55 @@ 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()) - { - } + /// + /// 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; - } - } - } + /// + /// 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/ForwardAnchorNotSupportedException.cs b/YamlDotNet/Core/ForwardAnchorNotSupportedException.cs index d1e7f0832..d29aaf010 100644 --- a/YamlDotNet/Core/ForwardAnchorNotSupportedException.cs +++ b/YamlDotNet/Core/ForwardAnchorNotSupportedException.cs @@ -24,59 +24,59 @@ namespace YamlDotNet.Core { - /// - /// The exception that is thrown when an alias references an anchor - /// that has not yet been defined in a context that does not support forward references. - /// - [Serializable] - public class ForwardAnchorNotSupportedException : YamlException - { - /// - /// Initializes a new instance of the class. - /// - public ForwardAnchorNotSupportedException() - { - } + /// + /// The exception that is thrown when an alias references an anchor + /// that has not yet been defined in a context that does not support forward references. + /// + [Serializable] + public class ForwardAnchorNotSupportedException : YamlException + { + /// + /// Initializes a new instance of the class. + /// + public ForwardAnchorNotSupportedException() + { + } - /// - /// Initializes a new instance of the class. - /// - /// The message. - public ForwardAnchorNotSupportedException(string message) - : base(message) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The message. + public ForwardAnchorNotSupportedException(string message) + : base(message) + { + } - /// - /// Initializes a new instance of the class. - /// - public ForwardAnchorNotSupportedException(Mark start, Mark end, string message) - : base(start, end, message) - { - } + /// + /// Initializes a new instance of the class. + /// + public ForwardAnchorNotSupportedException(Mark start, Mark end, string message) + : base(start, end, message) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The message. - /// The inner. - public ForwardAnchorNotSupportedException(string message, Exception inner) - : base(message, inner) - { + /// + /// Initializes a new instance of the class. + /// + /// The message. + /// The inner. + public ForwardAnchorNotSupportedException(string message, Exception inner) + : base(message, inner) + { } #if !(PORTABLE || UNITY) - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is null. - /// The class name is null or is zero (0). - protected ForwardAnchorNotSupportedException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is null. + /// The class name is null or is zero (0). + protected ForwardAnchorNotSupportedException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } #endif } } diff --git a/YamlDotNet/Core/HashCode.cs b/YamlDotNet/Core/HashCode.cs index f6559e94a..b229a624d 100644 --- a/YamlDotNet/Core/HashCode.cs +++ b/YamlDotNet/Core/HashCode.cs @@ -23,20 +23,20 @@ namespace YamlDotNet.Core { - /// + /// /// Supports implementations of by providing methods to combine two hash codes. /// - internal static class HashCode - { - /// - /// Combines two hash codes. - /// - /// The first hash code. - /// The second hash code. - /// - public static int CombineHashCodes(int h1, int h2) - { - return ((h1 << 5) + h1) ^ h2; - } - } + internal static class HashCode + { + /// + /// Combines two hash codes. + /// + /// The first hash code. + /// The second hash code. + /// + public static int CombineHashCodes(int h1, int h2) + { + return ((h1 << 5) + h1) ^ h2; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/IEmitter.cs b/YamlDotNet/Core/IEmitter.cs index 63110917b..1875c12f7 100644 --- a/YamlDotNet/Core/IEmitter.cs +++ b/YamlDotNet/Core/IEmitter.cs @@ -23,14 +23,14 @@ namespace YamlDotNet.Core { - /// - /// Represents a YAML stream emitter. - /// - public interface IEmitter - { - /// - /// Emits an event. - /// - void Emit(ParsingEvent @event); - } + /// + /// Represents a YAML stream emitter. + /// + public interface IEmitter + { + /// + /// Emits an event. + /// + void Emit(ParsingEvent @event); + } } diff --git a/YamlDotNet/Core/ILookAheadBuffer.cs b/YamlDotNet/Core/ILookAheadBuffer.cs index ebeccd6cc..f88371395 100644 --- a/YamlDotNet/Core/ILookAheadBuffer.cs +++ b/YamlDotNet/Core/ILookAheadBuffer.cs @@ -23,25 +23,25 @@ namespace YamlDotNet.Core { - internal interface ILookAheadBuffer - { - /// - /// Gets a value indicating whether the end of the input reader has been reached. - /// - bool EndOfInput - { - get; - } - - /// - /// Gets the character at thhe specified offset. - /// - char Peek(int offset); + internal interface ILookAheadBuffer + { + /// + /// Gets a value indicating whether the end of the input reader has been reached. + /// + bool EndOfInput + { + get; + } + + /// + /// Gets the character at thhe specified offset. + /// + char Peek(int offset); - /// - /// Skips the next characters. Those characters must have been - /// obtained first by calling the method. - /// - void Skip(int length); - } + /// + /// Skips the next characters. Those characters must have been + /// obtained first by calling the method. + /// + void Skip(int length); + } } diff --git a/YamlDotNet/Core/IParser.cs b/YamlDotNet/Core/IParser.cs index e9de9945d..fd1afffc3 100644 --- a/YamlDotNet/Core/IParser.cs +++ b/YamlDotNet/Core/IParser.cs @@ -23,20 +23,20 @@ namespace YamlDotNet.Core { - /// - /// Represents a YAML stream paser. - /// - public interface IParser - { - /// - /// Gets the current event. - /// - ParsingEvent Current { get; } + /// + /// Represents a YAML stream paser. + /// + public interface IParser + { + /// + /// Gets the current event. + /// + ParsingEvent Current { get; } - /// - /// Moves to the next event. - /// - /// Returns true if there are more events available, otherwise returns false. - bool MoveNext(); - } + /// + /// Moves to the next event. + /// + /// Returns true if there are more events available, otherwise returns false. + bool MoveNext(); + } } \ No newline at end of file diff --git a/YamlDotNet/Core/IScanner.cs b/YamlDotNet/Core/IScanner.cs index 153d7b243..67a5da263 100644 --- a/YamlDotNet/Core/IScanner.cs +++ b/YamlDotNet/Core/IScanner.cs @@ -24,33 +24,33 @@ namespace YamlDotNet.Core { - /// - /// Defines the interface for a stand-alone YAML scanner that - /// converts a sequence of characters into a sequence of YAML tokens. - /// - public interface IScanner - { - /// - /// Gets the current position inside the input stream. - /// - /// The current position. - Mark CurrentPosition - { - get; - } + /// + /// Defines the interface for a stand-alone YAML scanner that + /// converts a sequence of characters into a sequence of YAML tokens. + /// + public interface IScanner + { + /// + /// Gets the current position inside the input stream. + /// + /// The current position. + Mark CurrentPosition + { + get; + } - /// - /// Gets the current token. - /// - Token Current - { - get; - } + /// + /// Gets the current token. + /// + Token Current + { + get; + } - /// - /// Moves to the next token and consumes the current token. - /// - bool MoveNext(); + /// + /// Moves to the next token and consumes the current token. + /// + bool MoveNext(); /// /// Moves to the next token without consuming the current token. @@ -61,5 +61,5 @@ Token Current /// Consumes the current token. /// void ConsumeCurrent(); - } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/InsertionQueue.cs b/YamlDotNet/Core/InsertionQueue.cs index 601faeacb..37906f4e9 100644 --- a/YamlDotNet/Core/InsertionQueue.cs +++ b/YamlDotNet/Core/InsertionQueue.cs @@ -24,60 +24,60 @@ namespace YamlDotNet.Core { - /// - /// Generic queue on which items may be inserted - /// - [Serializable] - public class InsertionQueue - { - // TODO: Use a more efficient data structure + /// + /// Generic queue on which items may be inserted + /// + [Serializable] + public class InsertionQueue + { + // TODO: Use a more efficient data structure - private readonly IList items = new List(); + private readonly IList items = new List(); - /// - /// Gets the number of items that are contained by the queue. - /// - public int Count - { - get - { - return items.Count; - } - } + /// + /// Gets the number of items that are contained by the queue. + /// + public int Count + { + get + { + return items.Count; + } + } - /// - /// Enqueues the specified item. - /// - /// The item to be enqueued. - public void Enqueue(T item) - { - items.Add(item); - } + /// + /// Enqueues the specified item. + /// + /// The item to be enqueued. + public void Enqueue(T item) + { + items.Add(item); + } - /// - /// Dequeues an item. - /// - /// Returns the item that been dequeued. - public T Dequeue() - { - if (Count == 0) - { - throw new InvalidOperationException("The queue is empty"); - } + /// + /// Dequeues an item. + /// + /// Returns the item that been dequeued. + public T Dequeue() + { + if (Count == 0) + { + throw new InvalidOperationException("The queue is empty"); + } - T item = items[0]; - items.RemoveAt(0); - return item; - } + T item = items[0]; + items.RemoveAt(0); + return item; + } - /// - /// Inserts an item at the specified index. - /// - /// The index where to insert the item. - /// The item to be inserted. - public void Insert(int index, T item) - { - items.Insert(index, item); - } - } + /// + /// Inserts an item at the specified index. + /// + /// The index where to insert the item. + /// The item to be inserted. + public void Insert(int index, T item) + { + items.Insert(index, item); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/LookAheadBuffer.cs b/YamlDotNet/Core/LookAheadBuffer.cs index fb66dbdbf..cf1f1a7bb 100644 --- a/YamlDotNet/Core/LookAheadBuffer.cs +++ b/YamlDotNet/Core/LookAheadBuffer.cs @@ -24,125 +24,125 @@ namespace YamlDotNet.Core { - /// - /// Provides access to a stream and allows to peek at the next characters, - /// up to the buffer's capacity. - /// - /// - /// This class implements a circular buffer with a fixed capacity. - /// - [Serializable] - public class LookAheadBuffer : ILookAheadBuffer - { - private readonly TextReader input; - private readonly char[] buffer; - private int firstIndex; - private int count; - private bool endOfInput; + /// + /// Provides access to a stream and allows to peek at the next characters, + /// up to the buffer's capacity. + /// + /// + /// This class implements a circular buffer with a fixed capacity. + /// + [Serializable] + public class LookAheadBuffer : ILookAheadBuffer + { + private readonly TextReader input; + private readonly char[] buffer; + private int firstIndex; + private int count; + private bool endOfInput; - /// - /// Initializes a new instance of the class. - /// - /// The input. - /// The capacity. - public LookAheadBuffer(TextReader input, int capacity) - { - if (input == null) - { - throw new ArgumentNullException("input"); - } - if (capacity < 1) - { - throw new ArgumentOutOfRangeException("capacity", "The capacity must be positive."); - } + /// + /// Initializes a new instance of the class. + /// + /// The input. + /// The capacity. + public LookAheadBuffer(TextReader input, int capacity) + { + if (input == null) + { + throw new ArgumentNullException("input"); + } + if (capacity < 1) + { + throw new ArgumentOutOfRangeException("capacity", "The capacity must be positive."); + } - this.input = input; - buffer = new char[capacity]; - } + this.input = input; + buffer = new char[capacity]; + } - /// - /// Gets a value indicating whether the end of the input reader has been reached. - /// - public bool EndOfInput - { - get - { - return endOfInput && count == 0; - } - } + /// + /// Gets a value indicating whether the end of the input reader has been reached. + /// + public bool EndOfInput + { + get + { + return endOfInput && count == 0; + } + } - /// - /// Gets the index of the character for the specified offset. - /// - private int GetIndexForOffset(int offset) - { - int index = firstIndex + offset; - if (index >= buffer.Length) - { - index -= buffer.Length; - } - return index; - } + /// + /// Gets the index of the character for the specified offset. + /// + private int GetIndexForOffset(int offset) + { + int index = firstIndex + offset; + if (index >= buffer.Length) + { + index -= buffer.Length; + } + return index; + } - /// - /// Gets the character at thhe specified offset. - /// - public char Peek(int offset) - { - if (offset < 0 || offset >= buffer.Length) - { - throw new ArgumentOutOfRangeException("offset", "The offset must be betwwen zero and the capacity of the buffer."); - } + /// + /// Gets the character at thhe specified offset. + /// + public char Peek(int offset) + { + if (offset < 0 || offset >= buffer.Length) + { + throw new ArgumentOutOfRangeException("offset", "The offset must be betwwen zero and the capacity of the buffer."); + } - Cache(offset); + Cache(offset); - if (offset < count) - { - return buffer[GetIndexForOffset(offset)]; - } - else - { - return '\0'; - } - } + if (offset < count) + { + return buffer[GetIndexForOffset(offset)]; + } + else + { + return '\0'; + } + } - /// - /// Reads characters until at least characters are in the buffer. - /// - /// - /// Number of characters to cache. - /// - public void Cache(int length) - { - while (length >= count) - { - int nextChar = input.Read(); - if (nextChar >= 0) - { - int lastIndex = GetIndexForOffset(count); - buffer[lastIndex] = (char)nextChar; - ++count; - } - else - { - endOfInput = true; - return; - } - } - } + /// + /// Reads characters until at least characters are in the buffer. + /// + /// + /// Number of characters to cache. + /// + public void Cache(int length) + { + while (length >= count) + { + int nextChar = input.Read(); + if (nextChar >= 0) + { + int lastIndex = GetIndexForOffset(count); + buffer[lastIndex] = (char)nextChar; + ++count; + } + else + { + endOfInput = true; + return; + } + } + } - /// - /// Skips the next characters. Those characters must have been - /// obtained first by calling the or methods. - /// - public void Skip(int length) - { - if (length < 1 || length > count) - { - throw new ArgumentOutOfRangeException("length", "The length must be between 1 and the number of characters in the buffer. Use the Peek() and / or Cache() methods to fill the buffer."); - } - firstIndex = GetIndexForOffset(length); - count -= length; - } - } + /// + /// Skips the next characters. Those characters must have been + /// obtained first by calling the or methods. + /// + public void Skip(int length) + { + if (length < 1 || length > count) + { + throw new ArgumentOutOfRangeException("length", "The length must be between 1 and the number of characters in the buffer. Use the Peek() and / or Cache() methods to fill the buffer."); + } + firstIndex = GetIndexForOffset(length); + count -= length; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Mark.cs b/YamlDotNet/Core/Mark.cs index 616bf9869..0b3315e88 100644 --- a/YamlDotNet/Core/Mark.cs +++ b/YamlDotNet/Core/Mark.cs @@ -23,120 +23,120 @@ namespace YamlDotNet.Core { - /// - /// Represents a location inside a file - /// - [Serializable] - public class Mark : IEquatable, IComparable, IComparable - { - /// - /// Gets a with empty values. - /// - public static readonly Mark Empty = new Mark(); + /// + /// Represents a location inside a file + /// + [Serializable] + public class Mark : IEquatable, IComparable, IComparable + { + /// + /// Gets a with empty values. + /// + public static readonly Mark Empty = new Mark(); - /// - /// Gets / sets the absolute offset in the file - /// - public int Index { get; private set; } + /// + /// Gets / sets the absolute offset in the file + /// + public int Index { get; private set; } - /// - /// Gets / sets the number of the line - /// - public int Line { get; private set; } + /// + /// Gets / sets the number of the line + /// + public int Line { get; private set; } - /// - /// Gets / sets the index of the column - /// - public int Column { get; private set; } + /// + /// Gets / sets the index of the column + /// + public int Column { get; private set; } - public Mark() - { - Line = 1; - Column = 1; - } + public Mark() + { + Line = 1; + Column = 1; + } - public Mark(int index, int line, int column) - { - if (index < 0) - { - throw new ArgumentOutOfRangeException("index", "Index must be greater than or equal to zero."); - } - if (line < 1) - { - throw new ArgumentOutOfRangeException("line", "Line must be greater than or equal to 1."); - } - if (column < 1) - { - throw new ArgumentOutOfRangeException("column", "Column must be greater than or equal to 1."); - } + public Mark(int index, int line, int column) + { + if (index < 0) + { + throw new ArgumentOutOfRangeException("index", "Index must be greater than or equal to zero."); + } + if (line < 1) + { + throw new ArgumentOutOfRangeException("line", "Line must be greater than or equal to 1."); + } + if (column < 1) + { + throw new ArgumentOutOfRangeException("column", "Column must be greater than or equal to 1."); + } - Index = index; - Line = line; - Column = column; - } + Index = index; + Line = line; + Column = column; + } - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return string.Format("Line: {0}, Col: {1}, Idx: {2}", Line, Column, Index); - } + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + return string.Format("Line: {0}, Col: {1}, Idx: {2}", Line, Column, Index); + } - /// - public override bool Equals(object obj) - { - return Equals(obj as Mark); - } + /// + public override bool Equals(object obj) + { + return Equals(obj as Mark); + } - /// - public bool Equals(Mark other) - { - return other != null - && Index == other.Index - && Line == other.Line - && Column == other.Column; - } + /// + public bool Equals(Mark other) + { + return other != null + && Index == other.Index + && Line == other.Line + && Column == other.Column; + } - /// - public override int GetHashCode() - { - return HashCode.CombineHashCodes( - Index.GetHashCode(), - HashCode.CombineHashCodes( - Line.GetHashCode(), - Column.GetHashCode() - ) - ); - } + /// + public override int GetHashCode() + { + return HashCode.CombineHashCodes( + Index.GetHashCode(), + HashCode.CombineHashCodes( + Line.GetHashCode(), + Column.GetHashCode() + ) + ); + } - /// - public int CompareTo(object obj) - { - if (obj == null) - { - throw new ArgumentNullException("obj"); - } - return CompareTo(obj as Mark); - } + /// + public int CompareTo(object obj) + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + return CompareTo(obj as Mark); + } - /// - public int CompareTo(Mark other) - { - if (other == null) - { - throw new ArgumentNullException("other"); - } + /// + public int CompareTo(Mark other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } - var cmp = Line.CompareTo(other.Line); - if (cmp == 0) - { - cmp = Column.CompareTo(other.Column); - } - return cmp; - } - } + var cmp = Line.CompareTo(other.Line); + if (cmp == 0) + { + cmp = Column.CompareTo(other.Column); + } + return cmp; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/MergingParser.cs b/YamlDotNet/Core/MergingParser.cs index 7a7e8b6a4..e31ed8507 100644 --- a/YamlDotNet/Core/MergingParser.cs +++ b/YamlDotNet/Core/MergingParser.cs @@ -26,170 +26,170 @@ namespace YamlDotNet.Core { - /// - /// Simple implementation of that implements merging: http://yaml.org/type/merge.html - /// - public sealed class MergingParser : IParser - { - private readonly List _allEvents = new List(); - private readonly IParser _innerParser; - private int _currentIndex = -1; - - public MergingParser(IParser innerParser) - { - _innerParser = innerParser; - } - - public ParsingEvent Current { get; private set; } - - public bool MoveNext() - { - if (_currentIndex < 0) - { - while (_innerParser.MoveNext()) - { - _allEvents.Add(_innerParser.Current); - } - - for (int i = _allEvents.Count - 2; i >= 0; --i) - { - var merge = _allEvents[i] as Scalar; - if (merge != null && merge.Value == "<<") - { - var anchorAlias = _allEvents[i + 1] as AnchorAlias; - if (anchorAlias != null) - { - var mergedEvents = GetMappingEvents(anchorAlias.Value); - _allEvents.RemoveRange(i, 2); - _allEvents.InsertRange(i, mergedEvents); - continue; - } - - var sequence = _allEvents[i + 1] as SequenceStart; - if (sequence != null) - { - var mergedEvents = new List>(); - var sequenceEndFound = false; - for (var itemIndex = i + 2; itemIndex < _allEvents.Count; ++itemIndex) - { - anchorAlias = _allEvents[itemIndex] as AnchorAlias; - if (anchorAlias != null) - { - mergedEvents.Add(GetMappingEvents(anchorAlias.Value)); - continue; - } - - if (_allEvents[itemIndex] is SequenceEnd) - { - _allEvents.RemoveRange(i, itemIndex - i + 1); - _allEvents.InsertRange(i, mergedEvents.SelectMany(e => e)); - sequenceEndFound = true; - break; - } - } - - if (sequenceEndFound) - { - continue; - } - } - - throw new SemanticErrorException(merge.Start, merge.End, "Unrecognized merge key pattern"); - } - } - } - - var nextIndex = _currentIndex + 1; - if (nextIndex < _allEvents.Count) - { - Current = _allEvents[nextIndex]; - _currentIndex = nextIndex; - return true; - } - return false; - } - - private IEnumerable GetMappingEvents(string mappingAlias) - { - var cloner = new ParsingEventCloner(); - - var nesting = 0; - return _allEvents - .SkipWhile(e => - { - var mappingStart = e as MappingStart; - return mappingStart == null || mappingStart.Anchor != mappingAlias; - }) - .Skip(1) - .TakeWhile(e => (nesting += e.NestingIncrease) >= 0) - .Select(e => cloner.Clone(e)) - .ToList(); - } - - private class ParsingEventCloner : IParsingEventVisitor - { - private ParsingEvent clonedEvent; - - public ParsingEvent Clone(ParsingEvent e) - { - e.Accept(this); - return clonedEvent; - } - - void IParsingEventVisitor.Visit(AnchorAlias e) - { - clonedEvent = new AnchorAlias(e.Value, e.Start, e.End); - } - - void IParsingEventVisitor.Visit(StreamStart e) - { - throw new NotSupportedException(); - } - - void IParsingEventVisitor.Visit(StreamEnd e) - { - throw new NotSupportedException(); - } - - void IParsingEventVisitor.Visit(DocumentStart e) - { - throw new NotSupportedException(); - } - - void IParsingEventVisitor.Visit(DocumentEnd e) - { - throw new NotSupportedException(); - } - - void IParsingEventVisitor.Visit(Scalar e) - { - clonedEvent = new Scalar(null, e.Tag, e.Value, e.Style, e.IsPlainImplicit, e.IsQuotedImplicit, e.Start, e.End); - } - - void IParsingEventVisitor.Visit(SequenceStart e) - { - clonedEvent = new SequenceStart(null, e.Tag, e.IsImplicit, e.Style, e.Start, e.End); - } - - void IParsingEventVisitor.Visit(SequenceEnd e) - { - clonedEvent = new SequenceEnd(e.Start, e.End); - } - - void IParsingEventVisitor.Visit(MappingStart e) - { - clonedEvent = new MappingStart(null, e.Tag, e.IsImplicit, e.Style, e.Start, e.End); - } - - void IParsingEventVisitor.Visit(MappingEnd e) - { - clonedEvent = new MappingEnd(e.Start, e.End); - } - - void IParsingEventVisitor.Visit(Comment e) - { - throw new NotSupportedException(); - } - } - } + /// + /// Simple implementation of that implements merging: http://yaml.org/type/merge.html + /// + public sealed class MergingParser : IParser + { + private readonly List _allEvents = new List(); + private readonly IParser _innerParser; + private int _currentIndex = -1; + + public MergingParser(IParser innerParser) + { + _innerParser = innerParser; + } + + public ParsingEvent Current { get; private set; } + + public bool MoveNext() + { + if (_currentIndex < 0) + { + while (_innerParser.MoveNext()) + { + _allEvents.Add(_innerParser.Current); + } + + for (int i = _allEvents.Count - 2; i >= 0; --i) + { + var merge = _allEvents[i] as Scalar; + if (merge != null && merge.Value == "<<") + { + var anchorAlias = _allEvents[i + 1] as AnchorAlias; + if (anchorAlias != null) + { + var mergedEvents = GetMappingEvents(anchorAlias.Value); + _allEvents.RemoveRange(i, 2); + _allEvents.InsertRange(i, mergedEvents); + continue; + } + + var sequence = _allEvents[i + 1] as SequenceStart; + if (sequence != null) + { + var mergedEvents = new List>(); + var sequenceEndFound = false; + for (var itemIndex = i + 2; itemIndex < _allEvents.Count; ++itemIndex) + { + anchorAlias = _allEvents[itemIndex] as AnchorAlias; + if (anchorAlias != null) + { + mergedEvents.Add(GetMappingEvents(anchorAlias.Value)); + continue; + } + + if (_allEvents[itemIndex] is SequenceEnd) + { + _allEvents.RemoveRange(i, itemIndex - i + 1); + _allEvents.InsertRange(i, mergedEvents.SelectMany(e => e)); + sequenceEndFound = true; + break; + } + } + + if (sequenceEndFound) + { + continue; + } + } + + throw new SemanticErrorException(merge.Start, merge.End, "Unrecognized merge key pattern"); + } + } + } + + var nextIndex = _currentIndex + 1; + if (nextIndex < _allEvents.Count) + { + Current = _allEvents[nextIndex]; + _currentIndex = nextIndex; + return true; + } + return false; + } + + private IEnumerable GetMappingEvents(string mappingAlias) + { + var cloner = new ParsingEventCloner(); + + var nesting = 0; + return _allEvents + .SkipWhile(e => + { + var mappingStart = e as MappingStart; + return mappingStart == null || mappingStart.Anchor != mappingAlias; + }) + .Skip(1) + .TakeWhile(e => (nesting += e.NestingIncrease) >= 0) + .Select(e => cloner.Clone(e)) + .ToList(); + } + + private class ParsingEventCloner : IParsingEventVisitor + { + private ParsingEvent clonedEvent; + + public ParsingEvent Clone(ParsingEvent e) + { + e.Accept(this); + return clonedEvent; + } + + void IParsingEventVisitor.Visit(AnchorAlias e) + { + clonedEvent = new AnchorAlias(e.Value, e.Start, e.End); + } + + void IParsingEventVisitor.Visit(StreamStart e) + { + throw new NotSupportedException(); + } + + void IParsingEventVisitor.Visit(StreamEnd e) + { + throw new NotSupportedException(); + } + + void IParsingEventVisitor.Visit(DocumentStart e) + { + throw new NotSupportedException(); + } + + void IParsingEventVisitor.Visit(DocumentEnd e) + { + throw new NotSupportedException(); + } + + void IParsingEventVisitor.Visit(Scalar e) + { + clonedEvent = new Scalar(null, e.Tag, e.Value, e.Style, e.IsPlainImplicit, e.IsQuotedImplicit, e.Start, e.End); + } + + void IParsingEventVisitor.Visit(SequenceStart e) + { + clonedEvent = new SequenceStart(null, e.Tag, e.IsImplicit, e.Style, e.Start, e.End); + } + + void IParsingEventVisitor.Visit(SequenceEnd e) + { + clonedEvent = new SequenceEnd(e.Start, e.End); + } + + void IParsingEventVisitor.Visit(MappingStart e) + { + clonedEvent = new MappingStart(null, e.Tag, e.IsImplicit, e.Style, e.Start, e.End); + } + + void IParsingEventVisitor.Visit(MappingEnd e) + { + clonedEvent = new MappingEnd(e.Start, e.End); + } + + void IParsingEventVisitor.Visit(Comment e) + { + throw new NotSupportedException(); + } + } + } } diff --git a/YamlDotNet/Core/Parser.cs b/YamlDotNet/Core/Parser.cs index 31dc89e31..000c5896e 100644 --- a/YamlDotNet/Core/Parser.cs +++ b/YamlDotNet/Core/Parser.cs @@ -30,921 +30,921 @@ 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 IScanner scanner; - private ParsingEvent current; - - private Token currentToken; - - private Token GetCurrentToken() - { - if (currentToken == null) - { - while (scanner.MoveNextWithoutConsuming()) - { - currentToken = scanner.Current; - - var commentToken = currentToken as Comment; - if (commentToken != null) - { - pendingEvents.Enqueue(new Events.Comment(commentToken.Value, commentToken.IsInline, commentToken.Start, commentToken.End)); - } - else - { - break; - } - } - } - return currentToken; - } - - /// - /// Initializes a new instance of the class. - /// - /// The input where the YAML stream is to be read. - public Parser(TextReader input) - : this(new Scanner(input)) - { - } - - /// - /// Initializes a new instance of the class. - /// - public Parser(IScanner scanner) - { - this.scanner = scanner; - } - - /// - /// Gets the current event. - /// - public ParsingEvent Current - { - get - { - return current; - } - } - - private readonly Queue pendingEvents = new Queue(); - - /// - /// 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.StreamEnd) - { - current = null; - return false; - } - else if (pendingEvents.Count == 0) - { - // Generate the next event. - pendingEvents.Enqueue(StateMachine()); - } - - current = pendingEvents.Dequeue(); - return true; - } - - private ParsingEvent StateMachine() - { - switch (state) - { - case ParserState.StreamStart: - return ParseStreamStart(); - - case ParserState.ImplicitDocumentStart: - return ParseDocumentStart(true); - - case ParserState.DocumentStart: - return ParseDocumentStart(false); - - case ParserState.DocumentContent: - return ParseDocumentContent(); - - case ParserState.DocumentEnd: - return ParseDocumentEnd(); - - case ParserState.BlockNode: - return ParseNode(true, false); - - case ParserState.BlockNodeOrIndentlessSequence: - return ParseNode(true, true); - - case ParserState.FlowNode: - return ParseNode(false, false); - - case ParserState.BlockSequenceFirstEntry: - return ParseBlockSequenceEntry(true); - - case ParserState.BlockSequenceEntry: - return ParseBlockSequenceEntry(false); - - case ParserState.IndentlessSequenceEntry: - return ParseIndentlessSequenceEntry(); - - case ParserState.BlockMappingFirstKey: - return ParseBlockMappingKey(true); - - case ParserState.BlockMappingKey: - return ParseBlockMappingKey(false); - - case ParserState.BlockMappingValue: - return ParseBlockMappingValue(); - - case ParserState.FlowSequenceFirstEntry: - return ParseFlowSequenceEntry(true); - - case ParserState.FlowSequenceEntry: - return ParseFlowSequenceEntry(false); - - case ParserState.FlowSequenceEntryMappingKey: - return ParseFlowSequenceEntryMappingKey(); - - case ParserState.FlowSequenceEntryMappingValue: - return ParseFlowSequenceEntryMappingValue(); - - case ParserState.FlowSequenceEntryMappingEnd: - return ParseFlowSequenceEntryMappingEnd(); - - case ParserState.FlowMappingFirstKey: - return ParseFlowMappingKey(true); - - case ParserState.FlowMappingKey: - return ParseFlowMappingKey(false); - - case ParserState.FlowMappingValue: - return ParseFlowMappingValue(false); - - case ParserState.FlowMappingEmptyValue: - 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 ParsingEvent 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.ImplicitDocumentStart; - 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 ParsingEvent 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.DocumentEnd); - - state = ParserState.BlockNode; - - 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.DocumentEnd); - - state = ParserState.DocumentContent; - - ParsingEvent evt = new Events.DocumentStart(versionDirective, directives, false, start, current.End); - Skip(); - return evt; - } - - // Parse the stream end. - - else - { - state = ParserState.StreamEnd; - - ParsingEvent evt = new Events.StreamEnd(GetCurrentToken().Start, GetCurrentToken().End); - // Do not call skip here because that would throw an exception - if (scanner.MoveNextWithoutConsuming()) - { - throw new InvalidOperationException("The scanner should contain no more tokens."); - } - return evt; - } - } - - /// - /// Parse directives. - /// - private VersionDirective ProcessDirectives(TagDirectiveCollection tags) - { - VersionDirective version = null; - bool hasOwnDirectives = false; - - 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) - { - throw new SemanticErrorException(currentVersion.Start, currentVersion.End, "Found incompatible YAML document."); - } - - version = currentVersion; - hasOwnDirectives = true; - } - else if ((tag = GetCurrentToken() as TagDirective) != null) - { - if (tags.Contains(tag.Handle)) - { - throw new SemanticErrorException(tag.Start, tag.End, "Found duplicate %TAG directive."); - } - tags.Add(tag); - hasOwnDirectives = true; - } - else - { - break; - } - - Skip(); - } - - AddTagDirectives(tags, Constants.DefaultTagDirectives); - - if (hasOwnDirectives) - { - tagDirectives.Clear(); - } - - AddTagDirectives(tagDirectives, tags); - - return version; - } - - private static void AddTagDirectives(TagDirectiveCollection directives, IEnumerable source) - { - foreach (var directive in source) - { - if (!directives.Contains(directive)) - { - directives.Add(directive); - } - } - } - - /// - /// Parse the productions: - /// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* - /// *********** - /// - private ParsingEvent 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 ParsingEvent 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 ParsingEvent ParseNode(bool isBlock, bool isIndentlessSequence) - { - AnchorAlias alias = GetCurrentToken() as AnchorAlias; - if (alias != null) - { - state = states.Pop(); - ParsingEvent 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.IndentlessSequenceEntry; - - 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(); - ParsingEvent 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.FlowSequenceFirstEntry; - return new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Flow, start, flowSequenceStart.End); - } - - FlowMappingStart flowMappingStart = GetCurrentToken() as FlowMappingStart; - if (flowMappingStart != null) - { - state = ParserState.FlowMappingFirstKey; - return new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Flow, start, flowMappingStart.End); - } - - if (isBlock) - { - BlockSequenceStart blockSequenceStart = GetCurrentToken() as BlockSequenceStart; - if (blockSequenceStart != null) - { - state = ParserState.BlockSequenceFirstEntry; - return new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Block, start, blockSequenceStart.End); - } - - BlockMappingStart blockMappingStart = GetCurrentToken() as BlockMappingStart; - if (blockMappingStart != null) - { - state = ParserState.BlockMappingFirstKey; - 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 ParsingEvent ParseDocumentEnd() - { - bool isImplicit = true; - Mark start = GetCurrentToken().Start; - Mark end = start; - - if (GetCurrentToken() is DocumentEnd) - { - end = GetCurrentToken().End; - Skip(); - isImplicit = false; - } - - state = ParserState.DocumentStart; - return new Events.DocumentEnd(isImplicit, start, end); - } - - /// - /// Parse the productions: - /// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END - /// ******************** *********** * ********* - /// - - private ParsingEvent 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.BlockSequenceEntry); - return ParseNode(true, false); - } - else - { - state = ParserState.BlockSequenceEntry; - return ProcessEmptyScalar(mark); - } - } - else if (GetCurrentToken() is BlockEnd) - { - state = states.Pop(); - ParsingEvent 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 collection, did not find expected '-' indicator."); - } - } - - /// - /// Parse the productions: - /// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ - /// *********** * - /// - private ParsingEvent 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.IndentlessSequenceEntry); - return ParseNode(true, false); - } - else - { - state = ParserState.IndentlessSequenceEntry; - 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 ParsingEvent 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.BlockMappingValue); - return ParseNode(true, true); - } - else - { - state = ParserState.BlockMappingValue; - return ProcessEmptyScalar(mark); - } - } - - else if (GetCurrentToken() is BlockEnd) - { - state = states.Pop(); - ParsingEvent 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 ParsingEvent ParseBlockMappingValue() - { - if (GetCurrentToken() is Value) - { - Mark mark = GetCurrentToken().End; - Skip(); - - if (!(GetCurrentToken() is Key || GetCurrentToken() is Value || GetCurrentToken() is BlockEnd)) - { - states.Push(ParserState.BlockMappingKey); - return ParseNode(true, true); - } - else - { - state = ParserState.BlockMappingKey; - return ProcessEmptyScalar(mark); - } - } - - else - { - state = ParserState.BlockMappingKey; - 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 ParsingEvent ParseFlowSequenceEntry(bool isFirst) - { - if (isFirst) - { - GetCurrentToken(); - Skip(); - } - - ParsingEvent 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.FlowSequenceEntryMappingKey; - evt = new Events.MappingStart(null, null, true, MappingStyle.Flow); - Skip(); - return evt; - } - else if (!(GetCurrentToken() is FlowSequenceEnd)) - { - states.Push(ParserState.FlowSequenceEntry); - 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 ParsingEvent ParseFlowSequenceEntryMappingKey() - { - if (!(GetCurrentToken() is Value || GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowSequenceEnd)) - { - states.Push(ParserState.FlowSequenceEntryMappingValue); - return ParseNode(false, false); - } - else - { - Mark mark = GetCurrentToken().End; - Skip(); - state = ParserState.FlowSequenceEntryMappingValue; - return ProcessEmptyScalar(mark); - } - } - - /// - /// Parse the productions: - /// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - /// ***** * - /// - private ParsingEvent ParseFlowSequenceEntryMappingValue() - { - if (GetCurrentToken() is Value) - { - Skip(); - if (!(GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowSequenceEnd)) - { - states.Push(ParserState.FlowSequenceEntryMappingEnd); - return ParseNode(false, false); - } - } - state = ParserState.FlowSequenceEntryMappingEnd; - return ProcessEmptyScalar(GetCurrentToken().Start); - } - - /// - /// Parse the productions: - /// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? - /// * - /// - private ParsingEvent ParseFlowSequenceEntryMappingEnd() - { - state = ParserState.FlowSequenceEntry; - 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 ParsingEvent 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.FlowMappingValue); - return ParseNode(false, false); - } - else - { - state = ParserState.FlowMappingValue; - return ProcessEmptyScalar(GetCurrentToken().Start); - } - } - else if (!(GetCurrentToken() is FlowMappingEnd)) - { - states.Push(ParserState.FlowMappingEmptyValue); - return ParseNode(false, false); - } - } - - state = states.Pop(); - ParsingEvent 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 ParsingEvent ParseFlowMappingValue(bool isEmpty) - { - if (isEmpty) - { - state = ParserState.FlowMappingKey; - return ProcessEmptyScalar(GetCurrentToken().Start); - } - - if (GetCurrentToken() is Value) - { - Skip(); - if (!(GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowMappingEnd)) - { - states.Push(ParserState.FlowMappingKey); - return ParseNode(false, false); - } - } - - state = ParserState.FlowMappingKey; - return ProcessEmptyScalar(GetCurrentToken().Start); - } - } + /// + /// Parses YAML streams. + /// + public class Parser : IParser + { + private readonly Stack states = new Stack(); + private readonly TagDirectiveCollection tagDirectives = new TagDirectiveCollection(); + private ParserState state; + + private readonly IScanner scanner; + private ParsingEvent current; + + private Token currentToken; + + private Token GetCurrentToken() + { + if (currentToken == null) + { + while (scanner.MoveNextWithoutConsuming()) + { + currentToken = scanner.Current; + + var commentToken = currentToken as Comment; + if (commentToken != null) + { + pendingEvents.Enqueue(new Events.Comment(commentToken.Value, commentToken.IsInline, commentToken.Start, commentToken.End)); + } + else + { + break; + } + } + } + return currentToken; + } + + /// + /// Initializes a new instance of the class. + /// + /// The input where the YAML stream is to be read. + public Parser(TextReader input) + : this(new Scanner(input)) + { + } + + /// + /// Initializes a new instance of the class. + /// + public Parser(IScanner scanner) + { + this.scanner = scanner; + } + + /// + /// Gets the current event. + /// + public ParsingEvent Current + { + get + { + return current; + } + } + + private readonly Queue pendingEvents = new Queue(); + + /// + /// 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.StreamEnd) + { + current = null; + return false; + } + else if (pendingEvents.Count == 0) + { + // Generate the next event. + pendingEvents.Enqueue(StateMachine()); + } + + current = pendingEvents.Dequeue(); + return true; + } + + private ParsingEvent StateMachine() + { + switch (state) + { + case ParserState.StreamStart: + return ParseStreamStart(); + + case ParserState.ImplicitDocumentStart: + return ParseDocumentStart(true); + + case ParserState.DocumentStart: + return ParseDocumentStart(false); + + case ParserState.DocumentContent: + return ParseDocumentContent(); + + case ParserState.DocumentEnd: + return ParseDocumentEnd(); + + case ParserState.BlockNode: + return ParseNode(true, false); + + case ParserState.BlockNodeOrIndentlessSequence: + return ParseNode(true, true); + + case ParserState.FlowNode: + return ParseNode(false, false); + + case ParserState.BlockSequenceFirstEntry: + return ParseBlockSequenceEntry(true); + + case ParserState.BlockSequenceEntry: + return ParseBlockSequenceEntry(false); + + case ParserState.IndentlessSequenceEntry: + return ParseIndentlessSequenceEntry(); + + case ParserState.BlockMappingFirstKey: + return ParseBlockMappingKey(true); + + case ParserState.BlockMappingKey: + return ParseBlockMappingKey(false); + + case ParserState.BlockMappingValue: + return ParseBlockMappingValue(); + + case ParserState.FlowSequenceFirstEntry: + return ParseFlowSequenceEntry(true); + + case ParserState.FlowSequenceEntry: + return ParseFlowSequenceEntry(false); + + case ParserState.FlowSequenceEntryMappingKey: + return ParseFlowSequenceEntryMappingKey(); + + case ParserState.FlowSequenceEntryMappingValue: + return ParseFlowSequenceEntryMappingValue(); + + case ParserState.FlowSequenceEntryMappingEnd: + return ParseFlowSequenceEntryMappingEnd(); + + case ParserState.FlowMappingFirstKey: + return ParseFlowMappingKey(true); + + case ParserState.FlowMappingKey: + return ParseFlowMappingKey(false); + + case ParserState.FlowMappingValue: + return ParseFlowMappingValue(false); + + case ParserState.FlowMappingEmptyValue: + 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 ParsingEvent 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.ImplicitDocumentStart; + 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 ParsingEvent 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.DocumentEnd); + + state = ParserState.BlockNode; + + 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.DocumentEnd); + + state = ParserState.DocumentContent; + + ParsingEvent evt = new Events.DocumentStart(versionDirective, directives, false, start, current.End); + Skip(); + return evt; + } + + // Parse the stream end. + + else + { + state = ParserState.StreamEnd; + + ParsingEvent evt = new Events.StreamEnd(GetCurrentToken().Start, GetCurrentToken().End); + // Do not call skip here because that would throw an exception + if (scanner.MoveNextWithoutConsuming()) + { + throw new InvalidOperationException("The scanner should contain no more tokens."); + } + return evt; + } + } + + /// + /// Parse directives. + /// + private VersionDirective ProcessDirectives(TagDirectiveCollection tags) + { + VersionDirective version = null; + bool hasOwnDirectives = false; + + 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) + { + throw new SemanticErrorException(currentVersion.Start, currentVersion.End, "Found incompatible YAML document."); + } + + version = currentVersion; + hasOwnDirectives = true; + } + else if ((tag = GetCurrentToken() as TagDirective) != null) + { + if (tags.Contains(tag.Handle)) + { + throw new SemanticErrorException(tag.Start, tag.End, "Found duplicate %TAG directive."); + } + tags.Add(tag); + hasOwnDirectives = true; + } + else + { + break; + } + + Skip(); + } + + AddTagDirectives(tags, Constants.DefaultTagDirectives); + + if (hasOwnDirectives) + { + tagDirectives.Clear(); + } + + AddTagDirectives(tagDirectives, tags); + + return version; + } + + private static void AddTagDirectives(TagDirectiveCollection directives, IEnumerable source) + { + foreach (var directive in source) + { + if (!directives.Contains(directive)) + { + directives.Add(directive); + } + } + } + + /// + /// Parse the productions: + /// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + /// *********** + /// + private ParsingEvent 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 ParsingEvent 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 ParsingEvent ParseNode(bool isBlock, bool isIndentlessSequence) + { + AnchorAlias alias = GetCurrentToken() as AnchorAlias; + if (alias != null) + { + state = states.Pop(); + ParsingEvent 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.IndentlessSequenceEntry; + + 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(); + ParsingEvent 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.FlowSequenceFirstEntry; + return new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Flow, start, flowSequenceStart.End); + } + + FlowMappingStart flowMappingStart = GetCurrentToken() as FlowMappingStart; + if (flowMappingStart != null) + { + state = ParserState.FlowMappingFirstKey; + return new Events.MappingStart(anchorName, tagName, isImplicit, MappingStyle.Flow, start, flowMappingStart.End); + } + + if (isBlock) + { + BlockSequenceStart blockSequenceStart = GetCurrentToken() as BlockSequenceStart; + if (blockSequenceStart != null) + { + state = ParserState.BlockSequenceFirstEntry; + return new Events.SequenceStart(anchorName, tagName, isImplicit, SequenceStyle.Block, start, blockSequenceStart.End); + } + + BlockMappingStart blockMappingStart = GetCurrentToken() as BlockMappingStart; + if (blockMappingStart != null) + { + state = ParserState.BlockMappingFirstKey; + 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 ParsingEvent ParseDocumentEnd() + { + bool isImplicit = true; + Mark start = GetCurrentToken().Start; + Mark end = start; + + if (GetCurrentToken() is DocumentEnd) + { + end = GetCurrentToken().End; + Skip(); + isImplicit = false; + } + + state = ParserState.DocumentStart; + return new Events.DocumentEnd(isImplicit, start, end); + } + + /// + /// Parse the productions: + /// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END + /// ******************** *********** * ********* + /// + + private ParsingEvent 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.BlockSequenceEntry); + return ParseNode(true, false); + } + else + { + state = ParserState.BlockSequenceEntry; + return ProcessEmptyScalar(mark); + } + } + else if (GetCurrentToken() is BlockEnd) + { + state = states.Pop(); + ParsingEvent 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 collection, did not find expected '-' indicator."); + } + } + + /// + /// Parse the productions: + /// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ + /// *********** * + /// + private ParsingEvent 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.IndentlessSequenceEntry); + return ParseNode(true, false); + } + else + { + state = ParserState.IndentlessSequenceEntry; + 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 ParsingEvent 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.BlockMappingValue); + return ParseNode(true, true); + } + else + { + state = ParserState.BlockMappingValue; + return ProcessEmptyScalar(mark); + } + } + + else if (GetCurrentToken() is BlockEnd) + { + state = states.Pop(); + ParsingEvent 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 ParsingEvent ParseBlockMappingValue() + { + if (GetCurrentToken() is Value) + { + Mark mark = GetCurrentToken().End; + Skip(); + + if (!(GetCurrentToken() is Key || GetCurrentToken() is Value || GetCurrentToken() is BlockEnd)) + { + states.Push(ParserState.BlockMappingKey); + return ParseNode(true, true); + } + else + { + state = ParserState.BlockMappingKey; + return ProcessEmptyScalar(mark); + } + } + + else + { + state = ParserState.BlockMappingKey; + 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 ParsingEvent ParseFlowSequenceEntry(bool isFirst) + { + if (isFirst) + { + GetCurrentToken(); + Skip(); + } + + ParsingEvent 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.FlowSequenceEntryMappingKey; + evt = new Events.MappingStart(null, null, true, MappingStyle.Flow); + Skip(); + return evt; + } + else if (!(GetCurrentToken() is FlowSequenceEnd)) + { + states.Push(ParserState.FlowSequenceEntry); + 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 ParsingEvent ParseFlowSequenceEntryMappingKey() + { + if (!(GetCurrentToken() is Value || GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowSequenceEnd)) + { + states.Push(ParserState.FlowSequenceEntryMappingValue); + return ParseNode(false, false); + } + else + { + Mark mark = GetCurrentToken().End; + Skip(); + state = ParserState.FlowSequenceEntryMappingValue; + return ProcessEmptyScalar(mark); + } + } + + /// + /// Parse the productions: + /// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + /// ***** * + /// + private ParsingEvent ParseFlowSequenceEntryMappingValue() + { + if (GetCurrentToken() is Value) + { + Skip(); + if (!(GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowSequenceEnd)) + { + states.Push(ParserState.FlowSequenceEntryMappingEnd); + return ParseNode(false, false); + } + } + state = ParserState.FlowSequenceEntryMappingEnd; + return ProcessEmptyScalar(GetCurrentToken().Start); + } + + /// + /// Parse the productions: + /// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + /// * + /// + private ParsingEvent ParseFlowSequenceEntryMappingEnd() + { + state = ParserState.FlowSequenceEntry; + 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 ParsingEvent 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.FlowMappingValue); + return ParseNode(false, false); + } + else + { + state = ParserState.FlowMappingValue; + return ProcessEmptyScalar(GetCurrentToken().Start); + } + } + else if (!(GetCurrentToken() is FlowMappingEnd)) + { + states.Push(ParserState.FlowMappingEmptyValue); + return ParseNode(false, false); + } + } + + state = states.Pop(); + ParsingEvent 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 ParsingEvent ParseFlowMappingValue(bool isEmpty) + { + if (isEmpty) + { + state = ParserState.FlowMappingKey; + return ProcessEmptyScalar(GetCurrentToken().Start); + } + + if (GetCurrentToken() is Value) + { + Skip(); + if (!(GetCurrentToken() is FlowEntry || GetCurrentToken() is FlowMappingEnd)) + { + states.Push(ParserState.FlowMappingKey); + return ParseNode(false, false); + } + } + + state = ParserState.FlowMappingKey; + return ProcessEmptyScalar(GetCurrentToken().Start); + } + } } diff --git a/YamlDotNet/Core/ParserState.cs b/YamlDotNet/Core/ParserState.cs index 2cbf51df5..3fa36ea66 100644 --- a/YamlDotNet/Core/ParserState.cs +++ b/YamlDotNet/Core/ParserState.cs @@ -21,31 +21,31 @@ namespace YamlDotNet.Core { - internal enum ParserState - { - StreamStart, - StreamEnd, - ImplicitDocumentStart, - DocumentStart, - DocumentContent, - DocumentEnd, - BlockNode, - BlockNodeOrIndentlessSequence, - FlowNode, - BlockSequenceFirstEntry, - BlockSequenceEntry, - IndentlessSequenceEntry, - BlockMappingFirstKey, - BlockMappingKey, - BlockMappingValue, - FlowSequenceFirstEntry, - FlowSequenceEntry, - FlowSequenceEntryMappingKey, - FlowSequenceEntryMappingValue, - FlowSequenceEntryMappingEnd, - FlowMappingFirstKey, - FlowMappingKey, - FlowMappingValue, - FlowMappingEmptyValue - } + internal enum ParserState + { + StreamStart, + StreamEnd, + ImplicitDocumentStart, + DocumentStart, + DocumentContent, + DocumentEnd, + BlockNode, + BlockNodeOrIndentlessSequence, + FlowNode, + BlockSequenceFirstEntry, + BlockSequenceEntry, + IndentlessSequenceEntry, + BlockMappingFirstKey, + BlockMappingKey, + BlockMappingValue, + FlowSequenceFirstEntry, + FlowSequenceEntry, + FlowSequenceEntryMappingKey, + FlowSequenceEntryMappingValue, + FlowSequenceEntryMappingEnd, + FlowMappingFirstKey, + FlowMappingKey, + FlowMappingValue, + FlowMappingEmptyValue + } } diff --git a/YamlDotNet/Core/ScalarStyle.cs b/YamlDotNet/Core/ScalarStyle.cs index 7d736cbcb..13b42aec8 100644 --- a/YamlDotNet/Core/ScalarStyle.cs +++ b/YamlDotNet/Core/ScalarStyle.cs @@ -23,39 +23,39 @@ namespace YamlDotNet.Core { - /// - /// Specifies the style of a YAML scalar. - /// - public enum ScalarStyle - { - /// - /// Let the emitter choose the style. - /// - Any, + /// + /// Specifies the style of a YAML scalar. + /// + public enum ScalarStyle + { + /// + /// Let the emitter choose the style. + /// + Any, - /// - /// The plain scalar style. - /// - Plain, + /// + /// The plain scalar style. + /// + Plain, - /// - /// The single-quoted scalar style. - /// - SingleQuoted, + /// + /// The single-quoted scalar style. + /// + SingleQuoted, - /// - /// The double-quoted scalar style. - /// - DoubleQuoted, + /// + /// The double-quoted scalar style. + /// + DoubleQuoted, - /// - /// The literal scalar style. - /// - Literal, + /// + /// The literal scalar style. + /// + Literal, - /// - /// The folded scalar style. - /// - Folded, - } + /// + /// The folded scalar style. + /// + Folded, + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Scanner.cs b/YamlDotNet/Core/Scanner.cs index 6bc882459..cf905d563 100644 --- a/YamlDotNet/Core/Scanner.cs +++ b/YamlDotNet/Core/Scanner.cs @@ -1,16 +1,16 @@ // This file is part of YamlDotNet - A .NET library for YAML. // Copyright (c) Antoine Aubry and contributors - + // 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 @@ -28,2327 +28,2327 @@ namespace YamlDotNet.Core { - /// - /// Converts a sequence of characters into a sequence of YAML tokens. - /// - [Serializable] - public class Scanner : IScanner - { - private const int MaxVersionNumberLength = 9; - private const int MaxBufferLength = 8; - - private static readonly IDictionary simpleEscapeCodes = new SortedDictionary - { - { '0', '\0' }, - { 'a', '\x07' }, - { 'b', '\x08' }, - { 't', '\x09' }, - { '\t', '\x09' }, - { 'n', '\x0A' }, - { 'v', '\x0B' }, - { 'f', '\x0C' }, - { 'r', '\x0D' }, - { 'e', '\x1B' }, - { ' ', '\x20' }, - { '"', '"' }, - { '\'', '\'' }, - { '\\', '\\' }, - { 'N', '\x85' }, - { '_', '\xA0' }, - { 'L', '\x2028' }, - { 'P', '\x2029' }, - }; - - private readonly Stack indents = new Stack(); - private readonly InsertionQueue tokens = new InsertionQueue(); - private readonly Stack simpleKeys = new Stack(); - private readonly CharacterAnalyzer analyzer; - - private Cursor cursor; - private bool streamStartProduced; - private bool streamEndProduced; - private int indent = -1; - private bool simpleKeyAllowed; - private int flowLevel; - private int tokensParsed; - private bool tokenAvailable; - private Token previous; - - public bool SkipComments { get; private set; } - - /// - /// Gets the current token. - /// - public Token Current { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - /// The input. - /// Indicates whether comments should be ignored - public Scanner(TextReader input, bool skipComments = true) - { - analyzer = new CharacterAnalyzer(new LookAheadBuffer(input, MaxBufferLength)); - cursor = new Cursor(); - SkipComments = skipComments; - } - - /// - /// Gets the current position inside the input stream. - /// - /// The current position. - public Mark CurrentPosition - { - get - { - return cursor.Mark(); - } - } - - /// - /// Moves to the next token. - /// - /// - public bool MoveNext() - { - if (Current != null) - { - ConsumeCurrent(); - } - - return MoveNextWithoutConsuming(); - } - - public bool MoveNextWithoutConsuming() - { - if (!tokenAvailable && !streamEndProduced) - { - FetchMoreTokens(); - } - if (tokens.Count > 0) - { - Current = tokens.Dequeue(); - tokenAvailable = false; - return true; - } - else - { - Current = null; - return false; - } - } - - /// - /// Consumes the current token and increments the parsed token count - /// - public void ConsumeCurrent() - { - ++tokensParsed; - tokenAvailable = false; - previous = Current; - Current = null; - } - - private char ReadCurrentCharacter() - { - char currentCharacter = analyzer.Peek(0); - Skip(); - return currentCharacter; - } - - private char ReadLine() - { - if (analyzer.Check("\r\n\x85")) // CR LF -> LF --- CR|LF|NEL -> LF - { - SkipLine(); - return '\n'; - } - - char nextChar = analyzer.Peek(0); // LS|PS -> LS|PS - SkipLine(); - return nextChar; - } - - private void FetchMoreTokens() - { - // While we need more tokens to fetch, do it. - - while (true) - { - // Check if we really need to fetch more tokens. - - bool needsMoreTokens = false; - - if (tokens.Count == 0) - { - // Queue is empty. - - needsMoreTokens = true; - } - else - { - // Check if any potential simple key may occupy the head position. - - StaleSimpleKeys(); - - foreach(var simpleKey in simpleKeys) - { - if (simpleKey.IsPossible && simpleKey.TokenNumber == tokensParsed) - { - needsMoreTokens = true; - break; - } - } - } - - // We are finished. - if (!needsMoreTokens) - { - break; - } - - // Fetch the next token. - - FetchNextToken(); - } - tokenAvailable = true; - } - - private static bool StartsWith(StringBuilder what, char start) - { - return what.Length > 0 && what[0] == start; - } - - /// - /// Check the list of potential simple keys and remove the positions that - /// cannot contain simple keys anymore. - /// - - private void StaleSimpleKeys() - { - // Check for a potential simple key for each flow level. - - foreach(var key in simpleKeys) - { - - // The specification requires that a simple key - - // - is limited to a single line, - // - is shorter than 1024 characters. + /// + /// Converts a sequence of characters into a sequence of YAML tokens. + /// + [Serializable] + public class Scanner : IScanner + { + private const int MaxVersionNumberLength = 9; + private const int MaxBufferLength = 8; + + private static readonly IDictionary simpleEscapeCodes = new SortedDictionary + { + { '0', '\0' }, + { 'a', '\x07' }, + { 'b', '\x08' }, + { 't', '\x09' }, + { '\t', '\x09' }, + { 'n', '\x0A' }, + { 'v', '\x0B' }, + { 'f', '\x0C' }, + { 'r', '\x0D' }, + { 'e', '\x1B' }, + { ' ', '\x20' }, + { '"', '"' }, + { '\'', '\'' }, + { '\\', '\\' }, + { 'N', '\x85' }, + { '_', '\xA0' }, + { 'L', '\x2028' }, + { 'P', '\x2029' }, + }; + + private readonly Stack indents = new Stack(); + private readonly InsertionQueue tokens = new InsertionQueue(); + private readonly Stack simpleKeys = new Stack(); + private readonly CharacterAnalyzer analyzer; + + private Cursor cursor; + private bool streamStartProduced; + private bool streamEndProduced; + private int indent = -1; + private bool simpleKeyAllowed; + private int flowLevel; + private int tokensParsed; + private bool tokenAvailable; + private Token previous; + + public bool SkipComments { get; private set; } + + /// + /// Gets the current token. + /// + public Token Current { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + /// The input. + /// Indicates whether comments should be ignored + public Scanner(TextReader input, bool skipComments = true) + { + analyzer = new CharacterAnalyzer(new LookAheadBuffer(input, MaxBufferLength)); + cursor = new Cursor(); + SkipComments = skipComments; + } + + /// + /// Gets the current position inside the input stream. + /// + /// The current position. + public Mark CurrentPosition + { + get + { + return cursor.Mark(); + } + } + + /// + /// Moves to the next token. + /// + /// + public bool MoveNext() + { + if (Current != null) + { + ConsumeCurrent(); + } + + return MoveNextWithoutConsuming(); + } + + public bool MoveNextWithoutConsuming() + { + if (!tokenAvailable && !streamEndProduced) + { + FetchMoreTokens(); + } + if (tokens.Count > 0) + { + Current = tokens.Dequeue(); + tokenAvailable = false; + return true; + } + else + { + Current = null; + return false; + } + } + + /// + /// Consumes the current token and increments the parsed token count + /// + public void ConsumeCurrent() + { + ++tokensParsed; + tokenAvailable = false; + previous = Current; + Current = null; + } + + private char ReadCurrentCharacter() + { + char currentCharacter = analyzer.Peek(0); + Skip(); + return currentCharacter; + } + + private char ReadLine() + { + if (analyzer.Check("\r\n\x85")) // CR LF -> LF --- CR|LF|NEL -> LF + { + SkipLine(); + return '\n'; + } + + char nextChar = analyzer.Peek(0); // LS|PS -> LS|PS + SkipLine(); + return nextChar; + } + + private void FetchMoreTokens() + { + // While we need more tokens to fetch, do it. + + while (true) + { + // Check if we really need to fetch more tokens. + + bool needsMoreTokens = false; + + if (tokens.Count == 0) + { + // Queue is empty. + + needsMoreTokens = true; + } + else + { + // Check if any potential simple key may occupy the head position. + + StaleSimpleKeys(); + + foreach(var simpleKey in simpleKeys) + { + if (simpleKey.IsPossible && simpleKey.TokenNumber == tokensParsed) + { + needsMoreTokens = true; + break; + } + } + } + + // We are finished. + if (!needsMoreTokens) + { + break; + } + + // Fetch the next token. + + FetchNextToken(); + } + tokenAvailable = true; + } + + private static bool StartsWith(StringBuilder what, char start) + { + return what.Length > 0 && what[0] == start; + } + + /// + /// Check the list of potential simple keys and remove the positions that + /// cannot contain simple keys anymore. + /// + + private void StaleSimpleKeys() + { + // Check for a potential simple key for each flow level. + + foreach(var key in simpleKeys) + { + + // The specification requires that a simple key + + // - is limited to a single line, + // - is shorter than 1024 characters. - if (key.IsPossible && (key.Line < cursor.Line || key.Index + 1024 < cursor.Index)) - { + if (key.IsPossible && (key.Line < cursor.Line || key.Index + 1024 < cursor.Index)) + { - // Check if the potential simple key to be removed is required. + // Check if the potential simple key to be removed is required. - if (key.IsRequired) - { - var mark = cursor.Mark(); - throw new SyntaxErrorException(mark, mark, "While scanning a simple key, could not find expected ':'."); - } + if (key.IsRequired) + { + var mark = cursor.Mark(); + throw new SyntaxErrorException(mark, mark, "While scanning a simple key, could not find expected ':'."); + } - key.IsPossible = false; - } - } - } + key.IsPossible = false; + } + } + } - private void FetchNextToken() - { - // Check if we just started scanning. Fetch STREAM-START then. + private void FetchNextToken() + { + // Check if we just started scanning. Fetch STREAM-START then. - if (!streamStartProduced) - { - FetchStreamStart(); - return; - } + if (!streamStartProduced) + { + FetchStreamStart(); + return; + } - // Eat whitespaces and comments until we reach the next token. + // Eat whitespaces and comments until we reach the next token. - ScanToNextToken(); + ScanToNextToken(); - // Remove obsolete potential simple keys. + // Remove obsolete potential simple keys. - StaleSimpleKeys(); + StaleSimpleKeys(); - // Check the indentation level against the current column. + // Check the indentation level against the current column. - UnrollIndent(cursor.LineOffset); + UnrollIndent(cursor.LineOffset); - // Ensure that the buffer contains at least 4 characters. 4 is the length - // of the longest indicators ('--- ' and '... '). + // Ensure that the buffer contains at least 4 characters. 4 is the length + // of the longest indicators ('--- ' and '... '). - analyzer.Buffer.Cache(4); + analyzer.Buffer.Cache(4); - // Is it the end of the stream? + // Is it the end of the stream? - if (analyzer.Buffer.EndOfInput) - { - FetchStreamEnd(); - return; - } + if (analyzer.Buffer.EndOfInput) + { + FetchStreamEnd(); + return; + } - // Is it a directive? + // Is it a directive? - if (cursor.LineOffset == 0 && analyzer.Check('%')) - { - FetchDirective(); - return; - } + if (cursor.LineOffset == 0 && analyzer.Check('%')) + { + FetchDirective(); + return; + } - // Is it the document start indicator? + // Is it the document start indicator? - bool isDocumentStart = - cursor.LineOffset == 0 && - analyzer.Check('-', 0) && - analyzer.Check('-', 1) && - analyzer.Check('-', 2) && - analyzer.IsWhiteBreakOrZero(3); + bool isDocumentStart = + cursor.LineOffset == 0 && + analyzer.Check('-', 0) && + analyzer.Check('-', 1) && + analyzer.Check('-', 2) && + analyzer.IsWhiteBreakOrZero(3); - if (isDocumentStart) - { - FetchDocumentIndicator(true); - return; - } + if (isDocumentStart) + { + FetchDocumentIndicator(true); + return; + } - // Is it the document end indicator? + // Is it the document end indicator? - bool isDocumentEnd = - cursor.LineOffset == 0 && - analyzer.Check('.', 0) && - analyzer.Check('.', 1) && - analyzer.Check('.', 2) && - analyzer.IsWhiteBreakOrZero(3); + bool isDocumentEnd = + cursor.LineOffset == 0 && + analyzer.Check('.', 0) && + analyzer.Check('.', 1) && + analyzer.Check('.', 2) && + analyzer.IsWhiteBreakOrZero(3); - if (isDocumentEnd) - { - FetchDocumentIndicator(false); - return; - } + if (isDocumentEnd) + { + FetchDocumentIndicator(false); + return; + } - // Is it the flow sequence start indicator? + // Is it the flow sequence start indicator? - if (analyzer.Check('[')) - { - FetchFlowCollectionStart(true); - return; - } + if (analyzer.Check('[')) + { + FetchFlowCollectionStart(true); + return; + } - // Is it the flow mapping start indicator? + // Is it the flow mapping start indicator? - if (analyzer.Check('{')) - { - FetchFlowCollectionStart(false); - return; - } + if (analyzer.Check('{')) + { + FetchFlowCollectionStart(false); + return; + } - // Is it the flow sequence end indicator? + // Is it the flow sequence end indicator? - if (analyzer.Check(']')) - { - FetchFlowCollectionEnd(true); - return; - } + if (analyzer.Check(']')) + { + FetchFlowCollectionEnd(true); + return; + } - // Is it the flow mapping end indicator? + // Is it the flow mapping end indicator? - if (analyzer.Check('}')) - { - FetchFlowCollectionEnd(false); - return; - } + if (analyzer.Check('}')) + { + FetchFlowCollectionEnd(false); + return; + } - // Is it the flow entry indicator? + // Is it the flow entry indicator? - if (analyzer.Check(',')) - { - FetchFlowEntry(); - return; - } + if (analyzer.Check(',')) + { + FetchFlowEntry(); + return; + } - // Is it the block entry indicator? + // Is it the block entry indicator? - if (analyzer.Check('-') && analyzer.IsWhiteBreakOrZero(1)) - { - FetchBlockEntry(); - return; - } + if (analyzer.Check('-') && analyzer.IsWhiteBreakOrZero(1)) + { + FetchBlockEntry(); + return; + } - // Is it the key indicator? + // Is it the key indicator? - if (analyzer.Check('?') && (flowLevel > 0 || analyzer.IsWhiteBreakOrZero(1))) - { - FetchKey(); - return; - } + if (analyzer.Check('?') && (flowLevel > 0 || analyzer.IsWhiteBreakOrZero(1))) + { + FetchKey(); + return; + } - // Is it the value indicator? + // Is it the value indicator? - if (analyzer.Check(':') && (flowLevel > 0 || analyzer.IsWhiteBreakOrZero(1))) - { - FetchValue(); - return; - } + if (analyzer.Check(':') && (flowLevel > 0 || analyzer.IsWhiteBreakOrZero(1))) + { + FetchValue(); + return; + } - // Is it an alias? + // Is it an alias? - if (analyzer.Check('*')) - { - FetchAnchor(true); - return; - } + if (analyzer.Check('*')) + { + FetchAnchor(true); + return; + } - // Is it an anchor? + // Is it an anchor? - if (analyzer.Check('&')) - { - FetchAnchor(false); - return; - } + if (analyzer.Check('&')) + { + FetchAnchor(false); + return; + } - // Is it a tag? + // Is it a tag? - if (analyzer.Check('!')) - { - FetchTag(); - return; - } + if (analyzer.Check('!')) + { + FetchTag(); + return; + } - // Is it a literal scalar? + // Is it a literal scalar? - if (analyzer.Check('|') && flowLevel == 0) - { - FetchBlockScalar(true); - return; - } - - // Is it a folded scalar? - - if (analyzer.Check('>') && flowLevel == 0) - { - FetchBlockScalar(false); - return; - } - - // Is it a single-quoted scalar? - - if (analyzer.Check('\'')) - { - FetchFlowScalar(true); - return; - } - - // Is it a double-quoted scalar? - - if (analyzer.Check('"')) - { - FetchFlowScalar(false); - return; - } + if (analyzer.Check('|') && flowLevel == 0) + { + FetchBlockScalar(true); + return; + } + + // Is it a folded scalar? + + if (analyzer.Check('>') && flowLevel == 0) + { + FetchBlockScalar(false); + return; + } + + // Is it a single-quoted scalar? + + if (analyzer.Check('\'')) + { + FetchFlowScalar(true); + return; + } + + // Is it a double-quoted scalar? + + if (analyzer.Check('"')) + { + FetchFlowScalar(false); + return; + } - // Is it a plain scalar? + // Is it a plain scalar? - // A plain scalar may start with any non-blank characters except + // A plain scalar may start with any non-blank characters except - // '-', '?', ':', ',', '[', ']', '{', '}', - // '#', '&', '*', '!', '|', '>', '\'', '\"', - // '%', '@', '`'. + // '-', '?', ':', ',', '[', ']', '{', '}', + // '#', '&', '*', '!', '|', '>', '\'', '\"', + // '%', '@', '`'. - // In the block context (and, for the '-' indicator, in the flow context - // too), it may also start with the characters + // In the block context (and, for the '-' indicator, in the flow context + // too), it may also start with the characters - // '-', '?', ':' + // '-', '?', ':' - // if it is followed by a non-space character. + // if it is followed by a non-space character. - // The last rule is more restrictive than the specification requires. + // The last rule is more restrictive than the specification requires. - bool isInvalidPlainScalarCharacter = analyzer.IsWhiteBreakOrZero() || analyzer.Check("-?:,[]{}#&*!|>'\"%@`"); + bool isInvalidPlainScalarCharacter = analyzer.IsWhiteBreakOrZero() || analyzer.Check("-?:,[]{}#&*!|>'\"%@`"); - bool isPlainScalar = - !isInvalidPlainScalarCharacter || - (analyzer.Check('-') && !analyzer.IsWhite(1)) || - (flowLevel == 0 && (analyzer.Check("?:")) && !analyzer.IsWhiteBreakOrZero(1)); + bool isPlainScalar = + !isInvalidPlainScalarCharacter || + (analyzer.Check('-') && !analyzer.IsWhite(1)) || + (flowLevel == 0 && (analyzer.Check("?:")) && !analyzer.IsWhiteBreakOrZero(1)); - if (isPlainScalar) - { - FetchPlainScalar(); - return; - } - - // If we don't determine the token type so far, it is an error. - var start = cursor.Mark(); - Skip(); - var end = cursor.Mark(); - - throw new SyntaxErrorException(start, end, "While scanning for the next token, find character that cannot start any token."); - } - - private bool CheckWhiteSpace() - { - return analyzer.Check(' ') || ((flowLevel > 0 || !simpleKeyAllowed) && analyzer.Check('\t')); - } - - private bool IsDocumentIndicator() - { - if (cursor.LineOffset == 0 && analyzer.IsWhiteBreakOrZero(3)) - { - bool isDocumentStart = analyzer.Check('-', 0) && analyzer.Check('-', 1) && analyzer.Check('-', 2); - bool isDocumentEnd = analyzer.Check('.', 0) && analyzer.Check('.', 1) && analyzer.Check('.', 2); - - return isDocumentStart || isDocumentEnd; - } - else - { - return false; - } - } - - private void Skip() - { - cursor.Skip(); - analyzer.Buffer.Skip(1); - } - - private void SkipLine() - { - if (analyzer.IsCrLf()) - { - cursor.SkipLineByOffset(2); - analyzer.Buffer.Skip(2); - } - else if (analyzer.IsBreak()) - { - cursor.SkipLineByOffset(1); - analyzer.Buffer.Skip(1); - } - else if (!analyzer.IsZero()) - { - throw new InvalidOperationException("Not at a break."); - } - } + if (isPlainScalar) + { + FetchPlainScalar(); + return; + } + + // If we don't determine the token type so far, it is an error. + var start = cursor.Mark(); + Skip(); + var end = cursor.Mark(); + + throw new SyntaxErrorException(start, end, "While scanning for the next token, find character that cannot start any token."); + } + + private bool CheckWhiteSpace() + { + return analyzer.Check(' ') || ((flowLevel > 0 || !simpleKeyAllowed) && analyzer.Check('\t')); + } + + private bool IsDocumentIndicator() + { + if (cursor.LineOffset == 0 && analyzer.IsWhiteBreakOrZero(3)) + { + bool isDocumentStart = analyzer.Check('-', 0) && analyzer.Check('-', 1) && analyzer.Check('-', 2); + bool isDocumentEnd = analyzer.Check('.', 0) && analyzer.Check('.', 1) && analyzer.Check('.', 2); + + return isDocumentStart || isDocumentEnd; + } + else + { + return false; + } + } + + private void Skip() + { + cursor.Skip(); + analyzer.Buffer.Skip(1); + } + + private void SkipLine() + { + if (analyzer.IsCrLf()) + { + cursor.SkipLineByOffset(2); + analyzer.Buffer.Skip(2); + } + else if (analyzer.IsBreak()) + { + cursor.SkipLineByOffset(1); + analyzer.Buffer.Skip(1); + } + else if (!analyzer.IsZero()) + { + throw new InvalidOperationException("Not at a break."); + } + } - private void ScanToNextToken() - { - // Until the next token is not find. + private void ScanToNextToken() + { + // Until the next token is not find. - for (; ;) - { + for (; ;) + { - // Eat whitespaces. + // Eat whitespaces. - // Tabs are allowed: - - // - in the flow context; - // - in the block context, but not at the beginning of the line or - // after '-', '?', or ':' (complex value). + // Tabs are allowed: + + // - in the flow context; + // - in the block context, but not at the beginning of the line or + // after '-', '?', or ':' (complex value). - while (CheckWhiteSpace()) - { - Skip(); - } + while (CheckWhiteSpace()) + { + Skip(); + } - ProcessComment(); + ProcessComment(); - // If it is a line break, eat it. + // If it is a line break, eat it. - if (analyzer.IsBreak()) - { - SkipLine(); - - // In the block context, a new line may start a simple key. - - if (flowLevel == 0) - { - simpleKeyAllowed = true; - } - } - else - { - // We have find a token. - - break; - } - } - } - - private void ProcessComment() - { - if (analyzer.Check('#')) - { - var start = cursor.Mark(); + if (analyzer.IsBreak()) + { + SkipLine(); + + // In the block context, a new line may start a simple key. + + if (flowLevel == 0) + { + simpleKeyAllowed = true; + } + } + else + { + // We have find a token. + + break; + } + } + } + + private void ProcessComment() + { + if (analyzer.Check('#')) + { + var start = cursor.Mark(); - // Eat '#' - Skip(); - - // Eat leading whitespace - while (analyzer.IsSpace()) - { - Skip(); - } + // Eat '#' + Skip(); + + // Eat leading whitespace + while (analyzer.IsSpace()) + { + Skip(); + } - var text = new StringBuilder(); - while (!analyzer.IsBreakOrZero()) - { - text.Append(ReadCurrentCharacter()); - } + var text = new StringBuilder(); + while (!analyzer.IsBreakOrZero()) + { + text.Append(ReadCurrentCharacter()); + } - if (!SkipComments) - { - var isInline = previous != null - && previous.End.Line == start.Line - && !(previous is StreamStart); + if (!SkipComments) + { + var isInline = previous != null + && previous.End.Line == start.Line + && !(previous is StreamStart); - tokens.Enqueue(new Comment(text.ToString(), isInline, start, cursor.Mark())); - } - } - } + tokens.Enqueue(new Comment(text.ToString(), isInline, start, cursor.Mark())); + } + } + } - private void FetchStreamStart() - { - // Initialize the simple key stack. + private void FetchStreamStart() + { + // Initialize the simple key stack. - simpleKeys.Push(new SimpleKey()); + simpleKeys.Push(new SimpleKey()); - // A simple key is allowed at the beginning of the stream. + // A simple key is allowed at the beginning of the stream. - simpleKeyAllowed = true; + simpleKeyAllowed = true; - // We have started. + // We have started. - streamStartProduced = true; + streamStartProduced = true; - // Create the STREAM-START token and append it to the queue. + // Create the STREAM-START token and append it to the queue. - var mark = cursor.Mark(); - tokens.Enqueue(new StreamStart(mark, mark)); - } + var mark = cursor.Mark(); + tokens.Enqueue(new StreamStart(mark, mark)); + } - /// - /// Pop indentation levels from the indents stack until the current level - /// becomes less or equal to the column. For each intendation level, append - /// the BLOCK-END token. - /// + /// + /// Pop indentation levels from the indents stack until the current level + /// becomes less or equal to the column. For each intendation level, append + /// the BLOCK-END token. + /// - private void UnrollIndent(int column) - { - // In the flow context, do nothing. + private void UnrollIndent(int column) + { + // In the flow context, do nothing. - if (flowLevel != 0) - { - return; - } + if (flowLevel != 0) + { + return; + } - // Loop through the intendation levels in the stack. + // Loop through the intendation levels in the stack. - while (indent > column) - { - // Create a token and append it to the queue. + while (indent > column) + { + // Create a token and append it to the queue. - var mark = cursor.Mark(); - tokens.Enqueue(new BlockEnd(mark, mark)); + var mark = cursor.Mark(); + tokens.Enqueue(new BlockEnd(mark, mark)); - // Pop the indentation level. + // Pop the indentation level. - indent = indents.Pop(); - } - } + indent = indents.Pop(); + } + } - /// - /// Produce the STREAM-END token and shut down the scanner. - /// - private void FetchStreamEnd() - { - cursor.ForceSkipLineAfterNonBreak(); + /// + /// Produce the STREAM-END token and shut down the scanner. + /// + private void FetchStreamEnd() + { + cursor.ForceSkipLineAfterNonBreak(); - // Reset the indentation level. + // Reset the indentation level. - UnrollIndent(-1); + UnrollIndent(-1); - // Reset simple keys. + // Reset simple keys. - RemoveSimpleKey(); + RemoveSimpleKey(); - simpleKeyAllowed = false; + simpleKeyAllowed = false; - // Create the STREAM-END token and append it to the queue. + // Create the STREAM-END token and append it to the queue. - streamEndProduced = true; - var mark = cursor.Mark(); - tokens.Enqueue(new StreamEnd(mark, mark)); - } + streamEndProduced = true; + var mark = cursor.Mark(); + tokens.Enqueue(new StreamEnd(mark, mark)); + } - private void FetchDirective() - { - // Reset the indentation level. + private void FetchDirective() + { + // Reset the indentation level. - UnrollIndent(-1); + UnrollIndent(-1); - // Reset simple keys. + // Reset simple keys. - RemoveSimpleKey(); + RemoveSimpleKey(); - simpleKeyAllowed = false; + simpleKeyAllowed = false; - // Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. + // Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. - Token token = ScanDirective(); + Token token = ScanDirective(); - // Append the token to the queue. + // Append the token to the queue. - tokens.Enqueue(token); - } + tokens.Enqueue(token); + } - /// - /// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token. - /// - /// Scope: - /// %YAML 1.1 # a comment \n - /// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - /// %TAG !yaml! tag:yaml.org,2002: \n - /// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - /// - private Token ScanDirective() - { - // Eat '%'. + /// + /// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token. + /// + /// Scope: + /// %YAML 1.1 # a comment \n + /// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + /// %TAG !yaml! tag:yaml.org,2002: \n + /// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + /// + private Token ScanDirective() + { + // Eat '%'. - Mark start = cursor.Mark(); + Mark start = cursor.Mark(); - Skip(); + Skip(); - // Scan the directive name. + // Scan the directive name. - string name = ScanDirectiveName(start); + string name = ScanDirectiveName(start); - // Is it a YAML directive? + // Is it a YAML directive? - Token directive; - switch (name) - { - case "YAML": - directive = ScanVersionDirectiveValue(start); - break; + Token directive; + switch (name) + { + case "YAML": + directive = ScanVersionDirectiveValue(start); + break; - case "TAG": - directive = ScanTagDirectiveValue(start); - break; + case "TAG": + directive = ScanTagDirectiveValue(start); + break; - default: - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a directive, find uknown directive name."); - } + default: + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a directive, find uknown directive name."); + } - // Eat the rest of the line including any comments. + // Eat the rest of the line including any comments. - while (analyzer.IsWhite()) - { - Skip(); - } + while (analyzer.IsWhite()) + { + Skip(); + } - ProcessComment(); + ProcessComment(); - // Check if we are at the end of the line. + // Check if we are at the end of the line. - if (!analyzer.IsBreakOrZero()) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a directive, did not find expected comment or line break."); - } + if (!analyzer.IsBreakOrZero()) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a directive, did not find expected comment or line break."); + } - // Eat a line break. + // Eat a line break. - if (analyzer.IsBreak()) - { - SkipLine(); - } + if (analyzer.IsBreak()) + { + SkipLine(); + } - return directive; - } + return directive; + } - /// - /// Produce the DOCUMENT-START or DOCUMENT-END token. - /// + /// + /// Produce the DOCUMENT-START or DOCUMENT-END token. + /// - private void FetchDocumentIndicator(bool isStartToken) - { - // Reset the indentation level. + private void FetchDocumentIndicator(bool isStartToken) + { + // Reset the indentation level. - UnrollIndent(-1); + UnrollIndent(-1); - // Reset simple keys. + // Reset simple keys. - RemoveSimpleKey(); + RemoveSimpleKey(); - simpleKeyAllowed = false; + simpleKeyAllowed = false; - // Consume the token. + // Consume the token. - Mark start = cursor.Mark(); + Mark start = cursor.Mark(); - Skip(); - Skip(); - Skip(); + Skip(); + Skip(); + Skip(); - Token token = isStartToken ? (Token)new DocumentStart(start, cursor.Mark()) : new DocumentEnd(start, start); - tokens.Enqueue(token); - } + Token token = isStartToken ? (Token)new DocumentStart(start, cursor.Mark()) : new DocumentEnd(start, start); + tokens.Enqueue(token); + } - /// - /// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token. - /// + /// + /// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token. + /// - private void FetchFlowCollectionStart(bool isSequenceToken) - { - // The indicators '[' and '{' may start a simple key. + private void FetchFlowCollectionStart(bool isSequenceToken) + { + // The indicators '[' and '{' may start a simple key. - SaveSimpleKey(); + SaveSimpleKey(); - // Increase the flow level. + // Increase the flow level. - IncreaseFlowLevel(); + IncreaseFlowLevel(); - // A simple key may follow the indicators '[' and '{'. + // A simple key may follow the indicators '[' and '{'. - simpleKeyAllowed = true; + simpleKeyAllowed = true; - // Consume the token. + // Consume the token. - Mark start = cursor.Mark(); - Skip(); + Mark start = cursor.Mark(); + Skip(); - // Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. + // Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. - Token token; - if (isSequenceToken) - { - token = new FlowSequenceStart(start, start); - } - else - { - token = new FlowMappingStart(start, start); - } + Token token; + if (isSequenceToken) + { + token = new FlowSequenceStart(start, start); + } + else + { + token = new FlowMappingStart(start, start); + } - tokens.Enqueue(token); - } + tokens.Enqueue(token); + } - /// - /// Increase the flow level and resize the simple key list if needed. - /// + /// + /// Increase the flow level and resize the simple key list if needed. + /// - private void IncreaseFlowLevel() - { - // Reset the simple key on the next level. + private void IncreaseFlowLevel() + { + // Reset the simple key on the next level. - simpleKeys.Push(new SimpleKey()); + simpleKeys.Push(new SimpleKey()); - // Increase the flow level. + // Increase the flow level. - ++flowLevel; - } + ++flowLevel; + } - /// - /// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token. - /// + /// + /// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token. + /// - private void FetchFlowCollectionEnd(bool isSequenceToken) - { - // Reset any potential simple key on the current flow level. + private void FetchFlowCollectionEnd(bool isSequenceToken) + { + // Reset any potential simple key on the current flow level. - RemoveSimpleKey(); + RemoveSimpleKey(); - // Decrease the flow level. + // Decrease the flow level. - DecreaseFlowLevel(); + DecreaseFlowLevel(); - // No simple keys after the indicators ']' and '}'. + // No simple keys after the indicators ']' and '}'. - simpleKeyAllowed = false; + simpleKeyAllowed = false; - // Consume the token. + // Consume the token. - Mark start = cursor.Mark(); - Skip(); + Mark start = cursor.Mark(); + Skip(); - Token token; - if (isSequenceToken) - { - token = new FlowSequenceEnd(start, start); - } - else - { - token = new FlowMappingEnd(start, start); - } + Token token; + if (isSequenceToken) + { + token = new FlowSequenceEnd(start, start); + } + else + { + token = new FlowMappingEnd(start, start); + } - tokens.Enqueue(token); - } + tokens.Enqueue(token); + } - /// - /// Decrease the flow level. - /// + /// + /// Decrease the flow level. + /// - private void DecreaseFlowLevel() - { - Debug.Assert(flowLevel > 0, "Could flowLevel be zero when this method is called?"); - if (flowLevel > 0) - { - --flowLevel; - simpleKeys.Pop(); - } - } + private void DecreaseFlowLevel() + { + Debug.Assert(flowLevel > 0, "Could flowLevel be zero when this method is called?"); + if (flowLevel > 0) + { + --flowLevel; + simpleKeys.Pop(); + } + } - /// - /// Produce the FLOW-ENTRY token. - /// + /// + /// Produce the FLOW-ENTRY token. + /// - private void FetchFlowEntry() - { - // Reset any potential simple keys on the current flow level. + private void FetchFlowEntry() + { + // Reset any potential simple keys on the current flow level. - RemoveSimpleKey(); + RemoveSimpleKey(); - // Simple keys are allowed after ','. + // Simple keys are allowed after ','. - simpleKeyAllowed = true; + simpleKeyAllowed = true; - // Consume the token. + // Consume the token. - Mark start = cursor.Mark(); - Skip(); + Mark start = cursor.Mark(); + Skip(); - // Create the FLOW-ENTRY token and append it to the queue. + // Create the FLOW-ENTRY token and append it to the queue. - tokens.Enqueue(new FlowEntry(start, cursor.Mark())); - } + tokens.Enqueue(new FlowEntry(start, cursor.Mark())); + } - /// - /// Produce the BLOCK-ENTRY token. - /// + /// + /// Produce the BLOCK-ENTRY token. + /// - private void FetchBlockEntry() - { - // Check if the scanner is in the block context. + private void FetchBlockEntry() + { + // Check if the scanner is in the block context. - if (flowLevel == 0) - { - // Check if we are allowed to start a new entry. + if (flowLevel == 0) + { + // Check if we are allowed to start a new entry. - if (!simpleKeyAllowed) - { - var mark = cursor.Mark(); - throw new SyntaxErrorException(mark, mark, "Block sequence entries are not allowed in this context."); - } + if (!simpleKeyAllowed) + { + var mark = cursor.Mark(); + throw new SyntaxErrorException(mark, mark, "Block sequence entries are not allowed in this context."); + } - // Add the BLOCK-SEQUENCE-START token if needed. - RollIndent(cursor.LineOffset, -1, true, cursor.Mark()); - } - else - { + // Add the BLOCK-SEQUENCE-START token if needed. + RollIndent(cursor.LineOffset, -1, true, cursor.Mark()); + } + else + { - // It is an error for the '-' indicator to occur in the flow context, - // but we let the Parser detect and report about it because the Parser - // is able to point to the context. + // It is an error for the '-' indicator to occur in the flow context, + // but we let the Parser detect and report about it because the Parser + // is able to point to the context. - } + } - // Reset any potential simple keys on the current flow level. + // Reset any potential simple keys on the current flow level. - RemoveSimpleKey(); + RemoveSimpleKey(); - // Simple keys are allowed after '-'. + // Simple keys are allowed after '-'. - simpleKeyAllowed = true; + simpleKeyAllowed = true; - // Consume the token. + // Consume the token. - Mark start = cursor.Mark(); - Skip(); + Mark start = cursor.Mark(); + Skip(); - // Create the BLOCK-ENTRY token and append it to the queue. + // Create the BLOCK-ENTRY token and append it to the queue. - tokens.Enqueue(new BlockEntry(start, cursor.Mark())); - } + tokens.Enqueue(new BlockEntry(start, cursor.Mark())); + } - /// - /// Produce the KEY token. - /// + /// + /// Produce the KEY token. + /// - private void FetchKey() - { - // In the block context, additional checks are required. + private void FetchKey() + { + // In the block context, additional checks are required. - if (flowLevel == 0) - { - // Check if we are allowed to start a new key (not nessesary simple). + if (flowLevel == 0) + { + // Check if we are allowed to start a new key (not nessesary simple). - if (!simpleKeyAllowed) - { - var mark = cursor.Mark(); - throw new SyntaxErrorException(mark, mark, "Mapping keys are not allowed in this context."); - } + if (!simpleKeyAllowed) + { + var mark = cursor.Mark(); + throw new SyntaxErrorException(mark, mark, "Mapping keys are not allowed in this context."); + } - // Add the BLOCK-MAPPING-START token if needed. + // Add the BLOCK-MAPPING-START token if needed. - RollIndent(cursor.LineOffset, -1, false, cursor.Mark()); - } + RollIndent(cursor.LineOffset, -1, false, cursor.Mark()); + } - // Reset any potential simple keys on the current flow level. + // Reset any potential simple keys on the current flow level. - RemoveSimpleKey(); + RemoveSimpleKey(); - // Simple keys are allowed after '?' in the block context. + // Simple keys are allowed after '?' in the block context. - simpleKeyAllowed = flowLevel == 0; + simpleKeyAllowed = flowLevel == 0; - // Consume the token. + // Consume the token. - Mark start = cursor.Mark(); - Skip(); + Mark start = cursor.Mark(); + Skip(); - // Create the KEY token and append it to the queue. + // Create the KEY token and append it to the queue. - tokens.Enqueue(new Key(start, cursor.Mark())); - } + tokens.Enqueue(new Key(start, cursor.Mark())); + } - /// - /// Produce the VALUE token. - /// + /// + /// Produce the VALUE token. + /// - private void FetchValue() - { - SimpleKey simpleKey = simpleKeys.Peek(); + private void FetchValue() + { + SimpleKey simpleKey = simpleKeys.Peek(); - // Have we find a simple key? + // Have we find a simple key? - if (simpleKey.IsPossible) - { - // Create the KEY token and insert it into the queue. + if (simpleKey.IsPossible) + { + // Create the KEY token and insert it into the queue. - tokens.Insert(simpleKey.TokenNumber - tokensParsed, new Key(simpleKey.Mark, simpleKey.Mark)); + tokens.Insert(simpleKey.TokenNumber - tokensParsed, new Key(simpleKey.Mark, simpleKey.Mark)); - // In the block context, we may need to add the BLOCK-MAPPING-START token. + // In the block context, we may need to add the BLOCK-MAPPING-START token. - RollIndent(simpleKey.LineOffset, simpleKey.TokenNumber, false, simpleKey.Mark); + RollIndent(simpleKey.LineOffset, simpleKey.TokenNumber, false, simpleKey.Mark); - // Remove the simple key. + // Remove the simple key. - simpleKey.IsPossible = false; + simpleKey.IsPossible = false; - // A simple key cannot follow another simple key. + // A simple key cannot follow another simple key. - simpleKeyAllowed = false; - } - else - { - // The ':' indicator follows a complex key. + simpleKeyAllowed = false; + } + else + { + // The ':' indicator follows a complex key. - // In the block context, extra checks are required. + // In the block context, extra checks are required. - if (flowLevel == 0) - { - // Check if we are allowed to start a complex value. + if (flowLevel == 0) + { + // Check if we are allowed to start a complex value. - if (!simpleKeyAllowed) - { - var mark = cursor.Mark(); - throw new SyntaxErrorException(mark, mark, "Mapping values are not allowed in this context."); - } + if (!simpleKeyAllowed) + { + var mark = cursor.Mark(); + throw new SyntaxErrorException(mark, mark, "Mapping values are not allowed in this context."); + } - // Add the BLOCK-MAPPING-START token if needed. + // Add the BLOCK-MAPPING-START token if needed. - RollIndent(cursor.LineOffset, -1, false, cursor.Mark()); - } + RollIndent(cursor.LineOffset, -1, false, cursor.Mark()); + } - // Simple keys after ':' are allowed in the block context. + // Simple keys after ':' are allowed in the block context. - simpleKeyAllowed = flowLevel == 0; - } + simpleKeyAllowed = flowLevel == 0; + } - // Consume the token. + // Consume the token. - Mark start = cursor.Mark(); - Skip(); + Mark start = cursor.Mark(); + Skip(); - // Create the VALUE token and append it to the queue. + // Create the VALUE token and append it to the queue. - tokens.Enqueue(new Value(start, cursor.Mark())); - } + tokens.Enqueue(new Value(start, cursor.Mark())); + } - /// - /// Push the current indentation level to the stack and set the new level - /// the current column is greater than the indentation level. In this case, - /// append or insert the specified token into the token queue. - /// - private void RollIndent(int column, int number, bool isSequence, Mark position) - { - // In the flow context, do nothing. + /// + /// Push the current indentation level to the stack and set the new level + /// the current column is greater than the indentation level. In this case, + /// append or insert the specified token into the token queue. + /// + private void RollIndent(int column, int number, bool isSequence, Mark position) + { + // In the flow context, do nothing. - if (flowLevel > 0) - { - return; - } + if (flowLevel > 0) + { + return; + } - if (indent < column) - { + if (indent < column) + { - // Push the current indentation level to the stack and set the new - // indentation level. + // Push the current indentation level to the stack and set the new + // indentation level. - indents.Push(indent); + indents.Push(indent); - indent = column; + indent = column; - // Create a token and insert it into the queue. + // Create a token and insert it into the queue. - Token token; - if (isSequence) - { - token = new BlockSequenceStart(position, position); - } - else - { - token = new BlockMappingStart(position, position); - } + Token token; + if (isSequence) + { + token = new BlockSequenceStart(position, position); + } + else + { + token = new BlockMappingStart(position, position); + } - if (number == -1) - { - tokens.Enqueue(token); - } - else - { - tokens.Insert(number - tokensParsed, token); - } - } - } + if (number == -1) + { + tokens.Enqueue(token); + } + else + { + tokens.Insert(number - tokensParsed, token); + } + } + } - /// - /// Produce the ALIAS or ANCHOR token. - /// + /// + /// Produce the ALIAS or ANCHOR token. + /// - private void FetchAnchor(bool isAlias) - { - // An anchor or an alias could be a simple key. + private void FetchAnchor(bool isAlias) + { + // An anchor or an alias could be a simple key. - SaveSimpleKey(); + SaveSimpleKey(); - // A simple key cannot follow an anchor or an alias. + // A simple key cannot follow an anchor or an alias. - simpleKeyAllowed = false; + simpleKeyAllowed = false; - // Create the ALIAS or ANCHOR token and append it to the queue. + // Create the ALIAS or ANCHOR token and append it to the queue. - tokens.Enqueue(ScanAnchor(isAlias)); - } + tokens.Enqueue(ScanAnchor(isAlias)); + } - private Token ScanAnchor(bool isAlias) - { - // Eat the indicator character. + private Token ScanAnchor(bool isAlias) + { + // Eat the indicator character. - Mark start = cursor.Mark(); + Mark start = cursor.Mark(); - Skip(); + Skip(); - // Consume the value. + // Consume the value. - StringBuilder value = new StringBuilder(); - while (analyzer.IsAlphaNumericDashOrUnderscore()) - { - value.Append(ReadCurrentCharacter()); - } + StringBuilder value = new StringBuilder(); + while (analyzer.IsAlphaNumericDashOrUnderscore()) + { + value.Append(ReadCurrentCharacter()); + } - // Check if length of the anchor is greater than 0 and it is followed by - // a whitespace character or one of the indicators: + // Check if length of the anchor is greater than 0 and it is followed by + // a whitespace character or one of the indicators: - // '?', ':', ',', ']', '}', '%', '@', '`'. + // '?', ':', ',', ']', '}', '%', '@', '`'. - if (value.Length == 0 || !(analyzer.IsWhiteBreakOrZero() || analyzer.Check("?:,]}%@`"))) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning an anchor or alias, did not find expected alphabetic or numeric character."); - } + if (value.Length == 0 || !(analyzer.IsWhiteBreakOrZero() || analyzer.Check("?:,]}%@`"))) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning an anchor or alias, did not find expected alphabetic or numeric character."); + } - // Create a token. + // Create a token. - if (isAlias) - { - return new AnchorAlias(value.ToString(), start, cursor.Mark()); - } - else - { - return new Anchor(value.ToString(), start, cursor.Mark()); - } - } + if (isAlias) + { + return new AnchorAlias(value.ToString(), start, cursor.Mark()); + } + else + { + return new Anchor(value.ToString(), start, cursor.Mark()); + } + } - /// - /// Produce the TAG token. - /// + /// + /// Produce the TAG token. + /// - private void FetchTag() - { - // A tag could be a simple key. + private void FetchTag() + { + // A tag could be a simple key. - SaveSimpleKey(); + SaveSimpleKey(); - // A simple key cannot follow a tag. + // A simple key cannot follow a tag. - simpleKeyAllowed = false; + simpleKeyAllowed = false; - // Create the TAG token and append it to the queue. + // Create the TAG token and append it to the queue. - tokens.Enqueue(ScanTag()); - } + tokens.Enqueue(ScanTag()); + } - /// - /// Scan a TAG token. - /// + /// + /// Scan a TAG token. + /// - Token ScanTag() - { - Mark start = cursor.Mark(); + Token ScanTag() + { + Mark start = cursor.Mark(); - // Check if the tag is in the canonical form. + // Check if the tag is in the canonical form. - string handle; - string suffix; + string handle; + string suffix; - if (analyzer.Check('<', 1)) - { - // Set the handle to '' + if (analyzer.Check('<', 1)) + { + // Set the handle to '' - handle = string.Empty; + handle = string.Empty; - // Eat '!<' + // Eat '!<' - Skip(); - Skip(); + Skip(); + Skip(); - // Consume the tag value. + // Consume the tag value. - suffix = ScanTagUri(null, start); + suffix = ScanTagUri(null, start); - // Check for '>' and eat it. + // Check for '>' and eat it. - if (!analyzer.Check('>')) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a tag, did not find the expected '>'."); - } + if (!analyzer.Check('>')) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a tag, did not find the expected '>'."); + } - Skip(); - } - else - { - // The tag has either the '!suffix' or the '!handle!suffix' form. + Skip(); + } + else + { + // The tag has either the '!suffix' or the '!handle!suffix' form. - // First, try to scan a handle. + // First, try to scan a handle. - string firstPart = ScanTagHandle(false, start); + string firstPart = ScanTagHandle(false, start); - // Check if it is, indeed, handle. + // Check if it is, indeed, handle. - if (firstPart.Length > 1 && firstPart[0] == '!' && firstPart[firstPart.Length - 1] == '!') - { - handle = firstPart; + if (firstPart.Length > 1 && firstPart[0] == '!' && firstPart[firstPart.Length - 1] == '!') + { + handle = firstPart; - // Scan the suffix now. + // Scan the suffix now. - suffix = ScanTagUri(null, start); - } - else - { - // It wasn't a handle after all. Scan the rest of the tag. + suffix = ScanTagUri(null, start); + } + else + { + // It wasn't a handle after all. Scan the rest of the tag. - suffix = ScanTagUri(firstPart, start); + suffix = ScanTagUri(firstPart, start); - // Set the handle to '!'. + // Set the handle to '!'. - handle = "!"; + handle = "!"; - // A special case: the '!' tag. Set the handle to '' and the - // suffix to '!'. + // A special case: the '!' tag. Set the handle to '' and the + // suffix to '!'. - if (suffix.Length == 0) - { - suffix = handle; - handle = string.Empty; - } - } - } + if (suffix.Length == 0) + { + suffix = handle; + handle = string.Empty; + } + } + } - // Check the character which ends the tag. + // Check the character which ends the tag. - if (!analyzer.IsWhiteBreakOrZero()) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a tag, did not find expected whitespace or line break."); - } + if (!analyzer.IsWhiteBreakOrZero()) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a tag, did not find expected whitespace or line break."); + } - // Create a token. + // Create a token. - return new Tag(handle, suffix, start, cursor.Mark()); - } + return new Tag(handle, suffix, start, cursor.Mark()); + } - /// - /// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens. - /// + /// + /// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens. + /// - private void FetchBlockScalar(bool isLiteral) - { - // Remove any potential simple keys. + private void FetchBlockScalar(bool isLiteral) + { + // Remove any potential simple keys. - RemoveSimpleKey(); + RemoveSimpleKey(); - // A simple key may follow a block scalar. + // A simple key may follow a block scalar. - simpleKeyAllowed = true; + simpleKeyAllowed = true; - // Create the SCALAR token and append it to the queue. + // Create the SCALAR token and append it to the queue. - tokens.Enqueue(ScanBlockScalar(isLiteral)); - } + tokens.Enqueue(ScanBlockScalar(isLiteral)); + } - /// - /// Scan a block scalar. - /// + /// + /// Scan a block scalar. + /// - Token ScanBlockScalar(bool isLiteral) - { - StringBuilder value = new StringBuilder(); - StringBuilder leadingBreak = new StringBuilder(); - StringBuilder trailingBreaks = new StringBuilder(); + Token ScanBlockScalar(bool isLiteral) + { + StringBuilder value = new StringBuilder(); + StringBuilder leadingBreak = new StringBuilder(); + StringBuilder trailingBreaks = new StringBuilder(); - int chomping = 0; - int increment = 0; - int currentIndent = 0; - bool leadingBlank = false; + int chomping = 0; + int increment = 0; + int currentIndent = 0; + bool leadingBlank = false; - // Eat the indicator '|' or '>'. + // Eat the indicator '|' or '>'. - Mark start = cursor.Mark(); + Mark start = cursor.Mark(); - Skip(); + Skip(); - // Check for a chomping indicator. + // Check for a chomping indicator. - if (analyzer.Check("+-")) - { - // Set the chomping method and eat the indicator. + if (analyzer.Check("+-")) + { + // Set the chomping method and eat the indicator. - chomping = analyzer.Check('+') ? + 1 : -1; + chomping = analyzer.Check('+') ? + 1 : -1; - Skip(); + Skip(); - // Check for an indentation indicator. + // Check for an indentation indicator. - if (analyzer.IsDigit()) - { - // Check that the intendation is greater than 0. + if (analyzer.IsDigit()) + { + // Check that the intendation is greater than 0. - if (analyzer.Check('0')) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a block scalar, find an intendation indicator equal to 0."); - } + if (analyzer.Check('0')) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a block scalar, find an intendation indicator equal to 0."); + } - // Get the intendation level and eat the indicator. + // Get the intendation level and eat the indicator. - increment = analyzer.AsDigit(); + increment = analyzer.AsDigit(); - Skip(); - } - } + Skip(); + } + } - // Do the same as above, but in the opposite order. + // Do the same as above, but in the opposite order. - else if (analyzer.IsDigit()) - { - if (analyzer.Check('0')) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a block scalar, find an intendation indicator equal to 0."); - } + else if (analyzer.IsDigit()) + { + if (analyzer.Check('0')) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a block scalar, find an intendation indicator equal to 0."); + } - increment = analyzer.AsDigit(); + increment = analyzer.AsDigit(); - Skip(); + Skip(); - if (analyzer.Check("+-")) - { - chomping = analyzer.Check('+') ? + 1 : -1; + if (analyzer.Check("+-")) + { + chomping = analyzer.Check('+') ? + 1 : -1; - Skip(); - } - } + Skip(); + } + } - // Eat whitespaces and comments to the end of the line. + // Eat whitespaces and comments to the end of the line. - while (analyzer.IsWhite()) - { - Skip(); - } + while (analyzer.IsWhite()) + { + Skip(); + } - ProcessComment(); + ProcessComment(); - // Check if we are at the end of the line. + // Check if we are at the end of the line. - if (!analyzer.IsBreakOrZero()) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a block scalar, did not find expected comment or line break."); - } + if (!analyzer.IsBreakOrZero()) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a block scalar, did not find expected comment or line break."); + } - // Eat a line break. + // Eat a line break. - if (analyzer.IsBreak()) - { - SkipLine(); - } + if (analyzer.IsBreak()) + { + SkipLine(); + } - Mark end = cursor.Mark(); + Mark end = cursor.Mark(); - // Set the intendation level if it was specified. + // Set the intendation level if it was specified. - if (increment != 0) - { - currentIndent = indent >= 0 ? indent + increment : increment; - } + if (increment != 0) + { + currentIndent = indent >= 0 ? indent + increment : increment; + } - // Scan the leading line breaks and determine the indentation level if needed. + // Scan the leading line breaks and determine the indentation level if needed. - currentIndent = ScanBlockScalarBreaks(currentIndent, trailingBreaks, start, ref end); + currentIndent = ScanBlockScalarBreaks(currentIndent, trailingBreaks, start, ref end); - // Scan the block scalar content. + // Scan the block scalar content. - while (cursor.LineOffset == currentIndent && !analyzer.IsZero()) - { + while (cursor.LineOffset == currentIndent && !analyzer.IsZero()) + { - // We are at the beginning of a non-empty line. + // We are at the beginning of a non-empty line. - // Is it a trailing whitespace? + // Is it a trailing whitespace? - bool trailingBlank = analyzer.IsWhite(); + bool trailingBlank = analyzer.IsWhite(); - // Check if we need to fold the leading line break. + // Check if we need to fold the leading line break. - if (!isLiteral && StartsWith(leadingBreak, '\n') && !leadingBlank && !trailingBlank) - { - // Do we need to join the lines by space? + if (!isLiteral && StartsWith(leadingBreak, '\n') && !leadingBlank && !trailingBlank) + { + // Do we need to join the lines by space? - if (trailingBreaks.Length == 0) - { - value.Append(' '); - } + if (trailingBreaks.Length == 0) + { + value.Append(' '); + } - leadingBreak.Length = 0; - } - else - { - value.Append(leadingBreak.ToString()); - leadingBreak.Length = 0; - } + leadingBreak.Length = 0; + } + else + { + value.Append(leadingBreak.ToString()); + leadingBreak.Length = 0; + } - // Append the remaining line breaks. + // Append the remaining line breaks. - value.Append(trailingBreaks.ToString()); - trailingBreaks.Length = 0; + value.Append(trailingBreaks.ToString()); + trailingBreaks.Length = 0; - // Is it a leading whitespace? + // Is it a leading whitespace? - leadingBlank = analyzer.IsWhite(); + leadingBlank = analyzer.IsWhite(); - // Consume the current line. + // Consume the current line. - while (!analyzer.IsBreakOrZero()) - { - value.Append(ReadCurrentCharacter()); - } + while (!analyzer.IsBreakOrZero()) + { + value.Append(ReadCurrentCharacter()); + } - // Consume the line break. + // Consume the line break. - leadingBreak.Append(ReadLine()); + leadingBreak.Append(ReadLine()); - // Eat the following intendation spaces and line breaks. + // Eat the following intendation spaces and line breaks. - currentIndent = ScanBlockScalarBreaks(currentIndent, trailingBreaks, start, ref end); - } + currentIndent = ScanBlockScalarBreaks(currentIndent, trailingBreaks, start, ref end); + } - // Chomp the tail. + // Chomp the tail. - if (chomping != -1) - { - value.Append(leadingBreak); - } - if (chomping == 1) - { - value.Append(trailingBreaks); - } + if (chomping != -1) + { + value.Append(leadingBreak); + } + if (chomping == 1) + { + value.Append(trailingBreaks); + } - // Create a token. + // Create a token. - ScalarStyle style = isLiteral ? ScalarStyle.Literal : ScalarStyle.Folded; - return new Scalar(value.ToString(), style, start, end); - } + ScalarStyle style = isLiteral ? ScalarStyle.Literal : ScalarStyle.Folded; + return new Scalar(value.ToString(), style, start, end); + } - /// - /// Scan intendation spaces and line breaks for a block scalar. Determine the - /// intendation level if needed. - /// + /// + /// Scan intendation spaces and line breaks for a block scalar. Determine the + /// intendation level if needed. + /// - private int ScanBlockScalarBreaks(int currentIndent, StringBuilder breaks, Mark start, ref Mark end) - { - int maxIndent = 0; + private int ScanBlockScalarBreaks(int currentIndent, StringBuilder breaks, Mark start, ref Mark end) + { + int maxIndent = 0; - end = cursor.Mark(); + end = cursor.Mark(); - // Eat the intendation spaces and line breaks. + // Eat the intendation spaces and line breaks. - for (; ;) - { - // Eat the intendation spaces. + for (; ;) + { + // Eat the intendation spaces. - while ((currentIndent == 0 || cursor.LineOffset < currentIndent) && analyzer.IsSpace()) - { - Skip(); - } + while ((currentIndent == 0 || cursor.LineOffset < currentIndent) && analyzer.IsSpace()) + { + Skip(); + } - if (cursor.LineOffset > maxIndent) - { - maxIndent = cursor.LineOffset; - } + if (cursor.LineOffset > maxIndent) + { + maxIndent = cursor.LineOffset; + } - // Check for a tab character messing the intendation. + // Check for a tab character messing the intendation. - if ((currentIndent == 0 || cursor.LineOffset < currentIndent) && analyzer.IsTab()) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a block scalar, find a tab character where an intendation space is expected."); - } + if ((currentIndent == 0 || cursor.LineOffset < currentIndent) && analyzer.IsTab()) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a block scalar, find a tab character where an intendation space is expected."); + } - // Have we find a non-empty line? + // Have we find a non-empty line? - if (!analyzer.IsBreak()) - { - break; - } + if (!analyzer.IsBreak()) + { + break; + } - // Consume the line break. + // Consume the line break. - breaks.Append(ReadLine()); + breaks.Append(ReadLine()); - end = cursor.Mark(); - } + end = cursor.Mark(); + } - // Determine the indentation level if needed. + // Determine the indentation level if needed. - if (currentIndent == 0) - { - currentIndent = Math.Max(maxIndent, Math.Max(indent + 1, 1)); - } + if (currentIndent == 0) + { + currentIndent = Math.Max(maxIndent, Math.Max(indent + 1, 1)); + } - return currentIndent; - } + return currentIndent; + } - /// - /// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens. - /// + /// + /// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens. + /// - private void FetchFlowScalar(bool isSingleQuoted) - { - // A plain scalar could be a simple key. + private void FetchFlowScalar(bool isSingleQuoted) + { + // A plain scalar could be a simple key. - SaveSimpleKey(); + SaveSimpleKey(); - // A simple key cannot follow a flow scalar. + // A simple key cannot follow a flow scalar. - simpleKeyAllowed = false; + simpleKeyAllowed = false; - // Create the SCALAR token and append it to the queue. + // Create the SCALAR token and append it to the queue. - tokens.Enqueue(ScanFlowScalar(isSingleQuoted)); - } + tokens.Enqueue(ScanFlowScalar(isSingleQuoted)); + } - /// - /// Scan a quoted scalar. - /// + /// + /// Scan a quoted scalar. + /// - private Token ScanFlowScalar(bool isSingleQuoted) - { - // Eat the left quote. + private Token ScanFlowScalar(bool isSingleQuoted) + { + // Eat the left quote. - Mark start = cursor.Mark(); + Mark start = cursor.Mark(); - Skip(); + Skip(); - // Consume the content of the quoted scalar. + // Consume the content of the quoted scalar. - StringBuilder value = new StringBuilder(); - StringBuilder whitespaces = new StringBuilder(); - StringBuilder leadingBreak = new StringBuilder(); - StringBuilder trailingBreaks = new StringBuilder(); - for (; ;) - { - // Check that there are no document indicators at the beginning of the line. + StringBuilder value = new StringBuilder(); + StringBuilder whitespaces = new StringBuilder(); + StringBuilder leadingBreak = new StringBuilder(); + StringBuilder trailingBreaks = new StringBuilder(); + for (; ;) + { + // Check that there are no document indicators at the beginning of the line. - if (IsDocumentIndicator()) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a quoted scalar, find unexpected document indicator."); - } + if (IsDocumentIndicator()) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a quoted scalar, find unexpected document indicator."); + } - // Check for EOF. + // Check for EOF. - if (analyzer.IsZero()) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a quoted scalar, find unexpected end of stream."); - } + if (analyzer.IsZero()) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a quoted scalar, find unexpected end of stream."); + } - // Consume non-blank characters. + // Consume non-blank characters. - bool hasLeadingBlanks = false; + bool hasLeadingBlanks = false; - while (!analyzer.IsWhiteBreakOrZero()) - { - // Check for an escaped single quote. + while (!analyzer.IsWhiteBreakOrZero()) + { + // Check for an escaped single quote. - if (isSingleQuoted && analyzer.Check('\'', 0) && analyzer.Check('\'', 1)) - { - value.Append('\''); - Skip(); - Skip(); - } + if (isSingleQuoted && analyzer.Check('\'', 0) && analyzer.Check('\'', 1)) + { + value.Append('\''); + Skip(); + Skip(); + } - // Check for the right quote. + // Check for the right quote. - else if (analyzer.Check(isSingleQuoted ? '\'' : '"')) - { - break; - } + else if (analyzer.Check(isSingleQuoted ? '\'' : '"')) + { + break; + } - // Check for an escaped line break. + // Check for an escaped line break. - else if (!isSingleQuoted && analyzer.Check('\\') && analyzer.IsBreak(1)) - { - Skip(); - SkipLine(); - hasLeadingBlanks = true; - break; - } + else if (!isSingleQuoted && analyzer.Check('\\') && analyzer.IsBreak(1)) + { + Skip(); + SkipLine(); + hasLeadingBlanks = true; + break; + } - // Check for an escape sequence. + // Check for an escape sequence. - else if (!isSingleQuoted && analyzer.Check('\\')) - { - int codeLength = 0; - - // Check the escape character. - - char escapeCharacter = analyzer.Peek(1); - switch (escapeCharacter) - { - case 'x': - codeLength = 2; - break; - - case 'u': - codeLength = 4; - break; - - case 'U': - codeLength = 8; - break; - - default: - char unescapedCharacter; - if (simpleEscapeCodes.TryGetValue(escapeCharacter, out unescapedCharacter)) - { - value.Append(unescapedCharacter); - } - else - { - throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a quoted scalar, find unknown escape character."); - } - break; - } - - Skip(); - Skip(); - - // Consume an arbitrary escape code. - - if (codeLength > 0) - { - uint character = 0; - - // Scan the character value. - - for (int k = 0; k < codeLength; ++k) - { - if (!analyzer.IsHex(k)) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a quoted scalar, did not find expected hexdecimal number."); - } - character = (uint)((character << 4) + analyzer.AsHex(k)); - } - - // Check the value and write the character. - - if ((character >= 0xD800 && character <= 0xDFFF) || character > 0x10FFFF) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a quoted scalar, find invalid Unicode character escape code."); - } - - value.Append((char)character); - - // Advance the pointer. - - for (int k = 0; k < codeLength; ++k) - { - Skip(); - } - } - } - else - { - // It is a non-escaped non-blank character. - - value.Append(ReadCurrentCharacter()); - } - } - - // Check if we are at the end of the scalar. - - if (analyzer.Check(isSingleQuoted ? '\'' : '"')) - break; - - // Consume blank characters. - - while (analyzer.IsWhite() || analyzer.IsBreak()) - { - if (analyzer.IsWhite()) - { - // Consume a space or a tab character. - - if (!hasLeadingBlanks) - { - whitespaces.Append(ReadCurrentCharacter()); - } - else - { - Skip(); - } - } - else - { - // Check if it is a first line break. - - if (!hasLeadingBlanks) - { - whitespaces.Length = 0; - leadingBreak.Append(ReadLine()); - hasLeadingBlanks = true; - } - else - { - trailingBreaks.Append(ReadLine()); - } - } - } - - // Join the whitespaces or fold line breaks. - - if (hasLeadingBlanks) - { - // Do we need to fold line breaks? - - if (StartsWith(leadingBreak, '\n')) - { - if (trailingBreaks.Length == 0) - { - value.Append(' '); - } - else - { - value.Append(trailingBreaks.ToString()); - } - } - else - { - value.Append(leadingBreak.ToString()); - value.Append(trailingBreaks.ToString()); - } - leadingBreak.Length = 0; - trailingBreaks.Length = 0; - } - else - { - value.Append(whitespaces.ToString()); - whitespaces.Length = 0; - } - } - - // Eat the right quote. - - Skip(); - - return new Scalar(value.ToString(), isSingleQuoted ? ScalarStyle.SingleQuoted : ScalarStyle.DoubleQuoted, start, cursor.Mark()); - } - - /// - /// Produce the SCALAR(...,plain) token. - /// - - private void FetchPlainScalar() - { - // A plain scalar could be a simple key. - - SaveSimpleKey(); - - // A simple key cannot follow a flow scalar. - - simpleKeyAllowed = false; - - // Create the SCALAR token and append it to the queue. - - tokens.Enqueue(ScanPlainScalar()); - } - - /// - /// Scan a plain scalar. - /// - - private Token ScanPlainScalar() - { - StringBuilder value = new StringBuilder(); - StringBuilder whitespaces = new StringBuilder(); - StringBuilder leadingBreak = new StringBuilder(); - StringBuilder trailingBreaks = new StringBuilder(); - - bool hasLeadingBlanks = false; - int currentIndent = indent + 1; - - Mark start = cursor.Mark(); - Mark end = start; - - // Consume the content of the plain scalar. - - for (; ;) - { - // Check for a document indicator. - - if (IsDocumentIndicator()) - { - break; - } - - // Check for a comment. - - if (analyzer.Check('#')) - { - break; - } - - // Consume non-blank characters. - while (!analyzer.IsWhiteBreakOrZero()) - { - // Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". - - if (flowLevel > 0 && analyzer.Check(':') && !analyzer.IsWhiteBreakOrZero(1)) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a plain scalar, find unexpected ':'."); - } - - // Check for indicators that may end a plain scalar. - - if ((analyzer.Check(':') && analyzer.IsWhiteBreakOrZero(1)) || (flowLevel > 0 && analyzer.Check(",:?[]{}"))) - { - break; - } - - // Check if we need to join whitespaces and breaks. - - if (hasLeadingBlanks || whitespaces.Length > 0) - { - if (hasLeadingBlanks) - { - // Do we need to fold line breaks? - - if (StartsWith(leadingBreak, '\n')) - { - if (trailingBreaks.Length == 0) - { - value.Append(' '); - } - else - { - value.Append(trailingBreaks); - } - } - else - { - value.Append(leadingBreak); - value.Append(trailingBreaks); - } - - leadingBreak.Length = 0; - trailingBreaks.Length = 0; - - hasLeadingBlanks = false; - } - else - { - value.Append(whitespaces); - whitespaces.Length = 0; - } - } - - // Copy the character. - - value.Append(ReadCurrentCharacter()); - - end = cursor.Mark(); - } - - // Is it the end? - - if (!(analyzer.IsWhite() || analyzer.IsBreak())) - { - break; - } - - // Consume blank characters. - - while (analyzer.IsWhite() || analyzer.IsBreak()) - { - if (analyzer.IsWhite()) - { - // Check for tab character that abuse intendation. - - if (hasLeadingBlanks && cursor.LineOffset < currentIndent && analyzer.IsTab()) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a plain scalar, find a tab character that violate intendation."); - } - - // Consume a space or a tab character. - - if (!hasLeadingBlanks) - { - whitespaces.Append(ReadCurrentCharacter()); - } - else - { - Skip(); - } - } - else - { - // Check if it is a first line break. - - if (!hasLeadingBlanks) - { - whitespaces.Length = 0; - leadingBreak.Append(ReadLine()); - hasLeadingBlanks = true; - } - else - { - trailingBreaks.Append(ReadLine()); - } - } - } - - // Check intendation level. - - if (flowLevel == 0 && cursor.LineOffset < currentIndent) - { - break; - } - } - - // Note that we change the 'simple_key_allowed' flag. - - if (hasLeadingBlanks) - { - simpleKeyAllowed = true; - } - - // Create a token. - - return new Scalar(value.ToString(), ScalarStyle.Plain, start, end); - } - - - /// - /// Remove a potential simple key at the current flow level. - /// - - private void RemoveSimpleKey() - { - SimpleKey key = simpleKeys.Peek(); - - if (key.IsPossible && key.IsRequired) - { - // If the key is required, it is an error. - - throw new SyntaxErrorException(key.Mark, key.Mark, "While scanning a simple key, could not find expected ':'."); - } - - // Remove the key from the stack. - - key.IsPossible = false; - } - - /// - /// Scan the directive name. - /// - /// Scope: - /// %YAML 1.1 # a comment \n - /// ^^^^ - /// %TAG !yaml! tag:yaml.org,2002: \n - /// ^^^ - /// - private string ScanDirectiveName(Mark start) - { - StringBuilder name = new StringBuilder(); + else if (!isSingleQuoted && analyzer.Check('\\')) + { + int codeLength = 0; + + // Check the escape character. + + char escapeCharacter = analyzer.Peek(1); + switch (escapeCharacter) + { + case 'x': + codeLength = 2; + break; + + case 'u': + codeLength = 4; + break; + + case 'U': + codeLength = 8; + break; + + default: + char unescapedCharacter; + if (simpleEscapeCodes.TryGetValue(escapeCharacter, out unescapedCharacter)) + { + value.Append(unescapedCharacter); + } + else + { + throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a quoted scalar, find unknown escape character."); + } + break; + } + + Skip(); + Skip(); + + // Consume an arbitrary escape code. + + if (codeLength > 0) + { + uint character = 0; + + // Scan the character value. + + for (int k = 0; k < codeLength; ++k) + { + if (!analyzer.IsHex(k)) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a quoted scalar, did not find expected hexdecimal number."); + } + character = (uint)((character << 4) + analyzer.AsHex(k)); + } + + // Check the value and write the character. + + if ((character >= 0xD800 && character <= 0xDFFF) || character > 0x10FFFF) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a quoted scalar, find invalid Unicode character escape code."); + } + + value.Append((char)character); + + // Advance the pointer. + + for (int k = 0; k < codeLength; ++k) + { + Skip(); + } + } + } + else + { + // It is a non-escaped non-blank character. + + value.Append(ReadCurrentCharacter()); + } + } + + // Check if we are at the end of the scalar. + + if (analyzer.Check(isSingleQuoted ? '\'' : '"')) + break; + + // Consume blank characters. + + while (analyzer.IsWhite() || analyzer.IsBreak()) + { + if (analyzer.IsWhite()) + { + // Consume a space or a tab character. + + if (!hasLeadingBlanks) + { + whitespaces.Append(ReadCurrentCharacter()); + } + else + { + Skip(); + } + } + else + { + // Check if it is a first line break. + + if (!hasLeadingBlanks) + { + whitespaces.Length = 0; + leadingBreak.Append(ReadLine()); + hasLeadingBlanks = true; + } + else + { + trailingBreaks.Append(ReadLine()); + } + } + } + + // Join the whitespaces or fold line breaks. + + if (hasLeadingBlanks) + { + // Do we need to fold line breaks? + + if (StartsWith(leadingBreak, '\n')) + { + if (trailingBreaks.Length == 0) + { + value.Append(' '); + } + else + { + value.Append(trailingBreaks.ToString()); + } + } + else + { + value.Append(leadingBreak.ToString()); + value.Append(trailingBreaks.ToString()); + } + leadingBreak.Length = 0; + trailingBreaks.Length = 0; + } + else + { + value.Append(whitespaces.ToString()); + whitespaces.Length = 0; + } + } + + // Eat the right quote. + + Skip(); + + return new Scalar(value.ToString(), isSingleQuoted ? ScalarStyle.SingleQuoted : ScalarStyle.DoubleQuoted, start, cursor.Mark()); + } + + /// + /// Produce the SCALAR(...,plain) token. + /// + + private void FetchPlainScalar() + { + // A plain scalar could be a simple key. + + SaveSimpleKey(); + + // A simple key cannot follow a flow scalar. + + simpleKeyAllowed = false; + + // Create the SCALAR token and append it to the queue. + + tokens.Enqueue(ScanPlainScalar()); + } + + /// + /// Scan a plain scalar. + /// + + private Token ScanPlainScalar() + { + StringBuilder value = new StringBuilder(); + StringBuilder whitespaces = new StringBuilder(); + StringBuilder leadingBreak = new StringBuilder(); + StringBuilder trailingBreaks = new StringBuilder(); + + bool hasLeadingBlanks = false; + int currentIndent = indent + 1; + + Mark start = cursor.Mark(); + Mark end = start; + + // Consume the content of the plain scalar. + + for (; ;) + { + // Check for a document indicator. + + if (IsDocumentIndicator()) + { + break; + } + + // Check for a comment. + + if (analyzer.Check('#')) + { + break; + } + + // Consume non-blank characters. + while (!analyzer.IsWhiteBreakOrZero()) + { + // Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". + + if (flowLevel > 0 && analyzer.Check(':') && !analyzer.IsWhiteBreakOrZero(1)) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a plain scalar, find unexpected ':'."); + } + + // Check for indicators that may end a plain scalar. + + if ((analyzer.Check(':') && analyzer.IsWhiteBreakOrZero(1)) || (flowLevel > 0 && analyzer.Check(",:?[]{}"))) + { + break; + } + + // Check if we need to join whitespaces and breaks. + + if (hasLeadingBlanks || whitespaces.Length > 0) + { + if (hasLeadingBlanks) + { + // Do we need to fold line breaks? + + if (StartsWith(leadingBreak, '\n')) + { + if (trailingBreaks.Length == 0) + { + value.Append(' '); + } + else + { + value.Append(trailingBreaks); + } + } + else + { + value.Append(leadingBreak); + value.Append(trailingBreaks); + } + + leadingBreak.Length = 0; + trailingBreaks.Length = 0; + + hasLeadingBlanks = false; + } + else + { + value.Append(whitespaces); + whitespaces.Length = 0; + } + } + + // Copy the character. + + value.Append(ReadCurrentCharacter()); + + end = cursor.Mark(); + } + + // Is it the end? + + if (!(analyzer.IsWhite() || analyzer.IsBreak())) + { + break; + } + + // Consume blank characters. + + while (analyzer.IsWhite() || analyzer.IsBreak()) + { + if (analyzer.IsWhite()) + { + // Check for tab character that abuse intendation. + + if (hasLeadingBlanks && cursor.LineOffset < currentIndent && analyzer.IsTab()) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a plain scalar, find a tab character that violate intendation."); + } + + // Consume a space or a tab character. + + if (!hasLeadingBlanks) + { + whitespaces.Append(ReadCurrentCharacter()); + } + else + { + Skip(); + } + } + else + { + // Check if it is a first line break. + + if (!hasLeadingBlanks) + { + whitespaces.Length = 0; + leadingBreak.Append(ReadLine()); + hasLeadingBlanks = true; + } + else + { + trailingBreaks.Append(ReadLine()); + } + } + } + + // Check intendation level. + + if (flowLevel == 0 && cursor.LineOffset < currentIndent) + { + break; + } + } + + // Note that we change the 'simple_key_allowed' flag. + + if (hasLeadingBlanks) + { + simpleKeyAllowed = true; + } + + // Create a token. + + return new Scalar(value.ToString(), ScalarStyle.Plain, start, end); + } + + + /// + /// Remove a potential simple key at the current flow level. + /// + + private void RemoveSimpleKey() + { + SimpleKey key = simpleKeys.Peek(); + + if (key.IsPossible && key.IsRequired) + { + // If the key is required, it is an error. + + throw new SyntaxErrorException(key.Mark, key.Mark, "While scanning a simple key, could not find expected ':'."); + } + + // Remove the key from the stack. + + key.IsPossible = false; + } + + /// + /// Scan the directive name. + /// + /// Scope: + /// %YAML 1.1 # a comment \n + /// ^^^^ + /// %TAG !yaml! tag:yaml.org,2002: \n + /// ^^^ + /// + private string ScanDirectiveName(Mark start) + { + StringBuilder name = new StringBuilder(); - // Consume the directive name. - - while (analyzer.IsAlphaNumericDashOrUnderscore()) - { - name.Append(ReadCurrentCharacter()); - } + // Consume the directive name. + + while (analyzer.IsAlphaNumericDashOrUnderscore()) + { + name.Append(ReadCurrentCharacter()); + } - // Check if the name is empty. - - if (name.Length == 0) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a directive, could not find expected directive name."); - } - - // Check for an blank character after the name. - - if (!analyzer.IsWhiteBreakOrZero()) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a directive, find unexpected non-alphabetical character."); - } - - return name.ToString(); - } + // Check if the name is empty. + + if (name.Length == 0) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a directive, could not find expected directive name."); + } + + // Check for an blank character after the name. + + if (!analyzer.IsWhiteBreakOrZero()) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a directive, find unexpected non-alphabetical character."); + } + + return name.ToString(); + } - private void SkipWhitespaces() - { - // Eat whitespaces. + private void SkipWhitespaces() + { + // Eat whitespaces. - while (analyzer.IsWhite()) - { - Skip(); - } - } + while (analyzer.IsWhite()) + { + Skip(); + } + } - /// - /// Scan the value of VERSION-DIRECTIVE. - /// - /// Scope: - /// %YAML 1.1 # a comment \n - /// ^^^^^^ - /// - private Token ScanVersionDirectiveValue(Mark start) - { - SkipWhitespaces(); + /// + /// Scan the value of VERSION-DIRECTIVE. + /// + /// Scope: + /// %YAML 1.1 # a comment \n + /// ^^^^^^ + /// + private Token ScanVersionDirectiveValue(Mark start) + { + SkipWhitespaces(); - // Consume the major version number. + // Consume the major version number. - int major = ScanVersionDirectiveNumber(start); + int major = ScanVersionDirectiveNumber(start); - // Eat '.'. + // Eat '.'. - if (!analyzer.Check('.')) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a %YAML directive, did not find expected digit or '.' character."); - } + if (!analyzer.Check('.')) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a %YAML directive, did not find expected digit or '.' character."); + } - Skip(); + Skip(); - // Consume the minor version number. + // Consume the minor version number. - int minor = ScanVersionDirectiveNumber(start); + int minor = ScanVersionDirectiveNumber(start); - return new VersionDirective(new Version(major, minor), start, start); - } + return new VersionDirective(new Version(major, minor), start, start); + } - /// - /// Scan the value of a TAG-DIRECTIVE token. - /// - /// Scope: - /// %TAG !yaml! tag:yaml.org,2002: \n - /// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - /// - private Token ScanTagDirectiveValue(Mark start) - { - SkipWhitespaces(); + /// + /// Scan the value of a TAG-DIRECTIVE token. + /// + /// Scope: + /// %TAG !yaml! tag:yaml.org,2002: \n + /// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + /// + private Token ScanTagDirectiveValue(Mark start) + { + SkipWhitespaces(); - // Scan a handle. + // Scan a handle. - string handle = ScanTagHandle(true, start); + string handle = ScanTagHandle(true, start); - // Expect a whitespace. + // Expect a whitespace. - if (!analyzer.IsWhite()) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a %TAG directive, did not find expected whitespace."); - } + if (!analyzer.IsWhite()) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a %TAG directive, did not find expected whitespace."); + } - SkipWhitespaces(); + SkipWhitespaces(); - // Scan a prefix. + // Scan a prefix. - string prefix = ScanTagUri(null, start); + string prefix = ScanTagUri(null, start); - // Expect a whitespace or line break. + // Expect a whitespace or line break. - if (!analyzer.IsWhiteBreakOrZero()) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a %TAG directive, did not find expected whitespace or line break."); - } + if (!analyzer.IsWhiteBreakOrZero()) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a %TAG directive, did not find expected whitespace or line break."); + } - return new TagDirective(handle, prefix, start, start); - } + return new TagDirective(handle, prefix, start, start); + } - /// - /// Scan a tag. - /// + /// + /// Scan a tag. + /// - private string ScanTagUri(string head, Mark start) - { - StringBuilder tag = new StringBuilder(); - if (head != null && head.Length > 1) - { - tag.Append(head.Substring(1)); - } + private string ScanTagUri(string head, Mark start) + { + StringBuilder tag = new StringBuilder(); + if (head != null && head.Length > 1) + { + tag.Append(head.Substring(1)); + } - // Scan the tag. + // Scan the tag. - // The set of characters that may appear in URI is as follows: + // The set of characters that may appear in URI is as follows: - // '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&', - // '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']', - // '%'. + // '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&', + // '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']', + // '%'. - while (analyzer.IsAlphaNumericDashOrUnderscore() || analyzer.Check(";/?:@&=+$,.!~*'()[]%")) - { - // Check if it is a URI-escape sequence. + while (analyzer.IsAlphaNumericDashOrUnderscore() || analyzer.Check(";/?:@&=+$,.!~*'()[]%")) + { + // Check if it is a URI-escape sequence. - if (analyzer.Check('%')) - { - tag.Append(ScanUriEscapes(start)); - } - else - { - tag.Append(ReadCurrentCharacter()); - } - } + if (analyzer.Check('%')) + { + tag.Append(ScanUriEscapes(start)); + } + else + { + tag.Append(ReadCurrentCharacter()); + } + } - // Check if the tag is non-empty. + // Check if the tag is non-empty. - if (tag.Length == 0) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, did not find expected tag URI."); - } + if (tag.Length == 0) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, did not find expected tag URI."); + } - return tag.ToString(); - } + return tag.ToString(); + } - /// - /// Decode an URI-escape sequence corresponding to a single UTF-8 character. - /// + /// + /// Decode an URI-escape sequence corresponding to a single UTF-8 character. + /// - private char ScanUriEscapes(Mark start) - { - // Decode the required number of characters. + private char ScanUriEscapes(Mark start) + { + // Decode the required number of characters. - List charBytes = new List(); - int width = 0; - do - { - // Check for a URI-escaped octet. + List charBytes = new List(); + int width = 0; + do + { + // Check for a URI-escaped octet. - if (!(analyzer.Check('%') && analyzer.IsHex(1) && analyzer.IsHex(2))) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, did not find URI escaped octet."); - } + if (!(analyzer.Check('%') && analyzer.IsHex(1) && analyzer.IsHex(2))) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, did not find URI escaped octet."); + } - // Get the octet. + // Get the octet. - int octet = (analyzer.AsHex(1) << 4) + analyzer.AsHex(2); + int octet = (analyzer.AsHex(1) << 4) + analyzer.AsHex(2); - // If it is the leading octet, determine the length of the UTF-8 sequence. + // If it is the leading octet, determine the length of the UTF-8 sequence. - if (width == 0) - { - width = (octet & 0x80) == 0x00 ? 1 : - (octet & 0xE0) == 0xC0 ? 2 : - (octet & 0xF0) == 0xE0 ? 3 : - (octet & 0xF8) == 0xF0 ? 4 : 0; + if (width == 0) + { + width = (octet & 0x80) == 0x00 ? 1 : + (octet & 0xE0) == 0xC0 ? 2 : + (octet & 0xF0) == 0xE0 ? 3 : + (octet & 0xF8) == 0xF0 ? 4 : 0; - if (width == 0) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, find an incorrect leading UTF-8 octet."); - } - } - else - { - // Check if the trailing octet is correct. + if (width == 0) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, find an incorrect leading UTF-8 octet."); + } + } + else + { + // Check if the trailing octet is correct. - if ((octet & 0xC0) != 0x80) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, find an incorrect trailing UTF-8 octet."); - } - } + if ((octet & 0xC0) != 0x80) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, find an incorrect trailing UTF-8 octet."); + } + } - // Copy the octet and move the pointers. + // Copy the octet and move the pointers. - charBytes.Add((byte)octet); + charBytes.Add((byte)octet); - Skip(); - Skip(); - Skip(); - } - while (--width > 0); + Skip(); + Skip(); + Skip(); + } + while (--width > 0); - char[] characters = Encoding.UTF8.GetChars(charBytes.ToArray()); + char[] characters = Encoding.UTF8.GetChars(charBytes.ToArray()); - if (characters.Length != 1) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, find an incorrect UTF-8 sequence."); - } + if (characters.Length != 1) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag, find an incorrect UTF-8 sequence."); + } - return characters[0]; - } + return characters[0]; + } - /// - /// Scan a tag handle. - /// + /// + /// Scan a tag handle. + /// - private string ScanTagHandle(bool isDirective, Mark start) - { + private string ScanTagHandle(bool isDirective, Mark start) + { - // Check the initial '!' character. + // Check the initial '!' character. - if (!analyzer.Check('!')) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a tag, did not find expected '!'."); - } + if (!analyzer.Check('!')) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a tag, did not find expected '!'."); + } - // Copy the '!' character. + // Copy the '!' character. - StringBuilder tagHandle = new StringBuilder(); - tagHandle.Append(ReadCurrentCharacter()); + StringBuilder tagHandle = new StringBuilder(); + tagHandle.Append(ReadCurrentCharacter()); - // Copy all subsequent alphabetical and numerical characters. + // Copy all subsequent alphabetical and numerical characters. - while (analyzer.IsAlphaNumericDashOrUnderscore()) - { - tagHandle.Append(ReadCurrentCharacter()); - } + while (analyzer.IsAlphaNumericDashOrUnderscore()) + { + tagHandle.Append(ReadCurrentCharacter()); + } - // Check if the trailing character is '!' and copy it. + // Check if the trailing character is '!' and copy it. - if (analyzer.Check('!')) - { - tagHandle.Append(ReadCurrentCharacter()); - } - else - { + if (analyzer.Check('!')) + { + tagHandle.Append(ReadCurrentCharacter()); + } + else + { - // It's either the '!' tag or not really a tag handle. If it's a %TAG - // directive, it's an error. If it's a tag token, it must be a part of - // URI. + // It's either the '!' tag or not really a tag handle. If it's a %TAG + // directive, it's an error. If it's a tag token, it must be a part of + // URI. - if (isDirective && (tagHandle.Length != 1 || tagHandle[0] != '!')) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag directive, did not find expected '!'."); - } - } + if (isDirective && (tagHandle.Length != 1 || tagHandle[0] != '!')) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While parsing a tag directive, did not find expected '!'."); + } + } - return tagHandle.ToString(); - } + return tagHandle.ToString(); + } - /// - /// Scan the version number of VERSION-DIRECTIVE. - /// - /// Scope: - /// %YAML 1.1 # a comment \n - /// ^ - /// %YAML 1.1 # a comment \n - /// ^ - /// - private int ScanVersionDirectiveNumber(Mark start) - { - int value = 0; - int length = 0; + /// + /// Scan the version number of VERSION-DIRECTIVE. + /// + /// Scope: + /// %YAML 1.1 # a comment \n + /// ^ + /// %YAML 1.1 # a comment \n + /// ^ + /// + private int ScanVersionDirectiveNumber(Mark start) + { + int value = 0; + int length = 0; - // Repeat while the next character is digit. + // Repeat while the next character is digit. - while (analyzer.IsDigit()) - { - // Check if the number is too long. + while (analyzer.IsDigit()) + { + // Check if the number is too long. - if (++length > MaxVersionNumberLength) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a %YAML directive, find extremely long version number."); - } + if (++length > MaxVersionNumberLength) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a %YAML directive, find extremely long version number."); + } - value = value * 10 + analyzer.AsDigit(); + value = value * 10 + analyzer.AsDigit(); - Skip(); - } + Skip(); + } - // Check if the number was present. + // Check if the number was present. - if (length == 0) - { - throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a %YAML directive, did not find expected version number."); - } + if (length == 0) + { + throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a %YAML directive, did not find expected version number."); + } - return value; - } + return value; + } - /// - /// Check if a simple key may start at the current position and add it if - /// needed. - /// + /// + /// Check if a simple key may start at the current position and add it if + /// needed. + /// - private void SaveSimpleKey() - { + private void SaveSimpleKey() + { - // A simple key is required at the current position if the scanner is in - // the block context and the current column coincides with the indentation - // level. + // A simple key is required at the current position if the scanner is in + // the block context and the current column coincides with the indentation + // level. - bool isRequired = (flowLevel == 0 && indent == cursor.LineOffset); + bool isRequired = (flowLevel == 0 && indent == cursor.LineOffset); - // A simple key is required only when it is the first token in the current - // line. Therefore it is always allowed. But we add a check anyway. + // A simple key is required only when it is the first token in the current + // line. Therefore it is always allowed. But we add a check anyway. - Debug.Assert(simpleKeyAllowed || !isRequired, "Can't require a simple key and disallow it at the same time."); // Impossible. + Debug.Assert(simpleKeyAllowed || !isRequired, "Can't require a simple key and disallow it at the same time."); // Impossible. - // If the current position may start a simple key, save it. + // If the current position may start a simple key, save it. - if (simpleKeyAllowed) - { - var key = new SimpleKey(true, isRequired, tokensParsed + tokens.Count, cursor); + if (simpleKeyAllowed) + { + var key = new SimpleKey(true, isRequired, tokensParsed + tokens.Count, cursor); - RemoveSimpleKey(); + RemoveSimpleKey(); - simpleKeys.Pop(); - simpleKeys.Push(key); - } - } - } + simpleKeys.Pop(); + simpleKeys.Push(key); + } + } + } } diff --git a/YamlDotNet/Core/SemanticErrorException.cs b/YamlDotNet/Core/SemanticErrorException.cs index 8b5e1cccc..5098d33d0 100644 --- a/YamlDotNet/Core/SemanticErrorException.cs +++ b/YamlDotNet/Core/SemanticErrorException.cs @@ -24,58 +24,58 @@ namespace YamlDotNet.Core { - /// - /// Exception that is thrown when a semantic error is detected on a YAML stream. - /// - [Serializable] - public class SemanticErrorException : YamlException - { - /// - /// Initializes a new instance of the class. - /// - public SemanticErrorException() - { - } + /// + /// Exception that is thrown when a semantic error is detected on a YAML stream. + /// + [Serializable] + public class SemanticErrorException : YamlException + { + /// + /// Initializes a new instance of the class. + /// + public SemanticErrorException() + { + } - /// - /// Initializes a new instance of the class. - /// - /// The message. - public SemanticErrorException(string message) - : base(message) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The message. + public SemanticErrorException(string message) + : base(message) + { + } - /// - /// Initializes a new instance of the class. - /// - public SemanticErrorException(Mark start, Mark end, string message) - : base(start, end, message) - { - } + /// + /// Initializes a new instance of the class. + /// + public SemanticErrorException(Mark start, Mark end, string message) + : base(start, end, message) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The message. - /// The inner. - public SemanticErrorException(string message, Exception inner) - : base(message, inner) - { + /// + /// Initializes a new instance of the class. + /// + /// The message. + /// The inner. + public SemanticErrorException(string message, Exception inner) + : base(message, inner) + { } #if !(PORTABLE || UNITY) - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is null. - /// The class name is null or is zero (0). - protected SemanticErrorException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is null. + /// The class name is null or is zero (0). + protected SemanticErrorException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } #endif } } diff --git a/YamlDotNet/Core/SimpleKey.cs b/YamlDotNet/Core/SimpleKey.cs index 0da40b7c7..e1c0719f5 100644 --- a/YamlDotNet/Core/SimpleKey.cs +++ b/YamlDotNet/Core/SimpleKey.cs @@ -23,32 +23,32 @@ namespace YamlDotNet.Core { - [Serializable] - internal class SimpleKey - { - private readonly Cursor cursor; + [Serializable] + internal class SimpleKey + { + private readonly Cursor cursor; - public bool IsPossible { get; set; } + public bool IsPossible { get; set; } - public bool IsRequired { get; private set; } - public int TokenNumber { get; private set; } - public int Index { get { return cursor.Index; } } - public int Line { get { return cursor.Line; } } - public int LineOffset { get { return cursor.LineOffset; } } + public bool IsRequired { get; private set; } + public int TokenNumber { get; private set; } + public int Index { get { return cursor.Index; } } + public int Line { get { return cursor.Line; } } + public int LineOffset { get { return cursor.LineOffset; } } - public Mark Mark { get { return cursor.Mark(); } } + public Mark Mark { get { return cursor.Mark(); } } - public SimpleKey() - { - cursor = new Cursor(); - } + public SimpleKey() + { + cursor = new Cursor(); + } - public SimpleKey(bool isPossible, bool isRequired, int tokenNumber, Cursor cursor) - { - IsPossible = isPossible; - IsRequired = isRequired; - TokenNumber = tokenNumber; - this.cursor = new Cursor(cursor); - } - } + public SimpleKey(bool isPossible, bool isRequired, int tokenNumber, Cursor cursor) + { + IsPossible = isPossible; + IsRequired = isRequired; + TokenNumber = tokenNumber; + this.cursor = new Cursor(cursor); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/StringLookAheadBuffer.cs b/YamlDotNet/Core/StringLookAheadBuffer.cs index d8bd69acf..375c82ab8 100644 --- a/YamlDotNet/Core/StringLookAheadBuffer.cs +++ b/YamlDotNet/Core/StringLookAheadBuffer.cs @@ -23,50 +23,50 @@ namespace YamlDotNet.Core { - [Serializable] - internal class StringLookAheadBuffer : ILookAheadBuffer - { - private readonly string value; + [Serializable] + internal class StringLookAheadBuffer : ILookAheadBuffer + { + private readonly string value; - public int Position { get; private set; } + public int Position { get; private set; } - public StringLookAheadBuffer(string value) - { - this.value = value; - } + public StringLookAheadBuffer(string value) + { + this.value = value; + } - public int Length - { - get { - return value.Length; - } - } + public int Length + { + get { + return value.Length; + } + } - public bool EndOfInput - { - get { - return IsOutside(Position); - } - } + public bool EndOfInput + { + get { + return IsOutside(Position); + } + } - public char Peek(int offset) - { - var index = Position + offset; - return IsOutside(index) ? '\0' : value[index]; - } + public char Peek(int offset) + { + var index = Position + offset; + return IsOutside(index) ? '\0' : value[index]; + } - private bool IsOutside(int index) - { - return index >= value.Length; - } + private bool IsOutside(int index) + { + return index >= value.Length; + } - public void Skip(int length) - { - if (length < 0) - { - throw new ArgumentOutOfRangeException("length", "The length must be positive."); - } - Position += length; - } - } + public void Skip(int length) + { + if (length < 0) + { + throw new ArgumentOutOfRangeException("length", "The length must be positive."); + } + Position += length; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/SyntaxErrorException.cs b/YamlDotNet/Core/SyntaxErrorException.cs index a2b87a947..af17c96e3 100644 --- a/YamlDotNet/Core/SyntaxErrorException.cs +++ b/YamlDotNet/Core/SyntaxErrorException.cs @@ -24,58 +24,58 @@ namespace YamlDotNet.Core { - /// - /// Exception that is thrown when a syntax error is detected on a YAML stream. - /// - [Serializable] - public class SyntaxErrorException : YamlException - { - /// - /// Initializes a new instance of the class. - /// - public SyntaxErrorException() - { - } + /// + /// Exception that is thrown when a syntax error is detected on a YAML stream. + /// + [Serializable] + public class SyntaxErrorException : YamlException + { + /// + /// Initializes a new instance of the class. + /// + public SyntaxErrorException() + { + } - /// - /// Initializes a new instance of the class. - /// - /// The message. - public SyntaxErrorException(string message) - : base(message) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The message. + public SyntaxErrorException(string message) + : base(message) + { + } - /// - /// Initializes a new instance of the class. - /// - public SyntaxErrorException(Mark start, Mark end, string message) - : base(start, end, message) - { - } + /// + /// Initializes a new instance of the class. + /// + public SyntaxErrorException(Mark start, Mark end, string message) + : base(start, end, message) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The message. - /// The inner. - public SyntaxErrorException(string message, Exception inner) - : base(message, inner) - { + /// + /// Initializes a new instance of the class. + /// + /// The message. + /// The inner. + public SyntaxErrorException(string message, Exception inner) + : base(message, inner) + { } #if !(PORTABLE || UNITY) - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is null. - /// The class name is null or is zero (0). - protected SyntaxErrorException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is null. + /// The class name is null or is zero (0). + protected SyntaxErrorException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } #endif } } diff --git a/YamlDotNet/Core/TagDirectiveCollection.cs b/YamlDotNet/Core/TagDirectiveCollection.cs index ed448b5a6..3908bc016 100644 --- a/YamlDotNet/Core/TagDirectiveCollection.cs +++ b/YamlDotNet/Core/TagDirectiveCollection.cs @@ -25,42 +25,42 @@ namespace YamlDotNet.Core { - /// - /// Collection of . - /// - public class TagDirectiveCollection : KeyedCollection - { - /// - /// Initializes a new instance of the class. - /// - public TagDirectiveCollection() - { - } + /// + /// Collection of . + /// + public class TagDirectiveCollection : KeyedCollection + { + /// + /// Initializes a new instance of the class. + /// + public TagDirectiveCollection() + { + } - /// - /// Initializes a new instance of the class. - /// - /// Initial content of the collection. - public TagDirectiveCollection(IEnumerable tagDirectives) - { - foreach (var tagDirective in tagDirectives) - { - Add(tagDirective); - } - } + /// + /// Initializes a new instance of the class. + /// + /// Initial content of the collection. + public TagDirectiveCollection(IEnumerable tagDirectives) + { + foreach (var tagDirective in tagDirectives) + { + Add(tagDirective); + } + } - /// - protected override string GetKeyForItem(TagDirective item) - { - return item.Handle; - } - - /// - /// Gets a value indicating whether the collection contains a directive with the same handle - /// - public new bool Contains(TagDirective directive) - { - return Contains(GetKeyForItem(directive)); - } - } + /// + protected override string GetKeyForItem(TagDirective item) + { + return item.Handle; + } + + /// + /// Gets a value indicating whether the collection contains a directive with the same handle + /// + public new bool Contains(TagDirective directive) + { + return Contains(GetKeyForItem(directive)); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/Anchor.cs b/YamlDotNet/Core/Tokens/Anchor.cs index 4dddf1019..ee202cb92 100644 --- a/YamlDotNet/Core/Tokens/Anchor.cs +++ b/YamlDotNet/Core/Tokens/Anchor.cs @@ -23,45 +23,45 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents an anchor token. - /// - [Serializable] - public class Anchor : Token - { - private readonly string value; + /// + /// Represents an anchor token. + /// + [Serializable] + public class Anchor : Token + { + private readonly string value; - /// - /// Gets the value. - /// - /// The value. - public string Value - { - get - { - return value; - } - } + /// + /// Gets the value. + /// + /// The value. + public string Value + { + get + { + return value; + } + } - /// - /// Initializes a new instance of the class. - /// - /// The value. - public Anchor(string value) - : this(value, Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The value. + public Anchor(string value) + : this(value, Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The value. - /// The start position of the token. - /// The end position of the token. - public Anchor(string value, Mark start, Mark end) - : base(start, end) - { - this.value = value; - } - } + /// + /// Initializes a new instance of the class. + /// + /// The value. + /// The start position of the token. + /// The end position of the token. + public Anchor(string value, Mark start, Mark end) + : base(start, end) + { + this.value = value; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/AnchorAlias.cs b/YamlDotNet/Core/Tokens/AnchorAlias.cs index 260d4e181..6ab5559ba 100644 --- a/YamlDotNet/Core/Tokens/AnchorAlias.cs +++ b/YamlDotNet/Core/Tokens/AnchorAlias.cs @@ -23,44 +23,44 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents an alias token. - /// - [Serializable] - public class AnchorAlias : Token - { - private readonly string value; + /// + /// Represents an alias token. + /// + [Serializable] + public class AnchorAlias : Token + { + private readonly string value; - /// - /// Gets the value of the alias. - /// - public string Value - { - get - { - return 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. + 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; - } - } + /// + /// 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/Tokens/BlockEnd.cs b/YamlDotNet/Core/Tokens/BlockEnd.cs index 76c823e2c..0f963c3ac 100644 --- a/YamlDotNet/Core/Tokens/BlockEnd.cs +++ b/YamlDotNet/Core/Tokens/BlockEnd.cs @@ -24,28 +24,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a block end token. - /// - [Serializable] - public class BlockEnd : Token - { - /// - /// Initializes a new instance of the class. - /// - public BlockEnd() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a block end token. + /// + [Serializable] + public class BlockEnd : Token + { + /// + /// Initializes a new instance of the class. + /// + public BlockEnd() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public BlockEnd(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public BlockEnd(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/BlockEntry.cs b/YamlDotNet/Core/Tokens/BlockEntry.cs index 8be8f756d..9d86a5c7d 100644 --- a/YamlDotNet/Core/Tokens/BlockEntry.cs +++ b/YamlDotNet/Core/Tokens/BlockEntry.cs @@ -24,28 +24,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a block entry event. - /// - [Serializable] - public class BlockEntry : Token - { - /// - /// Initializes a new instance of the class. - /// - public BlockEntry() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a block entry event. + /// + [Serializable] + public class BlockEntry : Token + { + /// + /// Initializes a new instance of the class. + /// + public BlockEntry() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public BlockEntry(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public BlockEntry(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/BlockMappingStart.cs b/YamlDotNet/Core/Tokens/BlockMappingStart.cs index 651232416..46cc8ed11 100644 --- a/YamlDotNet/Core/Tokens/BlockMappingStart.cs +++ b/YamlDotNet/Core/Tokens/BlockMappingStart.cs @@ -24,28 +24,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a block mapping start token. - /// - [Serializable] - public class BlockMappingStart : Token - { - /// - /// Initializes a new instance of the class. - /// - public BlockMappingStart() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a block mapping start token. + /// + [Serializable] + public class BlockMappingStart : Token + { + /// + /// Initializes a new instance of the class. + /// + public BlockMappingStart() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public BlockMappingStart(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public BlockMappingStart(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/BlockSequenceStart.cs b/YamlDotNet/Core/Tokens/BlockSequenceStart.cs index bb4febdad..5035d0840 100644 --- a/YamlDotNet/Core/Tokens/BlockSequenceStart.cs +++ b/YamlDotNet/Core/Tokens/BlockSequenceStart.cs @@ -24,28 +24,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a block sequence start token. - /// - [Serializable] - public class BlockSequenceStart : Token - { - /// - /// Initializes a new instance of the class. - /// - public BlockSequenceStart() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a block sequence start token. + /// + [Serializable] + public class BlockSequenceStart : Token + { + /// + /// Initializes a new instance of the class. + /// + public BlockSequenceStart() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public BlockSequenceStart(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public BlockSequenceStart(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/Comment.cs b/YamlDotNet/Core/Tokens/Comment.cs index 4ba9d3d6c..34d15f89c 100644 --- a/YamlDotNet/Core/Tokens/Comment.cs +++ b/YamlDotNet/Core/Tokens/Comment.cs @@ -23,38 +23,38 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a comment - /// - [Serializable] - public class Comment : Token - { - /// - /// Gets the value of the comment - /// - public string Value { get; private set; } - - /// - /// Gets a value indicating whether the comment appears other tokens on that line. - /// - public bool IsInline { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - public Comment(string value, bool isInline) - : this(value, isInline, Mark.Empty, Mark.Empty) - { - } - - /// - /// Initializes a new instance of the class. - /// - public Comment(string value, bool isInline, Mark start, Mark end) - : base(start, end) - { - IsInline = isInline; - Value = value; - } - } + /// + /// Represents a comment + /// + [Serializable] + public class Comment : Token + { + /// + /// Gets the value of the comment + /// + public string Value { get; private set; } + + /// + /// Gets a value indicating whether the comment appears other tokens on that line. + /// + public bool IsInline { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + public Comment(string value, bool isInline) + : this(value, isInline, Mark.Empty, Mark.Empty) + { + } + + /// + /// Initializes a new instance of the class. + /// + public Comment(string value, bool isInline, Mark start, Mark end) + : base(start, end) + { + IsInline = isInline; + Value = value; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/DocumentEnd.cs b/YamlDotNet/Core/Tokens/DocumentEnd.cs index 06c74964b..851c2381d 100644 --- a/YamlDotNet/Core/Tokens/DocumentEnd.cs +++ b/YamlDotNet/Core/Tokens/DocumentEnd.cs @@ -24,28 +24,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a document end token. - /// - [Serializable] - public class DocumentEnd : Token - { - /// - /// Initializes a new instance of the class. - /// - public DocumentEnd() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a document end token. + /// + [Serializable] + public class DocumentEnd : Token + { + /// + /// Initializes a new instance of the class. + /// + public DocumentEnd() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public DocumentEnd(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public DocumentEnd(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/DocumentStart.cs b/YamlDotNet/Core/Tokens/DocumentStart.cs index 12071d13c..b326e2fd9 100644 --- a/YamlDotNet/Core/Tokens/DocumentStart.cs +++ b/YamlDotNet/Core/Tokens/DocumentStart.cs @@ -24,28 +24,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a document start token. - /// - [Serializable] - public class DocumentStart : Token - { - /// - /// Initializes a new instance of the class. - /// - public DocumentStart() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a document start token. + /// + [Serializable] + public class DocumentStart : Token + { + /// + /// Initializes a new instance of the class. + /// + public DocumentStart() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public DocumentStart(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public DocumentStart(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/FlowEntry.cs b/YamlDotNet/Core/Tokens/FlowEntry.cs index 250277f32..495f11688 100644 --- a/YamlDotNet/Core/Tokens/FlowEntry.cs +++ b/YamlDotNet/Core/Tokens/FlowEntry.cs @@ -24,28 +24,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a flow entry event. - /// - [Serializable] - public class FlowEntry : Token - { - /// - /// Initializes a new instance of the class. - /// - public FlowEntry() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a flow entry event. + /// + [Serializable] + public class FlowEntry : Token + { + /// + /// Initializes a new instance of the class. + /// + public FlowEntry() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public FlowEntry(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public FlowEntry(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/FlowMappingEnd.cs b/YamlDotNet/Core/Tokens/FlowMappingEnd.cs index 698d89fef..6048ec64e 100644 --- a/YamlDotNet/Core/Tokens/FlowMappingEnd.cs +++ b/YamlDotNet/Core/Tokens/FlowMappingEnd.cs @@ -24,28 +24,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a flow mapping end token. - /// - [Serializable] - public class FlowMappingEnd : Token - { - /// - /// Initializes a new instance of the class. - /// - public FlowMappingEnd() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a flow mapping end token. + /// + [Serializable] + public class FlowMappingEnd : Token + { + /// + /// Initializes a new instance of the class. + /// + public FlowMappingEnd() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public FlowMappingEnd(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public FlowMappingEnd(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/FlowMappingStart.cs b/YamlDotNet/Core/Tokens/FlowMappingStart.cs index 4668f01c9..6457fd985 100644 --- a/YamlDotNet/Core/Tokens/FlowMappingStart.cs +++ b/YamlDotNet/Core/Tokens/FlowMappingStart.cs @@ -24,28 +24,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a flow mapping start token. - /// - [Serializable] - public class FlowMappingStart : Token - { - /// - /// Initializes a new instance of the class. - /// - public FlowMappingStart() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a flow mapping start token. + /// + [Serializable] + public class FlowMappingStart : Token + { + /// + /// Initializes a new instance of the class. + /// + public FlowMappingStart() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public FlowMappingStart(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public FlowMappingStart(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/FlowSequenceEnd.cs b/YamlDotNet/Core/Tokens/FlowSequenceEnd.cs index 0c9917b10..d97067bd4 100644 --- a/YamlDotNet/Core/Tokens/FlowSequenceEnd.cs +++ b/YamlDotNet/Core/Tokens/FlowSequenceEnd.cs @@ -24,28 +24,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a flow sequence end token. - /// - [Serializable] - public class FlowSequenceEnd : Token - { - /// - /// Initializes a new instance of the class. - /// - public FlowSequenceEnd() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a flow sequence end token. + /// + [Serializable] + public class FlowSequenceEnd : Token + { + /// + /// Initializes a new instance of the class. + /// + public FlowSequenceEnd() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public FlowSequenceEnd(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public FlowSequenceEnd(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/FlowSequenceStart.cs b/YamlDotNet/Core/Tokens/FlowSequenceStart.cs index 36580dd5e..833f77c9b 100644 --- a/YamlDotNet/Core/Tokens/FlowSequenceStart.cs +++ b/YamlDotNet/Core/Tokens/FlowSequenceStart.cs @@ -24,28 +24,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a flow sequence start token. - /// - [Serializable] - public class FlowSequenceStart : Token - { - /// - /// Initializes a new instance of the class. - /// - public FlowSequenceStart() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a flow sequence start token. + /// + [Serializable] + public class FlowSequenceStart : Token + { + /// + /// Initializes a new instance of the class. + /// + public FlowSequenceStart() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public FlowSequenceStart(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public FlowSequenceStart(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/Key.cs b/YamlDotNet/Core/Tokens/Key.cs index 402d01412..6bb597daf 100644 --- a/YamlDotNet/Core/Tokens/Key.cs +++ b/YamlDotNet/Core/Tokens/Key.cs @@ -24,28 +24,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a key token. - /// - [Serializable] - public class Key : Token - { - /// - /// Initializes a new instance of the class. - /// - public Key() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a key token. + /// + [Serializable] + public class Key : Token + { + /// + /// Initializes a new instance of the class. + /// + public Key() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public Key(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public Key(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/Scalar.cs b/YamlDotNet/Core/Tokens/Scalar.cs index defaeea26..cedda5655 100644 --- a/YamlDotNet/Core/Tokens/Scalar.cs +++ b/YamlDotNet/Core/Tokens/Scalar.cs @@ -24,71 +24,71 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a scalar token. - /// - [Serializable] - public class Scalar : Token - { - private readonly string value; + /// + /// Represents a scalar token. + /// + [Serializable] + public class Scalar : Token + { + private readonly string value; - /// - /// Gets the value. - /// - /// The value. - public string Value - { - get - { - return value; - } - } + /// + /// Gets the value. + /// + /// The value. + public string Value + { + get + { + return value; + } + } - private readonly ScalarStyle style; + private readonly ScalarStyle style; - /// - /// Gets the style. - /// - /// The style. - public ScalarStyle Style - { - get - { - return style; - } - } + /// + /// Gets the style. + /// + /// The style. + public ScalarStyle Style + { + get + { + return style; + } + } - /// - /// Initializes a new instance of the class. - /// - /// The value. - public Scalar(string value) - : this(value, ScalarStyle.Any) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The value. + public Scalar(string value) + : this(value, ScalarStyle.Any) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The value. - /// The style. - public Scalar(string value, ScalarStyle style) - : this(value, style, Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The value. + /// The style. + public Scalar(string value, ScalarStyle style) + : this(value, style, Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The value. - /// The style. - /// The start position of the token. - /// The end position of the token. - public Scalar(string value, ScalarStyle style, Mark start, Mark end) - : base(start, end) - { - this.value = value; - this.style = style; - } - } + /// + /// Initializes a new instance of the class. + /// + /// The value. + /// The style. + /// The start position of the token. + /// The end position of the token. + public Scalar(string value, ScalarStyle style, Mark start, Mark end) + : base(start, end) + { + this.value = value; + this.style = style; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/StreamEnd.cs b/YamlDotNet/Core/Tokens/StreamEnd.cs index 8db43d3b8..5fd03c96b 100644 --- a/YamlDotNet/Core/Tokens/StreamEnd.cs +++ b/YamlDotNet/Core/Tokens/StreamEnd.cs @@ -24,28 +24,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a stream end event. - /// - [Serializable] - public class StreamEnd : Token - { - /// - /// Initializes a new instance of the class. - /// - public StreamEnd() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a stream end event. + /// + [Serializable] + public class StreamEnd : Token + { + /// + /// Initializes a new instance of the class. + /// + public StreamEnd() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public StreamEnd(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public StreamEnd(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/StreamStart.cs b/YamlDotNet/Core/Tokens/StreamStart.cs index c6d21d756..3bf4c8257 100644 --- a/YamlDotNet/Core/Tokens/StreamStart.cs +++ b/YamlDotNet/Core/Tokens/StreamStart.cs @@ -23,28 +23,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a stream start token. - /// - [Serializable] - public class StreamStart : Token - { - /// - /// Initializes a new instance of the class. - /// - public StreamStart() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a stream start token. + /// + [Serializable] + public class StreamStart : Token + { + /// + /// Initializes a new instance of the class. + /// + public StreamStart() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public StreamStart(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public StreamStart(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/Tag.cs b/YamlDotNet/Core/Tokens/Tag.cs index 79b711ead..69b23fd97 100644 --- a/YamlDotNet/Core/Tokens/Tag.cs +++ b/YamlDotNet/Core/Tokens/Tag.cs @@ -23,61 +23,61 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a tag token. - /// - [Serializable] - public class Tag : Token - { - private readonly string handle; - private readonly string suffix; + /// + /// Represents a tag token. + /// + [Serializable] + public class Tag : Token + { + private readonly string handle; + private readonly string suffix; - /// - /// Gets the handle. - /// - /// The handle. - public string Handle - { - get - { - return handle; - } - } + /// + /// Gets the handle. + /// + /// The handle. + public string Handle + { + get + { + return handle; + } + } - /// - /// Gets the suffix. - /// - /// The suffix. - public string Suffix - { - get - { - return suffix; - } - } + /// + /// Gets the suffix. + /// + /// The suffix. + public string Suffix + { + get + { + return suffix; + } + } - /// - /// Initializes a new instance of the class. - /// - /// The handle. - /// The suffix. - public Tag(string handle, string suffix) - : this(handle, suffix, Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The handle. + /// The suffix. + public Tag(string handle, string suffix) + : this(handle, suffix, Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The handle. - /// The suffix. - /// The start position of the token. - /// The end position of the token. - public Tag(string handle, string suffix, Mark start, Mark end) - : base(start, end) - { - this.handle = handle; - this.suffix = suffix; - } - } + /// + /// Initializes a new instance of the class. + /// + /// The handle. + /// The suffix. + /// The start position of the token. + /// The end position of the token. + public Tag(string handle, string suffix, Mark start, Mark end) + : base(start, end) + { + this.handle = handle; + this.suffix = suffix; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/TagDirective.cs b/YamlDotNet/Core/Tokens/TagDirective.cs index 97cf5c77c..1e143efc9 100644 --- a/YamlDotNet/Core/Tokens/TagDirective.cs +++ b/YamlDotNet/Core/Tokens/TagDirective.cs @@ -25,106 +25,106 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a tag directive token. - /// - [Serializable] - public class TagDirective : Token - { - private readonly string handle; - private readonly string prefix; + /// + /// Represents a tag directive token. + /// + [Serializable] + public class TagDirective : Token + { + private readonly string handle; + private readonly string prefix; - /// - /// Gets the handle. - /// - /// The handle. - public string Handle - { - get - { - return handle; - } - } + /// + /// Gets the handle. + /// + /// The handle. + public string Handle + { + get + { + return handle; + } + } - /// - /// Gets the prefix. - /// - /// The prefix. - public string Prefix - { - get - { - return prefix; - } - } + /// + /// Gets the prefix. + /// + /// The prefix. + public string Prefix + { + get + { + return prefix; + } + } - /// - /// Initializes a new instance of the class. - /// - /// The handle. - /// The prefix. - public TagDirective(string handle, string prefix) - : this(handle, prefix, Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The handle. + /// The prefix. + public TagDirective(string handle, string prefix) + : this(handle, prefix, Mark.Empty, Mark.Empty) + { + } - private static readonly Regex tagHandleValidator = new Regex(@"^!([0-9A-Za-z_\-]*!)?$", StandardRegexOptions.Compiled); - - /// - /// Initializes a new instance of the class. - /// - /// The handle. - /// The prefix. - /// The start position of the token. - /// The end position of the token. - public TagDirective(string handle, string prefix, Mark start, Mark end) - : base(start, end) - { - if(string.IsNullOrEmpty(handle)) { - throw new ArgumentNullException("handle", "Tag handle must not be empty."); - } - - if(!tagHandleValidator.IsMatch(handle)) { - throw new ArgumentException("Tag handle must start and end with '!' and contain alphanumerical characters only.", "handle"); - } - - this.handle = handle; + private static readonly Regex tagHandleValidator = new Regex(@"^!([0-9A-Za-z_\-]*!)?$", StandardRegexOptions.Compiled); + + /// + /// Initializes a new instance of the class. + /// + /// The handle. + /// The prefix. + /// The start position of the token. + /// The end position of the token. + public TagDirective(string handle, string prefix, Mark start, Mark end) + : base(start, end) + { + if(string.IsNullOrEmpty(handle)) { + throw new ArgumentNullException("handle", "Tag handle must not be empty."); + } + + if(!tagHandleValidator.IsMatch(handle)) { + throw new ArgumentException("Tag handle must start and end with '!' and contain alphanumerical characters only.", "handle"); + } + + this.handle = handle; - if(string.IsNullOrEmpty(prefix)) { - throw new ArgumentNullException("prefix", "Tag prefix must not be empty."); - } - - this.prefix = prefix; - } + if(string.IsNullOrEmpty(prefix)) { + throw new ArgumentNullException("prefix", "Tag prefix must not be empty."); + } + + this.prefix = prefix; + } - /// - /// Determines whether the specified System.Object is equal to the current System.Object. - /// - /// The System.Object to compare with the current System.Object. - /// - /// true if the specified System.Object is equal to the current System.Object; otherwise, false. - /// - public override bool Equals(object obj) - { - TagDirective other = obj as TagDirective; - return other != null && handle.Equals(other.handle) && prefix.Equals(other.prefix); - } + /// + /// Determines whether the specified System.Object is equal to the current System.Object. + /// + /// The System.Object to compare with the current System.Object. + /// + /// true if the specified System.Object is equal to the current System.Object; otherwise, false. + /// + public override bool Equals(object obj) + { + TagDirective other = obj as TagDirective; + return other != null && handle.Equals(other.handle) && prefix.Equals(other.prefix); + } - /// - /// Serves as a hash function for a particular type. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - return handle.GetHashCode() ^ prefix.GetHashCode(); - } + /// + /// Serves as a hash function for a particular type. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + return handle.GetHashCode() ^ prefix.GetHashCode(); + } - /// - public override string ToString() - { - return string.Format(CultureInfo.InvariantCulture, "{0} => {1}", handle, prefix); - } - } + /// + public override string ToString() + { + return string.Format(CultureInfo.InvariantCulture, "{0} => {1}", handle, prefix); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/Token.cs b/YamlDotNet/Core/Tokens/Token.cs index f5ed9339c..8a0a1b99c 100644 --- a/YamlDotNet/Core/Tokens/Token.cs +++ b/YamlDotNet/Core/Tokens/Token.cs @@ -23,47 +23,47 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Base class for YAML tokens. - /// - [Serializable] - public abstract class Token - { - private readonly Mark start; + /// + /// Base class for YAML tokens. + /// + [Serializable] + public abstract class Token + { + private readonly Mark start; - /// - /// Gets the start of the token in the input stream. - /// - public Mark Start - { - get - { - return start; - } - } + /// + /// Gets the start of the token in the input stream. + /// + public Mark Start + { + get + { + return start; + } + } - private readonly Mark end; + private readonly Mark end; - /// - /// Gets the end of the token in the input stream. - /// - public Mark End - { - get - { - return end; - } - } + /// + /// Gets the end of the token in the input stream. + /// + public Mark End + { + get + { + return end; + } + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - protected Token(Mark start, Mark end) - { - this.start = start; - this.end = end; - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + protected Token(Mark start, Mark end) + { + this.start = start; + this.end = end; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/Value.cs b/YamlDotNet/Core/Tokens/Value.cs index 63e551306..9ad526830 100644 --- a/YamlDotNet/Core/Tokens/Value.cs +++ b/YamlDotNet/Core/Tokens/Value.cs @@ -23,28 +23,28 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a value token. - /// - [Serializable] - public class Value : Token - { - /// - /// Initializes a new instance of the class. - /// - public Value() - : this(Mark.Empty, Mark.Empty) - { - } + /// + /// Represents a value token. + /// + [Serializable] + public class Value : Token + { + /// + /// Initializes a new instance of the class. + /// + public Value() + : this(Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The start position of the token. - /// The end position of the token. - public Value(Mark start, Mark end) - : base(start, end) - { - } - } + /// + /// Initializes a new instance of the class. + /// + /// The start position of the token. + /// The end position of the token. + public Value(Mark start, Mark end) + : base(start, end) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Tokens/VersionDirective.cs b/YamlDotNet/Core/Tokens/VersionDirective.cs index 6f80e07ae..800536695 100644 --- a/YamlDotNet/Core/Tokens/VersionDirective.cs +++ b/YamlDotNet/Core/Tokens/VersionDirective.cs @@ -23,69 +23,69 @@ namespace YamlDotNet.Core.Tokens { - /// - /// Represents a version directive token. - /// - [Serializable] - public class VersionDirective : Token - { - private readonly Version version; + /// + /// Represents a version directive token. + /// + [Serializable] + public class VersionDirective : Token + { + private readonly Version version; - /// - /// Gets the version. - /// - /// The version. - public Version Version - { - get - { - return version; - } - } + /// + /// Gets the version. + /// + /// The version. + public Version Version + { + get + { + return version; + } + } - /// - /// Initializes a new instance of the class. - /// - /// The version. - public VersionDirective(Version version) - : this(version, Mark.Empty, Mark.Empty) - { - } + /// + /// Initializes a new instance of the class. + /// + /// The version. + public VersionDirective(Version version) + : this(version, Mark.Empty, Mark.Empty) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The version. - /// The start position of the token. - /// The end position of the token. - public VersionDirective(Version version, Mark start, Mark end) - : base(start, end) - { - this.version = version; - } + /// + /// Initializes a new instance of the class. + /// + /// The version. + /// The start position of the token. + /// The end position of the token. + public VersionDirective(Version version, Mark start, Mark end) + : base(start, end) + { + this.version = version; + } - /// - /// Determines whether the specified System.Object is equal to the current System.Object. - /// - /// The System.Object to compare with the current System.Object. - /// - /// true if the specified System.Object is equal to the current System.Object; otherwise, false. - /// - public override bool Equals(object obj) - { - VersionDirective other = obj as VersionDirective; - return other != null && version.Equals(other.version); - } + /// + /// Determines whether the specified System.Object is equal to the current System.Object. + /// + /// The System.Object to compare with the current System.Object. + /// + /// true if the specified System.Object is equal to the current System.Object; otherwise, false. + /// + public override bool Equals(object obj) + { + VersionDirective other = obj as VersionDirective; + return other != null && version.Equals(other.version); + } - /// - /// Serves as a hash function for a particular type. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - return version.GetHashCode(); - } - } + /// + /// Serves as a hash function for a particular type. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + return version.GetHashCode(); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/Version.cs b/YamlDotNet/Core/Version.cs index 431a9be4b..5546432cb 100644 --- a/YamlDotNet/Core/Version.cs +++ b/YamlDotNet/Core/Version.cs @@ -23,55 +23,55 @@ namespace YamlDotNet.Core { - /// - /// Specifies the version of the YAML language. - /// - [Serializable] - public class Version - { - /// - /// Gets the major version number. - /// - public int Major { get; private set; } + /// + /// Specifies the version of the YAML language. + /// + [Serializable] + public class Version + { + /// + /// Gets the major version number. + /// + public int Major { get; private set; } - /// - /// Gets the minor version number. - /// - public int Minor { get; private set; } + /// + /// Gets the minor version number. + /// + public int Minor { get; private set; } - /// - /// Initializes a new instance of the class. - /// - /// The the major version number. - /// The the minor version number. - public Version(int major, int minor) - { - Major = major; - Minor = minor; - } + /// + /// Initializes a new instance of the class. + /// + /// The the major version number. + /// The the minor version number. + public Version(int major, int minor) + { + Major = major; + Minor = minor; + } - /// - /// Determines whether the specified System.Object is equal to the current System.Object. - /// - /// The System.Object to compare with the current System.Object. - /// - /// true if the specified System.Object is equal to the current System.Object; otherwise, false. - /// - public override bool Equals(object obj) - { - var that = obj as Version; - return that != null && Major == that.Major && Minor == that.Minor; - } + /// + /// Determines whether the specified System.Object is equal to the current System.Object. + /// + /// The System.Object to compare with the current System.Object. + /// + /// true if the specified System.Object is equal to the current System.Object; otherwise, false. + /// + public override bool Equals(object obj) + { + var that = obj as Version; + return that != null && Major == that.Major && Minor == that.Minor; + } - /// - /// Serves as a hash function for a particular type. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - return Major.GetHashCode() ^ Minor.GetHashCode(); - } - } + /// + /// Serves as a hash function for a particular type. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + return Major.GetHashCode() ^ Minor.GetHashCode(); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Core/YamlException.cs b/YamlDotNet/Core/YamlException.cs index 418c1416d..b441d4692 100644 --- a/YamlDotNet/Core/YamlException.cs +++ b/YamlDotNet/Core/YamlException.cs @@ -85,37 +85,37 @@ public YamlException(string message, Exception inner) } #if !(PORTABLE || UNITY) - /// - /// Initializes a new instance of the class. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is null. - /// The class name is null or is zero (0). - protected YamlException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - Start = (Mark)info.GetValue("Start", typeof(Mark)); - End = (Mark)info.GetValue("End", typeof(Mark)); - } + /// + /// Initializes a new instance of the class. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is null. + /// The class name is null or is zero (0). + protected YamlException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + Start = (Mark)info.GetValue("Start", typeof(Mark)); + End = (Mark)info.GetValue("End", typeof(Mark)); + } - /// - /// When overridden in a derived class, sets the with information about the exception. - /// - /// The that holds the serialized object data about the exception being thrown. - /// The that contains contextual information about the source or destination. - /// The parameter is a null reference (Nothing in Visual Basic). - /// - /// - /// - /// + /// + /// When overridden in a derived class, sets the with information about the exception. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + /// The parameter is a null reference (Nothing in Visual Basic). + /// + /// + /// + /// [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.LinkDemand, Flags = System.Security.Permissions.SecurityPermissionFlag.SerializationFormatter)] - public override void GetObjectData(SerializationInfo info, StreamingContext context) - { - base.GetObjectData(info, context); - info.AddValue("Start", Start); - info.AddValue("End", End); - } + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + base.GetObjectData(info, context); + info.AddValue("Start", Start); + info.AddValue("End", End); + } #endif } } diff --git a/YamlDotNet/Helpers/Portability.cs b/YamlDotNet/Helpers/Portability.cs index d473ab0b8..918b3a872 100644 --- a/YamlDotNet/Helpers/Portability.cs +++ b/YamlDotNet/Helpers/Portability.cs @@ -29,21 +29,21 @@ namespace YamlDotNet { #if (PORTABLE || UNITY) - internal static class StandardRegexOptions - { - public const RegexOptions Compiled = RegexOptions.None; - } + internal static class StandardRegexOptions + { + public const RegexOptions Compiled = RegexOptions.None; + } #else - internal static class StandardRegexOptions - { - public const RegexOptions Compiled = RegexOptions.Compiled; - } + internal static class StandardRegexOptions + { + public const RegexOptions Compiled = RegexOptions.Compiled; + } #endif #if PORTABLE - /// - /// Mock UTF7Encoding to avoid having to add #if all over the place - /// + /// + /// Mock UTF7Encoding to avoid having to add #if all over the place + /// internal sealed class UTF7Encoding : System.Text.Encoding { public override int GetByteCount(char[] chars, int index, int count) @@ -77,227 +77,227 @@ public override int GetMaxCharCount(int byteCount) } } - /// - /// Mock SerializableAttribute to avoid having to add #if all over the place - /// - [AttributeUsage(AttributeTargets.Class)] - internal sealed class SerializableAttribute : Attribute { } - - internal static class ReflectionExtensions - { - public static bool IsValueType(this Type type) - { - return type.GetTypeInfo().IsValueType; - } - - public static bool IsGenericType(this Type type) - { - return type.GetTypeInfo().IsGenericType; - } - - public static bool IsInterface(this Type type) - { - return type.GetTypeInfo().IsInterface; - } - - public static bool IsEnum(this Type type) - { - return type.GetTypeInfo().IsEnum; - } - - /// - /// Determines whether the specified type has a default constructor. - /// - /// The type. - /// - /// true if the type has a default constructor; otherwise, false. - /// - public static bool HasDefaultConstructor(this Type type) - { - var typeInfo = type.GetTypeInfo(); - return typeInfo.IsValueType || typeInfo.DeclaredConstructors - .Any(c => c.IsPublic && !c.IsStatic && c.GetParameters().Length == 0); - } - - public static bool IsAssignableFrom(this Type type, Type source) - { - return type.IsAssignableFrom(source.GetTypeInfo()); - } - - public static bool IsAssignableFrom(this Type type, TypeInfo source) - { - return type.GetTypeInfo().IsAssignableFrom(source); - } - - public static TypeCode GetTypeCode(this Type type) - { - bool isEnum = type.IsEnum(); - if (isEnum) - { - type = Enum.GetUnderlyingType(type); - } - - if (type == typeof(bool)) - { - return TypeCode.Boolean; - } - else if (type == typeof(char)) - { - return TypeCode.Char; - } - else if (type == typeof(sbyte)) - { - return TypeCode.SByte; - } - else if (type == typeof(byte)) - { - return TypeCode.Byte; - } - else if (type == typeof(short)) - { - return TypeCode.Int16; - } - else if (type == typeof(ushort)) - { - return TypeCode.UInt16; - } - else if (type == typeof(int)) - { - return TypeCode.Int32; - } - else if (type == typeof(uint)) - { - return TypeCode.UInt32; - } - else if (type == typeof(long)) - { - return TypeCode.Int64; - } - else if (type == typeof(ulong)) - { - return TypeCode.UInt64; - } - else if (type == typeof(float)) - { - return TypeCode.Single; - } - else if (type == typeof(double)) - { - return TypeCode.Double; - } - else if (type == typeof(decimal)) - { - return TypeCode.Decimal; - } - else if (type == typeof(DateTime)) - { - return TypeCode.DateTime; - } - else if (type == typeof(String)) - { - return TypeCode.String; - } - else - { - return TypeCode.Object; - } - } - - public static Type[] GetGenericArguments(this Type type) - { - return type.GetTypeInfo().GenericTypeArguments; - } - - public static IEnumerable GetPublicProperties(this Type type) - { - var instancePublic = new Func( - p => !p.GetMethod.IsStatic && p.GetMethod.IsPublic); - return type.IsInterface() - ? (new Type[] { type }) - .Concat(type.GetInterfaces()) - .SelectMany(i => i.GetRuntimeProperties().Where(instancePublic)) - : type.GetRuntimeProperties().Where(instancePublic); - } - - public static IEnumerable GetPublicStaticMethods(this Type type) - { - return type.GetRuntimeMethods() - .Where(m => m.IsPublic && m.IsStatic); - } - - public static MethodInfo GetPublicStaticMethod(this Type type, string name, params Type[] parameterTypes) - { - return type.GetRuntimeMethods() - .FirstOrDefault(m => - { - if (m.IsPublic && m.IsStatic && m.Name.Equals(name)) - { - var parameters = m.GetParameters(); - return parameters.Length == parameterTypes.Length - && parameters.Zip(parameterTypes, (pi, pt) => pi.Equals(pt)).All(r => r); - } - return false; - }); - } - - public static MethodInfo GetGetMethod(this PropertyInfo property) - { - return property.GetMethod; - } - - public static IEnumerable GetInterfaces(this Type type) - { - return type.GetTypeInfo().ImplementedInterfaces; - } - - public static Exception Unwrap(this TargetInvocationException ex) - { - return ex.InnerException; - } - } - - internal enum TypeCode - { - Empty = 0, - Object = 1, - DBNull = 2, - Boolean = 3, - Char = 4, - SByte = 5, - Byte = 6, - Int16 = 7, - UInt16 = 8, - Int32 = 9, - UInt32 = 10, - Int64 = 11, - UInt64 = 12, - Single = 13, - Double = 14, - Decimal = 15, - DateTime = 16, - String = 18, - } - - internal abstract class DBNull - { - private DBNull() {} - } - - internal sealed class CultureInfoAdapter : CultureInfo - { - private readonly IFormatProvider _provider; - - public CultureInfoAdapter(CultureInfo baseCulture, IFormatProvider provider) - : base(baseCulture.Name) - { - _provider = provider; - } - - public override object GetFormat(Type formatType) - { - return _provider.GetFormat(formatType); - } - } + /// + /// Mock SerializableAttribute to avoid having to add #if all over the place + /// + [AttributeUsage(AttributeTargets.Class)] + internal sealed class SerializableAttribute : Attribute { } + + internal static class ReflectionExtensions + { + public static bool IsValueType(this Type type) + { + return type.GetTypeInfo().IsValueType; + } + + public static bool IsGenericType(this Type type) + { + return type.GetTypeInfo().IsGenericType; + } + + public static bool IsInterface(this Type type) + { + return type.GetTypeInfo().IsInterface; + } + + public static bool IsEnum(this Type type) + { + return type.GetTypeInfo().IsEnum; + } + + /// + /// Determines whether the specified type has a default constructor. + /// + /// The type. + /// + /// true if the type has a default constructor; otherwise, false. + /// + public static bool HasDefaultConstructor(this Type type) + { + var typeInfo = type.GetTypeInfo(); + return typeInfo.IsValueType || typeInfo.DeclaredConstructors + .Any(c => c.IsPublic && !c.IsStatic && c.GetParameters().Length == 0); + } + + public static bool IsAssignableFrom(this Type type, Type source) + { + return type.IsAssignableFrom(source.GetTypeInfo()); + } + + public static bool IsAssignableFrom(this Type type, TypeInfo source) + { + return type.GetTypeInfo().IsAssignableFrom(source); + } + + public static TypeCode GetTypeCode(this Type type) + { + bool isEnum = type.IsEnum(); + if (isEnum) + { + type = Enum.GetUnderlyingType(type); + } + + if (type == typeof(bool)) + { + return TypeCode.Boolean; + } + else if (type == typeof(char)) + { + return TypeCode.Char; + } + else if (type == typeof(sbyte)) + { + return TypeCode.SByte; + } + else if (type == typeof(byte)) + { + return TypeCode.Byte; + } + else if (type == typeof(short)) + { + return TypeCode.Int16; + } + else if (type == typeof(ushort)) + { + return TypeCode.UInt16; + } + else if (type == typeof(int)) + { + return TypeCode.Int32; + } + else if (type == typeof(uint)) + { + return TypeCode.UInt32; + } + else if (type == typeof(long)) + { + return TypeCode.Int64; + } + else if (type == typeof(ulong)) + { + return TypeCode.UInt64; + } + else if (type == typeof(float)) + { + return TypeCode.Single; + } + else if (type == typeof(double)) + { + return TypeCode.Double; + } + else if (type == typeof(decimal)) + { + return TypeCode.Decimal; + } + else if (type == typeof(DateTime)) + { + return TypeCode.DateTime; + } + else if (type == typeof(String)) + { + return TypeCode.String; + } + else + { + return TypeCode.Object; + } + } + + public static Type[] GetGenericArguments(this Type type) + { + return type.GetTypeInfo().GenericTypeArguments; + } + + public static IEnumerable GetPublicProperties(this Type type) + { + var instancePublic = new Func( + p => !p.GetMethod.IsStatic && p.GetMethod.IsPublic); + return type.IsInterface() + ? (new Type[] { type }) + .Concat(type.GetInterfaces()) + .SelectMany(i => i.GetRuntimeProperties().Where(instancePublic)) + : type.GetRuntimeProperties().Where(instancePublic); + } + + public static IEnumerable GetPublicStaticMethods(this Type type) + { + return type.GetRuntimeMethods() + .Where(m => m.IsPublic && m.IsStatic); + } + + public static MethodInfo GetPublicStaticMethod(this Type type, string name, params Type[] parameterTypes) + { + return type.GetRuntimeMethods() + .FirstOrDefault(m => + { + if (m.IsPublic && m.IsStatic && m.Name.Equals(name)) + { + var parameters = m.GetParameters(); + return parameters.Length == parameterTypes.Length + && parameters.Zip(parameterTypes, (pi, pt) => pi.Equals(pt)).All(r => r); + } + return false; + }); + } + + public static MethodInfo GetGetMethod(this PropertyInfo property) + { + return property.GetMethod; + } + + public static IEnumerable GetInterfaces(this Type type) + { + return type.GetTypeInfo().ImplementedInterfaces; + } + + public static Exception Unwrap(this TargetInvocationException ex) + { + return ex.InnerException; + } + } + + internal enum TypeCode + { + Empty = 0, + Object = 1, + DBNull = 2, + Boolean = 3, + Char = 4, + SByte = 5, + Byte = 6, + Int16 = 7, + UInt16 = 8, + Int32 = 9, + UInt32 = 10, + Int64 = 11, + UInt64 = 12, + Single = 13, + Double = 14, + Decimal = 15, + DateTime = 16, + String = 18, + } + + internal abstract class DBNull + { + private DBNull() {} + } + + internal sealed class CultureInfoAdapter : CultureInfo + { + private readonly IFormatProvider _provider; + + public CultureInfoAdapter(CultureInfo baseCulture, IFormatProvider provider) + : base(baseCulture.Name) + { + _provider = provider; + } + + public override object GetFormat(Type formatType) + { + return _provider.GetFormat(formatType); + } + } #else internal static class ReflectionExtensions @@ -307,10 +307,10 @@ public static bool IsValueType(this Type type) return type.IsValueType; } - public static bool IsGenericType(this Type type) - { - return type.IsGenericType; - } + public static bool IsGenericType(this Type type) + { + return type.IsGenericType; + } public static bool IsInterface(this Type type) { @@ -327,85 +327,85 @@ public static bool IsEnum(this Type type) /// /// The type. /// - /// true if the type has a default constructor; otherwise, false. + /// true if the type has a default constructor; otherwise, false. /// public static bool HasDefaultConstructor(this Type type) { return type.IsValueType || type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null) != null; } - public static TypeCode GetTypeCode(this Type type) - { - return Type.GetTypeCode(type); - } + public static TypeCode GetTypeCode(this Type type) + { + return Type.GetTypeCode(type); + } - public static IEnumerable GetPublicProperties(this Type type) - { - var instancePublic = BindingFlags.Instance | BindingFlags.Public; - return type.IsInterface - ? (new Type[] { type }) - .Concat(type.GetInterfaces()) - .SelectMany(i => i.GetProperties(instancePublic)) - : type.GetProperties(instancePublic); - } - - public static IEnumerable GetPublicStaticMethods(this Type type) - { - return type.GetMethods(BindingFlags.Static | BindingFlags.Public); - } - - public static MethodInfo GetPublicStaticMethod(this Type type, string name, params Type[] parameterTypes) - { - return type.GetMethod(name, BindingFlags.Public | BindingFlags.Static, null, parameterTypes, null); - } - - private static readonly FieldInfo remoteStackTraceField = typeof(Exception) - .GetField("_remoteStackTraceString", BindingFlags.Instance | BindingFlags.NonPublic); - - public static Exception Unwrap(this TargetInvocationException ex) - { - var result = ex.InnerException; - if (remoteStackTraceField != null) - { - remoteStackTraceField.SetValue(ex.InnerException, ex.InnerException.StackTrace + "\r\n"); - } - return result; - } - } - - internal sealed class CultureInfoAdapter : CultureInfo - { - private readonly IFormatProvider _provider; - - public CultureInfoAdapter(CultureInfo baseCulture, IFormatProvider provider) - : base(baseCulture.LCID) - { - _provider = provider; - } - - public override object GetFormat(Type formatType) - { - return _provider.GetFormat(formatType); - } - } + public static IEnumerable GetPublicProperties(this Type type) + { + var instancePublic = BindingFlags.Instance | BindingFlags.Public; + return type.IsInterface + ? (new Type[] { type }) + .Concat(type.GetInterfaces()) + .SelectMany(i => i.GetProperties(instancePublic)) + : type.GetProperties(instancePublic); + } + + public static IEnumerable GetPublicStaticMethods(this Type type) + { + return type.GetMethods(BindingFlags.Static | BindingFlags.Public); + } + + public static MethodInfo GetPublicStaticMethod(this Type type, string name, params Type[] parameterTypes) + { + return type.GetMethod(name, BindingFlags.Public | BindingFlags.Static, null, parameterTypes, null); + } + + private static readonly FieldInfo remoteStackTraceField = typeof(Exception) + .GetField("_remoteStackTraceString", BindingFlags.Instance | BindingFlags.NonPublic); + + public static Exception Unwrap(this TargetInvocationException ex) + { + var result = ex.InnerException; + if (remoteStackTraceField != null) + { + remoteStackTraceField.SetValue(ex.InnerException, ex.InnerException.StackTrace + "\r\n"); + } + return result; + } + } + + internal sealed class CultureInfoAdapter : CultureInfo + { + private readonly IFormatProvider _provider; + + public CultureInfoAdapter(CultureInfo baseCulture, IFormatProvider provider) + : base(baseCulture.LCID) + { + _provider = provider; + } + + public override object GetFormat(Type formatType) + { + return _provider.GetFormat(formatType); + } + } #endif #if UNITY - internal static class PropertyInfoExtensions - { - public static object ReadValue(this PropertyInfo property, object target) - { - return property.GetGetMethod().Invoke(target, null); - } - } + internal static class PropertyInfoExtensions + { + public static object ReadValue(this PropertyInfo property, object target) + { + return property.GetGetMethod().Invoke(target, null); + } + } #else internal static class PropertyInfoExtensions - { - public static object ReadValue(this PropertyInfo property, object target) - { - return property.GetValue(target, null); - } - } + { + public static object ReadValue(this PropertyInfo property, object target) + { + return property.GetValue(target, null); + } + } #endif } diff --git a/YamlDotNet/RepresentationModel/DocumentLoadingState.cs b/YamlDotNet/RepresentationModel/DocumentLoadingState.cs index fdb1c2b08..7c1fea513 100644 --- a/YamlDotNet/RepresentationModel/DocumentLoadingState.cs +++ b/YamlDotNet/RepresentationModel/DocumentLoadingState.cs @@ -26,88 +26,88 @@ namespace YamlDotNet.RepresentationModel { - /// - /// Manages the state of a while it is loading. - /// - internal class DocumentLoadingState - { - private readonly IDictionary anchors = new Dictionary(); - private readonly IList nodesWithUnresolvedAliases = new List(); + /// + /// Manages the state of a while it is loading. + /// + internal class DocumentLoadingState + { + private readonly IDictionary anchors = new Dictionary(); + private readonly IList nodesWithUnresolvedAliases = new List(); - /// - /// Adds the specified node to the anchor list. - /// - /// The node. - public void AddAnchor(YamlNode node) - { - if (node.Anchor == null) - { - throw new ArgumentException("The specified node does not have an anchor"); - } + /// + /// Adds the specified node to the anchor list. + /// + /// The node. + public void AddAnchor(YamlNode node) + { + if (node.Anchor == null) + { + throw new ArgumentException("The specified node does not have an anchor"); + } - if (anchors.ContainsKey(node.Anchor)) - { - throw new DuplicateAnchorException(node.Start, node.End, string.Format(CultureInfo.InvariantCulture, "The anchor '{0}' already exists", node.Anchor)); - } + if (anchors.ContainsKey(node.Anchor)) + { + throw new DuplicateAnchorException(node.Start, node.End, string.Format(CultureInfo.InvariantCulture, "The anchor '{0}' already exists", node.Anchor)); + } - anchors.Add(node.Anchor, node); - } + anchors.Add(node.Anchor, node); + } - /// - /// Gets the node with the specified anchor. - /// - /// The anchor. - /// if set to true, the method should throw an exception if there is no node with that anchor. - /// The start position. - /// The end position. - /// - public YamlNode GetNode(string anchor, bool throwException, Mark start, Mark end) - { - YamlNode target; - if (anchors.TryGetValue(anchor, out target)) - { - return target; - } - else if (throwException) - { - throw new AnchorNotFoundException(start, end, string.Format(CultureInfo.InvariantCulture, "The anchor '{0}' does not exists", anchor)); - } - else - { - return null; - } - } + /// + /// Gets the node with the specified anchor. + /// + /// The anchor. + /// if set to true, the method should throw an exception if there is no node with that anchor. + /// The start position. + /// The end position. + /// + public YamlNode GetNode(string anchor, bool throwException, Mark start, Mark end) + { + YamlNode target; + if (anchors.TryGetValue(anchor, out target)) + { + return target; + } + else if (throwException) + { + throw new AnchorNotFoundException(start, end, string.Format(CultureInfo.InvariantCulture, "The anchor '{0}' does not exists", anchor)); + } + else + { + return null; + } + } - /// - /// Adds the specified node to the collection of nodes with unresolved aliases. - /// - /// - /// The that has unresolved aliases. - /// - public void AddNodeWithUnresolvedAliases(YamlNode node) - { - nodesWithUnresolvedAliases.Add(node); - } + /// + /// Adds the specified node to the collection of nodes with unresolved aliases. + /// + /// + /// The that has unresolved aliases. + /// + public void AddNodeWithUnresolvedAliases(YamlNode node) + { + nodesWithUnresolvedAliases.Add(node); + } - /// - /// Resolves the aliases that could not be resolved while loading the document. - /// - public void ResolveAliases() - { - foreach(var node in nodesWithUnresolvedAliases) - { - node.ResolveAliases(this); + /// + /// Resolves the aliases that could not be resolved while loading the document. + /// + public void ResolveAliases() + { + foreach(var node in nodesWithUnresolvedAliases) + { + node.ResolveAliases(this); #if DEBUG - foreach (var child in node.AllNodes) - { - if (child is YamlAliasNode) - { - throw new InvalidOperationException("Error in alias resolution."); - } - } + foreach (var child in node.AllNodes) + { + if (child is YamlAliasNode) + { + throw new InvalidOperationException("Error in alias resolution."); + } + } #endif - } - } - } + } + } + } } \ No newline at end of file diff --git a/YamlDotNet/RepresentationModel/EmitterState.cs b/YamlDotNet/RepresentationModel/EmitterState.cs index 1bd80b17d..31e7aa9c8 100644 --- a/YamlDotNet/RepresentationModel/EmitterState.cs +++ b/YamlDotNet/RepresentationModel/EmitterState.cs @@ -23,23 +23,23 @@ namespace YamlDotNet.RepresentationModel { - /// - /// Holds state that is used when emitting a stream. - /// - internal class EmitterState - { - private readonly HashSet emittedAnchors = new HashSet(); + /// + /// Holds state that is used when emitting a stream. + /// + internal class EmitterState + { + private readonly HashSet emittedAnchors = new HashSet(); - /// - /// Gets the already emitted anchors. - /// - /// The emitted anchors. - public HashSet EmittedAnchors - { - get - { - return emittedAnchors; - } - } - } + /// + /// Gets the already emitted anchors. + /// + /// The emitted anchors. + public HashSet EmittedAnchors + { + get + { + return emittedAnchors; + } + } + } } \ No newline at end of file diff --git a/YamlDotNet/RepresentationModel/IYamlVisitor.cs b/YamlDotNet/RepresentationModel/IYamlVisitor.cs index 3d0c93902..7fe614979 100644 --- a/YamlDotNet/RepresentationModel/IYamlVisitor.cs +++ b/YamlDotNet/RepresentationModel/IYamlVisitor.cs @@ -23,49 +23,49 @@ 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); + /// + /// 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(YamlDocument document); - /// - /// Visits a . - /// - /// - /// The that is being visited. - /// - void Visit(YamlScalarNode scalar); + /// + /// 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(YamlSequenceNode sequence); - /// - /// Visits a . - /// - /// - /// The that is being visited. - /// - void Visit(YamlMappingNode mapping); - } + /// + /// Visits a . + /// + /// + /// The that is being visited. + /// + void Visit(YamlMappingNode mapping); + } } \ No newline at end of file diff --git a/YamlDotNet/RepresentationModel/YamlAliasNode.cs b/YamlDotNet/RepresentationModel/YamlAliasNode.cs index cb0e69695..fccbcc426 100644 --- a/YamlDotNet/RepresentationModel/YamlAliasNode.cs +++ b/YamlDotNet/RepresentationModel/YamlAliasNode.cs @@ -25,86 +25,86 @@ namespace YamlDotNet.RepresentationModel { - /// - /// Represents an alias node in the YAML document. - /// - [Serializable] - internal class YamlAliasNode : YamlNode - { - /// - /// Initializes a new instance of the class. - /// - /// The anchor. - internal YamlAliasNode(string anchor) - { - Anchor = anchor; - } + /// + /// Represents an alias node in the YAML document. + /// + [Serializable] + internal class YamlAliasNode : YamlNode + { + /// + /// Initializes a new instance of the class. + /// + /// The anchor. + internal YamlAliasNode(string anchor) + { + Anchor = anchor; + } - /// - /// Resolves the aliases that could not be resolved when the node was created. - /// - /// The state of the document. - internal override void ResolveAliases(DocumentLoadingState state) - { - throw new NotSupportedException("Resolving an alias on an alias node does not make sense"); - } + /// + /// Resolves the aliases that could not be resolved when the node was created. + /// + /// The state of the document. + internal override void ResolveAliases(DocumentLoadingState state) + { + throw new NotSupportedException("Resolving an alias on an alias node does not make sense"); + } - /// - /// Saves the current node to the specified emitter. - /// - /// The emitter where the node is to be saved. - /// The state. - internal override void Emit(IEmitter emitter, EmitterState state) - { - throw new NotSupportedException("A YamlAliasNode is an implementation detail and should never be saved."); - } - - /// - /// Accepts the specified visitor by calling the appropriate Visit method on it. - /// - /// - /// A . - /// - public override void Accept(IYamlVisitor visitor) - { - throw new NotSupportedException("A YamlAliasNode is an implementation detail and should never be visited."); - } - - /// - public override bool Equals(object other) - { - var obj = other as YamlAliasNode; - return obj != null && Equals(obj) && SafeEquals(Anchor, obj.Anchor); - } - - /// - /// Serves as a hash function for a particular type. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - return base.GetHashCode(); - } + /// + /// Saves the current node to the specified emitter. + /// + /// The emitter where the node is to be saved. + /// The state. + internal override void Emit(IEmitter emitter, EmitterState state) + { + throw new NotSupportedException("A YamlAliasNode is an implementation detail and should never be saved."); + } + + /// + /// Accepts the specified visitor by calling the appropriate Visit method on it. + /// + /// + /// A . + /// + public override void Accept(IYamlVisitor visitor) + { + throw new NotSupportedException("A YamlAliasNode is an implementation detail and should never be visited."); + } + + /// + public override bool Equals(object other) + { + var obj = other as YamlAliasNode; + return obj != null && Equals(obj) && SafeEquals(Anchor, obj.Anchor); + } + + /// + /// Serves as a hash function for a particular type. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + return base.GetHashCode(); + } - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return "*" + Anchor; - } + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + return "*" + Anchor; + } - /// - /// Gets all nodes from the document, starting on the current node. - /// - public override IEnumerable AllNodes - { - get { yield return this; } - } - } + /// + /// Gets all nodes from the document, starting on the current node. + /// + public override IEnumerable AllNodes + { + get { yield return this; } + } + } } \ No newline at end of file diff --git a/YamlDotNet/RepresentationModel/YamlDocument.cs b/YamlDotNet/RepresentationModel/YamlDocument.cs index 7d02477ee..2c7b192c7 100644 --- a/YamlDotNet/RepresentationModel/YamlDocument.cs +++ b/YamlDotNet/RepresentationModel/YamlDocument.cs @@ -28,179 +28,179 @@ namespace YamlDotNet.RepresentationModel { - /// - /// Represents an YAML document. - /// - [Serializable] - public class YamlDocument - { - /// - /// Gets or sets the root node. - /// - /// The root node. - public YamlNode RootNode { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - public YamlDocument(YamlNode rootNode) - { - RootNode = rootNode; - } - - /// - /// Initializes a new instance of the class with a single scalar node. - /// - public YamlDocument(string rootNode) - { - RootNode = new YamlScalarNode(rootNode); - } - - /// - /// Initializes a new instance of the class. - /// - /// The events. - internal YamlDocument(EventReader events) - { - DocumentLoadingState state = new DocumentLoadingState(); - - events.Expect(); - - while (!events.Accept()) - { - Debug.Assert(RootNode == null); - RootNode = YamlNode.ParseNode(events, state); - - if (RootNode is YamlAliasNode) - { - throw new YamlException(); - } - } - - state.ResolveAliases(); + /// + /// Represents an YAML document. + /// + [Serializable] + public class YamlDocument + { + /// + /// Gets or sets the root node. + /// + /// The root node. + public YamlNode RootNode { get; private set; } + + /// + /// Initializes a new instance of the class. + /// + public YamlDocument(YamlNode rootNode) + { + RootNode = rootNode; + } + + /// + /// Initializes a new instance of the class with a single scalar node. + /// + public YamlDocument(string rootNode) + { + RootNode = new YamlScalarNode(rootNode); + } + + /// + /// Initializes a new instance of the class. + /// + /// The events. + internal YamlDocument(EventReader events) + { + DocumentLoadingState state = new DocumentLoadingState(); + + events.Expect(); + + while (!events.Accept()) + { + Debug.Assert(RootNode == null); + RootNode = YamlNode.ParseNode(events, state); + + if (RootNode is YamlAliasNode) + { + throw new YamlException(); + } + } + + state.ResolveAliases(); #if DEBUG - foreach (var node in AllNodes) - { - if (node is YamlAliasNode) - { - throw new InvalidOperationException("Error in alias resolution."); - } - } + foreach (var node in AllNodes) + { + if (node is YamlAliasNode) + { + throw new InvalidOperationException("Error in alias resolution."); + } + } #endif - events.Expect(); - } - - /// - /// Visitor that assigns anchors to nodes that are referenced more than once but have no anchor. - /// - private class AnchorAssigningVisitor : YamlVisitor - { - private readonly HashSet existingAnchors = new HashSet(); - private readonly Dictionary visitedNodes = new Dictionary(); - - public void AssignAnchors(YamlDocument document) - { - existingAnchors.Clear(); - visitedNodes.Clear(); - - document.Accept(this); - - Random random = new Random(); - foreach (var visitedNode in visitedNodes) - { - if (visitedNode.Value) - { - string anchor; - do - { - anchor = random.Next().ToString(CultureInfo.InvariantCulture); - } while (existingAnchors.Contains(anchor)); - existingAnchors.Add(anchor); - - visitedNode.Key.Anchor = anchor; - } - } - } - - private void VisitNode(YamlNode node) - { - if (string.IsNullOrEmpty(node.Anchor)) - { - bool isDuplicate; - if (visitedNodes.TryGetValue(node, out isDuplicate)) - { - if (!isDuplicate) - { - visitedNodes[node] = true; - } - } - else - { - visitedNodes.Add(node, false); - } - } - else - { - existingAnchors.Add(node.Anchor); - } - } - - protected override void Visit(YamlScalarNode scalar) - { - VisitNode(scalar); - } - - protected override void Visit(YamlMappingNode mapping) - { - VisitNode(mapping); - } - - protected override void Visit(YamlSequenceNode sequence) - { - VisitNode(sequence); - } - } - - private void AssignAnchors() - { - AnchorAssigningVisitor visitor = new AnchorAssigningVisitor(); - visitor.AssignAnchors(this); - } - - internal void Save(IEmitter emitter, bool assignAnchors = true) - { - if (assignAnchors) - { - AssignAnchors(); - } - - emitter.Emit(new DocumentStart()); - RootNode.Save(emitter, new EmitterState()); - emitter.Emit(new DocumentEnd(false)); - } - - /// - /// Accepts the specified visitor by calling the appropriate Visit method on it. - /// - /// - /// A . - /// - public void Accept(IYamlVisitor visitor) - { - visitor.Visit(this); - } - - /// - /// Gets all nodes from the document. - /// - public IEnumerable AllNodes - { - get - { - return RootNode.AllNodes; - } - } - } + events.Expect(); + } + + /// + /// Visitor that assigns anchors to nodes that are referenced more than once but have no anchor. + /// + private class AnchorAssigningVisitor : YamlVisitor + { + private readonly HashSet existingAnchors = new HashSet(); + private readonly Dictionary visitedNodes = new Dictionary(); + + public void AssignAnchors(YamlDocument document) + { + existingAnchors.Clear(); + visitedNodes.Clear(); + + document.Accept(this); + + Random random = new Random(); + foreach (var visitedNode in visitedNodes) + { + if (visitedNode.Value) + { + string anchor; + do + { + anchor = random.Next().ToString(CultureInfo.InvariantCulture); + } while (existingAnchors.Contains(anchor)); + existingAnchors.Add(anchor); + + visitedNode.Key.Anchor = anchor; + } + } + } + + private void VisitNode(YamlNode node) + { + if (string.IsNullOrEmpty(node.Anchor)) + { + bool isDuplicate; + if (visitedNodes.TryGetValue(node, out isDuplicate)) + { + if (!isDuplicate) + { + visitedNodes[node] = true; + } + } + else + { + visitedNodes.Add(node, false); + } + } + else + { + existingAnchors.Add(node.Anchor); + } + } + + protected override void Visit(YamlScalarNode scalar) + { + VisitNode(scalar); + } + + protected override void Visit(YamlMappingNode mapping) + { + VisitNode(mapping); + } + + protected override void Visit(YamlSequenceNode sequence) + { + VisitNode(sequence); + } + } + + private void AssignAnchors() + { + AnchorAssigningVisitor visitor = new AnchorAssigningVisitor(); + visitor.AssignAnchors(this); + } + + internal void Save(IEmitter emitter, bool assignAnchors = true) + { + if (assignAnchors) + { + AssignAnchors(); + } + + emitter.Emit(new DocumentStart()); + RootNode.Save(emitter, new EmitterState()); + emitter.Emit(new DocumentEnd(false)); + } + + /// + /// Accepts the specified visitor by calling the appropriate Visit method on it. + /// + /// + /// A . + /// + public void Accept(IYamlVisitor visitor) + { + visitor.Visit(this); + } + + /// + /// Gets all nodes from the document. + /// + public IEnumerable AllNodes + { + get + { + return RootNode.AllNodes; + } + } + } } \ No newline at end of file diff --git a/YamlDotNet/RepresentationModel/YamlMappingNode.cs b/YamlDotNet/RepresentationModel/YamlMappingNode.cs index 8f33d161b..9984ad944 100644 --- a/YamlDotNet/RepresentationModel/YamlMappingNode.cs +++ b/YamlDotNet/RepresentationModel/YamlMappingNode.cs @@ -28,354 +28,354 @@ namespace YamlDotNet.RepresentationModel { - /// - /// Represents a mapping node in the YAML document. - /// - [Serializable] - public class YamlMappingNode : YamlNode, IEnumerable> - { - private readonly IDictionary children = new Dictionary(); - - /// - /// Gets the children of the current node. - /// - /// The children. - public IDictionary Children - { - get - { - return children; - } - } + /// + /// Represents a mapping node in the YAML document. + /// + [Serializable] + public class YamlMappingNode : YamlNode, IEnumerable> + { + private readonly IDictionary children = new Dictionary(); /// - /// Gets or sets the style of the node. - /// - /// The style. - public MappingStyle Style { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The events. - /// The state. - internal YamlMappingNode(EventReader events, DocumentLoadingState state) - { - MappingStart mapping = events.Expect(); - Load(mapping, state); - - bool hasUnresolvedAliases = false; - while (!events.Accept()) - { - YamlNode key = ParseNode(events, state); - YamlNode value = ParseNode(events, state); - - try - { - children.Add(key, value); - } - catch (ArgumentException err) - { - throw new YamlException(key.Start, key.End, "Duplicate key", err); - } - - hasUnresolvedAliases |= key is YamlAliasNode || value is YamlAliasNode; - } - - if (hasUnresolvedAliases) - { - state.AddNodeWithUnresolvedAliases(this); - } + /// Gets the children of the current node. + /// + /// The children. + public IDictionary Children + { + get + { + return children; + } + } + + /// + /// Gets or sets the style of the node. + /// + /// The style. + public MappingStyle Style { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// The events. + /// The state. + internal YamlMappingNode(EventReader events, DocumentLoadingState state) + { + MappingStart mapping = events.Expect(); + Load(mapping, state); + + bool hasUnresolvedAliases = false; + while (!events.Accept()) + { + YamlNode key = ParseNode(events, state); + YamlNode value = ParseNode(events, state); + + try + { + children.Add(key, value); + } + catch (ArgumentException err) + { + throw new YamlException(key.Start, key.End, "Duplicate key", err); + } + + hasUnresolvedAliases |= key is YamlAliasNode || value is YamlAliasNode; + } + + if (hasUnresolvedAliases) + { + state.AddNodeWithUnresolvedAliases(this); + } #if DEBUG - else - { - foreach (var child in children) - { - if (child.Key is YamlAliasNode) - { - throw new InvalidOperationException("Error in alias resolution."); - } - if (child.Value is YamlAliasNode) - { - throw new InvalidOperationException("Error in alias resolution."); - } - } - } + else + { + foreach (var child in children) + { + if (child.Key is YamlAliasNode) + { + throw new InvalidOperationException("Error in alias resolution."); + } + if (child.Value is YamlAliasNode) + { + throw new InvalidOperationException("Error in alias resolution."); + } + } + } #endif - events.Expect(); - } - - /// - /// Initializes a new instance of the class. - /// - public YamlMappingNode() - { - } - - /// - /// Initializes a new instance of the class. - /// - public YamlMappingNode(params KeyValuePair[] children) - : this((IEnumerable>)children) - { - } - - /// - /// Initializes a new instance of the class. - /// - public YamlMappingNode(IEnumerable> children) - { - foreach (var child in children) - { - this.children.Add(child); - } - } - - /// - /// Initializes a new instance of the class. - /// - /// A sequence of where even elements are keys and odd elements are values. - public YamlMappingNode(params YamlNode[] children) - : this((IEnumerable)children) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// A sequence of where even elements are keys and odd elements are values. - public YamlMappingNode(IEnumerable children) - { - using (var enumerator = children.GetEnumerator()) - { - while (enumerator.MoveNext()) - { - var key = enumerator.Current; - if (!enumerator.MoveNext()) - { - throw new ArgumentException("When constructing a mapping node with a sequence, the number of elements of the sequence must be even."); - } - - Add(key, enumerator.Current); - } - } - } - - /// - /// Adds the specified mapping to the collection. - /// - /// The key node. - /// The value node. - public void Add(YamlNode key, YamlNode value) - { - children.Add(key, value); - } - - /// - /// Adds the specified mapping to the collection. - /// - /// The key node. - /// The value node. - public void Add(string key, YamlNode value) - { - children.Add(new YamlScalarNode(key), value); - } - - /// - /// Adds the specified mapping to the collection. - /// - /// The key node. - /// The value node. - public void Add(YamlNode key, string value) - { - children.Add(key, new YamlScalarNode(value)); - } - - /// - /// Adds the specified mapping to the collection. - /// - /// The key node. - /// The value node. - public void Add(string key, string value) - { - children.Add(new YamlScalarNode(key), new YamlScalarNode(value)); - } - - /// - /// Resolves the aliases that could not be resolved when the node was created. - /// - /// The state of the document. - internal override void ResolveAliases(DocumentLoadingState state) - { - Dictionary keysToUpdate = null; - Dictionary valuesToUpdate = null; - foreach (var entry in children) - { - if (entry.Key is YamlAliasNode) - { - if (keysToUpdate == null) - { - keysToUpdate = new Dictionary(); - } - keysToUpdate.Add(entry.Key, state.GetNode(entry.Key.Anchor, true, entry.Key.Start, entry.Key.End)); - } - if (entry.Value is YamlAliasNode) - { - if (valuesToUpdate == null) - { - valuesToUpdate = new Dictionary(); - } - valuesToUpdate.Add(entry.Key, state.GetNode(entry.Value.Anchor, true, entry.Value.Start, entry.Value.End)); - } - } - if (valuesToUpdate != null) - { - foreach (var entry in valuesToUpdate) - { - children[entry.Key] = entry.Value; - } - } - if (keysToUpdate != null) - { - foreach (var entry in keysToUpdate) - { - YamlNode value = children[entry.Key]; - children.Remove(entry.Key); - children.Add(entry.Value, value); - } - } - } - - /// - /// Saves the current node to the specified emitter. - /// - /// The emitter where the node is to be saved. - /// The state. - internal override void Emit(IEmitter emitter, EmitterState state) - { + events.Expect(); + } + + /// + /// Initializes a new instance of the class. + /// + public YamlMappingNode() + { + } + + /// + /// Initializes a new instance of the class. + /// + public YamlMappingNode(params KeyValuePair[] children) + : this((IEnumerable>)children) + { + } + + /// + /// Initializes a new instance of the class. + /// + public YamlMappingNode(IEnumerable> children) + { + foreach (var child in children) + { + this.children.Add(child); + } + } + + /// + /// Initializes a new instance of the class. + /// + /// A sequence of where even elements are keys and odd elements are values. + public YamlMappingNode(params YamlNode[] children) + : this((IEnumerable)children) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// A sequence of where even elements are keys and odd elements are values. + public YamlMappingNode(IEnumerable children) + { + using (var enumerator = children.GetEnumerator()) + { + while (enumerator.MoveNext()) + { + var key = enumerator.Current; + if (!enumerator.MoveNext()) + { + throw new ArgumentException("When constructing a mapping node with a sequence, the number of elements of the sequence must be even."); + } + + Add(key, enumerator.Current); + } + } + } + + /// + /// Adds the specified mapping to the collection. + /// + /// The key node. + /// The value node. + public void Add(YamlNode key, YamlNode value) + { + children.Add(key, value); + } + + /// + /// Adds the specified mapping to the collection. + /// + /// The key node. + /// The value node. + public void Add(string key, YamlNode value) + { + children.Add(new YamlScalarNode(key), value); + } + + /// + /// Adds the specified mapping to the collection. + /// + /// The key node. + /// The value node. + public void Add(YamlNode key, string value) + { + children.Add(key, new YamlScalarNode(value)); + } + + /// + /// Adds the specified mapping to the collection. + /// + /// The key node. + /// The value node. + public void Add(string key, string value) + { + children.Add(new YamlScalarNode(key), new YamlScalarNode(value)); + } + + /// + /// Resolves the aliases that could not be resolved when the node was created. + /// + /// The state of the document. + internal override void ResolveAliases(DocumentLoadingState state) + { + Dictionary keysToUpdate = null; + Dictionary valuesToUpdate = null; + foreach (var entry in children) + { + if (entry.Key is YamlAliasNode) + { + if (keysToUpdate == null) + { + keysToUpdate = new Dictionary(); + } + keysToUpdate.Add(entry.Key, state.GetNode(entry.Key.Anchor, true, entry.Key.Start, entry.Key.End)); + } + if (entry.Value is YamlAliasNode) + { + if (valuesToUpdate == null) + { + valuesToUpdate = new Dictionary(); + } + valuesToUpdate.Add(entry.Key, state.GetNode(entry.Value.Anchor, true, entry.Value.Start, entry.Value.End)); + } + } + if (valuesToUpdate != null) + { + foreach (var entry in valuesToUpdate) + { + children[entry.Key] = entry.Value; + } + } + if (keysToUpdate != null) + { + foreach (var entry in keysToUpdate) + { + YamlNode value = children[entry.Key]; + children.Remove(entry.Key); + children.Add(entry.Value, value); + } + } + } + + /// + /// Saves the current node to the specified emitter. + /// + /// The emitter where the node is to be saved. + /// The state. + internal override void Emit(IEmitter emitter, EmitterState state) + { emitter.Emit(new MappingStart(Anchor, Tag, true, Style)); - foreach (var entry in children) - { - entry.Key.Save(emitter, state); - entry.Value.Save(emitter, state); - } - emitter.Emit(new MappingEnd()); - } - - /// - /// Accepts the specified visitor by calling the appropriate Visit method on it. - /// - /// - /// A . - /// - public override void Accept(IYamlVisitor visitor) - { - visitor.Visit(this); - } - - /// - public override bool Equals(object other) - { - var obj = other as YamlMappingNode; - if (obj == null || !Equals(obj) || children.Count != obj.children.Count) - { - return false; - } - - foreach (var entry in children) - { - YamlNode otherNode; - if (!obj.children.TryGetValue(entry.Key, out otherNode) || !SafeEquals(entry.Value, otherNode)) - { - return false; - } - } - - return true; - } - - /// - /// Serves as a hash function for a particular type. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - var hashCode = base.GetHashCode(); - - foreach (var entry in children) - { - hashCode = CombineHashCodes(hashCode, GetHashCode(entry.Key)); - hashCode = CombineHashCodes(hashCode, GetHashCode(entry.Value)); - } - return hashCode; - } - - /// - /// Gets all nodes from the document, starting on the current node. - /// - public override IEnumerable AllNodes - { - get - { - yield return this; - foreach (var child in children) - { - foreach (var node in child.Key.AllNodes) - { - yield return node; - } - foreach (var node in child.Value.AllNodes) - { - yield return node; - } - } - } - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - var text = new StringBuilder("{ "); - - foreach (var child in children) - { - if (text.Length > 2) - { - text.Append(", "); - } - text.Append("{ ").Append(child.Key).Append(", ").Append(child.Value).Append(" }"); - } - - text.Append(" }"); - - return text.ToString(); - } - - #region IEnumerable> Members - - /// - public IEnumerator> GetEnumerator() - { - return children.GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - } + foreach (var entry in children) + { + entry.Key.Save(emitter, state); + entry.Value.Save(emitter, state); + } + emitter.Emit(new MappingEnd()); + } + + /// + /// Accepts the specified visitor by calling the appropriate Visit method on it. + /// + /// + /// A . + /// + public override void Accept(IYamlVisitor visitor) + { + visitor.Visit(this); + } + + /// + public override bool Equals(object other) + { + var obj = other as YamlMappingNode; + if (obj == null || !Equals(obj) || children.Count != obj.children.Count) + { + return false; + } + + foreach (var entry in children) + { + YamlNode otherNode; + if (!obj.children.TryGetValue(entry.Key, out otherNode) || !SafeEquals(entry.Value, otherNode)) + { + return false; + } + } + + return true; + } + + /// + /// Serves as a hash function for a particular type. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + var hashCode = base.GetHashCode(); + + foreach (var entry in children) + { + hashCode = CombineHashCodes(hashCode, GetHashCode(entry.Key)); + hashCode = CombineHashCodes(hashCode, GetHashCode(entry.Value)); + } + return hashCode; + } + + /// + /// Gets all nodes from the document, starting on the current node. + /// + public override IEnumerable AllNodes + { + get + { + yield return this; + foreach (var child in children) + { + foreach (var node in child.Key.AllNodes) + { + yield return node; + } + foreach (var node in child.Value.AllNodes) + { + yield return node; + } + } + } + } + + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + var text = new StringBuilder("{ "); + + foreach (var child in children) + { + if (text.Length > 2) + { + text.Append(", "); + } + text.Append("{ ").Append(child.Key).Append(", ").Append(child.Value).Append(" }"); + } + + text.Append(" }"); + + return text.ToString(); + } + + #region IEnumerable> Members + + /// + public IEnumerator> GetEnumerator() + { + return children.GetEnumerator(); + } + + #endregion + + #region IEnumerable Members + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + #endregion + } } \ No newline at end of file diff --git a/YamlDotNet/RepresentationModel/YamlNode.cs b/YamlDotNet/RepresentationModel/YamlNode.cs index 21920036f..0a6871c13 100644 --- a/YamlDotNet/RepresentationModel/YamlNode.cs +++ b/YamlDotNet/RepresentationModel/YamlNode.cs @@ -26,183 +26,183 @@ namespace YamlDotNet.RepresentationModel { - /// - /// Represents a single node in the YAML document. - /// - [Serializable] - public abstract class YamlNode - { - /// - /// Gets or sets the anchor of the node. - /// - /// The anchor. - public string Anchor { get; set; } - - /// - /// Gets or sets the tag of the node. - /// - /// The tag. - public string Tag { get; set; } - - /// - /// Gets the position in the input stream where the event that originated the node starts. - /// - public Mark Start { get; private set; } - - /// - /// Gets the position in the input stream where the event that originated the node ends. - /// - public Mark End { get; private set; } - - /// - /// Loads the specified event. - /// - /// The event. - /// The state of the document. - internal void Load(NodeEvent yamlEvent, DocumentLoadingState state) - { - Tag = yamlEvent.Tag; - if (yamlEvent.Anchor != null) - { - Anchor = yamlEvent.Anchor; - state.AddAnchor(this); - } - Start = yamlEvent.Start; - End = yamlEvent.End; - } - - /// - /// Parses the node represented by the next event in . - /// - /// The events. - /// The state. - /// Returns the node that has been parsed. - static internal YamlNode ParseNode(EventReader events, DocumentLoadingState state) - { - if (events.Accept()) - { - return new YamlScalarNode(events, state); - } - - if (events.Accept()) - { - return new YamlSequenceNode(events, state); - } - - if (events.Accept()) - { - return new YamlMappingNode(events, state); - } - - if (events.Accept()) - { - AnchorAlias alias = events.Expect(); - return state.GetNode(alias.Value, false, alias.Start, alias.End) ?? new YamlAliasNode(alias.Value); - } - - throw new ArgumentException("The current event is of an unsupported type.", "events"); - } - - /// - /// Resolves the aliases that could not be resolved when the node was created. - /// - /// The state of the document. - internal abstract void ResolveAliases(DocumentLoadingState state); - - /// - /// Saves the current node to the specified emitter. - /// - /// The emitter where the node is to be saved. - /// The state. - internal void Save(IEmitter emitter, EmitterState state) - { - if (!string.IsNullOrEmpty(Anchor) && !state.EmittedAnchors.Add(Anchor)) - { - emitter.Emit(new AnchorAlias(Anchor)); - } - else - { - Emit(emitter, state); - } - } - - /// - /// Saves the current node to the specified emitter. - /// - /// The emitter where the node is to be saved. - /// The state. - internal abstract void Emit(IEmitter emitter, EmitterState state); - - /// - /// Accepts the specified visitor by calling the appropriate Visit method on it. - /// - /// - /// A . - /// - public abstract void Accept(IYamlVisitor visitor); - - /// - /// Provides a basic implementation of Object.Equals - /// - protected bool Equals(YamlNode other) - { - // Do not use the anchor in the equality comparison because that would prevent anchored nodes from being found in dictionaries. - return SafeEquals(Tag, other.Tag); - } - - /// - /// Gets a value indicating whether two objects are equal. - /// - protected static bool SafeEquals(object first, object second) - { - if (first != null) - { - return first.Equals(second); - } - else if (second != null) - { - return second.Equals(first); - } - else - { - return true; - } - } - - /// - /// Serves as a hash function for a particular type. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - // Do not use the anchor in the hash code because that would prevent anchored nodes from being found in dictionaries. - return GetHashCode(Tag); - } - - /// - /// Gets the hash code of the specified object, or zero if the object is null. - /// - protected static int GetHashCode(object value) - { - return value == null ? 0 : value.GetHashCode(); - } - - /// - /// Combines two hash codes into one. - /// - protected static int CombineHashCodes(int h1, int h2) - { - return unchecked(((h1 << 5) + h1) ^ h2); - } - - /// - /// Gets all nodes from the document, starting on the current node. - /// - public abstract IEnumerable AllNodes - { - get; - } - } + /// + /// Represents a single node in the YAML document. + /// + [Serializable] + public abstract class YamlNode + { + /// + /// Gets or sets the anchor of the node. + /// + /// The anchor. + public string Anchor { get; set; } + + /// + /// Gets or sets the tag of the node. + /// + /// The tag. + public string Tag { get; set; } + + /// + /// Gets the position in the input stream where the event that originated the node starts. + /// + public Mark Start { get; private set; } + + /// + /// Gets the position in the input stream where the event that originated the node ends. + /// + public Mark End { get; private set; } + + /// + /// Loads the specified event. + /// + /// The event. + /// The state of the document. + internal void Load(NodeEvent yamlEvent, DocumentLoadingState state) + { + Tag = yamlEvent.Tag; + if (yamlEvent.Anchor != null) + { + Anchor = yamlEvent.Anchor; + state.AddAnchor(this); + } + Start = yamlEvent.Start; + End = yamlEvent.End; + } + + /// + /// Parses the node represented by the next event in . + /// + /// The events. + /// The state. + /// Returns the node that has been parsed. + static internal YamlNode ParseNode(EventReader events, DocumentLoadingState state) + { + if (events.Accept()) + { + return new YamlScalarNode(events, state); + } + + if (events.Accept()) + { + return new YamlSequenceNode(events, state); + } + + if (events.Accept()) + { + return new YamlMappingNode(events, state); + } + + if (events.Accept()) + { + AnchorAlias alias = events.Expect(); + return state.GetNode(alias.Value, false, alias.Start, alias.End) ?? new YamlAliasNode(alias.Value); + } + + throw new ArgumentException("The current event is of an unsupported type.", "events"); + } + + /// + /// Resolves the aliases that could not be resolved when the node was created. + /// + /// The state of the document. + internal abstract void ResolveAliases(DocumentLoadingState state); + + /// + /// Saves the current node to the specified emitter. + /// + /// The emitter where the node is to be saved. + /// The state. + internal void Save(IEmitter emitter, EmitterState state) + { + if (!string.IsNullOrEmpty(Anchor) && !state.EmittedAnchors.Add(Anchor)) + { + emitter.Emit(new AnchorAlias(Anchor)); + } + else + { + Emit(emitter, state); + } + } + + /// + /// Saves the current node to the specified emitter. + /// + /// The emitter where the node is to be saved. + /// The state. + internal abstract void Emit(IEmitter emitter, EmitterState state); + + /// + /// Accepts the specified visitor by calling the appropriate Visit method on it. + /// + /// + /// A . + /// + public abstract void Accept(IYamlVisitor visitor); + + /// + /// Provides a basic implementation of Object.Equals + /// + protected bool Equals(YamlNode other) + { + // Do not use the anchor in the equality comparison because that would prevent anchored nodes from being found in dictionaries. + return SafeEquals(Tag, other.Tag); + } + + /// + /// Gets a value indicating whether two objects are equal. + /// + protected static bool SafeEquals(object first, object second) + { + if (first != null) + { + return first.Equals(second); + } + else if (second != null) + { + return second.Equals(first); + } + else + { + return true; + } + } + + /// + /// Serves as a hash function for a particular type. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + // Do not use the anchor in the hash code because that would prevent anchored nodes from being found in dictionaries. + return GetHashCode(Tag); + } + + /// + /// Gets the hash code of the specified object, or zero if the object is null. + /// + protected static int GetHashCode(object value) + { + return value == null ? 0 : value.GetHashCode(); + } + + /// + /// Combines two hash codes into one. + /// + protected static int CombineHashCodes(int h1, int h2) + { + return unchecked(((h1 << 5) + h1) ^ h2); + } + + /// + /// Gets all nodes from the document, starting on the current node. + /// + public abstract IEnumerable AllNodes + { + get; + } + } } \ No newline at end of file diff --git a/YamlDotNet/RepresentationModel/YamlNodeIdentityEqualityComparer.cs b/YamlDotNet/RepresentationModel/YamlNodeIdentityEqualityComparer.cs index 2da89a738..1002a38c5 100644 --- a/YamlDotNet/RepresentationModel/YamlNodeIdentityEqualityComparer.cs +++ b/YamlDotNet/RepresentationModel/YamlNodeIdentityEqualityComparer.cs @@ -23,25 +23,25 @@ namespace YamlDotNet.RepresentationModel { - /// - /// Comparer that is based on identity comparisons. - /// - public sealed class YamlNodeIdentityEqualityComparer : IEqualityComparer - { - #region IEqualityComparer Members + /// + /// Comparer that is based on identity comparisons. + /// + public sealed class YamlNodeIdentityEqualityComparer : IEqualityComparer + { + #region IEqualityComparer Members - /// - public bool Equals(YamlNode x, YamlNode y) - { - return ReferenceEquals(x, y); - } + /// + public bool Equals(YamlNode x, YamlNode y) + { + return ReferenceEquals(x, y); + } - /// - public int GetHashCode(YamlNode obj) - { - return obj.GetHashCode(); - } + /// + public int GetHashCode(YamlNode obj) + { + return obj.GetHashCode(); + } - #endregion - } + #endregion + } } \ No newline at end of file diff --git a/YamlDotNet/RepresentationModel/YamlScalarNode.cs b/YamlDotNet/RepresentationModel/YamlScalarNode.cs index d5532002a..c81e4b088 100644 --- a/YamlDotNet/RepresentationModel/YamlScalarNode.cs +++ b/YamlDotNet/RepresentationModel/YamlScalarNode.cs @@ -28,141 +28,141 @@ namespace YamlDotNet.RepresentationModel { - /// - /// Represents a scalar node in the YAML document. - /// - [DebuggerDisplay("{Value}")] - [Serializable] - public class YamlScalarNode : YamlNode - { - /// - /// Gets or sets the value of the node. - /// - /// The value. - public string Value { get; set; } + /// + /// Represents a scalar node in the YAML document. + /// + [DebuggerDisplay("{Value}")] + [Serializable] + public class YamlScalarNode : YamlNode + { + /// + /// Gets or sets the value of the node. + /// + /// The value. + public string Value { get; set; } - /// - /// Gets or sets the style of the node. - /// - /// The style. - public ScalarStyle Style { get; set; } + /// + /// Gets or sets the style of the node. + /// + /// The style. + public ScalarStyle Style { get; set; } - /// - /// Initializes a new instance of the class. - /// - /// The events. - /// The state. - internal YamlScalarNode(EventReader events, DocumentLoadingState state) - { - Scalar scalar = events.Expect(); - Load(scalar, state); - Value = scalar.Value; - Style = scalar.Style; - } + /// + /// Initializes a new instance of the class. + /// + /// The events. + /// The state. + internal YamlScalarNode(EventReader events, DocumentLoadingState state) + { + Scalar scalar = events.Expect(); + Load(scalar, state); + Value = scalar.Value; + Style = scalar.Style; + } - /// - /// Initializes a new instance of the class. - /// - public YamlScalarNode() - { - } + /// + /// Initializes a new instance of the class. + /// + public YamlScalarNode() + { + } - /// - /// Initializes a new instance of the class. - /// - /// The value. - public YamlScalarNode(string value) - { - this.Value = value; - } + /// + /// Initializes a new instance of the class. + /// + /// The value. + public YamlScalarNode(string value) + { + this.Value = value; + } - /// - /// Resolves the aliases that could not be resolved when the node was created. - /// - /// The state of the document. - internal override void ResolveAliases(DocumentLoadingState state) - { - throw new NotSupportedException("Resolving an alias on a scalar node does not make sense"); - } + /// + /// Resolves the aliases that could not be resolved when the node was created. + /// + /// The state of the document. + internal override void ResolveAliases(DocumentLoadingState state) + { + throw new NotSupportedException("Resolving an alias on a scalar node does not make sense"); + } - /// - /// Saves the current node to the specified emitter. - /// - /// The emitter where the node is to be saved. - /// The state. - internal override void Emit(IEmitter emitter, EmitterState state) - { + /// + /// Saves the current node to the specified emitter. + /// + /// The emitter where the node is to be saved. + /// The state. + internal override void Emit(IEmitter emitter, EmitterState state) + { emitter.Emit(new Scalar(Anchor, Tag, Value, Style, true, false)); - } - - /// - /// Accepts the specified visitor by calling the appropriate Visit method on it. - /// - /// - /// A . - /// - public override void Accept(IYamlVisitor visitor) { - visitor.Visit(this); - } - - /// - public override bool Equals(object other) - { - var obj = other as YamlScalarNode; - return obj != null && Equals(obj) && SafeEquals(Value, obj.Value); - } - - /// - /// Serves as a hash function for a particular type. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - return CombineHashCodes( - base.GetHashCode(), - GetHashCode(Value) - ); - } + } + + /// + /// Accepts the specified visitor by calling the appropriate Visit method on it. + /// + /// + /// A . + /// + public override void Accept(IYamlVisitor visitor) { + visitor.Visit(this); + } + + /// + public override bool Equals(object other) + { + var obj = other as YamlScalarNode; + return obj != null && Equals(obj) && SafeEquals(Value, obj.Value); + } + + /// + /// Serves as a hash function for a particular type. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + return CombineHashCodes( + base.GetHashCode(), + GetHashCode(Value) + ); + } - /// - /// Performs an implicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static implicit operator YamlScalarNode(string value) - { - return new YamlScalarNode(value); - } + /// + /// Performs an implicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static implicit operator YamlScalarNode(string value) + { + return new YamlScalarNode(value); + } - /// - /// Performs an explicit conversion from to . - /// - /// The value. - /// The result of the conversion. - public static explicit operator string(YamlScalarNode value) - { - return value.Value; - } + /// + /// Performs an explicit conversion from to . + /// + /// The value. + /// The result of the conversion. + public static explicit operator string(YamlScalarNode value) + { + return value.Value; + } - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return Value; - } + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + return Value; + } - /// - /// Gets all nodes from the document, starting on the current node. - /// - public override IEnumerable AllNodes - { - get { yield return this; } - } - } + /// + /// Gets all nodes from the document, starting on the current node. + /// + public override IEnumerable AllNodes + { + get { yield return this; } + } + } } \ No newline at end of file diff --git a/YamlDotNet/RepresentationModel/YamlSequenceNode.cs b/YamlDotNet/RepresentationModel/YamlSequenceNode.cs index 03b6e5f01..2ebdfd518 100644 --- a/YamlDotNet/RepresentationModel/YamlSequenceNode.cs +++ b/YamlDotNet/RepresentationModel/YamlSequenceNode.cs @@ -29,26 +29,26 @@ namespace YamlDotNet.RepresentationModel { - /// - /// Represents a sequence node in the YAML document. - /// - [DebuggerDisplay("Count = {children.Count}")] - [Serializable] - public class YamlSequenceNode : YamlNode, IEnumerable - { - private readonly IList children = new List(); - - /// - /// Gets the collection of child nodes. - /// - /// The children. - public IList Children - { - get - { - return children; - } - } + /// + /// Represents a sequence node in the YAML document. + /// + [DebuggerDisplay("Count = {children.Count}")] + [Serializable] + public class YamlSequenceNode : YamlNode, IEnumerable + { + private readonly IList children = new List(); + + /// + /// Gets the collection of child nodes. + /// + /// The children. + public IList Children + { + get + { + return children; + } + } /// /// Gets or sets the style of the node. @@ -57,225 +57,225 @@ public IList Children public SequenceStyle Style { get; set; } - /// - /// Initializes a new instance of the class. - /// - /// The events. - /// The state. - internal YamlSequenceNode(EventReader events, DocumentLoadingState state) - { - SequenceStart sequence = events.Expect(); - Load(sequence, state); - - bool hasUnresolvedAliases = false; - while (!events.Accept()) - { - YamlNode child = ParseNode(events, state); - children.Add(child); - hasUnresolvedAliases |= child is YamlAliasNode; - } - - if (hasUnresolvedAliases) - { - state.AddNodeWithUnresolvedAliases(this); - } + /// + /// Initializes a new instance of the class. + /// + /// The events. + /// The state. + internal YamlSequenceNode(EventReader events, DocumentLoadingState state) + { + SequenceStart sequence = events.Expect(); + Load(sequence, state); + + bool hasUnresolvedAliases = false; + while (!events.Accept()) + { + YamlNode child = ParseNode(events, state); + children.Add(child); + hasUnresolvedAliases |= child is YamlAliasNode; + } + + if (hasUnresolvedAliases) + { + state.AddNodeWithUnresolvedAliases(this); + } #if DEBUG - else - { - foreach (var child in children) - { - if (child is YamlAliasNode) - { - throw new InvalidOperationException("Error in alias resolution."); - } - } - } + else + { + foreach (var child in children) + { + if (child is YamlAliasNode) + { + throw new InvalidOperationException("Error in alias resolution."); + } + } + } #endif - events.Expect(); - } - - /// - /// Initializes a new instance of the class. - /// - public YamlSequenceNode() - { - } - - /// - /// Initializes a new instance of the class. - /// - public YamlSequenceNode(params YamlNode[] children) - : this((IEnumerable)children) - { - } - - /// - /// Initializes a new instance of the class. - /// - public YamlSequenceNode(IEnumerable children) - { - foreach (var child in children) - { - this.children.Add(child); - } - } - - /// - /// Adds the specified child to the collection. - /// - /// The child. - public void Add(YamlNode child) - { - children.Add(child); - } - - /// - /// Adds a scalar node to the collection. - /// - /// The child. - public void Add(string child) - { - children.Add(new YamlScalarNode(child)); - } - - /// - /// Resolves the aliases that could not be resolved when the node was created. - /// - /// The state of the document. - internal override void ResolveAliases(DocumentLoadingState state) - { - for (int i = 0; i < children.Count; ++i) - { - if (children[i] is YamlAliasNode) - { - children[i] = state.GetNode(children[i].Anchor, true, children[i].Start, children[i].End); - } - } - } - - /// - /// Saves the current node to the specified emitter. - /// - /// The emitter where the node is to be saved. - /// The state. - internal override void Emit(IEmitter emitter, EmitterState state) - { + events.Expect(); + } + + /// + /// Initializes a new instance of the class. + /// + public YamlSequenceNode() + { + } + + /// + /// Initializes a new instance of the class. + /// + public YamlSequenceNode(params YamlNode[] children) + : this((IEnumerable)children) + { + } + + /// + /// Initializes a new instance of the class. + /// + public YamlSequenceNode(IEnumerable children) + { + foreach (var child in children) + { + this.children.Add(child); + } + } + + /// + /// Adds the specified child to the collection. + /// + /// The child. + public void Add(YamlNode child) + { + children.Add(child); + } + + /// + /// Adds a scalar node to the collection. + /// + /// The child. + public void Add(string child) + { + children.Add(new YamlScalarNode(child)); + } + + /// + /// Resolves the aliases that could not be resolved when the node was created. + /// + /// The state of the document. + internal override void ResolveAliases(DocumentLoadingState state) + { + for (int i = 0; i < children.Count; ++i) + { + if (children[i] is YamlAliasNode) + { + children[i] = state.GetNode(children[i].Anchor, true, children[i].Start, children[i].End); + } + } + } + + /// + /// Saves the current node to the specified emitter. + /// + /// The emitter where the node is to be saved. + /// The state. + internal override void Emit(IEmitter emitter, EmitterState state) + { emitter.Emit(new SequenceStart(Anchor, Tag, true, Style)); - foreach (var node in children) - { - node.Save(emitter, state); - } - emitter.Emit(new SequenceEnd()); - } - - /// - /// Accepts the specified visitor by calling the appropriate Visit method on it. - /// - /// - /// A . - /// - public override void Accept(IYamlVisitor visitor) - { - visitor.Visit(this); - } - - /// - public override bool Equals(object other) - { - var obj = other as YamlSequenceNode; - if (obj == null || !Equals(obj) || children.Count != obj.children.Count) - { - return false; - } - - for (int i = 0; i < children.Count; ++i) - { - if (!SafeEquals(children[i], obj.children[i])) - { - return false; - } - } - - return true; - } - - /// - /// Serves as a hash function for a particular type. - /// - /// - /// A hash code for the current . - /// - public override int GetHashCode() - { - var hashCode = base.GetHashCode(); - - foreach (var item in children) - { - hashCode = CombineHashCodes(hashCode, GetHashCode(item)); - } - return hashCode; - } - - /// - /// Gets all nodes from the document, starting on the current node. - /// - public override IEnumerable AllNodes - { - get - { - yield return this; - foreach (var child in children) - { - foreach (var node in child.AllNodes) - { - yield return node; - } - } - } - } - - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - var text = new StringBuilder("[ "); - - foreach (var child in children) - { - if(text.Length > 2) - { - text.Append(", "); - } - text.Append(child); - } - - text.Append(" ]"); - - return text.ToString(); - } - - #region IEnumerable Members - - /// - public IEnumerator GetEnumerator() - { - return Children.GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - } + foreach (var node in children) + { + node.Save(emitter, state); + } + emitter.Emit(new SequenceEnd()); + } + + /// + /// Accepts the specified visitor by calling the appropriate Visit method on it. + /// + /// + /// A . + /// + public override void Accept(IYamlVisitor visitor) + { + visitor.Visit(this); + } + + /// + public override bool Equals(object other) + { + var obj = other as YamlSequenceNode; + if (obj == null || !Equals(obj) || children.Count != obj.children.Count) + { + return false; + } + + for (int i = 0; i < children.Count; ++i) + { + if (!SafeEquals(children[i], obj.children[i])) + { + return false; + } + } + + return true; + } + + /// + /// Serves as a hash function for a particular type. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + var hashCode = base.GetHashCode(); + + foreach (var item in children) + { + hashCode = CombineHashCodes(hashCode, GetHashCode(item)); + } + return hashCode; + } + + /// + /// Gets all nodes from the document, starting on the current node. + /// + public override IEnumerable AllNodes + { + get + { + yield return this; + foreach (var child in children) + { + foreach (var node in child.AllNodes) + { + yield return node; + } + } + } + } + + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + var text = new StringBuilder("[ "); + + foreach (var child in children) + { + if(text.Length > 2) + { + text.Append(", "); + } + text.Append(child); + } + + text.Append(" ]"); + + return text.ToString(); + } + + #region IEnumerable Members + + /// + public IEnumerator GetEnumerator() + { + return Children.GetEnumerator(); + } + + #endregion + + #region IEnumerable Members + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + #endregion + } } \ No newline at end of file diff --git a/YamlDotNet/RepresentationModel/YamlStream.cs b/YamlDotNet/RepresentationModel/YamlStream.cs index 349c6fffa..04858feaf 100644 --- a/YamlDotNet/RepresentationModel/YamlStream.cs +++ b/YamlDotNet/RepresentationModel/YamlStream.cs @@ -27,69 +27,69 @@ namespace YamlDotNet.RepresentationModel { - /// - /// Represents an YAML stream. - /// - [Serializable] - public class YamlStream : IEnumerable - { - private readonly IList documents = new List(); - - /// - /// Gets the documents inside the stream. - /// - /// The documents. - public IList Documents - { - get - { - return documents; - } - } - - /// - /// Initializes a new instance of the class. - /// - public YamlStream() - { - } - - /// - /// Initializes a new instance of the class. - /// - public YamlStream(params YamlDocument[] documents) - : this((IEnumerable)documents) - { - } - - /// - /// Initializes a new instance of the class. - /// - public YamlStream(IEnumerable documents) - { - foreach (var document in documents) - { - this.documents.Add(document); - } - } - - /// - /// Adds the specified document to the collection. - /// - /// The document. - public void Add(YamlDocument document) - { - documents.Add(document); - } - - /// - /// Loads the stream from the specified input. - /// - /// The input. - public void Load(TextReader input) - { + /// + /// Represents an YAML stream. + /// + [Serializable] + public class YamlStream : IEnumerable + { + private readonly IList documents = new List(); + + /// + /// Gets the documents inside the stream. + /// + /// The documents. + public IList Documents + { + get + { + return documents; + } + } + + /// + /// Initializes a new instance of the class. + /// + public YamlStream() + { + } + + /// + /// Initializes a new instance of the class. + /// + public YamlStream(params YamlDocument[] documents) + : this((IEnumerable)documents) + { + } + + /// + /// Initializes a new instance of the class. + /// + public YamlStream(IEnumerable documents) + { + foreach (var document in documents) + { + this.documents.Add(document); + } + } + + /// + /// Adds the specified document to the collection. + /// + /// The document. + public void Add(YamlDocument document) + { + documents.Add(document); + } + + /// + /// Loads the stream from the specified input. + /// + /// The input. + public void Load(TextReader input) + { Load(new EventReader(new Parser(input))); - } + } /// /// Loads the stream from the specified . @@ -106,61 +106,61 @@ public void Load(EventReader reader) reader.Expect(); } - /// - /// Saves the stream to the specified output. - /// - /// The output. - public void Save(TextWriter output) - { - Save(output, true); - } - - /// - /// Saves the stream to the specified output. - /// - /// The output. - /// Indicates whether or not to assign node anchors. - public void Save(TextWriter output, bool assignAnchors) - { - IEmitter emitter = new Emitter(output); - emitter.Emit(new StreamStart()); - - foreach (var document in documents) - { - document.Save(emitter, assignAnchors); - } - - emitter.Emit(new StreamEnd()); - } - - /// - /// Accepts the specified visitor by calling the appropriate Visit method on it. - /// - /// - /// A . - /// - public void Accept(IYamlVisitor visitor) - { - visitor.Visit(this); - } - - #region IEnumerable Members - - /// - public IEnumerator GetEnumerator() - { - return documents.GetEnumerator(); - } - - #endregion - - #region IEnumerable Members - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - #endregion - } + /// + /// Saves the stream to the specified output. + /// + /// The output. + public void Save(TextWriter output) + { + Save(output, true); + } + + /// + /// Saves the stream to the specified output. + /// + /// The output. + /// Indicates whether or not to assign node anchors. + public void Save(TextWriter output, bool assignAnchors) + { + IEmitter emitter = new Emitter(output); + emitter.Emit(new StreamStart()); + + foreach (var document in documents) + { + document.Save(emitter, assignAnchors); + } + + emitter.Emit(new StreamEnd()); + } + + /// + /// Accepts the specified visitor by calling the appropriate Visit method on it. + /// + /// + /// A . + /// + public void Accept(IYamlVisitor visitor) + { + visitor.Visit(this); + } + + #region IEnumerable Members + + /// + public IEnumerator GetEnumerator() + { + return documents.GetEnumerator(); + } + + #endregion + + #region IEnumerable Members + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + #endregion + } } \ No newline at end of file diff --git a/YamlDotNet/RepresentationModel/YamlVisitor.cs b/YamlDotNet/RepresentationModel/YamlVisitor.cs index f685623c0..ab9fe95f4 100644 --- a/YamlDotNet/RepresentationModel/YamlVisitor.cs +++ b/YamlDotNet/RepresentationModel/YamlVisitor.cs @@ -23,200 +23,200 @@ 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); - } - } + /// + /// 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/Serialization/Deserializer.cs b/YamlDotNet/Serialization/Deserializer.cs index 85d56198e..7fec077f5 100644 --- a/YamlDotNet/Serialization/Deserializer.cs +++ b/YamlDotNet/Serialization/Deserializer.cs @@ -35,177 +35,177 @@ namespace YamlDotNet.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; - - public IList NodeDeserializers { get; private set; } - public IList TypeResolvers { get; private set; } - - private class TypeDescriptorProxy : ITypeInspector - { - public ITypeInspector TypeDescriptor; - - public IEnumerable GetProperties(Type type, object container) - { - return TypeDescriptor.GetProperties(type, container); - } - - public IPropertyDescriptor GetProperty(Type type, object container, string name, bool ignoreUnmatched) - { - return TypeDescriptor.GetProperty(type, container, name, ignoreUnmatched); - } - } - - public Deserializer( - IObjectFactory objectFactory = null, - INamingConvention namingConvention = null, - bool ignoreUnmatched = false) - { - objectFactory = objectFactory ?? new DefaultObjectFactory(); - namingConvention = namingConvention ?? new NullNamingConvention(); - - typeDescriptor.TypeDescriptor = - new CachedTypeInspector( - new YamlAttributesTypeInspector( - new NamingConventionTypeInspector( - new ReadableAndWritablePropertiesTypeInspector( - new ReadablePropertiesTypeInspector( - new StaticTypeResolver() - ) - ), - namingConvention - ) - ) - ); - - converters = new List(); + /// + /// 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; + + public IList NodeDeserializers { get; private set; } + public IList TypeResolvers { get; private set; } + + private class TypeDescriptorProxy : ITypeInspector + { + public ITypeInspector TypeDescriptor; + + public IEnumerable GetProperties(Type type, object container) + { + return TypeDescriptor.GetProperties(type, container); + } + + public IPropertyDescriptor GetProperty(Type type, object container, string name, bool ignoreUnmatched) + { + return TypeDescriptor.GetProperty(type, container, name, ignoreUnmatched); + } + } + + public Deserializer( + IObjectFactory objectFactory = null, + INamingConvention namingConvention = null, + bool ignoreUnmatched = false) + { + objectFactory = objectFactory ?? new DefaultObjectFactory(); + namingConvention = namingConvention ?? new NullNamingConvention(); + + typeDescriptor.TypeDescriptor = + new CachedTypeInspector( + new YamlAttributesTypeInspector( + new NamingConventionTypeInspector( + new ReadableAndWritablePropertiesTypeInspector( + new ReadablePropertiesTypeInspector( + new StaticTypeResolver() + ) + ), + namingConvention + ) + ) + ); + + converters = new List(); foreach (IYamlTypeConverter yamlTypeConverter in YamlTypeConverters.BuiltInConverters) { converters.Add(yamlTypeConverter); } - 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, ignoreUnmatched)); - - tagMappings = new Dictionary(predefinedTagMappings); - TypeResolvers = new List(); - TypeResolvers.Add(new TagNodeTypeResolver(tagMappings)); - TypeResolvers.Add(new TypeNameInTagNodeTypeResolver()); - TypeResolvers.Add(new DefaultContainersNodeTypeResolver()); - - valueDeserializer = - new AliasValueDeserializer( - new NodeValueDeserializer( - NodeDeserializers, - TypeResolvers - ) - ); - } - - public void RegisterTagMapping(string tag, Type type) - { - tagMappings.Add(tag, type); - } - - public void RegisterTypeConverter(IYamlTypeConverter typeConverter) - { - converters.Add(typeConverter); - } - - public T Deserialize(TextReader input) - { - return (T)Deserialize(input, typeof(T)); - } - - public object Deserialize(TextReader input) - { - return Deserialize(input, typeof(object)); - } - - public object Deserialize(TextReader input, Type type) - { - return Deserialize(new EventReader(new Parser(input)), type); - } - - public T Deserialize(EventReader reader) - { - return (T)Deserialize(reader, typeof(T)); - } - - public object Deserialize(EventReader reader) - { - return Deserialize(reader, typeof(object)); - } - - /// - /// Deserializes an object of the specified type. - /// - /// The where to deserialize the object. - /// The static type of the object to deserialize. - /// Returns the deserialized object. - public object Deserialize(EventReader reader, Type type) - { - if (reader == null) - { - throw new ArgumentNullException("reader"); - } - - if (type == null) - { - throw new ArgumentNullException("type"); - } - - var hasStreamStart = reader.Allow() != null; - - var hasDocumentStart = reader.Allow() != null; - - object result = null; - if (!reader.Accept() && !reader.Accept()) - { - using (var state = new SerializerState()) - { - result = valueDeserializer.DeserializeValue(reader, type, state, valueDeserializer); - state.OnDeserialization(); - } - } - - if (hasDocumentStart) - { - reader.Expect(); - } - - if (hasStreamStart) - { - reader.Expect(); - } - - return result; - } - } + 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, ignoreUnmatched)); + + tagMappings = new Dictionary(predefinedTagMappings); + TypeResolvers = new List(); + TypeResolvers.Add(new TagNodeTypeResolver(tagMappings)); + TypeResolvers.Add(new TypeNameInTagNodeTypeResolver()); + TypeResolvers.Add(new DefaultContainersNodeTypeResolver()); + + valueDeserializer = + new AliasValueDeserializer( + new NodeValueDeserializer( + NodeDeserializers, + TypeResolvers + ) + ); + } + + public void RegisterTagMapping(string tag, Type type) + { + tagMappings.Add(tag, type); + } + + public void RegisterTypeConverter(IYamlTypeConverter typeConverter) + { + converters.Add(typeConverter); + } + + public T Deserialize(TextReader input) + { + return (T)Deserialize(input, typeof(T)); + } + + public object Deserialize(TextReader input) + { + return Deserialize(input, typeof(object)); + } + + public object Deserialize(TextReader input, Type type) + { + return Deserialize(new EventReader(new Parser(input)), type); + } + + public T Deserialize(EventReader reader) + { + return (T)Deserialize(reader, typeof(T)); + } + + public object Deserialize(EventReader reader) + { + return Deserialize(reader, typeof(object)); + } + + /// + /// Deserializes an object of the specified type. + /// + /// The where to deserialize the object. + /// The static type of the object to deserialize. + /// Returns the deserialized object. + public object Deserialize(EventReader reader, Type type) + { + if (reader == null) + { + throw new ArgumentNullException("reader"); + } + + if (type == null) + { + throw new ArgumentNullException("type"); + } + + var hasStreamStart = reader.Allow() != null; + + var hasDocumentStart = reader.Allow() != null; + + object result = null; + if (!reader.Accept() && !reader.Accept()) + { + using (var state = new SerializerState()) + { + result = valueDeserializer.DeserializeValue(reader, type, state, valueDeserializer); + state.OnDeserialization(); + } + } + + if (hasDocumentStart) + { + reader.Expect(); + } + + if (hasStreamStart) + { + reader.Expect(); + } + + return result; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/EventEmitters/ChainedEventEmitter.cs b/YamlDotNet/Serialization/EventEmitters/ChainedEventEmitter.cs index 2095a455a..5bd847a1d 100644 --- a/YamlDotNet/Serialization/EventEmitters/ChainedEventEmitter.cs +++ b/YamlDotNet/Serialization/EventEmitters/ChainedEventEmitter.cs @@ -23,52 +23,52 @@ namespace YamlDotNet.Serialization.EventEmitters { - /// - /// Provided the base implementation for an IEventEmitter that is a - /// decorator for another IEventEmitter. - /// - public abstract class ChainedEventEmitter : IEventEmitter - { - protected readonly IEventEmitter nextEmitter; + /// + /// Provided the base implementation for an IEventEmitter that is a + /// decorator for another IEventEmitter. + /// + public abstract class ChainedEventEmitter : IEventEmitter + { + protected readonly IEventEmitter nextEmitter; - protected ChainedEventEmitter(IEventEmitter nextEmitter) - { - if (nextEmitter == null) - { - throw new ArgumentNullException("nextEmitter"); - } + protected ChainedEventEmitter(IEventEmitter nextEmitter) + { + if (nextEmitter == null) + { + throw new ArgumentNullException("nextEmitter"); + } - this.nextEmitter = nextEmitter; - } + this.nextEmitter = nextEmitter; + } - public virtual void Emit(AliasEventInfo eventInfo) - { - nextEmitter.Emit(eventInfo); - } + public virtual void Emit(AliasEventInfo eventInfo) + { + nextEmitter.Emit(eventInfo); + } - public virtual void Emit(ScalarEventInfo eventInfo) - { - nextEmitter.Emit(eventInfo); - } + public virtual void Emit(ScalarEventInfo eventInfo) + { + nextEmitter.Emit(eventInfo); + } - public virtual void Emit(MappingStartEventInfo eventInfo) - { - nextEmitter.Emit(eventInfo); - } + public virtual void Emit(MappingStartEventInfo eventInfo) + { + nextEmitter.Emit(eventInfo); + } - public virtual void Emit(MappingEndEventInfo eventInfo) - { - nextEmitter.Emit(eventInfo); - } + public virtual void Emit(MappingEndEventInfo eventInfo) + { + nextEmitter.Emit(eventInfo); + } - public virtual void Emit(SequenceStartEventInfo eventInfo) - { - nextEmitter.Emit(eventInfo); - } + public virtual void Emit(SequenceStartEventInfo eventInfo) + { + nextEmitter.Emit(eventInfo); + } - public virtual void Emit(SequenceEndEventInfo eventInfo) - { - nextEmitter.Emit(eventInfo); - } - } + public virtual void Emit(SequenceEndEventInfo eventInfo) + { + nextEmitter.Emit(eventInfo); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/EventEmitters/JsonEventEmitter.cs b/YamlDotNet/Serialization/EventEmitters/JsonEventEmitter.cs index bb1457467..de2280fc7 100644 --- a/YamlDotNet/Serialization/EventEmitters/JsonEventEmitter.cs +++ b/YamlDotNet/Serialization/EventEmitters/JsonEventEmitter.cs @@ -26,86 +26,86 @@ namespace YamlDotNet.Serialization.EventEmitters { - public sealed class JsonEventEmitter : ChainedEventEmitter - { - public JsonEventEmitter(IEventEmitter nextEmitter) - : base(nextEmitter) - { - } - - public override void Emit(AliasEventInfo eventInfo) - { - throw new NotSupportedException("Aliases are not supported in JSON"); - } - - public override void Emit(ScalarEventInfo eventInfo) - { - eventInfo.IsPlainImplicit = true; - eventInfo.Style = ScalarStyle.Plain; - - var typeCode = eventInfo.Source.Value != null - ? eventInfo.Source.Type.GetTypeCode() - : TypeCode.Empty; - - switch (typeCode) - { - case TypeCode.Boolean: - eventInfo.RenderedValue = YamlFormatter.FormatBoolean(eventInfo.Source.Value); - break; - - case TypeCode.Byte: - case TypeCode.Int16: - case TypeCode.Int32: - case TypeCode.Int64: - case TypeCode.SByte: - case TypeCode.UInt16: - case TypeCode.UInt32: - case TypeCode.UInt64: - case TypeCode.Single: - case TypeCode.Double: - case TypeCode.Decimal: - eventInfo.RenderedValue = YamlFormatter.FormatNumber(eventInfo.Source.Value); - break; - - case TypeCode.String: - case TypeCode.Char: - eventInfo.RenderedValue = eventInfo.Source.Value.ToString(); - eventInfo.Style = ScalarStyle.DoubleQuoted; - break; - - case TypeCode.DateTime: - eventInfo.RenderedValue = YamlFormatter.FormatDateTime(eventInfo.Source.Value); - break; - - case TypeCode.Empty: - eventInfo.RenderedValue = "null"; - break; - - default: - if (eventInfo.Source.Type == typeof(TimeSpan)) - { - eventInfo.RenderedValue = YamlFormatter.FormatTimeSpan(eventInfo.Source.Value); - break; - } - - throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "TypeCode.{0} is not supported.", typeCode)); - } - - base.Emit(eventInfo); - } - - public override void Emit(MappingStartEventInfo eventInfo) - { - eventInfo.Style = MappingStyle.Flow; - - base.Emit(eventInfo); - } - - public override void Emit(SequenceStartEventInfo eventInfo) - { - eventInfo.Style = SequenceStyle.Flow; - - base.Emit(eventInfo); - } - } + public sealed class JsonEventEmitter : ChainedEventEmitter + { + public JsonEventEmitter(IEventEmitter nextEmitter) + : base(nextEmitter) + { + } + + public override void Emit(AliasEventInfo eventInfo) + { + throw new NotSupportedException("Aliases are not supported in JSON"); + } + + public override void Emit(ScalarEventInfo eventInfo) + { + eventInfo.IsPlainImplicit = true; + eventInfo.Style = ScalarStyle.Plain; + + var typeCode = eventInfo.Source.Value != null + ? eventInfo.Source.Type.GetTypeCode() + : TypeCode.Empty; + + switch (typeCode) + { + case TypeCode.Boolean: + eventInfo.RenderedValue = YamlFormatter.FormatBoolean(eventInfo.Source.Value); + break; + + case TypeCode.Byte: + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.Int64: + case TypeCode.SByte: + case TypeCode.UInt16: + case TypeCode.UInt32: + case TypeCode.UInt64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + eventInfo.RenderedValue = YamlFormatter.FormatNumber(eventInfo.Source.Value); + break; + + case TypeCode.String: + case TypeCode.Char: + eventInfo.RenderedValue = eventInfo.Source.Value.ToString(); + eventInfo.Style = ScalarStyle.DoubleQuoted; + break; + + case TypeCode.DateTime: + eventInfo.RenderedValue = YamlFormatter.FormatDateTime(eventInfo.Source.Value); + break; + + case TypeCode.Empty: + eventInfo.RenderedValue = "null"; + break; + + default: + if (eventInfo.Source.Type == typeof(TimeSpan)) + { + eventInfo.RenderedValue = YamlFormatter.FormatTimeSpan(eventInfo.Source.Value); + break; + } + + throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "TypeCode.{0} is not supported.", typeCode)); + } + + base.Emit(eventInfo); + } + + public override void Emit(MappingStartEventInfo eventInfo) + { + eventInfo.Style = MappingStyle.Flow; + + base.Emit(eventInfo); + } + + public override void Emit(SequenceStartEventInfo eventInfo) + { + eventInfo.Style = SequenceStyle.Flow; + + base.Emit(eventInfo); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/EventEmitters/TypeAssigningEventEmitter.cs b/YamlDotNet/Serialization/EventEmitters/TypeAssigningEventEmitter.cs index 7f6a438b5..09702886d 100644 --- a/YamlDotNet/Serialization/EventEmitters/TypeAssigningEventEmitter.cs +++ b/YamlDotNet/Serialization/EventEmitters/TypeAssigningEventEmitter.cs @@ -25,107 +25,107 @@ namespace YamlDotNet.Serialization.EventEmitters { - public sealed class TypeAssigningEventEmitter : ChainedEventEmitter - { - private readonly bool _assignTypeWhenDifferent; - - public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool assignTypeWhenDifferent) - : base(nextEmitter) - { - _assignTypeWhenDifferent = assignTypeWhenDifferent; - } - - public override void Emit(ScalarEventInfo eventInfo) - { - var suggestedStyle = ScalarStyle.Plain; - - var typeCode = eventInfo.Source.Value != null - ? eventInfo.Source.Type.GetTypeCode() - : TypeCode.Empty; - - switch (typeCode) - { - case TypeCode.Boolean: - eventInfo.Tag = "tag:yaml.org,2002:bool"; - eventInfo.RenderedValue = YamlFormatter.FormatBoolean(eventInfo.Source.Value); - break; - - case TypeCode.Byte: - case TypeCode.Int16: - case TypeCode.Int32: - case TypeCode.Int64: - case TypeCode.SByte: - case TypeCode.UInt16: - case TypeCode.UInt32: - case TypeCode.UInt64: - eventInfo.Tag = "tag:yaml.org,2002:int"; - eventInfo.RenderedValue = YamlFormatter.FormatNumber(eventInfo.Source.Value); - break; - - case TypeCode.Single: - case TypeCode.Double: - case TypeCode.Decimal: - eventInfo.Tag = "tag:yaml.org,2002:float"; - eventInfo.RenderedValue = YamlFormatter.FormatNumber(eventInfo.Source.Value); - break; - - case TypeCode.String: - case TypeCode.Char: - eventInfo.Tag = "tag:yaml.org,2002:str"; - eventInfo.RenderedValue = eventInfo.Source.Value.ToString(); - suggestedStyle = ScalarStyle.Any; - break; - - case TypeCode.DateTime: - eventInfo.Tag = "tag:yaml.org,2002:timestamp"; - eventInfo.RenderedValue = YamlFormatter.FormatDateTime(eventInfo.Source.Value); - break; - - case TypeCode.Empty: - eventInfo.Tag = "tag:yaml.org,2002:null"; - eventInfo.RenderedValue = ""; - break; - - default: - if (eventInfo.Source.Type == typeof(TimeSpan)) - { - eventInfo.RenderedValue = YamlFormatter.FormatTimeSpan(eventInfo.Source.Value); - break; - } - - throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "TypeCode.{0} is not supported.", typeCode)); - } - - eventInfo.IsPlainImplicit = true; - if (eventInfo.Style == ScalarStyle.Any) - { - eventInfo.Style = suggestedStyle; - } - - base.Emit(eventInfo); - } - - public override void Emit(MappingStartEventInfo eventInfo) - { - AssignTypeIfDifferent(eventInfo); - base.Emit(eventInfo); - } - - public override void Emit(SequenceStartEventInfo eventInfo) - { - AssignTypeIfDifferent(eventInfo); - base.Emit(eventInfo); - } - - private void AssignTypeIfDifferent(ObjectEventInfo eventInfo) - { - if (_assignTypeWhenDifferent && eventInfo.Source.Value != null) - { - if (eventInfo.Source.Type != eventInfo.Source.StaticType) - { - eventInfo.Tag = "!" + eventInfo.Source.Type.AssemblyQualifiedName; - } - } - } - } + public sealed class TypeAssigningEventEmitter : ChainedEventEmitter + { + private readonly bool _assignTypeWhenDifferent; + + public TypeAssigningEventEmitter(IEventEmitter nextEmitter, bool assignTypeWhenDifferent) + : base(nextEmitter) + { + _assignTypeWhenDifferent = assignTypeWhenDifferent; + } + + public override void Emit(ScalarEventInfo eventInfo) + { + var suggestedStyle = ScalarStyle.Plain; + + var typeCode = eventInfo.Source.Value != null + ? eventInfo.Source.Type.GetTypeCode() + : TypeCode.Empty; + + switch (typeCode) + { + case TypeCode.Boolean: + eventInfo.Tag = "tag:yaml.org,2002:bool"; + eventInfo.RenderedValue = YamlFormatter.FormatBoolean(eventInfo.Source.Value); + break; + + case TypeCode.Byte: + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.Int64: + case TypeCode.SByte: + case TypeCode.UInt16: + case TypeCode.UInt32: + case TypeCode.UInt64: + eventInfo.Tag = "tag:yaml.org,2002:int"; + eventInfo.RenderedValue = YamlFormatter.FormatNumber(eventInfo.Source.Value); + break; + + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + eventInfo.Tag = "tag:yaml.org,2002:float"; + eventInfo.RenderedValue = YamlFormatter.FormatNumber(eventInfo.Source.Value); + break; + + case TypeCode.String: + case TypeCode.Char: + eventInfo.Tag = "tag:yaml.org,2002:str"; + eventInfo.RenderedValue = eventInfo.Source.Value.ToString(); + suggestedStyle = ScalarStyle.Any; + break; + + case TypeCode.DateTime: + eventInfo.Tag = "tag:yaml.org,2002:timestamp"; + eventInfo.RenderedValue = YamlFormatter.FormatDateTime(eventInfo.Source.Value); + break; + + case TypeCode.Empty: + eventInfo.Tag = "tag:yaml.org,2002:null"; + eventInfo.RenderedValue = ""; + break; + + default: + if (eventInfo.Source.Type == typeof(TimeSpan)) + { + eventInfo.RenderedValue = YamlFormatter.FormatTimeSpan(eventInfo.Source.Value); + break; + } + + throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "TypeCode.{0} is not supported.", typeCode)); + } + + eventInfo.IsPlainImplicit = true; + if (eventInfo.Style == ScalarStyle.Any) + { + eventInfo.Style = suggestedStyle; + } + + base.Emit(eventInfo); + } + + public override void Emit(MappingStartEventInfo eventInfo) + { + AssignTypeIfDifferent(eventInfo); + base.Emit(eventInfo); + } + + public override void Emit(SequenceStartEventInfo eventInfo) + { + AssignTypeIfDifferent(eventInfo); + base.Emit(eventInfo); + } + + private void AssignTypeIfDifferent(ObjectEventInfo eventInfo) + { + if (_assignTypeWhenDifferent && eventInfo.Source.Value != null) + { + if (eventInfo.Source.Type != eventInfo.Source.StaticType) + { + eventInfo.Tag = "!" + eventInfo.Source.Type.AssemblyQualifiedName; + } + } + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/EventEmitters/WriterEventEmitter.cs b/YamlDotNet/Serialization/EventEmitters/WriterEventEmitter.cs index 32844faff..6c9b23956 100644 --- a/YamlDotNet/Serialization/EventEmitters/WriterEventEmitter.cs +++ b/YamlDotNet/Serialization/EventEmitters/WriterEventEmitter.cs @@ -24,43 +24,43 @@ namespace YamlDotNet.Serialization.EventEmitters { - public sealed class WriterEventEmitter : IEventEmitter - { - private readonly IEmitter emitter; + public sealed class WriterEventEmitter : IEventEmitter + { + private readonly IEmitter emitter; - public WriterEventEmitter(IEmitter emitter) - { - this.emitter = emitter; - } + public WriterEventEmitter(IEmitter emitter) + { + this.emitter = emitter; + } - void IEventEmitter.Emit(AliasEventInfo eventInfo) - { - emitter.Emit(new AnchorAlias(eventInfo.Alias)); - } + void IEventEmitter.Emit(AliasEventInfo eventInfo) + { + emitter.Emit(new AnchorAlias(eventInfo.Alias)); + } - void IEventEmitter.Emit(ScalarEventInfo eventInfo) - { - emitter.Emit(new Scalar(eventInfo.Anchor, eventInfo.Tag, eventInfo.RenderedValue, eventInfo.Style, eventInfo.IsPlainImplicit, eventInfo.IsQuotedImplicit)); - } + void IEventEmitter.Emit(ScalarEventInfo eventInfo) + { + emitter.Emit(new Scalar(eventInfo.Anchor, eventInfo.Tag, eventInfo.RenderedValue, eventInfo.Style, eventInfo.IsPlainImplicit, eventInfo.IsQuotedImplicit)); + } - void IEventEmitter.Emit(MappingStartEventInfo eventInfo) - { - emitter.Emit(new MappingStart(eventInfo.Anchor, eventInfo.Tag, eventInfo.IsImplicit, eventInfo.Style)); - } + void IEventEmitter.Emit(MappingStartEventInfo eventInfo) + { + emitter.Emit(new MappingStart(eventInfo.Anchor, eventInfo.Tag, eventInfo.IsImplicit, eventInfo.Style)); + } - void IEventEmitter.Emit(MappingEndEventInfo eventInfo) - { - emitter.Emit(new MappingEnd()); - } + void IEventEmitter.Emit(MappingEndEventInfo eventInfo) + { + emitter.Emit(new MappingEnd()); + } - void IEventEmitter.Emit(SequenceStartEventInfo eventInfo) - { - emitter.Emit(new SequenceStart(eventInfo.Anchor, eventInfo.Tag, eventInfo.IsImplicit, eventInfo.Style)); - } + void IEventEmitter.Emit(SequenceStartEventInfo eventInfo) + { + emitter.Emit(new SequenceStart(eventInfo.Anchor, eventInfo.Tag, eventInfo.IsImplicit, eventInfo.Style)); + } - void IEventEmitter.Emit(SequenceEndEventInfo eventInfo) - { - emitter.Emit(new SequenceEnd()); - } - } + void IEventEmitter.Emit(SequenceEndEventInfo eventInfo) + { + emitter.Emit(new SequenceEnd()); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/EventInfo.cs b/YamlDotNet/Serialization/EventInfo.cs index 0f5be33b5..37116cb8d 100644 --- a/YamlDotNet/Serialization/EventInfo.cs +++ b/YamlDotNet/Serialization/EventInfo.cs @@ -24,86 +24,86 @@ namespace YamlDotNet.Serialization { - public abstract class EventInfo - { - public IObjectDescriptor Source { get; private set; } + public abstract class EventInfo + { + public IObjectDescriptor Source { get; private set; } - protected EventInfo(IObjectDescriptor source) - { - Source = source; - } - } + protected EventInfo(IObjectDescriptor source) + { + Source = source; + } + } - public class AliasEventInfo : EventInfo - { - public AliasEventInfo(IObjectDescriptor source) - : base(source) - { - } + public class AliasEventInfo : EventInfo + { + public AliasEventInfo(IObjectDescriptor source) + : base(source) + { + } - public string Alias { get; set; } - } + public string Alias { get; set; } + } - public class ObjectEventInfo : EventInfo - { - protected ObjectEventInfo(IObjectDescriptor source) - : base(source) - { - } + public class ObjectEventInfo : EventInfo + { + protected ObjectEventInfo(IObjectDescriptor source) + : base(source) + { + } - public string Anchor { get; set; } - public string Tag { get; set; } - } + public string Anchor { get; set; } + public string Tag { get; set; } + } - public sealed class ScalarEventInfo : ObjectEventInfo - { - public ScalarEventInfo(IObjectDescriptor source) - : base(source) - { - Style = source.ScalarStyle; - } + public sealed class ScalarEventInfo : ObjectEventInfo + { + public ScalarEventInfo(IObjectDescriptor source) + : base(source) + { + Style = source.ScalarStyle; + } - public string RenderedValue { get; set; } - public ScalarStyle Style { get; set; } - public bool IsPlainImplicit { get; set; } - public bool IsQuotedImplicit { get; set; } - } + public string RenderedValue { get; set; } + public ScalarStyle Style { get; set; } + public bool IsPlainImplicit { get; set; } + public bool IsQuotedImplicit { get; set; } + } - public sealed class MappingStartEventInfo : ObjectEventInfo - { - public MappingStartEventInfo(IObjectDescriptor source) - : base(source) - { - } + public sealed class MappingStartEventInfo : ObjectEventInfo + { + public MappingStartEventInfo(IObjectDescriptor source) + : base(source) + { + } - public bool IsImplicit { get; set; } - public MappingStyle Style { get; set; } - } + public bool IsImplicit { get; set; } + public MappingStyle Style { get; set; } + } - public sealed class MappingEndEventInfo : EventInfo - { - public MappingEndEventInfo(IObjectDescriptor source) - : base(source) - { - } - } + public sealed class MappingEndEventInfo : EventInfo + { + public MappingEndEventInfo(IObjectDescriptor source) + : base(source) + { + } + } - public sealed class SequenceStartEventInfo : ObjectEventInfo - { - public SequenceStartEventInfo(IObjectDescriptor source) - : base(source) - { - } + public sealed class SequenceStartEventInfo : ObjectEventInfo + { + public SequenceStartEventInfo(IObjectDescriptor source) + : base(source) + { + } - public bool IsImplicit { get; set; } - public SequenceStyle Style { get; set; } - } + public bool IsImplicit { get; set; } + public SequenceStyle Style { get; set; } + } - public sealed class SequenceEndEventInfo : EventInfo - { - public SequenceEndEventInfo(IObjectDescriptor source) - : base(source) - { - } - } + public sealed class SequenceEndEventInfo : EventInfo + { + public SequenceEndEventInfo(IObjectDescriptor source) + : base(source) + { + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/IAliasProvider.cs b/YamlDotNet/Serialization/IAliasProvider.cs index 5ef10f73f..bd2b51f71 100644 --- a/YamlDotNet/Serialization/IAliasProvider.cs +++ b/YamlDotNet/Serialization/IAliasProvider.cs @@ -21,8 +21,8 @@ namespace YamlDotNet.Serialization { - public interface IAliasProvider - { - string GetAlias(object target); - } + public interface IAliasProvider + { + string GetAlias(object target); + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/IEventEmitter.cs b/YamlDotNet/Serialization/IEventEmitter.cs index c8c82a611..52a0ed702 100644 --- a/YamlDotNet/Serialization/IEventEmitter.cs +++ b/YamlDotNet/Serialization/IEventEmitter.cs @@ -21,13 +21,13 @@ namespace YamlDotNet.Serialization { - public interface IEventEmitter - { - void Emit(AliasEventInfo eventInfo); - void Emit(ScalarEventInfo eventInfo); - void Emit(MappingStartEventInfo eventInfo); - void Emit(MappingEndEventInfo eventInfo); - void Emit(SequenceStartEventInfo eventInfo); - void Emit(SequenceEndEventInfo eventInfo); - } + public interface IEventEmitter + { + void Emit(AliasEventInfo eventInfo); + void Emit(ScalarEventInfo eventInfo); + void Emit(MappingStartEventInfo eventInfo); + void Emit(MappingEndEventInfo eventInfo); + void Emit(SequenceStartEventInfo eventInfo); + void Emit(SequenceEndEventInfo eventInfo); + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/INamingConvention.cs b/YamlDotNet/Serialization/INamingConvention.cs index 19672fc3f..bd618c7ff 100644 --- a/YamlDotNet/Serialization/INamingConvention.cs +++ b/YamlDotNet/Serialization/INamingConvention.cs @@ -22,11 +22,11 @@ namespace YamlDotNet.Serialization { - /// - /// Translates property names according to a specific convention. - /// - public interface INamingConvention - { - string Apply(string value); - } + /// + /// Translates property names according to a specific convention. + /// + public interface INamingConvention + { + string Apply(string value); + } } diff --git a/YamlDotNet/Serialization/INodeDeserializer.cs b/YamlDotNet/Serialization/INodeDeserializer.cs index ccd9b7942..4c78a858a 100644 --- a/YamlDotNet/Serialization/INodeDeserializer.cs +++ b/YamlDotNet/Serialization/INodeDeserializer.cs @@ -24,8 +24,8 @@ namespace YamlDotNet.Serialization { - public interface INodeDeserializer - { - bool Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value); - } + public interface INodeDeserializer + { + bool Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value); + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/INodeTypeResolver.cs b/YamlDotNet/Serialization/INodeTypeResolver.cs index 3cc0d10f6..7f39a6158 100644 --- a/YamlDotNet/Serialization/INodeTypeResolver.cs +++ b/YamlDotNet/Serialization/INodeTypeResolver.cs @@ -24,17 +24,17 @@ namespace YamlDotNet.Serialization { - public interface INodeTypeResolver - { - /// - /// Determines the type of the specified node. - /// - /// The node to be deserialized. - /// The type that has been determined so far. - /// - /// true if has been resolved completely; - /// false if the next type should be invoked. - /// - bool Resolve(NodeEvent nodeEvent, ref Type currentType); - } + public interface INodeTypeResolver + { + /// + /// Determines the type of the specified node. + /// + /// The node to be deserialized. + /// The type that has been determined so far. + /// + /// true if has been resolved completely; + /// false if the next type should be invoked. + /// + bool Resolve(NodeEvent nodeEvent, ref Type currentType); + } } diff --git a/YamlDotNet/Serialization/IObjectDescriptor.cs b/YamlDotNet/Serialization/IObjectDescriptor.cs index a56b86157..ea75ef7fd 100644 --- a/YamlDotNet/Serialization/IObjectDescriptor.cs +++ b/YamlDotNet/Serialization/IObjectDescriptor.cs @@ -24,29 +24,29 @@ namespace YamlDotNet.Serialization { - /// - /// Represents an object along with its type. - /// - public interface IObjectDescriptor - { - /// - /// A reference to the object. - /// - object Value { get; } + /// + /// Represents an object along with its type. + /// + public interface IObjectDescriptor + { + /// + /// A reference to the object. + /// + object Value { get; } - /// - /// The type that should be used when to interpret the . - /// - Type Type { get; } + /// + /// The type that should be used when to interpret the . + /// + Type Type { get; } - /// - /// The type of as determined by its container (e.g. a property). - /// - Type StaticType { get; } + /// + /// The type of as determined by its container (e.g. a property). + /// + Type StaticType { get; } - /// - /// The style to be used for scalars. - /// - ScalarStyle ScalarStyle { get; } - } + /// + /// The style to be used for scalars. + /// + ScalarStyle ScalarStyle { get; } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/IObjectFactory.cs b/YamlDotNet/Serialization/IObjectFactory.cs index 8abf0989c..184a7e9b7 100644 --- a/YamlDotNet/Serialization/IObjectFactory.cs +++ b/YamlDotNet/Serialization/IObjectFactory.cs @@ -23,17 +23,17 @@ namespace YamlDotNet.Serialization { - /// - /// Creates instances of types. - /// - /// - /// This interface allows to provide a custom logic for creating instances during deserialization. - /// - public interface IObjectFactory - { - /// - /// Creates an instance of the specified type. - /// - object Create(Type type); - } + /// + /// Creates instances of types. + /// + /// + /// This interface allows to provide a custom logic for creating instances during deserialization. + /// + public interface IObjectFactory + { + /// + /// Creates an instance of the specified type. + /// + object Create(Type type); + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/IObjectGraphTraversalStrategy.cs b/YamlDotNet/Serialization/IObjectGraphTraversalStrategy.cs index 5819a050e..1385cbe51 100644 --- a/YamlDotNet/Serialization/IObjectGraphTraversalStrategy.cs +++ b/YamlDotNet/Serialization/IObjectGraphTraversalStrategy.cs @@ -21,16 +21,16 @@ namespace YamlDotNet.Serialization { - /// - /// Defines a strategy that walks through an object graph. - /// - public interface IObjectGraphTraversalStrategy - { - /// - /// Traverses the specified object graph. - /// - /// The graph. - /// An that is to be notified during the traversal. - void Traverse(IObjectDescriptor graph, IObjectGraphVisitor visitor); - } + /// + /// Defines a strategy that walks through an object graph. + /// + public interface IObjectGraphTraversalStrategy + { + /// + /// Traverses the specified object graph. + /// + /// The graph. + /// An that is to be notified during the traversal. + void Traverse(IObjectDescriptor graph, IObjectGraphVisitor visitor); + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/IObjectGraphVisitor.cs b/YamlDotNet/Serialization/IObjectGraphVisitor.cs index 74b90318e..63d47e293 100644 --- a/YamlDotNet/Serialization/IObjectGraphVisitor.cs +++ b/YamlDotNet/Serialization/IObjectGraphVisitor.cs @@ -24,69 +24,69 @@ namespace YamlDotNet.Serialization { - /// - /// Defined the interface of a type that can be notified during an object graph traversal. - /// - public interface IObjectGraphVisitor - { - /// - /// Indicates whether the specified value should be entered. This allows the visitor to - /// override the handling of a particular object or type. - /// - /// The value that is about to be entered. - /// If the value is to be entered, returns true; otherwise returns false; - bool Enter(IObjectDescriptor value); + /// + /// Defined the interface of a type that can be notified during an object graph traversal. + /// + public interface IObjectGraphVisitor + { + /// + /// Indicates whether the specified value should be entered. This allows the visitor to + /// override the handling of a particular object or type. + /// + /// The value that is about to be entered. + /// If the value is to be entered, returns true; otherwise returns false; + bool Enter(IObjectDescriptor value); - /// - /// Indicates whether the specified mapping should be entered. This allows the visitor to - /// override the handling of a particular pair. - /// - /// The key of the mapping that is about to be entered. - /// The value of the mapping that is about to be entered. - /// If the mapping is to be entered, returns true; otherwise returns false; - bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value); + /// + /// Indicates whether the specified mapping should be entered. This allows the visitor to + /// override the handling of a particular pair. + /// + /// The key of the mapping that is about to be entered. + /// The value of the mapping that is about to be entered. + /// If the mapping is to be entered, returns true; otherwise returns false; + bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value); - /// - /// Indicates whether the specified mapping should be entered. This allows the visitor to - /// override the handling of a particular pair. This overload should be invoked when the - /// mapping is produced by an object's property. - /// - /// The that provided access to . - /// The value of the mapping that is about to be entered. - /// If the mapping is to be entered, returns true; otherwise returns false; - bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value); + /// + /// Indicates whether the specified mapping should be entered. This allows the visitor to + /// override the handling of a particular pair. This overload should be invoked when the + /// mapping is produced by an object's property. + /// + /// The that provided access to . + /// The value of the mapping that is about to be entered. + /// If the mapping is to be entered, returns true; otherwise returns false; + bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value); - /// - /// Notifies the visitor that a scalar value has been encountered. - /// - /// The value of the scalar. - void VisitScalar(IObjectDescriptor scalar); + /// + /// Notifies the visitor that a scalar value has been encountered. + /// + /// The value of the scalar. + void VisitScalar(IObjectDescriptor scalar); - /// - /// Notifies the visitor that the traversal of a mapping is about to begin. - /// - /// The value that corresponds to the mapping. - /// The static type of the keys of the mapping. - /// The static type of the values of the mapping. - void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType); + /// + /// Notifies the visitor that the traversal of a mapping is about to begin. + /// + /// The value that corresponds to the mapping. + /// The static type of the keys of the mapping. + /// The static type of the values of the mapping. + void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType); - /// - /// Notifies the visitor that the traversal of a mapping has ended. - /// - /// The value that corresponds to the mapping. - void VisitMappingEnd(IObjectDescriptor mapping); + /// + /// Notifies the visitor that the traversal of a mapping has ended. + /// + /// The value that corresponds to the mapping. + void VisitMappingEnd(IObjectDescriptor mapping); - /// - /// Notifies the visitor that the traversal of a sequence is about to begin. - /// - /// The value that corresponds to the sequence. - /// The static type of the elements of the sequence. - void VisitSequenceStart(IObjectDescriptor sequence, Type elementType); + /// + /// Notifies the visitor that the traversal of a sequence is about to begin. + /// + /// The value that corresponds to the sequence. + /// The static type of the elements of the sequence. + void VisitSequenceStart(IObjectDescriptor sequence, Type elementType); - /// - /// Notifies the visitor that the traversal of a sequence has ended. - /// - /// The value that corresponds to the sequence. - void VisitSequenceEnd(IObjectDescriptor sequence); - } + /// + /// Notifies the visitor that the traversal of a sequence has ended. + /// + /// The value that corresponds to the sequence. + void VisitSequenceEnd(IObjectDescriptor sequence); + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/IPropertyDescriptor.cs b/YamlDotNet/Serialization/IPropertyDescriptor.cs index 06e30b748..fbceba040 100644 --- a/YamlDotNet/Serialization/IPropertyDescriptor.cs +++ b/YamlDotNet/Serialization/IPropertyDescriptor.cs @@ -24,18 +24,18 @@ namespace YamlDotNet.Serialization { - public interface IPropertyDescriptor - { - string Name { get; } - bool CanWrite { get; } - Type Type { get; } - Type TypeOverride { get; set; } + public interface IPropertyDescriptor + { + string Name { get; } + bool CanWrite { get; } + Type Type { get; } + Type TypeOverride { get; set; } int Order { get; set; } - ScalarStyle ScalarStyle { get; set; } + ScalarStyle ScalarStyle { get; set; } - T GetCustomAttribute() where T : Attribute; + T GetCustomAttribute() where T : Attribute; - IObjectDescriptor Read(object target); - void Write(object target, object value); - } + IObjectDescriptor Read(object target); + void Write(object target, object value); + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/ITypeInspector.cs b/YamlDotNet/Serialization/ITypeInspector.cs index c4f0234a8..2dd3be5df 100644 --- a/YamlDotNet/Serialization/ITypeInspector.cs +++ b/YamlDotNet/Serialization/ITypeInspector.cs @@ -24,30 +24,30 @@ namespace YamlDotNet.Serialization { - /// - /// Provides access to the properties of a type. - /// - public interface ITypeInspector - { - /// - /// Gets all properties of the specified type. - /// - /// The type whose properties are to be enumerated. - /// The actual object of type whose properties are to be enumerated. Can be null. - /// - IEnumerable GetProperties(Type type, object container); + /// + /// Provides access to the properties of a type. + /// + public interface ITypeInspector + { + /// + /// Gets all properties of the specified type. + /// + /// The type whose properties are to be enumerated. + /// The actual object of type whose properties are to be enumerated. Can be null. + /// + IEnumerable GetProperties(Type type, object container); - /// - /// Gets the property of the type with the specified name. - /// - /// The type whose properties are to be searched. - /// The actual object of type whose properties are to be searched. Can be null. - /// The name of the property. - /// - /// Determines if an exception or null should be returned if can't be - /// found in - /// - /// - IPropertyDescriptor GetProperty(Type type, object container, string name, bool ignoreUnmatched); - } + /// + /// Gets the property of the type with the specified name. + /// + /// The type whose properties are to be searched. + /// The actual object of type whose properties are to be searched. Can be null. + /// The name of the property. + /// + /// Determines if an exception or null should be returned if can't be + /// found in + /// + /// + IPropertyDescriptor GetProperty(Type type, object container, string name, bool ignoreUnmatched); + } } diff --git a/YamlDotNet/Serialization/ITypeResolver.cs b/YamlDotNet/Serialization/ITypeResolver.cs index d8f86c97b..9232bb041 100644 --- a/YamlDotNet/Serialization/ITypeResolver.cs +++ b/YamlDotNet/Serialization/ITypeResolver.cs @@ -23,11 +23,11 @@ namespace YamlDotNet.Serialization { - /// - /// Resolves the type of values. - /// - public interface ITypeResolver - { - Type Resolve(Type staticType, object actualValue); - } + /// + /// Resolves the type of values. + /// + public interface ITypeResolver + { + Type Resolve(Type staticType, object actualValue); + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/IValueDeserializer.cs b/YamlDotNet/Serialization/IValueDeserializer.cs index 1bdaff954..a94df498e 100644 --- a/YamlDotNet/Serialization/IValueDeserializer.cs +++ b/YamlDotNet/Serialization/IValueDeserializer.cs @@ -25,8 +25,8 @@ namespace YamlDotNet.Serialization { - public interface IValueDeserializer - { - object DeserializeValue(EventReader reader, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer); - } + public interface IValueDeserializer + { + object DeserializeValue(EventReader reader, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer); + } } diff --git a/YamlDotNet/Serialization/IValuePromise.cs b/YamlDotNet/Serialization/IValuePromise.cs index 133e9ab80..c1dd51528 100644 --- a/YamlDotNet/Serialization/IValuePromise.cs +++ b/YamlDotNet/Serialization/IValuePromise.cs @@ -24,9 +24,9 @@ namespace YamlDotNet.Serialization { - public interface IValuePromise - { - [SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")] - event Action ValueAvailable; - } + public interface IValuePromise + { + [SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly")] + event Action ValueAvailable; + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/IYamlSerializable.cs b/YamlDotNet/Serialization/IYamlSerializable.cs index 000153007..f83b46650 100644 --- a/YamlDotNet/Serialization/IYamlSerializable.cs +++ b/YamlDotNet/Serialization/IYamlSerializable.cs @@ -23,19 +23,19 @@ namespace YamlDotNet.Serialization { - /// - /// 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); + /// + /// 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); - } + /// + /// Writes this object's state to a YAML emitter. + /// + void WriteYaml(IEmitter emitter); + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/IYamlTypeConverter.cs b/YamlDotNet/Serialization/IYamlTypeConverter.cs index ab1ee829b..8160aff1c 100644 --- a/YamlDotNet/Serialization/IYamlTypeConverter.cs +++ b/YamlDotNet/Serialization/IYamlTypeConverter.cs @@ -24,24 +24,24 @@ namespace YamlDotNet.Serialization { - /// - /// Allows to customize how a type is serialized and deserialized. - /// - public interface IYamlTypeConverter - { - /// - /// Gets a value indicating whether the current converter supports converting the specified type. - /// - bool Accepts(Type type); + /// + /// Allows to customize how a type is serialized and deserialized. + /// + public interface IYamlTypeConverter + { + /// + /// Gets a value indicating whether the current converter supports converting the specified type. + /// + bool Accepts(Type type); - /// - /// Reads an object's state from a YAML parser. - /// - object ReadYaml(IParser parser, Type type); + /// + /// Reads an object's state from a YAML parser. + /// + object ReadYaml(IParser parser, Type type); - /// - /// Writes the specified object's state to a YAML emitter. - /// - void WriteYaml(IEmitter emitter, object value, Type type); - } + /// + /// Writes the specified object's state to a YAML emitter. + /// + void WriteYaml(IEmitter emitter, object value, Type type); + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/NamingConventions/CamelCaseNamingConvention.cs b/YamlDotNet/Serialization/NamingConventions/CamelCaseNamingConvention.cs index eacce5343..1d68f2d2a 100644 --- a/YamlDotNet/Serialization/NamingConventions/CamelCaseNamingConvention.cs +++ b/YamlDotNet/Serialization/NamingConventions/CamelCaseNamingConvention.cs @@ -23,16 +23,16 @@ namespace YamlDotNet.Serialization.NamingConventions { - /// - /// 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. - /// - public sealed class CamelCaseNamingConvention : INamingConvention - { - public string Apply(string value) - { - return value.ToCamelCase(); - } - } + /// + /// 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. + /// + public sealed class CamelCaseNamingConvention : INamingConvention + { + public string Apply(string value) + { + return value.ToCamelCase(); + } + } } diff --git a/YamlDotNet/Serialization/NamingConventions/HyphenatedNamingConvention.cs b/YamlDotNet/Serialization/NamingConventions/HyphenatedNamingConvention.cs index 8cf2ed082..682919c29 100644 --- a/YamlDotNet/Serialization/NamingConventions/HyphenatedNamingConvention.cs +++ b/YamlDotNet/Serialization/NamingConventions/HyphenatedNamingConvention.cs @@ -23,14 +23,14 @@ namespace YamlDotNet.Serialization.NamingConventions { - /// - /// Convert the string from camelcase (thisIsATest) to a hyphenated (this-is-a-test) string - /// - public sealed class HyphenatedNamingConvention : INamingConvention - { - public string Apply(string value) - { - return value.FromCamelCase("-"); - } - } + /// + /// Convert the string from camelcase (thisIsATest) to a hyphenated (this-is-a-test) string + /// + public sealed class HyphenatedNamingConvention : INamingConvention + { + public string Apply(string value) + { + return value.FromCamelCase("-"); + } + } } diff --git a/YamlDotNet/Serialization/NamingConventions/NullNamingConvention.cs b/YamlDotNet/Serialization/NamingConventions/NullNamingConvention.cs index e32740e4f..68b8686cb 100644 --- a/YamlDotNet/Serialization/NamingConventions/NullNamingConvention.cs +++ b/YamlDotNet/Serialization/NamingConventions/NullNamingConvention.cs @@ -22,14 +22,14 @@ namespace YamlDotNet.Serialization.NamingConventions { - /// - /// Performs no naming conversion. - /// - public sealed class NullNamingConvention : INamingConvention - { - public string Apply(string value) - { - return value; - } - } + /// + /// Performs no naming conversion. + /// + public sealed class NullNamingConvention : INamingConvention + { + public string Apply(string value) + { + return value; + } + } } diff --git a/YamlDotNet/Serialization/NamingConventions/PascalCaseNamingConvention.cs b/YamlDotNet/Serialization/NamingConventions/PascalCaseNamingConvention.cs index b06c23fbe..77ad93e67 100644 --- a/YamlDotNet/Serialization/NamingConventions/PascalCaseNamingConvention.cs +++ b/YamlDotNet/Serialization/NamingConventions/PascalCaseNamingConvention.cs @@ -23,16 +23,16 @@ namespace YamlDotNet.Serialization.NamingConventions { - /// - /// 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. - /// - public sealed class PascalCaseNamingConvention : INamingConvention - { - public string Apply(string value) - { - return value.ToPascalCase(); - } - } + /// + /// 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. + /// + public sealed class PascalCaseNamingConvention : INamingConvention + { + public string Apply(string value) + { + return value.ToPascalCase(); + } + } } diff --git a/YamlDotNet/Serialization/NamingConventions/UnderscoredNamingConvention.cs b/YamlDotNet/Serialization/NamingConventions/UnderscoredNamingConvention.cs index 6897ca1e7..9797c298e 100644 --- a/YamlDotNet/Serialization/NamingConventions/UnderscoredNamingConvention.cs +++ b/YamlDotNet/Serialization/NamingConventions/UnderscoredNamingConvention.cs @@ -23,14 +23,14 @@ namespace YamlDotNet.Serialization.NamingConventions { - /// - /// Convert the string from camelcase (thisIsATest) to a underscored (this_is_a_test) string - /// - public sealed class UnderscoredNamingConvention : INamingConvention - { - public string Apply(string value) - { - return value.FromCamelCase("_"); - } - } + /// + /// Convert the string from camelcase (thisIsATest) to a underscored (this_is_a_test) string + /// + public sealed class UnderscoredNamingConvention : INamingConvention + { + public string Apply(string value) + { + return value.FromCamelCase("_"); + } + } } diff --git a/YamlDotNet/Serialization/NodeDeserializers/ArrayNodeDeserializer.cs b/YamlDotNet/Serialization/NodeDeserializers/ArrayNodeDeserializer.cs index 86a8e143d..d27664d28 100644 --- a/YamlDotNet/Serialization/NodeDeserializers/ArrayNodeDeserializer.cs +++ b/YamlDotNet/Serialization/NodeDeserializers/ArrayNodeDeserializer.cs @@ -26,28 +26,28 @@ namespace YamlDotNet.Serialization.NodeDeserializers { - public sealed class ArrayNodeDeserializer : INodeDeserializer - { - bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) - { - if (!expectedType.IsArray) - { - value = false; - return false; - } - - value = _deserializeHelper.Invoke(new[] { expectedType.GetElementType() }, reader, expectedType, nestedObjectDeserializer); - return true; - } - - private static readonly GenericStaticMethod _deserializeHelper = new GenericStaticMethod(() => DeserializeHelper(null, null, null)); - - private static TItem[] DeserializeHelper(EventReader reader, Type expectedType, Func nestedObjectDeserializer) - { - var items = new List(); - GenericCollectionNodeDeserializer.DeserializeHelper(reader, expectedType, nestedObjectDeserializer, items); - return items.ToArray(); - } - } + public sealed class ArrayNodeDeserializer : INodeDeserializer + { + bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) + { + if (!expectedType.IsArray) + { + value = false; + return false; + } + + value = _deserializeHelper.Invoke(new[] { expectedType.GetElementType() }, reader, expectedType, nestedObjectDeserializer); + return true; + } + + private static readonly GenericStaticMethod _deserializeHelper = new GenericStaticMethod(() => DeserializeHelper(null, null, null)); + + private static TItem[] DeserializeHelper(EventReader reader, Type expectedType, Func nestedObjectDeserializer) + { + var items = new List(); + GenericCollectionNodeDeserializer.DeserializeHelper(reader, expectedType, nestedObjectDeserializer, items); + return items.ToArray(); + } + } } diff --git a/YamlDotNet/Serialization/NodeDeserializers/EnumerableNodeDeserializer.cs b/YamlDotNet/Serialization/NodeDeserializers/EnumerableNodeDeserializer.cs index d56f7fdeb..7d27e8811 100644 --- a/YamlDotNet/Serialization/NodeDeserializers/EnumerableNodeDeserializer.cs +++ b/YamlDotNet/Serialization/NodeDeserializers/EnumerableNodeDeserializer.cs @@ -27,31 +27,31 @@ namespace YamlDotNet.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/Serialization/NodeDeserializers/GenericCollectionNodeDeserializer.cs b/YamlDotNet/Serialization/NodeDeserializers/GenericCollectionNodeDeserializer.cs index a3d40b48d..ab1a03936 100644 --- a/YamlDotNet/Serialization/NodeDeserializers/GenericCollectionNodeDeserializer.cs +++ b/YamlDotNet/Serialization/NodeDeserializers/GenericCollectionNodeDeserializer.cs @@ -27,63 +27,63 @@ namespace YamlDotNet.Serialization.NodeDeserializers { - public sealed class GenericCollectionNodeDeserializer : INodeDeserializer - { - private readonly IObjectFactory _objectFactory; + public sealed class GenericCollectionNodeDeserializer : INodeDeserializer + { + private readonly IObjectFactory _objectFactory; - public GenericCollectionNodeDeserializer(IObjectFactory objectFactory) - { - _objectFactory = objectFactory; - } + public GenericCollectionNodeDeserializer(IObjectFactory objectFactory) + { + _objectFactory = objectFactory; + } - bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) - { - var iCollection = ReflectionUtility.GetImplementedGenericInterface(expectedType, typeof(ICollection<>)); - if (iCollection == null) - { - value = false; - return false; - } + bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) + { + var iCollection = ReflectionUtility.GetImplementedGenericInterface(expectedType, typeof(ICollection<>)); + if (iCollection == null) + { + value = false; + return false; + } - value = _objectFactory.Create(expectedType); - _deserializeHelper.Invoke(iCollection.GetGenericArguments(), reader, expectedType, nestedObjectDeserializer, value); + value = _objectFactory.Create(expectedType); + _deserializeHelper.Invoke(iCollection.GetGenericArguments(), reader, expectedType, nestedObjectDeserializer, value); - return true; - } + return true; + } - private static readonly GenericStaticMethod _deserializeHelper = new GenericStaticMethod(() => DeserializeHelper(null, null, null, null)); + private static readonly GenericStaticMethod _deserializeHelper = new GenericStaticMethod(() => DeserializeHelper(null, null, null, null)); - internal static void DeserializeHelper(EventReader reader, Type expectedType, Func nestedObjectDeserializer, ICollection result) - { - var list = result as IList; + internal static void DeserializeHelper(EventReader reader, Type expectedType, Func nestedObjectDeserializer, ICollection result) + { + var list = result as IList; - reader.Expect(); - while (!reader.Accept()) - { - var current = reader.Parser.Current; + reader.Expect(); + while (!reader.Accept()) + { + var current = reader.Parser.Current; - var value = nestedObjectDeserializer(reader, typeof(TItem)); - var promise = value as IValuePromise; - if (promise == null) - { - result.Add(TypeConverter.ChangeType(value)); - } - else if(list != null) - { - var index = list.Count; - result.Add(default(TItem)); - promise.ValueAvailable += v => list[index] = TypeConverter.ChangeType(v); - } - else - { - throw new ForwardAnchorNotSupportedException( - current.Start, - current.End, - "Forward alias references are not allowed because this type does not implement IList<>" - ); - } - } - reader.Expect(); - } - } + var value = nestedObjectDeserializer(reader, typeof(TItem)); + var promise = value as IValuePromise; + if (promise == null) + { + result.Add(TypeConverter.ChangeType(value)); + } + else if(list != null) + { + var index = list.Count; + result.Add(default(TItem)); + promise.ValueAvailable += v => list[index] = TypeConverter.ChangeType(v); + } + else + { + throw new ForwardAnchorNotSupportedException( + current.Start, + current.End, + "Forward alias references are not allowed because this type does not implement IList<>" + ); + } + } + reader.Expect(); + } + } } diff --git a/YamlDotNet/Serialization/NodeDeserializers/GenericDictionaryNodeDeserializer.cs b/YamlDotNet/Serialization/NodeDeserializers/GenericDictionaryNodeDeserializer.cs index ff5bd6976..6b6c0c74f 100644 --- a/YamlDotNet/Serialization/NodeDeserializers/GenericDictionaryNodeDeserializer.cs +++ b/YamlDotNet/Serialization/NodeDeserializers/GenericDictionaryNodeDeserializer.cs @@ -27,103 +27,103 @@ namespace YamlDotNet.Serialization.NodeDeserializers { - public sealed class GenericDictionaryNodeDeserializer : INodeDeserializer - { - private readonly IObjectFactory _objectFactory; + public sealed class GenericDictionaryNodeDeserializer : INodeDeserializer + { + private readonly IObjectFactory _objectFactory; - public GenericDictionaryNodeDeserializer(IObjectFactory objectFactory) - { - _objectFactory = objectFactory; - } - - bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) - { - var iDictionary = ReflectionUtility.GetImplementedGenericInterface(expectedType, typeof(IDictionary<,>)); - if (iDictionary == null) - { - value = false; - return false; - } + public GenericDictionaryNodeDeserializer(IObjectFactory objectFactory) + { + _objectFactory = objectFactory; + } + + bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) + { + var iDictionary = ReflectionUtility.GetImplementedGenericInterface(expectedType, typeof(IDictionary<,>)); + if (iDictionary == null) + { + value = false; + return false; + } - reader.Expect(); + reader.Expect(); - value = _objectFactory.Create(expectedType); - deserializeHelperMethod.Invoke(iDictionary.GetGenericArguments(), reader, expectedType, nestedObjectDeserializer, value); + value = _objectFactory.Create(expectedType); + deserializeHelperMethod.Invoke(iDictionary.GetGenericArguments(), reader, expectedType, nestedObjectDeserializer, value); - reader.Expect(); + reader.Expect(); - return true; - } + return true; + } - private static readonly GenericStaticMethod deserializeHelperMethod = - new GenericStaticMethod(() => DeserializeHelper(null, null, null, null)); + private static readonly GenericStaticMethod deserializeHelperMethod = + new GenericStaticMethod(() => DeserializeHelper(null, null, null, null)); - //private static MethodInfo _deserializeHelperMethod = typeof(GenericDictionaryNodeDeserializer) - // .GetMethod("DeserializeHelper", BindingFlags.Static | BindingFlags.NonPublic); + //private static MethodInfo _deserializeHelperMethod = typeof(GenericDictionaryNodeDeserializer) + // .GetMethod("DeserializeHelper", BindingFlags.Static | BindingFlags.NonPublic); - private static void DeserializeHelper(EventReader reader, Type expectedType, Func nestedObjectDeserializer, IDictionary result) - { - while (!reader.Accept()) - { - var key = nestedObjectDeserializer(reader, typeof(TKey)); - var keyPromise = key as IValuePromise; + private static void DeserializeHelper(EventReader reader, Type expectedType, Func nestedObjectDeserializer, IDictionary result) + { + while (!reader.Accept()) + { + var key = nestedObjectDeserializer(reader, typeof(TKey)); + var keyPromise = key as IValuePromise; - var value = nestedObjectDeserializer(reader, typeof(TValue)); - var valuePromise = value as IValuePromise; + var value = nestedObjectDeserializer(reader, typeof(TValue)); + var valuePromise = value as IValuePromise; - if (keyPromise == null) - { - if (valuePromise == null) - { - // Happy path: both key and value are known - result[(TKey)key] = (TValue)value; - } - else - { - // Key is known, value is pending - valuePromise.ValueAvailable += v => result[(TKey)key] = (TValue)v; - } - } - else - { - if (valuePromise == null) - { - // Key is pending, value is known - keyPromise.ValueAvailable += v => result[(TKey)v] = (TValue)value; - } - else - { - // Both key and value are pending. We need to wait until both of them becom available. - var hasFirstPart = false; + if (keyPromise == null) + { + if (valuePromise == null) + { + // Happy path: both key and value are known + result[(TKey)key] = (TValue)value; + } + else + { + // Key is known, value is pending + valuePromise.ValueAvailable += v => result[(TKey)key] = (TValue)v; + } + } + else + { + if (valuePromise == null) + { + // Key is pending, value is known + keyPromise.ValueAvailable += v => result[(TKey)v] = (TValue)value; + } + else + { + // Both key and value are pending. We need to wait until both of them becom available. + var hasFirstPart = false; - keyPromise.ValueAvailable += v => - { - if (hasFirstPart) - { - result[(TKey)v] = (TValue)value; - } - else - { - key = v; - hasFirstPart = true; - } - }; + keyPromise.ValueAvailable += v => + { + if (hasFirstPart) + { + result[(TKey)v] = (TValue)value; + } + else + { + key = v; + hasFirstPart = true; + } + }; - valuePromise.ValueAvailable += v => - { - if (hasFirstPart) - { - result[(TKey)key] = (TValue)v; - } - else - { - value = v; - hasFirstPart = true; - } - }; - } - } - } - } - } + valuePromise.ValueAvailable += v => + { + if (hasFirstPart) + { + result[(TKey)key] = (TValue)v; + } + else + { + value = v; + hasFirstPart = true; + } + }; + } + } + } + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/NodeDeserializers/NonGenericDictionaryNodeDeserializer.cs b/YamlDotNet/Serialization/NodeDeserializers/NonGenericDictionaryNodeDeserializer.cs index 635e97959..c1925affe 100644 --- a/YamlDotNet/Serialization/NodeDeserializers/NonGenericDictionaryNodeDeserializer.cs +++ b/YamlDotNet/Serialization/NodeDeserializers/NonGenericDictionaryNodeDeserializer.cs @@ -26,92 +26,92 @@ namespace YamlDotNet.Serialization.NodeDeserializers { - public sealed class NonGenericDictionaryNodeDeserializer : INodeDeserializer - { - private readonly IObjectFactory _objectFactory; + public sealed class NonGenericDictionaryNodeDeserializer : INodeDeserializer + { + private readonly IObjectFactory _objectFactory; - public NonGenericDictionaryNodeDeserializer(IObjectFactory objectFactory) - { - _objectFactory = objectFactory; - } + public NonGenericDictionaryNodeDeserializer(IObjectFactory objectFactory) + { + _objectFactory = objectFactory; + } - bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) - { - if(!typeof(IDictionary).IsAssignableFrom(expectedType)) - { - value = false; - return false; - } + bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) + { + if(!typeof(IDictionary).IsAssignableFrom(expectedType)) + { + value = false; + return false; + } - reader.Expect(); + reader.Expect(); - var dictionary = (IDictionary)_objectFactory.Create(expectedType); - while (!reader.Accept()) - { - var key = nestedObjectDeserializer(reader, typeof(object)); - var keyPromise = key as IValuePromise; + var dictionary = (IDictionary)_objectFactory.Create(expectedType); + while (!reader.Accept()) + { + var key = nestedObjectDeserializer(reader, typeof(object)); + var keyPromise = key as IValuePromise; - var keyValue = nestedObjectDeserializer(reader, typeof(object)); - var valuePromise = keyValue as IValuePromise; + var keyValue = nestedObjectDeserializer(reader, typeof(object)); + var valuePromise = keyValue as IValuePromise; - if (keyPromise == null) - { - if (valuePromise == null) - { - // Happy path: both key and value are known - dictionary.Add(key, keyValue); - } - else - { - // Key is known, value is pending - valuePromise.ValueAvailable += v => dictionary.Add(key, v); - } - } - else - { - if (valuePromise == null) - { - // Key is pending, value is known - keyPromise.ValueAvailable += v => dictionary.Add(v, keyValue); - } - else - { - // Both key and value are pending. We need to wait until both of them becom available. - var hasFirstPart = false; + if (keyPromise == null) + { + if (valuePromise == null) + { + // Happy path: both key and value are known + dictionary.Add(key, keyValue); + } + else + { + // Key is known, value is pending + valuePromise.ValueAvailable += v => dictionary.Add(key, v); + } + } + else + { + if (valuePromise == null) + { + // Key is pending, value is known + keyPromise.ValueAvailable += v => dictionary.Add(v, keyValue); + } + else + { + // Both key and value are pending. We need to wait until both of them becom available. + var hasFirstPart = false; - keyPromise.ValueAvailable += v => - { - if (hasFirstPart) - { - dictionary.Add(v, keyValue); - } - else - { - key = v; - hasFirstPart = true; - } - }; + keyPromise.ValueAvailable += v => + { + if (hasFirstPart) + { + dictionary.Add(v, keyValue); + } + else + { + key = v; + hasFirstPart = true; + } + }; - valuePromise.ValueAvailable += v => - { - if (hasFirstPart) - { - dictionary.Add(key, v); - } - else - { - keyValue = v; - hasFirstPart = true; - } - }; - } - } - } - value = dictionary; + valuePromise.ValueAvailable += v => + { + if (hasFirstPart) + { + dictionary.Add(key, v); + } + else + { + keyValue = v; + hasFirstPart = true; + } + }; + } + } + } + value = dictionary; - reader.Expect(); + reader.Expect(); - return true; - } - } + return true; + } + } } diff --git a/YamlDotNet/Serialization/NodeDeserializers/NonGenericListNodeDeserializer.cs b/YamlDotNet/Serialization/NodeDeserializers/NonGenericListNodeDeserializer.cs index ea66a1c4c..84719bc1b 100644 --- a/YamlDotNet/Serialization/NodeDeserializers/NonGenericListNodeDeserializer.cs +++ b/YamlDotNet/Serialization/NodeDeserializers/NonGenericListNodeDeserializer.cs @@ -26,47 +26,47 @@ namespace YamlDotNet.Serialization.NodeDeserializers { - public sealed class NonGenericListNodeDeserializer : INodeDeserializer - { - private readonly IObjectFactory _objectFactory; + public sealed class NonGenericListNodeDeserializer : INodeDeserializer + { + private readonly IObjectFactory _objectFactory; - public NonGenericListNodeDeserializer(IObjectFactory objectFactory) - { - _objectFactory = objectFactory; - } + public NonGenericListNodeDeserializer(IObjectFactory objectFactory) + { + _objectFactory = objectFactory; + } - bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) - { - if (!typeof(IList).IsAssignableFrom(expectedType)) - { - value = false; - return false; - } + bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) + { + if (!typeof(IList).IsAssignableFrom(expectedType)) + { + value = false; + return false; + } - reader.Expect(); + reader.Expect(); - var list = (IList)_objectFactory.Create(expectedType); - while (!reader.Accept()) - { - var item = nestedObjectDeserializer(reader, typeof(object)); - var promise = item as IValuePromise; - if (promise == null) - { - list.Add(item); - } - else - { - var index = list.Count; - list.Add(null); - promise.ValueAvailable += v => list[index] = v; - } - } - value = list; + var list = (IList)_objectFactory.Create(expectedType); + while (!reader.Accept()) + { + var item = nestedObjectDeserializer(reader, typeof(object)); + var promise = item as IValuePromise; + if (promise == null) + { + list.Add(item); + } + else + { + var index = list.Count; + list.Add(null); + promise.ValueAvailable += v => list[index] = v; + } + } + value = list; - reader.Expect(); + reader.Expect(); - return true; - } - } + return true; + } + } } diff --git a/YamlDotNet/Serialization/NodeDeserializers/NullNodeDeserializer.cs b/YamlDotNet/Serialization/NodeDeserializers/NullNodeDeserializer.cs index 0fca5e2ee..82914c534 100644 --- a/YamlDotNet/Serialization/NodeDeserializers/NullNodeDeserializer.cs +++ b/YamlDotNet/Serialization/NodeDeserializers/NullNodeDeserializer.cs @@ -25,37 +25,37 @@ namespace YamlDotNet.Serialization.NodeDeserializers { - public sealed class NullNodeDeserializer : INodeDeserializer - { - bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) - { - value = null; - var evt = reader.Peek(); - var isNull = evt != null - && NodeIsNull(evt); + public sealed class NullNodeDeserializer : INodeDeserializer + { + bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) + { + value = null; + var evt = reader.Peek(); + var isNull = evt != null + && NodeIsNull(evt); - if (isNull) - { - reader.SkipThisAndNestedEvents(); - } - return isNull; - } + if (isNull) + { + reader.SkipThisAndNestedEvents(); + } + return isNull; + } - private bool NodeIsNull(NodeEvent nodeEvent) - { - // http://yaml.org/type/null.html + private bool NodeIsNull(NodeEvent nodeEvent) + { + // http://yaml.org/type/null.html - if (nodeEvent.Tag == "tag:yaml.org,2002:null") - { - return true; - } + if (nodeEvent.Tag == "tag:yaml.org,2002:null") + { + return true; + } - var scalar = nodeEvent as Scalar; - if (scalar == null || scalar.Style != Core.ScalarStyle.Plain) - return false; + var scalar = nodeEvent as Scalar; + if (scalar == null || scalar.Style != Core.ScalarStyle.Plain) + return false; - var value = scalar.Value; - return value == "" || value == "~" || value == "null" || value == "Null" || value == "NULL"; - } - } + var value = scalar.Value; + return value == "" || value == "~" || value == "null" || value == "Null" || value == "NULL"; + } + } } diff --git a/YamlDotNet/Serialization/NodeDeserializers/ObjectNodeDeserializer.cs b/YamlDotNet/Serialization/NodeDeserializers/ObjectNodeDeserializer.cs index de7365f7c..2da537c30 100644 --- a/YamlDotNet/Serialization/NodeDeserializers/ObjectNodeDeserializer.cs +++ b/YamlDotNet/Serialization/NodeDeserializers/ObjectNodeDeserializer.cs @@ -29,59 +29,59 @@ namespace YamlDotNet.Serialization.NodeDeserializers { - public sealed class ObjectNodeDeserializer : INodeDeserializer - { - private readonly IObjectFactory _objectFactory; - private readonly ITypeInspector _typeDescriptor; - private readonly bool _ignoreUnmatched; + public sealed class ObjectNodeDeserializer : INodeDeserializer + { + private readonly IObjectFactory _objectFactory; + private readonly ITypeInspector _typeDescriptor; + private readonly bool _ignoreUnmatched; - public ObjectNodeDeserializer(IObjectFactory objectFactory, ITypeInspector typeDescriptor, bool ignoreUnmatched) - { - _objectFactory = objectFactory; - _typeDescriptor = typeDescriptor; - _ignoreUnmatched = ignoreUnmatched; - } + public ObjectNodeDeserializer(IObjectFactory objectFactory, ITypeInspector typeDescriptor, bool ignoreUnmatched) + { + _objectFactory = objectFactory; + _typeDescriptor = typeDescriptor; + _ignoreUnmatched = ignoreUnmatched; + } - bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) - { - var mapping = reader.Allow(); - if (mapping == null) - { - value = null; - return false; - } - - value = _objectFactory.Create(expectedType); - while (!reader.Accept()) - { - var propertyName = reader.Expect(); - var property = _typeDescriptor.GetProperty(expectedType, null, propertyName.Value, _ignoreUnmatched); - if (property == null) - { - reader.SkipThisAndNestedEvents(); - continue; - } + bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) + { + var mapping = reader.Allow(); + if (mapping == null) + { + value = null; + return false; + } + + value = _objectFactory.Create(expectedType); + while (!reader.Accept()) + { + var propertyName = reader.Expect(); + var property = _typeDescriptor.GetProperty(expectedType, null, propertyName.Value, _ignoreUnmatched); + if (property == null) + { + reader.SkipThisAndNestedEvents(); + continue; + } - var propertyValue = nestedObjectDeserializer(reader, property.Type); - var propertyValuePromise = propertyValue as IValuePromise; - if (propertyValuePromise == null) - { - var convertedValue = TypeConverter.ChangeType(propertyValue, property.Type); - property.Write(value, convertedValue); - } - else - { - var valueRef = value; - propertyValuePromise.ValueAvailable += v => - { - var convertedValue = TypeConverter.ChangeType(v, property.Type); - property.Write(valueRef, convertedValue); - }; - } - } + var propertyValue = nestedObjectDeserializer(reader, property.Type); + var propertyValuePromise = propertyValue as IValuePromise; + if (propertyValuePromise == null) + { + var convertedValue = TypeConverter.ChangeType(propertyValue, property.Type); + property.Write(value, convertedValue); + } + else + { + var valueRef = value; + propertyValuePromise.ValueAvailable += v => + { + var convertedValue = TypeConverter.ChangeType(v, property.Type); + property.Write(valueRef, convertedValue); + }; + } + } - reader.Expect(); - return true; - } - } + reader.Expect(); + return true; + } + } } diff --git a/YamlDotNet/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs b/YamlDotNet/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs index f980c9872..6c6a1a1b4 100644 --- a/YamlDotNet/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs +++ b/YamlDotNet/Serialization/NodeDeserializers/ScalarNodeDeserializer.cs @@ -28,218 +28,218 @@ namespace YamlDotNet.Serialization.NodeDeserializers { - public sealed class ScalarNodeDeserializer : INodeDeserializer - { - bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) - { - var scalar = reader.Allow(); - if (scalar == null) - { - value = null; - return false; - } - - if (expectedType.IsEnum()) - { - value = Enum.Parse(expectedType, scalar.Value); - } - else - { - TypeCode typeCode = expectedType.GetTypeCode(); - switch (typeCode) - { - case TypeCode.Boolean: - value = bool.Parse(scalar.Value); - break; - - case TypeCode.Byte: - case TypeCode.Int16: - case TypeCode.Int32: - case TypeCode.Int64: - case TypeCode.SByte: - case TypeCode.UInt16: - case TypeCode.UInt32: - case TypeCode.UInt64: - value = DeserializeIntegerHelper(typeCode, scalar.Value, YamlFormatter.NumberFormat); - break; - - case TypeCode.Single: - value = Single.Parse(scalar.Value, YamlFormatter.NumberFormat); - break; - - case TypeCode.Double: - value = Double.Parse(scalar.Value, YamlFormatter.NumberFormat); - break; - - case TypeCode.Decimal: - value = Decimal.Parse(scalar.Value, YamlFormatter.NumberFormat); - break; - - case TypeCode.String: - value = scalar.Value; - break; - - case TypeCode.Char: - value = scalar.Value[0]; - break; - - case TypeCode.DateTime: - // TODO: This is probably incorrect. Use the correct regular expression. - value = DateTime.Parse(scalar.Value, CultureInfo.InvariantCulture); - break; - - default: - if (expectedType == typeof(object)) - { - // Default to string - value = scalar.Value; - } - else - { - value = TypeConverter.ChangeType(scalar.Value, expectedType); - } - break; - } - } - return true; - } - - private object DeserializeIntegerHelper(TypeCode typeCode, string value, IFormatProvider formatProvider) - { - StringBuilder numberBuilder = new StringBuilder(); - int currentIndex = 0; - bool isNegative = false; - int numberBase = 0; - long result = 0; - - if (value[0] == '-') - { - currentIndex++; - isNegative = true; - } - - else if (value[0] == '+') - { - currentIndex++; - } - - if (value[currentIndex] == '0') - { - // Could be binary, octal, hex, decimal (0) - - // If there are no characters remaining, it's a decimal zero - if (currentIndex == value.Length - 1) - { - numberBase = 10; - result = 0; - } - - else - { - // Check the next character - currentIndex++; - - if (value[currentIndex] == 'b') - { - // Binary - numberBase = 2; - - currentIndex++; - } - - else if (value[currentIndex] == 'x') - { - // Hex - numberBase = 16; - - currentIndex++; - } - - else - { - // Octal - numberBase = 8; - } - } - - // Copy remaining digits to the number buffer (skip underscores) - while (currentIndex < value.Length) - { - if (value[currentIndex] != '_') - { - numberBuilder.Append(value[currentIndex]); - } - currentIndex++; - } - - // Parse the magnitude of the number - switch (numberBase) - { - case 2: - case 8: - // TODO: how to incorporate the numberFormat? - result = Convert.ToInt64(numberBuilder.ToString(), numberBase); - break; - - case 16: - result = Int64.Parse(numberBuilder.ToString(), NumberStyles.HexNumber, YamlFormatter.NumberFormat); - break; - - case 10: - // Result is already zero - break; - } - } - - else - { - // Could be decimal or base 60 - string[] chunks = value.Substring(currentIndex).Split(':'); - result = 0; - - for (int chunkIndex = 0; chunkIndex < chunks.Length; chunkIndex++) - { - result *= 60; - - // TODO: verify that chunks after the first are non-negative and less than 60 - result += long.Parse(chunks[chunkIndex].Replace("_", "")); - } - } - - if (isNegative) - { - result = -result; - } - - switch (typeCode) - { - case TypeCode.Byte: - return (byte)result; - - case TypeCode.Int16: - return (short)result; - - case TypeCode.Int32: - return (int)result; - - case TypeCode.Int64: - return result; - - case TypeCode.SByte: - return (sbyte)result; - - case TypeCode.UInt16: - return (ushort)result; - - case TypeCode.UInt32: - return (uint)result; - - case TypeCode.UInt64: - return (ulong)result; - - default: - return result; - } - } - } + public sealed class ScalarNodeDeserializer : INodeDeserializer + { + bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) + { + var scalar = reader.Allow(); + if (scalar == null) + { + value = null; + return false; + } + + if (expectedType.IsEnum()) + { + value = Enum.Parse(expectedType, scalar.Value); + } + else + { + TypeCode typeCode = expectedType.GetTypeCode(); + switch (typeCode) + { + case TypeCode.Boolean: + value = bool.Parse(scalar.Value); + break; + + case TypeCode.Byte: + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.Int64: + case TypeCode.SByte: + case TypeCode.UInt16: + case TypeCode.UInt32: + case TypeCode.UInt64: + value = DeserializeIntegerHelper(typeCode, scalar.Value, YamlFormatter.NumberFormat); + break; + + case TypeCode.Single: + value = Single.Parse(scalar.Value, YamlFormatter.NumberFormat); + break; + + case TypeCode.Double: + value = Double.Parse(scalar.Value, YamlFormatter.NumberFormat); + break; + + case TypeCode.Decimal: + value = Decimal.Parse(scalar.Value, YamlFormatter.NumberFormat); + break; + + case TypeCode.String: + value = scalar.Value; + break; + + case TypeCode.Char: + value = scalar.Value[0]; + break; + + case TypeCode.DateTime: + // TODO: This is probably incorrect. Use the correct regular expression. + value = DateTime.Parse(scalar.Value, CultureInfo.InvariantCulture); + break; + + default: + if (expectedType == typeof(object)) + { + // Default to string + value = scalar.Value; + } + else + { + value = TypeConverter.ChangeType(scalar.Value, expectedType); + } + break; + } + } + return true; + } + + private object DeserializeIntegerHelper(TypeCode typeCode, string value, IFormatProvider formatProvider) + { + StringBuilder numberBuilder = new StringBuilder(); + int currentIndex = 0; + bool isNegative = false; + int numberBase = 0; + long result = 0; + + if (value[0] == '-') + { + currentIndex++; + isNegative = true; + } + + else if (value[0] == '+') + { + currentIndex++; + } + + if (value[currentIndex] == '0') + { + // Could be binary, octal, hex, decimal (0) + + // If there are no characters remaining, it's a decimal zero + if (currentIndex == value.Length - 1) + { + numberBase = 10; + result = 0; + } + + else + { + // Check the next character + currentIndex++; + + if (value[currentIndex] == 'b') + { + // Binary + numberBase = 2; + + currentIndex++; + } + + else if (value[currentIndex] == 'x') + { + // Hex + numberBase = 16; + + currentIndex++; + } + + else + { + // Octal + numberBase = 8; + } + } + + // Copy remaining digits to the number buffer (skip underscores) + while (currentIndex < value.Length) + { + if (value[currentIndex] != '_') + { + numberBuilder.Append(value[currentIndex]); + } + currentIndex++; + } + + // Parse the magnitude of the number + switch (numberBase) + { + case 2: + case 8: + // TODO: how to incorporate the numberFormat? + result = Convert.ToInt64(numberBuilder.ToString(), numberBase); + break; + + case 16: + result = Int64.Parse(numberBuilder.ToString(), NumberStyles.HexNumber, YamlFormatter.NumberFormat); + break; + + case 10: + // Result is already zero + break; + } + } + + else + { + // Could be decimal or base 60 + string[] chunks = value.Substring(currentIndex).Split(':'); + result = 0; + + for (int chunkIndex = 0; chunkIndex < chunks.Length; chunkIndex++) + { + result *= 60; + + // TODO: verify that chunks after the first are non-negative and less than 60 + result += long.Parse(chunks[chunkIndex].Replace("_", "")); + } + } + + if (isNegative) + { + result = -result; + } + + switch (typeCode) + { + case TypeCode.Byte: + return (byte)result; + + case TypeCode.Int16: + return (short)result; + + case TypeCode.Int32: + return (int)result; + + case TypeCode.Int64: + return result; + + case TypeCode.SByte: + return (sbyte)result; + + case TypeCode.UInt16: + return (ushort)result; + + case TypeCode.UInt32: + return (uint)result; + + case TypeCode.UInt64: + return (ulong)result; + + default: + return result; + } + } + } } diff --git a/YamlDotNet/Serialization/NodeDeserializers/TypeConverterNodeDeserializer.cs b/YamlDotNet/Serialization/NodeDeserializers/TypeConverterNodeDeserializer.cs index cb33d6440..b86157fe1 100644 --- a/YamlDotNet/Serialization/NodeDeserializers/TypeConverterNodeDeserializer.cs +++ b/YamlDotNet/Serialization/NodeDeserializers/TypeConverterNodeDeserializer.cs @@ -26,32 +26,32 @@ namespace YamlDotNet.Serialization.NodeDeserializers { - public sealed class TypeConverterNodeDeserializer : INodeDeserializer - { - private readonly IEnumerable converters; - - public TypeConverterNodeDeserializer(IEnumerable converters) - { - if (converters == null) - { - throw new ArgumentNullException("converters"); - } - - this.converters = converters; - } - - bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) - { - var converter = converters.FirstOrDefault(c => c.Accepts(expectedType)); - if (converter == null) - { - value = null; - return false; - } - - value = converter.ReadYaml(reader.Parser, expectedType); - return true; - } - } + public sealed class TypeConverterNodeDeserializer : INodeDeserializer + { + private readonly IEnumerable converters; + + public TypeConverterNodeDeserializer(IEnumerable converters) + { + if (converters == null) + { + throw new ArgumentNullException("converters"); + } + + this.converters = converters; + } + + bool INodeDeserializer.Deserialize(EventReader reader, Type expectedType, Func nestedObjectDeserializer, out object value) + { + var converter = converters.FirstOrDefault(c => c.Accepts(expectedType)); + if (converter == null) + { + value = null; + return false; + } + + value = converter.ReadYaml(reader.Parser, expectedType); + return true; + } + } } diff --git a/YamlDotNet/Serialization/NodeTypeResolvers/DefaultContainersNodeTypeResolver.cs b/YamlDotNet/Serialization/NodeTypeResolvers/DefaultContainersNodeTypeResolver.cs index 3a28372d8..c4a857fc2 100644 --- a/YamlDotNet/Serialization/NodeTypeResolvers/DefaultContainersNodeTypeResolver.cs +++ b/YamlDotNet/Serialization/NodeTypeResolvers/DefaultContainersNodeTypeResolver.cs @@ -25,25 +25,25 @@ namespace YamlDotNet.Serialization.NodeTypeResolvers { - public sealed class DefaultContainersNodeTypeResolver : INodeTypeResolver - { - bool INodeTypeResolver.Resolve(NodeEvent nodeEvent, ref Type currentType) - { - if (currentType == typeof(object)) - { - if (nodeEvent is SequenceStart) - { - currentType = typeof(List); - return true; - } - if (nodeEvent is MappingStart) - { - currentType = typeof(Dictionary); - return true; - } - } + public sealed class DefaultContainersNodeTypeResolver : INodeTypeResolver + { + bool INodeTypeResolver.Resolve(NodeEvent nodeEvent, ref Type currentType) + { + if (currentType == typeof(object)) + { + if (nodeEvent is SequenceStart) + { + currentType = typeof(List); + return true; + } + if (nodeEvent is MappingStart) + { + currentType = typeof(Dictionary); + return true; + } + } - return false; - } - } + return false; + } + } } diff --git a/YamlDotNet/Serialization/NodeTypeResolvers/TagNodeTypeResolver.cs b/YamlDotNet/Serialization/NodeTypeResolvers/TagNodeTypeResolver.cs index d5f6d13b3..0418a1316 100644 --- a/YamlDotNet/Serialization/NodeTypeResolvers/TagNodeTypeResolver.cs +++ b/YamlDotNet/Serialization/NodeTypeResolvers/TagNodeTypeResolver.cs @@ -25,29 +25,29 @@ namespace YamlDotNet.Serialization.NodeTypeResolvers { - public sealed class TagNodeTypeResolver : INodeTypeResolver - { - private readonly IDictionary tagMappings; + public sealed class TagNodeTypeResolver : INodeTypeResolver + { + private readonly IDictionary tagMappings; - public TagNodeTypeResolver(IDictionary tagMappings) - { - if (tagMappings == null) - { - throw new ArgumentNullException("tagMappings"); - } + public TagNodeTypeResolver(IDictionary tagMappings) + { + if (tagMappings == null) + { + throw new ArgumentNullException("tagMappings"); + } - this.tagMappings = tagMappings; - } - - bool INodeTypeResolver.Resolve(NodeEvent nodeEvent, ref Type currentType) - { - Type predefinedType; - if (!string.IsNullOrEmpty(nodeEvent.Tag) && tagMappings.TryGetValue(nodeEvent.Tag, out predefinedType)) - { - currentType = predefinedType; - return true; - } - return false; - } - } + this.tagMappings = tagMappings; + } + + bool INodeTypeResolver.Resolve(NodeEvent nodeEvent, ref Type currentType) + { + Type predefinedType; + if (!string.IsNullOrEmpty(nodeEvent.Tag) && tagMappings.TryGetValue(nodeEvent.Tag, out predefinedType)) + { + currentType = predefinedType; + return true; + } + return false; + } + } } diff --git a/YamlDotNet/Serialization/NodeTypeResolvers/TypeNameInTagNodeTypeResolver.cs b/YamlDotNet/Serialization/NodeTypeResolvers/TypeNameInTagNodeTypeResolver.cs index 1b7f49891..b70218248 100644 --- a/YamlDotNet/Serialization/NodeTypeResolvers/TypeNameInTagNodeTypeResolver.cs +++ b/YamlDotNet/Serialization/NodeTypeResolvers/TypeNameInTagNodeTypeResolver.cs @@ -24,22 +24,22 @@ namespace YamlDotNet.Serialization.NodeTypeResolvers { - public sealed class TypeNameInTagNodeTypeResolver : INodeTypeResolver - { - bool INodeTypeResolver.Resolve(NodeEvent nodeEvent, ref Type currentType) - { - if (!string.IsNullOrEmpty(nodeEvent.Tag)) - { - // If type could not be loaded, make sure to pass resolving - // to the next resolver - try - { - currentType = Type.GetType(nodeEvent.Tag.Substring(1), true); - return true; - } - catch { } - } - return false; - } - } + public sealed class TypeNameInTagNodeTypeResolver : INodeTypeResolver + { + bool INodeTypeResolver.Resolve(NodeEvent nodeEvent, ref Type currentType) + { + if (!string.IsNullOrEmpty(nodeEvent.Tag)) + { + // If type could not be loaded, make sure to pass resolving + // to the next resolver + try + { + currentType = Type.GetType(nodeEvent.Tag.Substring(1), true); + return true; + } + catch { } + } + return false; + } + } } diff --git a/YamlDotNet/Serialization/ObjectDescriptor.cs b/YamlDotNet/Serialization/ObjectDescriptor.cs index 0c0172674..661d0f848 100644 --- a/YamlDotNet/Serialization/ObjectDescriptor.cs +++ b/YamlDotNet/Serialization/ObjectDescriptor.cs @@ -24,37 +24,37 @@ namespace YamlDotNet.Serialization { - public sealed class ObjectDescriptor : IObjectDescriptor - { - public object Value { get; private set; } - public Type Type { get; private set; } - public Type StaticType { get; private set; } - public ScalarStyle ScalarStyle { get; private set; } - - public ObjectDescriptor(object value, Type type, Type staticType) - : this(value, type, staticType, ScalarStyle.Any) - { - } - - public ObjectDescriptor(object value, Type type, Type staticType, ScalarStyle scalarStyle) - { - Value = value; - - if (type == null) - { - throw new ArgumentNullException("type"); - } - - Type = type; - - if (staticType == null) - { - throw new ArgumentNullException("staticType"); - } - - StaticType = staticType; - - ScalarStyle = scalarStyle; - } - } + public sealed class ObjectDescriptor : IObjectDescriptor + { + public object Value { get; private set; } + public Type Type { get; private set; } + public Type StaticType { get; private set; } + public ScalarStyle ScalarStyle { get; private set; } + + public ObjectDescriptor(object value, Type type, Type staticType) + : this(value, type, staticType, ScalarStyle.Any) + { + } + + public ObjectDescriptor(object value, Type type, Type staticType, ScalarStyle scalarStyle) + { + Value = value; + + if (type == null) + { + throw new ArgumentNullException("type"); + } + + Type = type; + + if (staticType == null) + { + throw new ArgumentNullException("staticType"); + } + + StaticType = staticType; + + ScalarStyle = scalarStyle; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/ObjectFactories/DefaultObjectFactory.cs b/YamlDotNet/Serialization/ObjectFactories/DefaultObjectFactory.cs index 901a831a0..12ed514bb 100644 --- a/YamlDotNet/Serialization/ObjectFactories/DefaultObjectFactory.cs +++ b/YamlDotNet/Serialization/ObjectFactories/DefaultObjectFactory.cs @@ -24,39 +24,39 @@ namespace YamlDotNet.Serialization.ObjectFactories { - /// - /// Creates objects using Activator.CreateInstance. - /// - public sealed class DefaultObjectFactory : IObjectFactory - { - private static readonly Dictionary defaultInterfaceImplementations = new Dictionary - { - { typeof(IEnumerable<>), typeof(List<>) }, - { typeof(ICollection<>), typeof(List<>) }, - { typeof(IList<>), typeof(List<>) }, - { typeof(IDictionary<,>), typeof(Dictionary<,>) }, - }; + /// + /// Creates objects using Activator.CreateInstance. + /// + public sealed class DefaultObjectFactory : IObjectFactory + { + private static readonly Dictionary defaultInterfaceImplementations = new Dictionary + { + { typeof(IEnumerable<>), typeof(List<>) }, + { typeof(ICollection<>), typeof(List<>) }, + { typeof(IList<>), typeof(List<>) }, + { typeof(IDictionary<,>), typeof(Dictionary<,>) }, + }; - public object Create(Type type) - { - if (type.IsInterface()) - { - Type implementationType; - if (defaultInterfaceImplementations.TryGetValue(type.GetGenericTypeDefinition(), out implementationType)) - { - type = implementationType.MakeGenericType(type.GetGenericArguments()); - } - } + public object Create(Type type) + { + if (type.IsInterface()) + { + Type implementationType; + if (defaultInterfaceImplementations.TryGetValue(type.GetGenericTypeDefinition(), out implementationType)) + { + type = implementationType.MakeGenericType(type.GetGenericArguments()); + } + } - try - { - return Activator.CreateInstance(type); - } - catch (Exception err) - { - var message = string.Format("Failed to create an instance of type '{0}'.", type); - throw new InvalidOperationException(message, err); - } - } - } + try + { + return Activator.CreateInstance(type); + } + catch (Exception err) + { + var message = string.Format("Failed to create an instance of type '{0}'.", type); + throw new InvalidOperationException(message, err); + } + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/ObjectFactories/LambdaObjectFactory.cs b/YamlDotNet/Serialization/ObjectFactories/LambdaObjectFactory.cs index 270b8a3a9..2176c0413 100644 --- a/YamlDotNet/Serialization/ObjectFactories/LambdaObjectFactory.cs +++ b/YamlDotNet/Serialization/ObjectFactories/LambdaObjectFactory.cs @@ -23,26 +23,26 @@ namespace YamlDotNet.Serialization.ObjectFactories { - /// - /// Creates objects using a Func{Type,object}"/>. - /// - public sealed class LambdaObjectFactory : IObjectFactory - { - private readonly Func _factory; + /// + /// Creates objects using a Func{Type,object}"/>. + /// + public sealed class LambdaObjectFactory : IObjectFactory + { + private readonly Func _factory; - public LambdaObjectFactory(Func factory) - { - if (factory == null) - { - throw new ArgumentNullException("factory"); - } + public LambdaObjectFactory(Func factory) + { + if (factory == null) + { + throw new ArgumentNullException("factory"); + } - _factory = factory; - } + _factory = factory; + } - public object Create(Type type) - { - return _factory(type); - } - } + public object Create(Type type) + { + return _factory(type); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/ObjectGraphTraversalStrategies/FullObjectGraphTraversalStrategy.cs b/YamlDotNet/Serialization/ObjectGraphTraversalStrategies/FullObjectGraphTraversalStrategy.cs index b18fb67a3..252d83024 100644 --- a/YamlDotNet/Serialization/ObjectGraphTraversalStrategies/FullObjectGraphTraversalStrategy.cs +++ b/YamlDotNet/Serialization/ObjectGraphTraversalStrategies/FullObjectGraphTraversalStrategy.cs @@ -29,226 +29,226 @@ namespace YamlDotNet.Serialization.ObjectGraphTraversalStrategies { - /// - /// An implementation of that traverses - /// readable properties, collections and dictionaries. - /// - public class FullObjectGraphTraversalStrategy : IObjectGraphTraversalStrategy - { - protected readonly Serializer serializer; - private readonly int maxRecursion; - private readonly ITypeInspector typeDescriptor; - private readonly ITypeResolver typeResolver; - private INamingConvention namingConvention; - - public FullObjectGraphTraversalStrategy(Serializer serializer, ITypeInspector typeDescriptor, ITypeResolver typeResolver, int maxRecursion, INamingConvention namingConvention) - { - if (maxRecursion <= 0) - { - throw new ArgumentOutOfRangeException("maxRecursion", maxRecursion, "maxRecursion must be greater than 1"); - } - - this.serializer = serializer; - - if (typeDescriptor == null) - { - throw new ArgumentNullException("typeDescriptor"); - } - - this.typeDescriptor = typeDescriptor; - - if (typeResolver == null) - { - throw new ArgumentNullException("typeResolver"); - } - - this.typeResolver = typeResolver; - - this.maxRecursion = maxRecursion; - this.namingConvention = namingConvention; - } - - void IObjectGraphTraversalStrategy.Traverse(IObjectDescriptor graph, IObjectGraphVisitor visitor) - { - Traverse(graph, visitor, 0); - } - - protected virtual void Traverse(IObjectDescriptor value, IObjectGraphVisitor visitor, int currentDepth) - { - if (++currentDepth > maxRecursion) - { - throw new InvalidOperationException("Too much recursion when traversing the object graph"); - } - - if (!visitor.Enter(value)) - { - return; - } - - var typeCode = value.Type.GetTypeCode(); - switch (typeCode) - { - case TypeCode.Boolean: - case TypeCode.Byte: - case TypeCode.Int16: - case TypeCode.Int32: - case TypeCode.Int64: - case TypeCode.SByte: - case TypeCode.UInt16: - case TypeCode.UInt32: - case TypeCode.UInt64: - case TypeCode.Single: - case TypeCode.Double: - case TypeCode.Decimal: - case TypeCode.String: - case TypeCode.Char: - case TypeCode.DateTime: - visitor.VisitScalar(value); - break; - - case TypeCode.DBNull: - visitor.VisitScalar(new ObjectDescriptor(null, typeof(object), typeof(object))); - break; - - case TypeCode.Empty: - throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "TypeCode.{0} is not supported.", typeCode)); - - default: - if (value.Value == null || value.Type == typeof(TimeSpan)) - { - visitor.VisitScalar(value); - break; - } - - var underlyingType = Nullable.GetUnderlyingType(value.Type); - if (underlyingType != null) - { - // This is a nullable type, recursively handle it with its underlying type. - // Note that if it contains null, the condition above already took care of it - Traverse(new ObjectDescriptor(value.Value, underlyingType, value.Type, value.ScalarStyle), visitor, currentDepth); - } - else - { - TraverseObject(value, visitor, currentDepth); - } - break; - } - } - - protected virtual void TraverseObject(IObjectDescriptor value, IObjectGraphVisitor visitor, int currentDepth) - { - if (typeof(IDictionary).IsAssignableFrom(value.Type)) - { - TraverseDictionary(value, visitor, currentDepth); - return; - } - - var dictionaryType = ReflectionUtility.GetImplementedGenericInterface(value.Type, typeof(IDictionary<,>)); - if (dictionaryType != null) - { - TraverseGenericDictionary(value, dictionaryType, visitor, currentDepth); - return; - } - - if (typeof(IEnumerable).IsAssignableFrom(value.Type)) - { - TraverseList(value, visitor, currentDepth); - return; - } - - TraverseProperties(value, visitor, currentDepth); - } - - protected virtual void TraverseDictionary(IObjectDescriptor dictionary, IObjectGraphVisitor visitor, int currentDepth) - { - visitor.VisitMappingStart(dictionary, typeof(object), typeof(object)); - - foreach (DictionaryEntry entry in (IDictionary)dictionary.Value) - { - var key = GetObjectDescriptor(entry.Key, typeof(object)); - var value = GetObjectDescriptor(entry.Value, typeof(object)); - - if (visitor.EnterMapping(key, value)) - { - Traverse(key, visitor, currentDepth); - Traverse(value, visitor, currentDepth); - } - } - - visitor.VisitMappingEnd(dictionary); - } - - private void TraverseGenericDictionary(IObjectDescriptor dictionary, Type dictionaryType, IObjectGraphVisitor visitor, int currentDepth) - { - var entryTypes = dictionaryType.GetGenericArguments(); - - // dictionaryType is IDictionary - visitor.VisitMappingStart(dictionary, entryTypes[0], entryTypes[1]); - - // Invoke TraverseGenericDictionaryHelper<,> - traverseGenericDictionaryHelper.Invoke(entryTypes, this, dictionary.Value, visitor, currentDepth, namingConvention ?? new NullNamingConvention()); - - visitor.VisitMappingEnd(dictionary); - } - - private static readonly GenericInstanceMethod traverseGenericDictionaryHelper = - new GenericInstanceMethod(s => s.TraverseGenericDictionaryHelper(null, null, 0, null)); - - private void TraverseGenericDictionaryHelper( - IDictionary dictionary, - IObjectGraphVisitor visitor, int currentDepth, INamingConvention namingConvention) - { - var isDynamic = dictionary.GetType().FullName.Equals("System.Dynamic.ExpandoObject"); - foreach (var entry in dictionary) - { - var keyString = isDynamic ? namingConvention.Apply(entry.Key.ToString()) : entry.Key.ToString(); - var key = GetObjectDescriptor(keyString, typeof(TKey)); - var value = GetObjectDescriptor(entry.Value, typeof(TValue)); - - if (visitor.EnterMapping(key, value)) - { - Traverse(key, visitor, currentDepth); - Traverse(value, visitor, currentDepth); - } - } - } - - private void TraverseList(IObjectDescriptor value, IObjectGraphVisitor visitor, int currentDepth) - { - var enumerableType = ReflectionUtility.GetImplementedGenericInterface(value.Type, typeof(IEnumerable<>)); - var itemType = enumerableType != null ? enumerableType.GetGenericArguments()[0] : typeof(object); - - visitor.VisitSequenceStart(value, itemType); - - foreach (var item in (IEnumerable)value.Value) - { - Traverse(GetObjectDescriptor(item, itemType), visitor, currentDepth); - } - - visitor.VisitSequenceEnd(value); - } - - protected virtual void TraverseProperties(IObjectDescriptor value, IObjectGraphVisitor visitor, int currentDepth) - { - visitor.VisitMappingStart(value, typeof(string), typeof(object)); - - foreach (var propertyDescriptor in typeDescriptor.GetProperties(value.Type, value.Value)) - { - var propertyValue = propertyDescriptor.Read(value.Value); - - if (visitor.EnterMapping(propertyDescriptor, propertyValue)) - { - Traverse(new ObjectDescriptor(propertyDescriptor.Name, typeof(string), typeof(string)), visitor, currentDepth); - Traverse(propertyValue, visitor, currentDepth); - } - } - - visitor.VisitMappingEnd(value); - } - - private IObjectDescriptor GetObjectDescriptor(object value, Type staticType) - { - return new ObjectDescriptor(value, typeResolver.Resolve(staticType, value), staticType); - } - } + /// + /// An implementation of that traverses + /// readable properties, collections and dictionaries. + /// + public class FullObjectGraphTraversalStrategy : IObjectGraphTraversalStrategy + { + protected readonly Serializer serializer; + private readonly int maxRecursion; + private readonly ITypeInspector typeDescriptor; + private readonly ITypeResolver typeResolver; + private INamingConvention namingConvention; + + public FullObjectGraphTraversalStrategy(Serializer serializer, ITypeInspector typeDescriptor, ITypeResolver typeResolver, int maxRecursion, INamingConvention namingConvention) + { + if (maxRecursion <= 0) + { + throw new ArgumentOutOfRangeException("maxRecursion", maxRecursion, "maxRecursion must be greater than 1"); + } + + this.serializer = serializer; + + if (typeDescriptor == null) + { + throw new ArgumentNullException("typeDescriptor"); + } + + this.typeDescriptor = typeDescriptor; + + if (typeResolver == null) + { + throw new ArgumentNullException("typeResolver"); + } + + this.typeResolver = typeResolver; + + this.maxRecursion = maxRecursion; + this.namingConvention = namingConvention; + } + + void IObjectGraphTraversalStrategy.Traverse(IObjectDescriptor graph, IObjectGraphVisitor visitor) + { + Traverse(graph, visitor, 0); + } + + protected virtual void Traverse(IObjectDescriptor value, IObjectGraphVisitor visitor, int currentDepth) + { + if (++currentDepth > maxRecursion) + { + throw new InvalidOperationException("Too much recursion when traversing the object graph"); + } + + if (!visitor.Enter(value)) + { + return; + } + + var typeCode = value.Type.GetTypeCode(); + switch (typeCode) + { + case TypeCode.Boolean: + case TypeCode.Byte: + case TypeCode.Int16: + case TypeCode.Int32: + case TypeCode.Int64: + case TypeCode.SByte: + case TypeCode.UInt16: + case TypeCode.UInt32: + case TypeCode.UInt64: + case TypeCode.Single: + case TypeCode.Double: + case TypeCode.Decimal: + case TypeCode.String: + case TypeCode.Char: + case TypeCode.DateTime: + visitor.VisitScalar(value); + break; + + case TypeCode.DBNull: + visitor.VisitScalar(new ObjectDescriptor(null, typeof(object), typeof(object))); + break; + + case TypeCode.Empty: + throw new NotSupportedException(string.Format(CultureInfo.InvariantCulture, "TypeCode.{0} is not supported.", typeCode)); + + default: + if (value.Value == null || value.Type == typeof(TimeSpan)) + { + visitor.VisitScalar(value); + break; + } + + var underlyingType = Nullable.GetUnderlyingType(value.Type); + if (underlyingType != null) + { + // This is a nullable type, recursively handle it with its underlying type. + // Note that if it contains null, the condition above already took care of it + Traverse(new ObjectDescriptor(value.Value, underlyingType, value.Type, value.ScalarStyle), visitor, currentDepth); + } + else + { + TraverseObject(value, visitor, currentDepth); + } + break; + } + } + + protected virtual void TraverseObject(IObjectDescriptor value, IObjectGraphVisitor visitor, int currentDepth) + { + if (typeof(IDictionary).IsAssignableFrom(value.Type)) + { + TraverseDictionary(value, visitor, currentDepth); + return; + } + + var dictionaryType = ReflectionUtility.GetImplementedGenericInterface(value.Type, typeof(IDictionary<,>)); + if (dictionaryType != null) + { + TraverseGenericDictionary(value, dictionaryType, visitor, currentDepth); + return; + } + + if (typeof(IEnumerable).IsAssignableFrom(value.Type)) + { + TraverseList(value, visitor, currentDepth); + return; + } + + TraverseProperties(value, visitor, currentDepth); + } + + protected virtual void TraverseDictionary(IObjectDescriptor dictionary, IObjectGraphVisitor visitor, int currentDepth) + { + visitor.VisitMappingStart(dictionary, typeof(object), typeof(object)); + + foreach (DictionaryEntry entry in (IDictionary)dictionary.Value) + { + var key = GetObjectDescriptor(entry.Key, typeof(object)); + var value = GetObjectDescriptor(entry.Value, typeof(object)); + + if (visitor.EnterMapping(key, value)) + { + Traverse(key, visitor, currentDepth); + Traverse(value, visitor, currentDepth); + } + } + + visitor.VisitMappingEnd(dictionary); + } + + private void TraverseGenericDictionary(IObjectDescriptor dictionary, Type dictionaryType, IObjectGraphVisitor visitor, int currentDepth) + { + var entryTypes = dictionaryType.GetGenericArguments(); + + // dictionaryType is IDictionary + visitor.VisitMappingStart(dictionary, entryTypes[0], entryTypes[1]); + + // Invoke TraverseGenericDictionaryHelper<,> + traverseGenericDictionaryHelper.Invoke(entryTypes, this, dictionary.Value, visitor, currentDepth, namingConvention ?? new NullNamingConvention()); + + visitor.VisitMappingEnd(dictionary); + } + + private static readonly GenericInstanceMethod traverseGenericDictionaryHelper = + new GenericInstanceMethod(s => s.TraverseGenericDictionaryHelper(null, null, 0, null)); + + private void TraverseGenericDictionaryHelper( + IDictionary dictionary, + IObjectGraphVisitor visitor, int currentDepth, INamingConvention namingConvention) + { + var isDynamic = dictionary.GetType().FullName.Equals("System.Dynamic.ExpandoObject"); + foreach (var entry in dictionary) + { + var keyString = isDynamic ? namingConvention.Apply(entry.Key.ToString()) : entry.Key.ToString(); + var key = GetObjectDescriptor(keyString, typeof(TKey)); + var value = GetObjectDescriptor(entry.Value, typeof(TValue)); + + if (visitor.EnterMapping(key, value)) + { + Traverse(key, visitor, currentDepth); + Traverse(value, visitor, currentDepth); + } + } + } + + private void TraverseList(IObjectDescriptor value, IObjectGraphVisitor visitor, int currentDepth) + { + var enumerableType = ReflectionUtility.GetImplementedGenericInterface(value.Type, typeof(IEnumerable<>)); + var itemType = enumerableType != null ? enumerableType.GetGenericArguments()[0] : typeof(object); + + visitor.VisitSequenceStart(value, itemType); + + foreach (var item in (IEnumerable)value.Value) + { + Traverse(GetObjectDescriptor(item, itemType), visitor, currentDepth); + } + + visitor.VisitSequenceEnd(value); + } + + protected virtual void TraverseProperties(IObjectDescriptor value, IObjectGraphVisitor visitor, int currentDepth) + { + visitor.VisitMappingStart(value, typeof(string), typeof(object)); + + foreach (var propertyDescriptor in typeDescriptor.GetProperties(value.Type, value.Value)) + { + var propertyValue = propertyDescriptor.Read(value.Value); + + if (visitor.EnterMapping(propertyDescriptor, propertyValue)) + { + Traverse(new ObjectDescriptor(propertyDescriptor.Name, typeof(string), typeof(string)), visitor, currentDepth); + Traverse(propertyValue, visitor, currentDepth); + } + } + + visitor.VisitMappingEnd(value); + } + + private IObjectDescriptor GetObjectDescriptor(object value, Type staticType) + { + return new ObjectDescriptor(value, typeResolver.Resolve(staticType, value), staticType); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/ObjectGraphTraversalStrategies/RoundtripObjectGraphTraversalStrategy.cs b/YamlDotNet/Serialization/ObjectGraphTraversalStrategies/RoundtripObjectGraphTraversalStrategy.cs index a267ea9f9..e383bbc8f 100644 --- a/YamlDotNet/Serialization/ObjectGraphTraversalStrategies/RoundtripObjectGraphTraversalStrategy.cs +++ b/YamlDotNet/Serialization/ObjectGraphTraversalStrategies/RoundtripObjectGraphTraversalStrategy.cs @@ -26,26 +26,26 @@ namespace YamlDotNet.Serialization.ObjectGraphTraversalStrategies { - /// - /// An implementation of that traverses - /// properties that are read/write, collections and dictionaries, while ensuring that - /// the graph can be regenerated from the resulting document. - /// - public class RoundtripObjectGraphTraversalStrategy : FullObjectGraphTraversalStrategy - { - public RoundtripObjectGraphTraversalStrategy(Serializer serializer, ITypeInspector typeDescriptor, ITypeResolver typeResolver, int maxRecursion) - : base(serializer, typeDescriptor, typeResolver, maxRecursion, null) - { - } + /// + /// An implementation of that traverses + /// properties that are read/write, collections and dictionaries, while ensuring that + /// the graph can be regenerated from the resulting document. + /// + public class RoundtripObjectGraphTraversalStrategy : FullObjectGraphTraversalStrategy + { + public RoundtripObjectGraphTraversalStrategy(Serializer serializer, ITypeInspector typeDescriptor, ITypeResolver typeResolver, int maxRecursion) + : base(serializer, typeDescriptor, typeResolver, maxRecursion, null) + { + } - protected override void TraverseProperties(IObjectDescriptor value, IObjectGraphVisitor visitor, int currentDepth) - { - if (!value.Type.HasDefaultConstructor() && !serializer.Converters.Any(c => c.Accepts(value.Type))) - { - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Type '{0}' cannot be deserialized because it does not have a default constructor or a type converter.", value.Type)); - } + protected override void TraverseProperties(IObjectDescriptor value, IObjectGraphVisitor visitor, int currentDepth) + { + if (!value.Type.HasDefaultConstructor() && !serializer.Converters.Any(c => c.Accepts(value.Type))) + { + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Type '{0}' cannot be deserialized because it does not have a default constructor or a type converter.", value.Type)); + } - base.TraverseProperties(value, visitor, currentDepth); - } - } + base.TraverseProperties(value, visitor, currentDepth); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigner.cs b/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigner.cs index a6fc7ba6f..1ed775ee1 100644 --- a/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigner.cs +++ b/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigner.cs @@ -26,65 +26,65 @@ namespace YamlDotNet.Serialization.ObjectGraphVisitors { - public sealed class AnchorAssigner : IObjectGraphVisitor, IAliasProvider - { - private class AnchorAssignment - { - public string Anchor; - } + public sealed class AnchorAssigner : IObjectGraphVisitor, IAliasProvider + { + private class AnchorAssignment + { + public string Anchor; + } - private readonly IDictionary assignments = new Dictionary(); - private uint nextId; + private readonly IDictionary assignments = new Dictionary(); + private uint nextId; - bool IObjectGraphVisitor.Enter(IObjectDescriptor value) - { - // Do not assign anchors to basic types - if (value.Value == null || value.Type.GetTypeCode() != TypeCode.Object) - { - return false; - } + bool IObjectGraphVisitor.Enter(IObjectDescriptor value) + { + // Do not assign anchors to basic types + if (value.Value == null || value.Type.GetTypeCode() != TypeCode.Object) + { + return false; + } - AnchorAssignment assignment; - if (assignments.TryGetValue(value.Value, out assignment)) - { - if (assignment.Anchor == null) - { - assignment.Anchor = "o" + nextId.ToString(CultureInfo.InvariantCulture); - ++nextId; - } - return false; - } - else - { - assignments.Add(value.Value, new AnchorAssignment()); - return true; - } - } + AnchorAssignment assignment; + if (assignments.TryGetValue(value.Value, out assignment)) + { + if (assignment.Anchor == null) + { + assignment.Anchor = "o" + nextId.ToString(CultureInfo.InvariantCulture); + ++nextId; + } + return false; + } + else + { + assignments.Add(value.Value, new AnchorAssignment()); + return true; + } + } - bool IObjectGraphVisitor.EnterMapping(IObjectDescriptor key, IObjectDescriptor value) - { - return true; - } + bool IObjectGraphVisitor.EnterMapping(IObjectDescriptor key, IObjectDescriptor value) + { + return true; + } - bool IObjectGraphVisitor.EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) - { - return true; - } + bool IObjectGraphVisitor.EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) + { + return true; + } - void IObjectGraphVisitor.VisitScalar(IObjectDescriptor scalar) { } - void IObjectGraphVisitor.VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType) { } - void IObjectGraphVisitor.VisitMappingEnd(IObjectDescriptor mapping) { } - void IObjectGraphVisitor.VisitSequenceStart(IObjectDescriptor sequence, Type elementType) { } - void IObjectGraphVisitor.VisitSequenceEnd(IObjectDescriptor sequence) { } + void IObjectGraphVisitor.VisitScalar(IObjectDescriptor scalar) { } + void IObjectGraphVisitor.VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType) { } + void IObjectGraphVisitor.VisitMappingEnd(IObjectDescriptor mapping) { } + void IObjectGraphVisitor.VisitSequenceStart(IObjectDescriptor sequence, Type elementType) { } + void IObjectGraphVisitor.VisitSequenceEnd(IObjectDescriptor sequence) { } - string IAliasProvider.GetAlias(object target) - { - AnchorAssignment assignment; - if (target != null && assignments.TryGetValue(target, out assignment)) - { - return assignment.Anchor; - } - return null; - } - } + string IAliasProvider.GetAlias(object target) + { + AnchorAssignment assignment; + if (target != null && assignments.TryGetValue(target, out assignment)) + { + return assignment.Anchor; + } + return null; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigningObjectGraphVisitor.cs b/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigningObjectGraphVisitor.cs index 134f02219..eaa0fb812 100644 --- a/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigningObjectGraphVisitor.cs +++ b/YamlDotNet/Serialization/ObjectGraphVisitors/AnchorAssigningObjectGraphVisitor.cs @@ -25,44 +25,44 @@ namespace YamlDotNet.Serialization.ObjectGraphVisitors { - public sealed class AnchorAssigningObjectGraphVisitor : ChainedObjectGraphVisitor - { - private readonly IEventEmitter eventEmitter; - private readonly IAliasProvider aliasProvider; - private readonly HashSet emittedAliases = new HashSet(); + public sealed class AnchorAssigningObjectGraphVisitor : ChainedObjectGraphVisitor + { + private readonly IEventEmitter eventEmitter; + private readonly IAliasProvider aliasProvider; + private readonly HashSet emittedAliases = new HashSet(); - public AnchorAssigningObjectGraphVisitor(IObjectGraphVisitor nextVisitor, IEventEmitter eventEmitter, IAliasProvider aliasProvider) - : base(nextVisitor) - { - this.eventEmitter = eventEmitter; - this.aliasProvider = aliasProvider; - } + public AnchorAssigningObjectGraphVisitor(IObjectGraphVisitor nextVisitor, IEventEmitter eventEmitter, IAliasProvider aliasProvider) + : base(nextVisitor) + { + this.eventEmitter = eventEmitter; + this.aliasProvider = aliasProvider; + } - public override bool Enter(IObjectDescriptor value) - { - var alias = aliasProvider.GetAlias(value.Value); - if (alias != null && !emittedAliases.Add(alias)) - { - eventEmitter.Emit(new AliasEventInfo(value) { Alias = alias }); - return false; - } + public override bool Enter(IObjectDescriptor value) + { + var alias = aliasProvider.GetAlias(value.Value); + if (alias != null && !emittedAliases.Add(alias)) + { + eventEmitter.Emit(new AliasEventInfo(value) { Alias = alias }); + return false; + } - return base.Enter(value); - } + return base.Enter(value); + } - public override void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType) - { - eventEmitter.Emit(new MappingStartEventInfo(mapping) { Anchor = aliasProvider.GetAlias(mapping.Value) }); - } + public override void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType) + { + eventEmitter.Emit(new MappingStartEventInfo(mapping) { Anchor = aliasProvider.GetAlias(mapping.Value) }); + } - public override void VisitSequenceStart(IObjectDescriptor sequence, Type elementType) - { - eventEmitter.Emit(new SequenceStartEventInfo(sequence) { Anchor = aliasProvider.GetAlias(sequence.Value) }); - } + public override void VisitSequenceStart(IObjectDescriptor sequence, Type elementType) + { + eventEmitter.Emit(new SequenceStartEventInfo(sequence) { Anchor = aliasProvider.GetAlias(sequence.Value) }); + } - public override void VisitScalar(IObjectDescriptor scalar) - { - eventEmitter.Emit(new ScalarEventInfo(scalar) { Anchor = aliasProvider.GetAlias(scalar.Value) }); - } - } + public override void VisitScalar(IObjectDescriptor scalar) + { + eventEmitter.Emit(new ScalarEventInfo(scalar) { Anchor = aliasProvider.GetAlias(scalar.Value) }); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/ObjectGraphVisitors/ChainedObjectGraphVisitor.cs b/YamlDotNet/Serialization/ObjectGraphVisitors/ChainedObjectGraphVisitor.cs index 11729c4f7..f31b886be 100644 --- a/YamlDotNet/Serialization/ObjectGraphVisitors/ChainedObjectGraphVisitor.cs +++ b/YamlDotNet/Serialization/ObjectGraphVisitors/ChainedObjectGraphVisitor.cs @@ -24,53 +24,53 @@ namespace YamlDotNet.Serialization.ObjectGraphVisitors { - public abstract class ChainedObjectGraphVisitor : IObjectGraphVisitor - { - private readonly IObjectGraphVisitor nextVisitor; + public abstract class ChainedObjectGraphVisitor : IObjectGraphVisitor + { + private readonly IObjectGraphVisitor nextVisitor; - protected ChainedObjectGraphVisitor(IObjectGraphVisitor nextVisitor) - { - this.nextVisitor = nextVisitor; - } + protected ChainedObjectGraphVisitor(IObjectGraphVisitor nextVisitor) + { + this.nextVisitor = nextVisitor; + } - public virtual bool Enter(IObjectDescriptor value) - { - return nextVisitor.Enter(value); - } + public virtual bool Enter(IObjectDescriptor value) + { + return nextVisitor.Enter(value); + } - public virtual bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value) - { - return nextVisitor.EnterMapping(key, value); - } + public virtual bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value) + { + return nextVisitor.EnterMapping(key, value); + } - public virtual bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) - { - return nextVisitor.EnterMapping(key, value); - } + public virtual bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) + { + return nextVisitor.EnterMapping(key, value); + } - public virtual void VisitScalar(IObjectDescriptor scalar) - { - nextVisitor.VisitScalar(scalar); - } + public virtual void VisitScalar(IObjectDescriptor scalar) + { + nextVisitor.VisitScalar(scalar); + } - public virtual void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType) - { - nextVisitor.VisitMappingStart(mapping, keyType, valueType); - } + public virtual void VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType) + { + nextVisitor.VisitMappingStart(mapping, keyType, valueType); + } - public virtual void VisitMappingEnd(IObjectDescriptor mapping) - { - nextVisitor.VisitMappingEnd(mapping); - } + public virtual void VisitMappingEnd(IObjectDescriptor mapping) + { + nextVisitor.VisitMappingEnd(mapping); + } - public virtual void VisitSequenceStart(IObjectDescriptor sequence, Type elementType) - { - nextVisitor.VisitSequenceStart(sequence, elementType); - } + public virtual void VisitSequenceStart(IObjectDescriptor sequence, Type elementType) + { + nextVisitor.VisitSequenceStart(sequence, elementType); + } - public virtual void VisitSequenceEnd(IObjectDescriptor sequence) - { - nextVisitor.VisitSequenceEnd(sequence); - } - } + public virtual void VisitSequenceEnd(IObjectDescriptor sequence) + { + nextVisitor.VisitSequenceEnd(sequence); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/ObjectGraphVisitors/CustomSerializationObjectGraphVisitor.cs b/YamlDotNet/Serialization/ObjectGraphVisitors/CustomSerializationObjectGraphVisitor.cs index 4a2d3c5ee..4c8ee7b19 100644 --- a/YamlDotNet/Serialization/ObjectGraphVisitors/CustomSerializationObjectGraphVisitor.cs +++ b/YamlDotNet/Serialization/ObjectGraphVisitors/CustomSerializationObjectGraphVisitor.cs @@ -25,37 +25,37 @@ namespace YamlDotNet.Serialization.ObjectGraphVisitors { - public sealed class CustomSerializationObjectGraphVisitor : ChainedObjectGraphVisitor - { - private readonly IEmitter emitter; - private readonly IEnumerable typeConverters; + public sealed class CustomSerializationObjectGraphVisitor : ChainedObjectGraphVisitor + { + private readonly IEmitter emitter; + private readonly IEnumerable typeConverters; - public CustomSerializationObjectGraphVisitor(IEmitter emitter, IObjectGraphVisitor nextVisitor, IEnumerable typeConverters) - : base(nextVisitor) - { - this.emitter = emitter; - this.typeConverters = typeConverters != null - ? typeConverters.ToList() - : Enumerable.Empty(); - } + public CustomSerializationObjectGraphVisitor(IEmitter emitter, IObjectGraphVisitor nextVisitor, IEnumerable typeConverters) + : base(nextVisitor) + { + this.emitter = emitter; + this.typeConverters = typeConverters != null + ? typeConverters.ToList() + : Enumerable.Empty(); + } - public override bool Enter(IObjectDescriptor value) - { - var typeConverter = typeConverters.FirstOrDefault(t => t.Accepts(value.Type)); - if (typeConverter != null) - { - typeConverter.WriteYaml(emitter, value.Value, value.Type); - return false; - } + public override bool Enter(IObjectDescriptor value) + { + var typeConverter = typeConverters.FirstOrDefault(t => t.Accepts(value.Type)); + if (typeConverter != null) + { + typeConverter.WriteYaml(emitter, value.Value, value.Type); + return false; + } - var serializable = value as IYamlSerializable; - if (serializable != null) - { - serializable.WriteYaml(emitter); - return false; - } + var serializable = value as IYamlSerializable; + if (serializable != null) + { + serializable.WriteYaml(emitter); + return false; + } - return base.Enter(value); - } - } + return base.Enter(value); + } + } } diff --git a/YamlDotNet/Serialization/ObjectGraphVisitors/DefaultExclusiveObjectGraphVisitor.cs b/YamlDotNet/Serialization/ObjectGraphVisitors/DefaultExclusiveObjectGraphVisitor.cs index 701bb7e72..b12abf4b5 100644 --- a/YamlDotNet/Serialization/ObjectGraphVisitors/DefaultExclusiveObjectGraphVisitor.cs +++ b/YamlDotNet/Serialization/ObjectGraphVisitors/DefaultExclusiveObjectGraphVisitor.cs @@ -25,35 +25,35 @@ namespace YamlDotNet.Serialization.ObjectGraphVisitors { - public sealed class DefaultExclusiveObjectGraphVisitor : ChainedObjectGraphVisitor - { - public DefaultExclusiveObjectGraphVisitor(IObjectGraphVisitor nextVisitor) - : base(nextVisitor) - { - } + public sealed class DefaultExclusiveObjectGraphVisitor : ChainedObjectGraphVisitor + { + public DefaultExclusiveObjectGraphVisitor(IObjectGraphVisitor nextVisitor) + : base(nextVisitor) + { + } - private static object GetDefault(Type type) - { - return type.IsValueType() ? Activator.CreateInstance(type) : null; + private static object GetDefault(Type type) + { + return type.IsValueType() ? Activator.CreateInstance(type) : null; } - private static readonly IEqualityComparer _objectComparer = EqualityComparer.Default; + private static readonly IEqualityComparer _objectComparer = EqualityComparer.Default; - public override bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value) - { - return !_objectComparer.Equals(value, GetDefault(value.Type)) - && base.EnterMapping(key, value); - } + public override bool EnterMapping(IObjectDescriptor key, IObjectDescriptor value) + { + return !_objectComparer.Equals(value, GetDefault(value.Type)) + && base.EnterMapping(key, value); + } - public override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) - { - var defaultValueAttribute = key.GetCustomAttribute(); - var defaultValue = defaultValueAttribute != null - ? defaultValueAttribute.Value - : GetDefault(key.Type); + public override bool EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) + { + var defaultValueAttribute = key.GetCustomAttribute(); + var defaultValue = defaultValueAttribute != null + ? defaultValueAttribute.Value + : GetDefault(key.Type); - return !_objectComparer.Equals(value.Value, defaultValue) - && base.EnterMapping(key, value); - } - } + return !_objectComparer.Equals(value.Value, defaultValue) + && base.EnterMapping(key, value); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/ObjectGraphVisitors/EmittingObjectGraphVisitor.cs b/YamlDotNet/Serialization/ObjectGraphVisitors/EmittingObjectGraphVisitor.cs index 4aae8c832..d22376a00 100644 --- a/YamlDotNet/Serialization/ObjectGraphVisitors/EmittingObjectGraphVisitor.cs +++ b/YamlDotNet/Serialization/ObjectGraphVisitors/EmittingObjectGraphVisitor.cs @@ -24,53 +24,53 @@ namespace YamlDotNet.Serialization.ObjectGraphVisitors { - public sealed class EmittingObjectGraphVisitor : IObjectGraphVisitor - { - private readonly IEventEmitter eventEmitter; + public sealed class EmittingObjectGraphVisitor : IObjectGraphVisitor + { + private readonly IEventEmitter eventEmitter; - public EmittingObjectGraphVisitor(IEventEmitter eventEmitter) - { - this.eventEmitter = eventEmitter; - } + public EmittingObjectGraphVisitor(IEventEmitter eventEmitter) + { + this.eventEmitter = eventEmitter; + } - bool IObjectGraphVisitor.Enter(IObjectDescriptor value) - { - return true; - } + bool IObjectGraphVisitor.Enter(IObjectDescriptor value) + { + return true; + } - bool IObjectGraphVisitor.EnterMapping(IObjectDescriptor key, IObjectDescriptor value) - { - return true; - } + bool IObjectGraphVisitor.EnterMapping(IObjectDescriptor key, IObjectDescriptor value) + { + return true; + } - bool IObjectGraphVisitor.EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) - { - return true; - } + bool IObjectGraphVisitor.EnterMapping(IPropertyDescriptor key, IObjectDescriptor value) + { + return true; + } - void IObjectGraphVisitor.VisitScalar(IObjectDescriptor scalar) - { - eventEmitter.Emit(new ScalarEventInfo(scalar)); - } + void IObjectGraphVisitor.VisitScalar(IObjectDescriptor scalar) + { + eventEmitter.Emit(new ScalarEventInfo(scalar)); + } - void IObjectGraphVisitor.VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType) - { - eventEmitter.Emit(new MappingStartEventInfo(mapping)); - } + void IObjectGraphVisitor.VisitMappingStart(IObjectDescriptor mapping, Type keyType, Type valueType) + { + eventEmitter.Emit(new MappingStartEventInfo(mapping)); + } - void IObjectGraphVisitor.VisitMappingEnd(IObjectDescriptor mapping) - { - eventEmitter.Emit(new MappingEndEventInfo(mapping)); - } + void IObjectGraphVisitor.VisitMappingEnd(IObjectDescriptor mapping) + { + eventEmitter.Emit(new MappingEndEventInfo(mapping)); + } - void IObjectGraphVisitor.VisitSequenceStart(IObjectDescriptor sequence, Type elementType) - { - eventEmitter.Emit(new SequenceStartEventInfo(sequence)); - } + void IObjectGraphVisitor.VisitSequenceStart(IObjectDescriptor sequence, Type elementType) + { + eventEmitter.Emit(new SequenceStartEventInfo(sequence)); + } - void IObjectGraphVisitor.VisitSequenceEnd(IObjectDescriptor sequence) - { - eventEmitter.Emit(new SequenceEndEventInfo(sequence)); - } - } + void IObjectGraphVisitor.VisitSequenceEnd(IObjectDescriptor sequence) + { + eventEmitter.Emit(new SequenceEndEventInfo(sequence)); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/PropertyDescriptor.cs b/YamlDotNet/Serialization/PropertyDescriptor.cs index df4669816..b28398223 100644 --- a/YamlDotNet/Serialization/PropertyDescriptor.cs +++ b/YamlDotNet/Serialization/PropertyDescriptor.cs @@ -24,52 +24,52 @@ namespace YamlDotNet.Serialization { - public sealed class PropertyDescriptor : IPropertyDescriptor - { - private readonly IPropertyDescriptor baseDescriptor; + public sealed class PropertyDescriptor : IPropertyDescriptor + { + private readonly IPropertyDescriptor baseDescriptor; - public PropertyDescriptor(IPropertyDescriptor baseDescriptor) - { - this.baseDescriptor = baseDescriptor; - Name = baseDescriptor.Name; - } + public PropertyDescriptor(IPropertyDescriptor baseDescriptor) + { + this.baseDescriptor = baseDescriptor; + Name = baseDescriptor.Name; + } - public string Name { get; set; } + public string Name { get; set; } - public Type Type { get { return baseDescriptor.Type; } } + public Type Type { get { return baseDescriptor.Type; } } - public Type TypeOverride - { - get { return baseDescriptor.TypeOverride; } - set { baseDescriptor.TypeOverride = value; } - } + public Type TypeOverride + { + get { return baseDescriptor.TypeOverride; } + set { baseDescriptor.TypeOverride = value; } + } - public int Order { get; set; } + public int Order { get; set; } - public ScalarStyle ScalarStyle - { - get { return baseDescriptor.ScalarStyle; } - set { baseDescriptor.ScalarStyle = value; } - } + public ScalarStyle ScalarStyle + { + get { return baseDescriptor.ScalarStyle; } + set { baseDescriptor.ScalarStyle = value; } + } - public bool CanWrite - { - get { return baseDescriptor.CanWrite; } - } + public bool CanWrite + { + get { return baseDescriptor.CanWrite; } + } - public void Write(object target, object value) - { - baseDescriptor.Write(target, value); - } + public void Write(object target, object value) + { + baseDescriptor.Write(target, value); + } - public T GetCustomAttribute() where T : Attribute - { - return baseDescriptor.GetCustomAttribute(); - } + public T GetCustomAttribute() where T : Attribute + { + return baseDescriptor.GetCustomAttribute(); + } - public IObjectDescriptor Read(object target) - { - return baseDescriptor.Read(target); - } - } + public IObjectDescriptor Read(object target) + { + return baseDescriptor.Read(target); + } + } } diff --git a/YamlDotNet/Serialization/SerializationOptions.cs b/YamlDotNet/Serialization/SerializationOptions.cs index ba1dc9ac7..418f33a6e 100644 --- a/YamlDotNet/Serialization/SerializationOptions.cs +++ b/YamlDotNet/Serialization/SerializationOptions.cs @@ -23,47 +23,47 @@ namespace YamlDotNet.Serialization { - /// - /// Options that control the serialization process. - /// - [Flags] - public enum SerializationOptions - { - /// - /// Serializes using the default options - /// - None = 0, + /// + /// Options that control the serialization process. + /// + [Flags] + public enum SerializationOptions + { + /// + /// Serializes using the default options + /// + None = 0, - /// - /// Ensures that it will be possible to deserialize the serialized objects. - /// - Roundtrip = 1, + /// + /// Ensures that it will be possible to deserialize the serialized objects. + /// + Roundtrip = 1, - /// - /// If this flag is specified, if the same object appears more than once in the - /// serialization graph, it will be serialized each time instead of just once. - /// - /// - /// If the serialization graph contains circular references and this flag is set, - /// a StackOverflowException will be thrown. - /// If this flag is not set, there is a performance penalty because the entire - /// object graph must be walked twice. - /// - DisableAliases = 2, + /// + /// If this flag is specified, if the same object appears more than once in the + /// serialization graph, it will be serialized each time instead of just once. + /// + /// + /// If the serialization graph contains circular references and this flag is set, + /// a StackOverflowException will be thrown. + /// If this flag is not set, there is a performance penalty because the entire + /// object graph must be walked twice. + /// + DisableAliases = 2, - /// - /// Forces every value to be serialized, even if it is the default value for that type. - /// - EmitDefaults = 4, + /// + /// Forces every value to be serialized, even if it is the default value for that type. + /// + EmitDefaults = 4, - /// - /// Ensures that the result of the serialization is valid JSON. - /// - JsonCompatible = 8, + /// + /// Ensures that the result of the serialization is valid JSON. + /// + JsonCompatible = 8, - /// - /// Use the static type of values instead of their actual type. - /// - DefaultToStaticType = 16, - } + /// + /// Use the static type of values instead of their actual type. + /// + DefaultToStaticType = 16, + } } diff --git a/YamlDotNet/Serialization/Serializer.cs b/YamlDotNet/Serialization/Serializer.cs index ea8705ab5..930075d4a 100644 --- a/YamlDotNet/Serialization/Serializer.cs +++ b/YamlDotNet/Serialization/Serializer.cs @@ -33,182 +33,182 @@ namespace YamlDotNet.Serialization { - /// - /// Writes objects to YAML. - /// - public sealed class Serializer - { - internal IList Converters { get; private set; } - - private readonly SerializationOptions options; - private readonly INamingConvention namingConvention; - private readonly ITypeResolver typeResolver; - - /// - /// - /// - /// Options that control how the serialization is to be performed. - /// Naming strategy to use for serialized property names - public Serializer(SerializationOptions options = SerializationOptions.None, INamingConvention namingConvention = null) - { - this.options = options; - this.namingConvention = namingConvention ?? new NullNamingConvention(); - - Converters = new List(); + /// + /// Writes objects to YAML. + /// + public sealed class Serializer + { + internal IList Converters { get; private set; } + + private readonly SerializationOptions options; + private readonly INamingConvention namingConvention; + private readonly ITypeResolver typeResolver; + + /// + /// + /// + /// Options that control how the serialization is to be performed. + /// Naming strategy to use for serialized property names + public Serializer(SerializationOptions options = SerializationOptions.None, INamingConvention namingConvention = null) + { + this.options = options; + this.namingConvention = namingConvention ?? new NullNamingConvention(); + + Converters = new List(); foreach (IYamlTypeConverter yamlTypeConverter in Utilities.YamlTypeConverters.BuiltInConverters) - { - Converters.Add(yamlTypeConverter); - } + { + Converters.Add(yamlTypeConverter); + } - typeResolver = IsOptionSet(SerializationOptions.DefaultToStaticType) - ? (ITypeResolver)new StaticTypeResolver() - : (ITypeResolver)new DynamicTypeResolver(); - } - - private bool IsOptionSet(SerializationOptions option) - { - return (options & option) != 0; - } - - /// - /// Registers a type converter to be used to serialize and deserialize specific types. - /// - public void RegisterTypeConverter(IYamlTypeConverter converter) - { - Converters.Add(converter); - } - - /// - /// Serializes the specified object. - /// - /// The where to serialize the object. - /// The object to serialize. - public void Serialize(TextWriter writer, object graph) - { - Serialize(new Emitter(writer), graph); - } - - /// - /// Serializes the specified object. - /// - /// The where to serialize the object. - /// The object to serialize. - /// The static type of the object to serialize. - public void Serialize(TextWriter writer, object graph, Type type) - { - Serialize(new Emitter(writer), graph, type); - } - - /// - /// Serializes the specified object. - /// - /// The where to serialize the object. - /// The object to serialize. - public void Serialize(IEmitter emitter, object graph) - { - if (emitter == null) - { - throw new ArgumentNullException("emitter"); - } - - EmitDocument(emitter, new ObjectDescriptor(graph, graph != null ? graph.GetType() : typeof(object), typeof(object))); - } - - /// - /// Serializes the specified object. - /// - /// The where to serialize the object. - /// The object to serialize. - /// The static type of the object to serialize. - public void Serialize(IEmitter emitter, object graph, Type type) - { - if (emitter == null) - { - throw new ArgumentNullException("emitter"); - } - - if (type == null) - { - throw new ArgumentNullException("type"); - } - - EmitDocument(emitter, new ObjectDescriptor(graph, type, type)); - } - - private void EmitDocument(IEmitter emitter, IObjectDescriptor graph) - { - var traversalStrategy = CreateTraversalStrategy(); - var eventEmitter = CreateEventEmitter(emitter); - var emittingVisitor = CreateEmittingVisitor(emitter, traversalStrategy, eventEmitter, graph); - - emitter.Emit(new StreamStart()); - emitter.Emit(new DocumentStart()); - - traversalStrategy.Traverse(graph, emittingVisitor); - - emitter.Emit(new DocumentEnd(true)); - emitter.Emit(new StreamEnd()); - } - - private IObjectGraphVisitor CreateEmittingVisitor(IEmitter emitter, IObjectGraphTraversalStrategy traversalStrategy, IEventEmitter eventEmitter, IObjectDescriptor graph) - { - IObjectGraphVisitor emittingVisitor = new EmittingObjectGraphVisitor(eventEmitter); - - emittingVisitor = new CustomSerializationObjectGraphVisitor(emitter, emittingVisitor, Converters); - - if (!IsOptionSet(SerializationOptions.DisableAliases)) - { - var anchorAssigner = new AnchorAssigner(); - traversalStrategy.Traverse(graph, anchorAssigner); - - emittingVisitor = new AnchorAssigningObjectGraphVisitor(emittingVisitor, eventEmitter, anchorAssigner); - } - - if (!IsOptionSet(SerializationOptions.EmitDefaults)) - { - emittingVisitor = new DefaultExclusiveObjectGraphVisitor(emittingVisitor); - } - - return emittingVisitor; - } - - private IEventEmitter CreateEventEmitter(IEmitter emitter) - { - var writer = new WriterEventEmitter(emitter); - - if (IsOptionSet(SerializationOptions.JsonCompatible)) - { - return new JsonEventEmitter(writer); - } - else - { - return new TypeAssigningEventEmitter(writer, IsOptionSet(SerializationOptions.Roundtrip)); - } - } - - private IObjectGraphTraversalStrategy CreateTraversalStrategy() - { - ITypeInspector typeDescriptor = new ReadablePropertiesTypeInspector(typeResolver); - if (IsOptionSet(SerializationOptions.Roundtrip)) - { - typeDescriptor = new ReadableAndWritablePropertiesTypeInspector(typeDescriptor); - } - - typeDescriptor = new NamingConventionTypeInspector(typeDescriptor, namingConvention); - typeDescriptor = new YamlAttributesTypeInspector(typeDescriptor); - if (IsOptionSet(SerializationOptions.DefaultToStaticType)) - { - typeDescriptor = new CachedTypeInspector(typeDescriptor); - } - - if (IsOptionSet(SerializationOptions.Roundtrip)) - { - return new RoundtripObjectGraphTraversalStrategy(this, typeDescriptor, typeResolver, 50); - } - else - { - return new FullObjectGraphTraversalStrategy(this, typeDescriptor, typeResolver, 50, namingConvention); - } - } - } + typeResolver = IsOptionSet(SerializationOptions.DefaultToStaticType) + ? (ITypeResolver)new StaticTypeResolver() + : (ITypeResolver)new DynamicTypeResolver(); + } + + private bool IsOptionSet(SerializationOptions option) + { + return (options & option) != 0; + } + + /// + /// Registers a type converter to be used to serialize and deserialize specific types. + /// + public void RegisterTypeConverter(IYamlTypeConverter converter) + { + Converters.Add(converter); + } + + /// + /// Serializes the specified object. + /// + /// The where to serialize the object. + /// The object to serialize. + public void Serialize(TextWriter writer, object graph) + { + Serialize(new Emitter(writer), graph); + } + + /// + /// Serializes the specified object. + /// + /// The where to serialize the object. + /// The object to serialize. + /// The static type of the object to serialize. + public void Serialize(TextWriter writer, object graph, Type type) + { + Serialize(new Emitter(writer), graph, type); + } + + /// + /// Serializes the specified object. + /// + /// The where to serialize the object. + /// The object to serialize. + public void Serialize(IEmitter emitter, object graph) + { + if (emitter == null) + { + throw new ArgumentNullException("emitter"); + } + + EmitDocument(emitter, new ObjectDescriptor(graph, graph != null ? graph.GetType() : typeof(object), typeof(object))); + } + + /// + /// Serializes the specified object. + /// + /// The where to serialize the object. + /// The object to serialize. + /// The static type of the object to serialize. + public void Serialize(IEmitter emitter, object graph, Type type) + { + if (emitter == null) + { + throw new ArgumentNullException("emitter"); + } + + if (type == null) + { + throw new ArgumentNullException("type"); + } + + EmitDocument(emitter, new ObjectDescriptor(graph, type, type)); + } + + private void EmitDocument(IEmitter emitter, IObjectDescriptor graph) + { + var traversalStrategy = CreateTraversalStrategy(); + var eventEmitter = CreateEventEmitter(emitter); + var emittingVisitor = CreateEmittingVisitor(emitter, traversalStrategy, eventEmitter, graph); + + emitter.Emit(new StreamStart()); + emitter.Emit(new DocumentStart()); + + traversalStrategy.Traverse(graph, emittingVisitor); + + emitter.Emit(new DocumentEnd(true)); + emitter.Emit(new StreamEnd()); + } + + private IObjectGraphVisitor CreateEmittingVisitor(IEmitter emitter, IObjectGraphTraversalStrategy traversalStrategy, IEventEmitter eventEmitter, IObjectDescriptor graph) + { + IObjectGraphVisitor emittingVisitor = new EmittingObjectGraphVisitor(eventEmitter); + + emittingVisitor = new CustomSerializationObjectGraphVisitor(emitter, emittingVisitor, Converters); + + if (!IsOptionSet(SerializationOptions.DisableAliases)) + { + var anchorAssigner = new AnchorAssigner(); + traversalStrategy.Traverse(graph, anchorAssigner); + + emittingVisitor = new AnchorAssigningObjectGraphVisitor(emittingVisitor, eventEmitter, anchorAssigner); + } + + if (!IsOptionSet(SerializationOptions.EmitDefaults)) + { + emittingVisitor = new DefaultExclusiveObjectGraphVisitor(emittingVisitor); + } + + return emittingVisitor; + } + + private IEventEmitter CreateEventEmitter(IEmitter emitter) + { + var writer = new WriterEventEmitter(emitter); + + if (IsOptionSet(SerializationOptions.JsonCompatible)) + { + return new JsonEventEmitter(writer); + } + else + { + return new TypeAssigningEventEmitter(writer, IsOptionSet(SerializationOptions.Roundtrip)); + } + } + + private IObjectGraphTraversalStrategy CreateTraversalStrategy() + { + ITypeInspector typeDescriptor = new ReadablePropertiesTypeInspector(typeResolver); + if (IsOptionSet(SerializationOptions.Roundtrip)) + { + typeDescriptor = new ReadableAndWritablePropertiesTypeInspector(typeDescriptor); + } + + typeDescriptor = new NamingConventionTypeInspector(typeDescriptor, namingConvention); + typeDescriptor = new YamlAttributesTypeInspector(typeDescriptor); + if (IsOptionSet(SerializationOptions.DefaultToStaticType)) + { + typeDescriptor = new CachedTypeInspector(typeDescriptor); + } + + if (IsOptionSet(SerializationOptions.Roundtrip)) + { + return new RoundtripObjectGraphTraversalStrategy(this, typeDescriptor, typeResolver, 50); + } + else + { + return new FullObjectGraphTraversalStrategy(this, typeDescriptor, typeResolver, 50, namingConvention); + } + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/StreamFragment.cs b/YamlDotNet/Serialization/StreamFragment.cs index 497cc7e43..e7f4505f4 100644 --- a/YamlDotNet/Serialization/StreamFragment.cs +++ b/YamlDotNet/Serialization/StreamFragment.cs @@ -27,60 +27,60 @@ namespace YamlDotNet.Serialization { - /// - /// An object that contains part of a YAML stream. - /// - public sealed class StreamFragment : IYamlSerializable - { - private readonly List events = new List(); + /// + /// An object that contains part of a YAML stream. + /// + public sealed class StreamFragment : IYamlSerializable + { + private readonly List events = new List(); - /// - /// Gets or sets the events. - /// - /// The events. - public IList Events - { - get - { - return events; - } - } + /// + /// Gets or sets the events. + /// + /// The events. + public IList Events + { + get + { + return events; + } + } - #region IYamlSerializable Members - /// - /// Reads this object's state from a YAML parser. - /// - /// - void IYamlSerializable.ReadYaml(IParser parser) - { - events.Clear(); + #region IYamlSerializable Members + /// + /// Reads this object's state from a YAML parser. + /// + /// + void IYamlSerializable.ReadYaml(IParser parser) + { + events.Clear(); - int depth = 0; - do - { - if (!parser.MoveNext()) - { - throw new InvalidOperationException("The parser has reached the end before deserialization completed."); - } + int depth = 0; + do + { + if (!parser.MoveNext()) + { + throw new InvalidOperationException("The parser has reached the end before deserialization completed."); + } - events.Add(parser.Current); - depth += parser.Current.NestingIncrease; - } while (depth > 0); + events.Add(parser.Current); + depth += parser.Current.NestingIncrease; + } while (depth > 0); - Debug.Assert(depth == 0); - } + Debug.Assert(depth == 0); + } - /// - /// Writes this object's state to a YAML emitter. - /// - /// - void IYamlSerializable.WriteYaml(IEmitter emitter) - { - foreach (var item in events) - { - emitter.Emit(item); - } - } - #endregion - } + /// + /// Writes this object's state to a YAML emitter. + /// + /// + void IYamlSerializable.WriteYaml(IEmitter emitter) + { + foreach (var item in events) + { + emitter.Emit(item); + } + } + #endregion + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/TagMappings.cs b/YamlDotNet/Serialization/TagMappings.cs index ca6b1dde1..7a8a41a85 100644 --- a/YamlDotNet/Serialization/TagMappings.cs +++ b/YamlDotNet/Serialization/TagMappings.cs @@ -24,56 +24,56 @@ namespace YamlDotNet.Serialization { - /// - /// Contains mappings between tags and types. - /// - public sealed class TagMappings - { - private readonly IDictionary mappings; + /// + /// Contains mappings between tags and types. + /// + public sealed class TagMappings + { + private readonly IDictionary mappings; - /// - /// Initializes a new instance of the class. - /// - public TagMappings() - { - mappings = new Dictionary(); - } + /// + /// Initializes a new instance of the class. + /// + public TagMappings() + { + mappings = new Dictionary(); + } - /// - /// Initializes a new instance of the class. - /// - /// The mappings. - public TagMappings(IDictionary mappings) - { - this.mappings = new Dictionary(mappings); - } + /// + /// Initializes a new instance of the class. + /// + /// The mappings. + public TagMappings(IDictionary mappings) + { + this.mappings = new Dictionary(mappings); + } - /// - /// Adds the specified tag. - /// - /// The tag. - /// The mapping. - public void Add(string tag, Type mapping) - { - mappings.Add(tag, mapping); - } + /// + /// Adds the specified tag. + /// + /// The tag. + /// The mapping. + public void Add(string tag, Type mapping) + { + mappings.Add(tag, mapping); + } - /// - /// Gets the mapping. - /// - /// The tag. - /// - internal Type GetMapping(string tag) - { - Type mapping; - if (mappings.TryGetValue(tag, out mapping)) - { - return mapping; - } - else - { - return null; - } - } - } + /// + /// Gets the mapping. + /// + /// The tag. + /// + internal Type GetMapping(string tag) + { + Type mapping; + if (mappings.TryGetValue(tag, out mapping)) + { + return mapping; + } + else + { + return null; + } + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/TypeInspectors/CachedTypeInspector.cs b/YamlDotNet/Serialization/TypeInspectors/CachedTypeInspector.cs index 27367ace2..2aa44a9e1 100644 --- a/YamlDotNet/Serialization/TypeInspectors/CachedTypeInspector.cs +++ b/YamlDotNet/Serialization/TypeInspectors/CachedTypeInspector.cs @@ -25,32 +25,32 @@ namespace YamlDotNet.Serialization.TypeInspectors { - /// - /// Wraps another and applies caching. - /// - public sealed class CachedTypeInspector : TypeInspectorSkeleton - { - private readonly ITypeInspector innerTypeDescriptor; - private readonly Dictionary> cache = new Dictionary>(); - - public CachedTypeInspector(ITypeInspector innerTypeDescriptor) - { - if (innerTypeDescriptor == null) - { - throw new ArgumentNullException("innerTypeDescriptor"); - } - - this.innerTypeDescriptor = innerTypeDescriptor; - } - - public override IEnumerable GetProperties(Type type, object container) - { - List list; - if (!cache.TryGetValue(type, out list)) - { - list = new List(innerTypeDescriptor.GetProperties(type, container)); - } - return list; - } - } + /// + /// Wraps another and applies caching. + /// + public sealed class CachedTypeInspector : TypeInspectorSkeleton + { + private readonly ITypeInspector innerTypeDescriptor; + private readonly Dictionary> cache = new Dictionary>(); + + public CachedTypeInspector(ITypeInspector innerTypeDescriptor) + { + if (innerTypeDescriptor == null) + { + throw new ArgumentNullException("innerTypeDescriptor"); + } + + this.innerTypeDescriptor = innerTypeDescriptor; + } + + public override IEnumerable GetProperties(Type type, object container) + { + List list; + if (!cache.TryGetValue(type, out list)) + { + list = new List(innerTypeDescriptor.GetProperties(type, container)); + } + return list; + } + } } diff --git a/YamlDotNet/Serialization/TypeInspectors/NamingConventionTypeInspector.cs b/YamlDotNet/Serialization/TypeInspectors/NamingConventionTypeInspector.cs index 255be9b0b..f2d7f1530 100644 --- a/YamlDotNet/Serialization/TypeInspectors/NamingConventionTypeInspector.cs +++ b/YamlDotNet/Serialization/TypeInspectors/NamingConventionTypeInspector.cs @@ -25,36 +25,36 @@ namespace YamlDotNet.Serialization.TypeInspectors { - /// - /// Wraps another and applies a - /// naming convention to the names of the properties. - /// - public sealed class NamingConventionTypeInspector : TypeInspectorSkeleton - { - private readonly ITypeInspector innerTypeDescriptor; - private readonly INamingConvention namingConvention; + /// + /// Wraps another and applies a + /// naming convention to the names of the properties. + /// + public sealed class NamingConventionTypeInspector : TypeInspectorSkeleton + { + private readonly ITypeInspector innerTypeDescriptor; + private readonly INamingConvention namingConvention; - public NamingConventionTypeInspector(ITypeInspector innerTypeDescriptor, INamingConvention namingConvention) - { - if (innerTypeDescriptor == null) - { - throw new ArgumentNullException("innerTypeDescriptor"); - } + public NamingConventionTypeInspector(ITypeInspector innerTypeDescriptor, INamingConvention namingConvention) + { + if (innerTypeDescriptor == null) + { + throw new ArgumentNullException("innerTypeDescriptor"); + } - this.innerTypeDescriptor = innerTypeDescriptor; + this.innerTypeDescriptor = innerTypeDescriptor; - if (namingConvention == null) - { - throw new ArgumentNullException("namingConvention"); - } + if (namingConvention == null) + { + throw new ArgumentNullException("namingConvention"); + } - this.namingConvention = namingConvention; - } + this.namingConvention = namingConvention; + } - public override IEnumerable GetProperties(Type type, object container) - { - return innerTypeDescriptor.GetProperties(type, container) - .Select(p => (IPropertyDescriptor)new PropertyDescriptor(p) { Name = namingConvention.Apply(p.Name) }); - } - } + public override IEnumerable GetProperties(Type type, object container) + { + return innerTypeDescriptor.GetProperties(type, container) + .Select(p => (IPropertyDescriptor)new PropertyDescriptor(p) { Name = namingConvention.Apply(p.Name) }); + } + } } diff --git a/YamlDotNet/Serialization/TypeInspectors/ReadableAndWritablePropertiesTypeInspector.cs b/YamlDotNet/Serialization/TypeInspectors/ReadableAndWritablePropertiesTypeInspector.cs index 6af324319..605cc4b0e 100644 --- a/YamlDotNet/Serialization/TypeInspectors/ReadableAndWritablePropertiesTypeInspector.cs +++ b/YamlDotNet/Serialization/TypeInspectors/ReadableAndWritablePropertiesTypeInspector.cs @@ -25,22 +25,22 @@ namespace YamlDotNet.Serialization.TypeInspectors { - /// - /// Returns the properties of a type that are both readable and writable. - /// - public sealed class ReadableAndWritablePropertiesTypeInspector : TypeInspectorSkeleton - { - private readonly ITypeInspector _innerTypeDescriptor; + /// + /// Returns the properties of a type that are both readable and writable. + /// + public sealed class ReadableAndWritablePropertiesTypeInspector : TypeInspectorSkeleton + { + private readonly ITypeInspector _innerTypeDescriptor; - public ReadableAndWritablePropertiesTypeInspector(ITypeInspector innerTypeDescriptor) - { - _innerTypeDescriptor = innerTypeDescriptor; - } - - public override IEnumerable GetProperties(Type type, object container) - { - return _innerTypeDescriptor.GetProperties(type, container) - .Where(p => p.CanWrite); - } - } + public ReadableAndWritablePropertiesTypeInspector(ITypeInspector innerTypeDescriptor) + { + _innerTypeDescriptor = innerTypeDescriptor; + } + + public override IEnumerable GetProperties(Type type, object container) + { + return _innerTypeDescriptor.GetProperties(type, container) + .Where(p => p.CanWrite); + } + } } diff --git a/YamlDotNet/Serialization/TypeInspectors/ReadablePropertiesTypeInspector.cs b/YamlDotNet/Serialization/TypeInspectors/ReadablePropertiesTypeInspector.cs index c70629817..78f6d7af3 100644 --- a/YamlDotNet/Serialization/TypeInspectors/ReadablePropertiesTypeInspector.cs +++ b/YamlDotNet/Serialization/TypeInspectors/ReadablePropertiesTypeInspector.cs @@ -27,73 +27,73 @@ namespace YamlDotNet.Serialization.TypeInspectors { - /// - /// Returns the properties of a type that are readable. - /// - public sealed class ReadablePropertiesTypeInspector : TypeInspectorSkeleton - { - private readonly ITypeResolver _typeResolver; + /// + /// Returns the properties of a type that are readable. + /// + public sealed class ReadablePropertiesTypeInspector : TypeInspectorSkeleton + { + private readonly ITypeResolver _typeResolver; - public ReadablePropertiesTypeInspector(ITypeResolver typeResolver) - { - if (typeResolver == null) - { - throw new ArgumentNullException("typeResolver"); - } + public ReadablePropertiesTypeInspector(ITypeResolver typeResolver) + { + if (typeResolver == null) + { + throw new ArgumentNullException("typeResolver"); + } - _typeResolver = typeResolver; - } + _typeResolver = typeResolver; + } - private static bool IsValidProperty(PropertyInfo property) - { - return property.CanRead - && property.GetGetMethod().GetParameters().Length == 0; - } + private static bool IsValidProperty(PropertyInfo property) + { + return property.CanRead + && property.GetGetMethod().GetParameters().Length == 0; + } - public override IEnumerable GetProperties(Type type, object container) - { - return type - .GetPublicProperties() - .Where(IsValidProperty) - .Select(p => (IPropertyDescriptor)new ReflectionPropertyDescriptor(p, _typeResolver)); - } + public override IEnumerable GetProperties(Type type, object container) + { + return type + .GetPublicProperties() + .Where(IsValidProperty) + .Select(p => (IPropertyDescriptor)new ReflectionPropertyDescriptor(p, _typeResolver)); + } - private sealed class ReflectionPropertyDescriptor : IPropertyDescriptor - { - private readonly PropertyInfo _propertyInfo; - private readonly ITypeResolver _typeResolver; + private sealed class ReflectionPropertyDescriptor : IPropertyDescriptor + { + private readonly PropertyInfo _propertyInfo; + private readonly ITypeResolver _typeResolver; - public ReflectionPropertyDescriptor(PropertyInfo propertyInfo, ITypeResolver typeResolver) - { - _propertyInfo = propertyInfo; - _typeResolver = typeResolver; - ScalarStyle = ScalarStyle.Any; - } + public ReflectionPropertyDescriptor(PropertyInfo propertyInfo, ITypeResolver typeResolver) + { + _propertyInfo = propertyInfo; + _typeResolver = typeResolver; + ScalarStyle = ScalarStyle.Any; + } - public string Name { get { return _propertyInfo.Name; } } - public Type Type { get { return _propertyInfo.PropertyType; } } - public Type TypeOverride { get; set; } - public int Order { get; set; } - public bool CanWrite { get { return _propertyInfo.CanWrite; } } - public ScalarStyle ScalarStyle { get; set; } + public string Name { get { return _propertyInfo.Name; } } + public Type Type { get { return _propertyInfo.PropertyType; } } + public Type TypeOverride { get; set; } + public int Order { get; set; } + public bool CanWrite { get { return _propertyInfo.CanWrite; } } + public ScalarStyle ScalarStyle { get; set; } - public void Write(object target, object value) - { - _propertyInfo.SetValue(target, value, null); - } + public void Write(object target, object value) + { + _propertyInfo.SetValue(target, value, null); + } - public T GetCustomAttribute() where T : Attribute - { - var attributes = _propertyInfo.GetCustomAttributes(typeof(T), true); - return (T)attributes.FirstOrDefault(); - } + public T GetCustomAttribute() where T : Attribute + { + var attributes = _propertyInfo.GetCustomAttributes(typeof(T), true); + return (T)attributes.FirstOrDefault(); + } - public IObjectDescriptor Read(object target) - { - var propertyValue = _propertyInfo.ReadValue(target); - var actualType = TypeOverride ?? _typeResolver.Resolve(Type, propertyValue); - return new ObjectDescriptor(propertyValue, actualType, Type, ScalarStyle); - } - } - } + public IObjectDescriptor Read(object target) + { + var propertyValue = _propertyInfo.ReadValue(target); + var actualType = TypeOverride ?? _typeResolver.Resolve(Type, propertyValue); + return new ObjectDescriptor(propertyValue, actualType, Type, ScalarStyle); + } + } + } } diff --git a/YamlDotNet/Serialization/TypeInspectors/TypeInspectorSkeleton.cs b/YamlDotNet/Serialization/TypeInspectors/TypeInspectorSkeleton.cs index 9cd9b32b1..685c0596d 100644 --- a/YamlDotNet/Serialization/TypeInspectors/TypeInspectorSkeleton.cs +++ b/YamlDotNet/Serialization/TypeInspectors/TypeInspectorSkeleton.cs @@ -27,51 +27,51 @@ namespace YamlDotNet.Serialization.TypeInspectors { - public abstract class TypeInspectorSkeleton : ITypeInspector - { - public abstract IEnumerable GetProperties(Type type, object container); + public abstract class TypeInspectorSkeleton : ITypeInspector + { + public abstract IEnumerable GetProperties(Type type, object container); - public IPropertyDescriptor GetProperty(Type type, object container, string name, bool ignoreUnmatched) - { - var candidates = GetProperties(type, container) - .Where(p => p.Name == name); + public IPropertyDescriptor GetProperty(Type type, object container, string name, bool ignoreUnmatched) + { + var candidates = GetProperties(type, container) + .Where(p => p.Name == name); - using(var enumerator = candidates.GetEnumerator()) - { - if(!enumerator.MoveNext()) - { - if (ignoreUnmatched) - { - return null; - } + using(var enumerator = candidates.GetEnumerator()) + { + if(!enumerator.MoveNext()) + { + if (ignoreUnmatched) + { + return null; + } - throw new SerializationException( - string.Format( - CultureInfo.InvariantCulture, - "Property '{0}' not found on type '{1}'.", - name, - type.FullName - ) - ); - } - - var property = enumerator.Current; - - if(enumerator.MoveNext()) - { - throw new SerializationException( - string.Format( - CultureInfo.InvariantCulture, - "Multiple properties with the name/alias '{0}' already exists on type '{1}', maybe you're misusing YamlAlias or maybe you are using the wrong naming convention? The matching properties are: {2}", - name, - type.FullName, - string.Join(", ", candidates.Select(p => p.Name).ToArray()) - ) - ); - } + throw new SerializationException( + string.Format( + CultureInfo.InvariantCulture, + "Property '{0}' not found on type '{1}'.", + name, + type.FullName + ) + ); + } + + var property = enumerator.Current; + + if(enumerator.MoveNext()) + { + throw new SerializationException( + string.Format( + CultureInfo.InvariantCulture, + "Multiple properties with the name/alias '{0}' already exists on type '{1}', maybe you're misusing YamlAlias or maybe you are using the wrong naming convention? The matching properties are: {2}", + name, + type.FullName, + string.Join(", ", candidates.Select(p => p.Name).ToArray()) + ) + ); + } - return property; - } - } - } + return property; + } + } + } } diff --git a/YamlDotNet/Serialization/TypeResolvers/DynamicTypeResolver.cs b/YamlDotNet/Serialization/TypeResolvers/DynamicTypeResolver.cs index 90b73962e..e205c0eb9 100644 --- a/YamlDotNet/Serialization/TypeResolvers/DynamicTypeResolver.cs +++ b/YamlDotNet/Serialization/TypeResolvers/DynamicTypeResolver.cs @@ -23,14 +23,14 @@ namespace YamlDotNet.Serialization.TypeResolvers { - /// - /// The type returned will be the actual type of the value, if available. - /// - public sealed class DynamicTypeResolver : ITypeResolver - { - public Type Resolve(Type staticType, object actualValue) - { - return actualValue != null ? actualValue.GetType() : staticType; - } - } + /// + /// The type returned will be the actual type of the value, if available. + /// + public sealed class DynamicTypeResolver : ITypeResolver + { + public Type Resolve(Type staticType, object actualValue) + { + return actualValue != null ? actualValue.GetType() : staticType; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/TypeResolvers/StaticTypeResolver.cs b/YamlDotNet/Serialization/TypeResolvers/StaticTypeResolver.cs index 1e7ef4e90..06ffd05d1 100644 --- a/YamlDotNet/Serialization/TypeResolvers/StaticTypeResolver.cs +++ b/YamlDotNet/Serialization/TypeResolvers/StaticTypeResolver.cs @@ -23,14 +23,14 @@ namespace YamlDotNet.Serialization.TypeResolvers { - /// - /// The type returned will always be the static type. - /// - public sealed class StaticTypeResolver : ITypeResolver - { - public Type Resolve(Type staticType, object actualValue) - { - return staticType; - } - } + /// + /// The type returned will always be the static type. + /// + public sealed class StaticTypeResolver : ITypeResolver + { + public Type Resolve(Type staticType, object actualValue) + { + return staticType; + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/Utilities/IPostDeserializationCallback.cs b/YamlDotNet/Serialization/Utilities/IPostDeserializationCallback.cs index 4caee0d86..c2d3396ca 100644 --- a/YamlDotNet/Serialization/Utilities/IPostDeserializationCallback.cs +++ b/YamlDotNet/Serialization/Utilities/IPostDeserializationCallback.cs @@ -21,12 +21,12 @@ namespace YamlDotNet.Serialization.Utilities { - /// - /// Indicates that a class used as deserialization state - /// needs to be notified after deserialization. - /// - public interface IPostDeserializationCallback - { - void OnDeserialization(); - } + /// + /// Indicates that a class used as deserialization state + /// needs to be notified after deserialization. + /// + public interface IPostDeserializationCallback + { + void OnDeserialization(); + } } diff --git a/YamlDotNet/Serialization/Utilities/ObjectAnchorCollection.cs b/YamlDotNet/Serialization/Utilities/ObjectAnchorCollection.cs index 920defb60..1af9f3b43 100644 --- a/YamlDotNet/Serialization/Utilities/ObjectAnchorCollection.cs +++ b/YamlDotNet/Serialization/Utilities/ObjectAnchorCollection.cs @@ -25,52 +25,52 @@ namespace YamlDotNet.Serialization.Utilities { - internal sealed class ObjectAnchorCollection - { - private readonly IDictionary objectsByAnchor = new Dictionary(); - private readonly IDictionary anchorsByObject = new Dictionary(); + internal sealed class ObjectAnchorCollection + { + private readonly IDictionary objectsByAnchor = new Dictionary(); + private readonly IDictionary anchorsByObject = new Dictionary(); - /// - /// Adds the specified anchor. - /// - /// The anchor. - /// The @object. - public void Add(string anchor, object @object) - { - objectsByAnchor.Add(anchor, @object); - if (@object != null) - { - anchorsByObject.Add(@object, anchor); - } - } + /// + /// Adds the specified anchor. + /// + /// The anchor. + /// The @object. + public void Add(string anchor, object @object) + { + objectsByAnchor.Add(anchor, @object); + if (@object != null) + { + anchorsByObject.Add(@object, anchor); + } + } - /// - /// Gets the anchor for the specified object. - /// - /// The object. - /// The anchor. - /// - public bool TryGetAnchor(object @object, out string anchor) - { - return anchorsByObject.TryGetValue(@object, out anchor); - } + /// + /// Gets the anchor for the specified object. + /// + /// The object. + /// The anchor. + /// + public bool TryGetAnchor(object @object, out string anchor) + { + return anchorsByObject.TryGetValue(@object, out anchor); + } - /// - /// Gets the with the specified anchor. - /// - /// - public object this[string anchor] - { - get - { - object value; - if (objectsByAnchor.TryGetValue(anchor, out value)) - { - return value; - } + /// + /// Gets the with the specified anchor. + /// + /// + public object this[string anchor] + { + get + { + object value; + if (objectsByAnchor.TryGetValue(anchor, out value)) + { + return value; + } - throw new AnchorNotFoundException(string.Format(CultureInfo.InvariantCulture, "The anchor '{0}' does not exists", anchor)); - } - } - } + throw new AnchorNotFoundException(string.Format(CultureInfo.InvariantCulture, "The anchor '{0}' does not exists", anchor)); + } + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/Utilities/ReflectionUtility.cs b/YamlDotNet/Serialization/Utilities/ReflectionUtility.cs index ef35ebee0..8cf3df310 100644 --- a/YamlDotNet/Serialization/Utilities/ReflectionUtility.cs +++ b/YamlDotNet/Serialization/Utilities/ReflectionUtility.cs @@ -27,101 +27,101 @@ namespace YamlDotNet.Serialization.Utilities { - internal static class ReflectionUtility - { - public static Type GetImplementedGenericInterface(Type type, Type genericInterfaceType) - { - foreach (var interfacetype in GetImplementedInterfaces(type)) - { - if (interfacetype.IsGenericType() && interfacetype.GetGenericTypeDefinition() == genericInterfaceType) - { - return interfacetype; - } - } - return null; - } + internal static class ReflectionUtility + { + public static Type GetImplementedGenericInterface(Type type, Type genericInterfaceType) + { + foreach (var interfacetype in GetImplementedInterfaces(type)) + { + if (interfacetype.IsGenericType() && interfacetype.GetGenericTypeDefinition() == genericInterfaceType) + { + return interfacetype; + } + } + return null; + } - public static IEnumerable GetImplementedInterfaces(Type type) - { - if (type.IsInterface()) - { - yield return type; - } + public static IEnumerable GetImplementedInterfaces(Type type) + { + if (type.IsInterface()) + { + yield return type; + } - foreach (var implementedInterface in type.GetInterfaces()) - { - yield return implementedInterface; - } - } + foreach (var implementedInterface in type.GetInterfaces()) + { + yield return implementedInterface; + } + } public static MethodInfo GetMethod(Expression methodAccess) - { - var method = ((MethodCallExpression)methodAccess.Body).Method; - if (method.IsGenericMethod) - { - method = method.GetGenericMethodDefinition(); - } - return method; - } + { + var method = ((MethodCallExpression)methodAccess.Body).Method; + if (method.IsGenericMethod) + { + method = method.GetGenericMethodDefinition(); + } + return method; + } - public static MethodInfo GetMethod(Expression> methodAccess) - { - var method = ((MethodCallExpression)methodAccess.Body).Method; - if (method.IsGenericMethod) - { - method = method.GetGenericMethodDefinition(); - } - return method; - } - } + public static MethodInfo GetMethod(Expression> methodAccess) + { + var method = ((MethodCallExpression)methodAccess.Body).Method; + if (method.IsGenericMethod) + { + method = method.GetGenericMethodDefinition(); + } + return method; + } + } - public sealed class GenericStaticMethod - { - private readonly MethodInfo methodToCall; + public sealed class GenericStaticMethod + { + private readonly MethodInfo methodToCall; - public GenericStaticMethod(Expression methodCall) - { - var callExpression = (MethodCallExpression)methodCall.Body; - methodToCall = callExpression.Method.GetGenericMethodDefinition(); - } + public GenericStaticMethod(Expression methodCall) + { + var callExpression = (MethodCallExpression)methodCall.Body; + methodToCall = callExpression.Method.GetGenericMethodDefinition(); + } - public object Invoke(Type[] genericArguments, params object[] arguments) - { - try - { - return methodToCall - .MakeGenericMethod(genericArguments) - .Invoke(null, arguments); - } - catch (TargetInvocationException ex) - { - throw ex.Unwrap(); - } - } - } + public object Invoke(Type[] genericArguments, params object[] arguments) + { + try + { + return methodToCall + .MakeGenericMethod(genericArguments) + .Invoke(null, arguments); + } + catch (TargetInvocationException ex) + { + throw ex.Unwrap(); + } + } + } - public sealed class GenericInstanceMethod - { - private readonly MethodInfo methodToCall; + public sealed class GenericInstanceMethod + { + private readonly MethodInfo methodToCall; - public GenericInstanceMethod(Expression> methodCall) - { - var callExpression = (MethodCallExpression)methodCall.Body; - methodToCall = callExpression.Method.GetGenericMethodDefinition(); - } + public GenericInstanceMethod(Expression> methodCall) + { + var callExpression = (MethodCallExpression)methodCall.Body; + methodToCall = callExpression.Method.GetGenericMethodDefinition(); + } - public object Invoke(Type[] genericArguments, TInstance instance, params object[] arguments) - { - try - { - return methodToCall - .MakeGenericMethod(genericArguments) - .Invoke(instance, arguments); - } - catch (TargetInvocationException ex) - { - throw ex.Unwrap(); - } - } - } + public object Invoke(Type[] genericArguments, TInstance instance, params object[] arguments) + { + try + { + return methodToCall + .MakeGenericMethod(genericArguments) + .Invoke(instance, arguments); + } + catch (TargetInvocationException ex) + { + throw ex.Unwrap(); + } + } + } } diff --git a/YamlDotNet/Serialization/Utilities/SerializerState.cs b/YamlDotNet/Serialization/Utilities/SerializerState.cs index b097f4942..c54b269e2 100644 --- a/YamlDotNet/Serialization/Utilities/SerializerState.cs +++ b/YamlDotNet/Serialization/Utilities/SerializerState.cs @@ -25,44 +25,44 @@ namespace YamlDotNet.Serialization.Utilities { - /// - /// 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; - } + /// + /// 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; + } - /// - /// Invokes on all - /// objects added to this collection that implement . - /// - public void OnDeserialization() - { - foreach (var callback in items.Values.OfType()) - { - callback.OnDeserialization(); - } - } + /// + /// Invokes on all + /// objects added to this collection that implement . + /// + public void OnDeserialization() + { + foreach (var callback in items.Values.OfType()) + { + callback.OnDeserialization(); + } + } - public void Dispose() - { - foreach (var disposable in items.Values.OfType()) - { - disposable.Dispose(); - } - } - } + public void Dispose() + { + foreach (var disposable in items.Values.OfType()) + { + disposable.Dispose(); + } + } + } } diff --git a/YamlDotNet/Serialization/Utilities/StringExtensions.cs b/YamlDotNet/Serialization/Utilities/StringExtensions.cs index 953b9a9fe..d8f01fd0c 100644 --- a/YamlDotNet/Serialization/Utilities/StringExtensions.cs +++ b/YamlDotNet/Serialization/Utilities/StringExtensions.cs @@ -24,56 +24,56 @@ namespace YamlDotNet.Serialization.Utilities { - /// - /// 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); - } + /// + /// 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) - { - return ToCamelOrPascalCase(str, char.ToUpperInvariant); - } + /// + /// 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); + /// + /// 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; - } - } + str = Regex.Replace(str.ToCamelCase(), "(?[A-Z])", match => separator + match.Groups["char"].Value.ToLowerInvariant()); + return str; + } + } } diff --git a/YamlDotNet/Serialization/Utilities/TypeConverter.cs b/YamlDotNet/Serialization/Utilities/TypeConverter.cs index bab94a45b..555444880 100644 --- a/YamlDotNet/Serialization/Utilities/TypeConverter.cs +++ b/YamlDotNet/Serialization/Utilities/TypeConverter.cs @@ -31,225 +31,225 @@ namespace YamlDotNet.Serialization.Utilities { - /// - /// Performs type conversions using every standard provided by the .NET library. - /// - public static class TypeConverter - { + /// + /// Performs type conversions using every standard provided by the .NET library. + /// + public static class TypeConverter + { #if !(PORTABLE || UNITY) - /// - /// Registers a dynamically. - /// - /// The type to which the coverter should be associated. - /// The type of the converter. - [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.LinkDemand, Name = "FullTrust")] - public static void RegisterTypeConverter() - where TConverter : System.ComponentModel.TypeConverter - { - var alreadyRegistered = TypeDescriptor.GetAttributes(typeof(TConvertible)) - .OfType() - .Any(a => a.ConverterTypeName == typeof(TConverter).AssemblyQualifiedName); - - if (!alreadyRegistered) - { - TypeDescriptor.AddAttributes(typeof(TConvertible), new TypeConverterAttribute(typeof(TConverter))); - } - } + /// + /// Registers a dynamically. + /// + /// The type to which the coverter should be associated. + /// The type of the converter. + [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.LinkDemand, Name = "FullTrust")] + public static void RegisterTypeConverter() + where TConverter : System.ComponentModel.TypeConverter + { + var alreadyRegistered = TypeDescriptor.GetAttributes(typeof(TConvertible)) + .OfType() + .Any(a => a.ConverterTypeName == typeof(TConverter).AssemblyQualifiedName); + + if (!alreadyRegistered) + { + TypeDescriptor.AddAttributes(typeof(TConvertible), new TypeConverterAttribute(typeof(TConverter))); + } + } #endif - /// - /// Converts the specified value. - /// - /// The type to which the value is to be converted. - /// The value to convert. - /// - public static T ChangeType(object value) - { - return (T)ChangeType(value, typeof(T)); - } - - /// - /// Converts the specified value. - /// - /// The type to which the value is to be converted. - /// The value to convert. - /// The provider. - /// - public static T ChangeType(object value, IFormatProvider provider) - { - return (T)ChangeType(value, typeof(T), provider); - } - - /// - /// Converts the specified value. - /// - /// The type to which the value is to be converted. - /// The value to convert. - /// The culture. - /// - public static T ChangeType(object value, CultureInfo culture) - { - return (T)ChangeType(value, typeof(T), culture); - } - - /// - /// Converts the specified value using the invariant culture. - /// - /// The value to convert. - /// The type to which the value is to be converted. - /// - public static object ChangeType(object value, Type destinationType) - { - return ChangeType(value, destinationType, CultureInfo.InvariantCulture); - } - - /// - /// Converts the specified value. - /// - /// The value to convert. - /// The type to which the value is to be converted. - /// The format provider. - /// - public static object ChangeType(object value, Type destinationType, IFormatProvider provider) - { - return ChangeType(value, destinationType, new CultureInfoAdapter(CultureInfo.CurrentCulture, provider)); - } - - /// - /// Converts the specified value. - /// - /// The value to convert. - /// The type to which the value is to be converted. - /// The culture. - /// - public static object ChangeType(object value, Type destinationType, CultureInfo culture) - { - // Handle null and DBNull - if (value == null || value is DBNull) - { - return destinationType.IsValueType() ? Activator.CreateInstance(destinationType) : null; - } - - var sourceType = value.GetType(); - - // If the source type is compatible with the destination type, no conversion is needed - if (destinationType.IsAssignableFrom(sourceType)) - { - return value; - } - - // Nullable types get a special treatment - if (destinationType.IsGenericType()) - { - var genericTypeDefinition = destinationType.GetGenericTypeDefinition(); - if (genericTypeDefinition == typeof(Nullable<>)) - { - var innerType = destinationType.GetGenericArguments()[0]; - var convertedValue = ChangeType(value, innerType, culture); - return Activator.CreateInstance(destinationType, convertedValue); - } - } - - // Enums also require special handling - if (destinationType.IsEnum()) - { - var valueText = value as string; - return valueText != null ? Enum.Parse(destinationType, valueText, true) : value; - } - - // Special case for booleans to support parsing "1" and "0". This is - // necessary for compatibility with XML Schema. - if (destinationType == typeof(bool)) - { - if ("0".Equals(value)) - return false; - - if ("1".Equals(value)) - return true; - } + /// + /// Converts the specified value. + /// + /// The type to which the value is to be converted. + /// The value to convert. + /// + public static T ChangeType(object value) + { + return (T)ChangeType(value, typeof(T)); + } + + /// + /// Converts the specified value. + /// + /// The type to which the value is to be converted. + /// The value to convert. + /// The provider. + /// + public static T ChangeType(object value, IFormatProvider provider) + { + return (T)ChangeType(value, typeof(T), provider); + } + + /// + /// Converts the specified value. + /// + /// The type to which the value is to be converted. + /// The value to convert. + /// The culture. + /// + public static T ChangeType(object value, CultureInfo culture) + { + return (T)ChangeType(value, typeof(T), culture); + } + + /// + /// Converts the specified value using the invariant culture. + /// + /// The value to convert. + /// The type to which the value is to be converted. + /// + public static object ChangeType(object value, Type destinationType) + { + return ChangeType(value, destinationType, CultureInfo.InvariantCulture); + } + + /// + /// Converts the specified value. + /// + /// The value to convert. + /// The type to which the value is to be converted. + /// The format provider. + /// + public static object ChangeType(object value, Type destinationType, IFormatProvider provider) + { + return ChangeType(value, destinationType, new CultureInfoAdapter(CultureInfo.CurrentCulture, provider)); + } + + /// + /// Converts the specified value. + /// + /// The value to convert. + /// The type to which the value is to be converted. + /// The culture. + /// + public static object ChangeType(object value, Type destinationType, CultureInfo culture) + { + // Handle null and DBNull + if (value == null || value is DBNull) + { + return destinationType.IsValueType() ? Activator.CreateInstance(destinationType) : null; + } + + var sourceType = value.GetType(); + + // If the source type is compatible with the destination type, no conversion is needed + if (destinationType.IsAssignableFrom(sourceType)) + { + return value; + } + + // Nullable types get a special treatment + if (destinationType.IsGenericType()) + { + var genericTypeDefinition = destinationType.GetGenericTypeDefinition(); + if (genericTypeDefinition == typeof(Nullable<>)) + { + var innerType = destinationType.GetGenericArguments()[0]; + var convertedValue = ChangeType(value, innerType, culture); + return Activator.CreateInstance(destinationType, convertedValue); + } + } + + // Enums also require special handling + if (destinationType.IsEnum()) + { + var valueText = value as string; + return valueText != null ? Enum.Parse(destinationType, valueText, true) : value; + } + + // Special case for booleans to support parsing "1" and "0". This is + // necessary for compatibility with XML Schema. + if (destinationType == typeof(bool)) + { + if ("0".Equals(value)) + return false; + + if ("1".Equals(value)) + return true; + } #if !PORTABLE - // Try with the source type's converter - var sourceConverter = TypeDescriptor.GetConverter(value); - if (sourceConverter != null && sourceConverter.CanConvertTo(destinationType)) - { - return sourceConverter.ConvertTo(null, culture, value, destinationType); - } - - // Try with the destination type's converter - var destinationConverter = TypeDescriptor.GetConverter(destinationType); - if (destinationConverter != null && destinationConverter.CanConvertFrom(sourceType)) - { - return destinationConverter.ConvertFrom(null, culture, value); - } + // Try with the source type's converter + var sourceConverter = TypeDescriptor.GetConverter(value); + if (sourceConverter != null && sourceConverter.CanConvertTo(destinationType)) + { + return sourceConverter.ConvertTo(null, culture, value, destinationType); + } + + // Try with the destination type's converter + var destinationConverter = TypeDescriptor.GetConverter(destinationType); + if (destinationConverter != null && destinationConverter.CanConvertFrom(sourceType)) + { + return destinationConverter.ConvertFrom(null, culture, value); + } #endif - // Try to find a casting operator in the source or destination type - foreach (var type in new[] { sourceType, destinationType }) - { + // Try to find a casting operator in the source or destination type + foreach (var type in new[] { sourceType, destinationType }) + { foreach (var method in type.GetPublicStaticMethods()) - { - var isCastingOperator = - method.IsSpecialName && - (method.Name == "op_Implicit" || method.Name == "op_Explicit") && - destinationType.IsAssignableFrom(method.ReturnParameter.ParameterType); - - if (isCastingOperator) - { - var parameters = method.GetParameters(); - - var isCompatible = - parameters.Length == 1 && - parameters[0].ParameterType.IsAssignableFrom(sourceType); - - if (isCompatible) - { - try - { - return method.Invoke(null, new[] { value }); - } - catch (TargetInvocationException ex) - { - throw ex.Unwrap(); - } - } - } - } - } - - // If source type is string, try to find a Parse or TryParse method - if (sourceType == typeof(string)) - { - try - { - // Try with - public static T Parse(string, IFormatProvider) - var parseMethod = destinationType.GetPublicStaticMethod("Parse", typeof(string), typeof(IFormatProvider)); - if (parseMethod != null) - { - return parseMethod.Invoke(null, new object[] { value, culture }); - } - - // Try with - public static T Parse(string) - parseMethod = destinationType.GetPublicStaticMethod("Parse", typeof(string)); - if (parseMethod != null) - { - return parseMethod.Invoke(null, new object[] { value }); - } - } - catch (TargetInvocationException ex) - { - throw ex.Unwrap(); - } - } - - // Handle TimeSpan - if (destinationType == typeof(TimeSpan)) - { - return TimeSpan.Parse((string)ChangeType(value, typeof(string), CultureInfo.InvariantCulture)); - } - - // Default to the Convert class - return Convert.ChangeType(value, destinationType, CultureInfo.InvariantCulture); - } - } + { + var isCastingOperator = + method.IsSpecialName && + (method.Name == "op_Implicit" || method.Name == "op_Explicit") && + destinationType.IsAssignableFrom(method.ReturnParameter.ParameterType); + + if (isCastingOperator) + { + var parameters = method.GetParameters(); + + var isCompatible = + parameters.Length == 1 && + parameters[0].ParameterType.IsAssignableFrom(sourceType); + + if (isCompatible) + { + try + { + return method.Invoke(null, new[] { value }); + } + catch (TargetInvocationException ex) + { + throw ex.Unwrap(); + } + } + } + } + } + + // If source type is string, try to find a Parse or TryParse method + if (sourceType == typeof(string)) + { + try + { + // Try with - public static T Parse(string, IFormatProvider) + var parseMethod = destinationType.GetPublicStaticMethod("Parse", typeof(string), typeof(IFormatProvider)); + if (parseMethod != null) + { + return parseMethod.Invoke(null, new object[] { value, culture }); + } + + // Try with - public static T Parse(string) + parseMethod = destinationType.GetPublicStaticMethod("Parse", typeof(string)); + if (parseMethod != null) + { + return parseMethod.Invoke(null, new object[] { value }); + } + } + catch (TargetInvocationException ex) + { + throw ex.Unwrap(); + } + } + + // Handle TimeSpan + if (destinationType == typeof(TimeSpan)) + { + return TimeSpan.Parse((string)ChangeType(value, typeof(string), CultureInfo.InvariantCulture)); + } + + // Default to the Convert class + return Convert.ChangeType(value, destinationType, CultureInfo.InvariantCulture); + } + } } diff --git a/YamlDotNet/Serialization/Utilities/YamlTypeConverters.cs b/YamlDotNet/Serialization/Utilities/YamlTypeConverters.cs index 0a3035455..016a792c8 100644 --- a/YamlDotNet/Serialization/Utilities/YamlTypeConverters.cs +++ b/YamlDotNet/Serialization/Utilities/YamlTypeConverters.cs @@ -24,13 +24,13 @@ namespace YamlDotNet.Serialization.Utilities { - internal static class YamlTypeConverters - { - private static readonly IEnumerable _builtInTypeConverters = new IYamlTypeConverter[] - { - new GuidConverter(), - }; + internal static class YamlTypeConverters + { + private static readonly IEnumerable _builtInTypeConverters = new IYamlTypeConverter[] + { + new GuidConverter(), + }; - public static IEnumerable BuiltInConverters { get { return _builtInTypeConverters; } } - } + public static IEnumerable BuiltInConverters { get { return _builtInTypeConverters; } } + } } diff --git a/YamlDotNet/Serialization/ValueDeserializers/AliasValueDeserializer.cs b/YamlDotNet/Serialization/ValueDeserializers/AliasValueDeserializer.cs index 4436a82c6..b4ad68029 100644 --- a/YamlDotNet/Serialization/ValueDeserializers/AliasValueDeserializer.cs +++ b/YamlDotNet/Serialization/ValueDeserializers/AliasValueDeserializer.cs @@ -27,135 +27,135 @@ namespace YamlDotNet.Serialization.ValueDeserializers { - public sealed class AliasValueDeserializer : IValueDeserializer - { - private readonly IValueDeserializer innerDeserializer; - - public AliasValueDeserializer(IValueDeserializer innerDeserializer) - { - if (innerDeserializer == null) - { - throw new ArgumentNullException ("innerDeserializer"); - } - - this.innerDeserializer = innerDeserializer; - } + public sealed class AliasValueDeserializer : IValueDeserializer + { + private readonly IValueDeserializer innerDeserializer; + + public AliasValueDeserializer(IValueDeserializer innerDeserializer) + { + if (innerDeserializer == null) + { + throw new ArgumentNullException ("innerDeserializer"); + } + + this.innerDeserializer = innerDeserializer; + } - private sealed class AliasState : Dictionary, IPostDeserializationCallback - { - public void OnDeserialization() - { - foreach (var promise in Values) - { - if (!promise.HasValue) - { - throw new AnchorNotFoundException(promise.Alias.Start, promise.Alias.End, string.Format( - "Anchor '{0}' not found", - promise.Alias.Value - )); - } - } - } - } + private sealed class AliasState : Dictionary, IPostDeserializationCallback + { + public void OnDeserialization() + { + foreach (var promise in Values) + { + if (!promise.HasValue) + { + throw new AnchorNotFoundException(promise.Alias.Start, promise.Alias.End, string.Format( + "Anchor '{0}' not found", + promise.Alias.Value + )); + } + } + } + } - private sealed class ValuePromise : IValuePromise - { - public event Action ValueAvailable; + private sealed class ValuePromise : IValuePromise + { + public event Action ValueAvailable; - public bool HasValue { get; private set; } + public bool HasValue { get; private set; } - private object value; + private object value; - public readonly AnchorAlias Alias; + public readonly AnchorAlias Alias; - public ValuePromise(AnchorAlias alias) - { - this.Alias = alias; - } + public ValuePromise(AnchorAlias alias) + { + this.Alias = alias; + } - public ValuePromise(object value) - { - HasValue = true; - this.value = value; - } + public ValuePromise(object value) + { + HasValue = true; + this.value = value; + } - public object Value - { - get - { - if (!HasValue) - { - throw new InvalidOperationException("Value not set"); - } - return value; - } - set - { - if (HasValue) - { - throw new InvalidOperationException("Value already set"); - } - HasValue = true; - this.value = value; + public object Value + { + get + { + if (!HasValue) + { + throw new InvalidOperationException("Value not set"); + } + return value; + } + set + { + if (HasValue) + { + throw new InvalidOperationException("Value already set"); + } + HasValue = true; + this.value = value; - if (ValueAvailable != null) - { - ValueAvailable(value); - } - } - } - } - - public object DeserializeValue (EventReader reader, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) - { - object value; - var alias = reader.Allow(); - if(alias != null) - { - var aliasState = state.Get(); - ValuePromise valuePromise; - if(!aliasState.TryGetValue(alias.Value, out valuePromise)) - { - valuePromise = new ValuePromise(alias); - aliasState.Add(alias.Value, valuePromise); - } + if (ValueAvailable != null) + { + ValueAvailable(value); + } + } + } + } + + public object DeserializeValue (EventReader reader, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) + { + object value; + var alias = reader.Allow(); + if(alias != null) + { + var aliasState = state.Get(); + ValuePromise valuePromise; + if(!aliasState.TryGetValue(alias.Value, out valuePromise)) + { + valuePromise = new ValuePromise(alias); + 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; - } - - value = innerDeserializer.DeserializeValue(reader, expectedType, state, nestedObjectDeserializer); - - if(anchor != null) - { - var aliasState = state.Get(); + return valuePromise.HasValue ? valuePromise.Value : valuePromise; + } + + 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)) - { - aliasState.Add(anchor, new ValuePromise(value)); - } - else if (!valuePromise.HasValue) - { - valuePromise.Value = value; - } - else - { - throw new DuplicateAnchorException(nodeEvent.Start, nodeEvent.End, string.Format( - "Anchor '{0}' already defined", - anchor - )); - } - } - - return value; - } - } + ValuePromise valuePromise; + if (!aliasState.TryGetValue(anchor, out valuePromise)) + { + aliasState.Add(anchor, new ValuePromise(value)); + } + else if (!valuePromise.HasValue) + { + valuePromise.Value = value; + } + else + { + throw new DuplicateAnchorException(nodeEvent.Start, nodeEvent.End, string.Format( + "Anchor '{0}' already defined", + anchor + )); + } + } + + return value; + } + } } diff --git a/YamlDotNet/Serialization/ValueDeserializers/NodeValueDeserializer.cs b/YamlDotNet/Serialization/ValueDeserializers/NodeValueDeserializer.cs index daa3800d6..96986b1d5 100644 --- a/YamlDotNet/Serialization/ValueDeserializers/NodeValueDeserializer.cs +++ b/YamlDotNet/Serialization/ValueDeserializers/NodeValueDeserializer.cs @@ -28,73 +28,73 @@ namespace YamlDotNet.Serialization.ValueDeserializers { - public sealed class NodeValueDeserializer : IValueDeserializer - { - private readonly IList deserializers; - private readonly IList typeResolvers; - - public NodeValueDeserializer(IList deserializers, IList typeResolvers) - { - if(deserializers == null) - { - throw new ArgumentNullException("deserializers"); - } + public sealed class NodeValueDeserializer : IValueDeserializer + { + private readonly IList deserializers; + private readonly IList typeResolvers; + + public NodeValueDeserializer(IList deserializers, IList typeResolvers) + { + if(deserializers == null) + { + throw new ArgumentNullException("deserializers"); + } - this.deserializers = deserializers; - - if(typeResolvers == null) - { - throw new ArgumentNullException("typeResolvers"); - } - this.typeResolvers = typeResolvers; - } - - public object DeserializeValue (EventReader reader, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) - { - var nodeEvent = reader.Peek(); + this.deserializers = deserializers; + + if(typeResolvers == null) + { + throw new ArgumentNullException("typeResolvers"); + } + this.typeResolvers = typeResolvers; + } + + public object DeserializeValue (EventReader reader, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer) + { + var nodeEvent = reader.Peek(); - var nodeType = GetTypeFromEvent(nodeEvent, expectedType); + var nodeType = GetTypeFromEvent(nodeEvent, expectedType); - try - { - foreach (var deserializer in deserializers) - { - object value; - if (deserializer.Deserialize(reader, nodeType, (r, t) => nestedObjectDeserializer.DeserializeValue(r, t, state, nestedObjectDeserializer), out value)) - { - return value; - } - } - } - catch (YamlException) - { - throw; - } - catch (Exception ex) - { - throw new YamlException(nodeEvent.Start, nodeEvent.End, "Exception during deserialization", ex); - } + try + { + foreach (var deserializer in deserializers) + { + object value; + if (deserializer.Deserialize(reader, nodeType, (r, t) => nestedObjectDeserializer.DeserializeValue(r, t, state, nestedObjectDeserializer), out value)) + { + return value; + } + } + } + catch (YamlException) + { + throw; + } + catch (Exception ex) + { + throw new YamlException(nodeEvent.Start, nodeEvent.End, "Exception during deserialization", ex); + } - throw new YamlException( - nodeEvent.Start, - nodeEvent.End, - string.Format( - "No node deserializer was able to deserialize the node into type {0}", - expectedType.AssemblyQualifiedName - ) - ); - } + throw new YamlException( + nodeEvent.Start, + nodeEvent.End, + string.Format( + "No node deserializer was able to deserialize the node into type {0}", + expectedType.AssemblyQualifiedName + ) + ); + } - private Type GetTypeFromEvent(NodeEvent nodeEvent, Type currentType) - { - foreach (var typeResolver in typeResolvers) - { - if (typeResolver.Resolve(nodeEvent, ref currentType)) - { - break; - } - } - return currentType; - } - } + private Type GetTypeFromEvent(NodeEvent nodeEvent, Type currentType) + { + foreach (var typeResolver in typeResolvers) + { + if (typeResolver.Resolve(nodeEvent, ref currentType)) + { + break; + } + } + return currentType; + } + } } diff --git a/YamlDotNet/Serialization/YamlAliasAttribute.cs b/YamlDotNet/Serialization/YamlAliasAttribute.cs index e82f999a7..0b0e253ad 100644 --- a/YamlDotNet/Serialization/YamlAliasAttribute.cs +++ b/YamlDotNet/Serialization/YamlAliasAttribute.cs @@ -23,25 +23,25 @@ namespace YamlDotNet.Serialization { - /// - /// Instructs the to use a different field name for serialization. - /// - [Obsolete("Please use YamlMember instead")] - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] - public class YamlAliasAttribute : Attribute - { - /// - /// Gets or sets the alias name. - /// - public string Alias { get; set; } + /// + /// Instructs the to use a different field name for serialization. + /// + [Obsolete("Please use YamlMember instead")] + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] + public class YamlAliasAttribute : Attribute + { + /// + /// Gets or sets the alias name. + /// + public string Alias { get; set; } - /// - /// Initializes a new instance of the class. - /// - /// The alias to use for this field. - public YamlAliasAttribute(string alias) - { - Alias = alias; - } - } + /// + /// Initializes a new instance of the class. + /// + /// The alias to use for this field. + public YamlAliasAttribute(string alias) + { + Alias = alias; + } + } } diff --git a/YamlDotNet/Serialization/YamlAttributesTypeInspector.cs b/YamlDotNet/Serialization/YamlAttributesTypeInspector.cs index 9037c3a6a..85bcd2c19 100644 --- a/YamlDotNet/Serialization/YamlAttributesTypeInspector.cs +++ b/YamlDotNet/Serialization/YamlAttributesTypeInspector.cs @@ -26,58 +26,58 @@ namespace YamlDotNet.Serialization { - /// - /// Applies the Yaml* attributes to another . - /// - public sealed class YamlAttributesTypeInspector : TypeInspectorSkeleton - { - private readonly ITypeInspector innerTypeDescriptor; + /// + /// Applies the Yaml* attributes to another . + /// + public sealed class YamlAttributesTypeInspector : TypeInspectorSkeleton + { + private readonly ITypeInspector innerTypeDescriptor; - public YamlAttributesTypeInspector(ITypeInspector innerTypeDescriptor) - { - this.innerTypeDescriptor = innerTypeDescriptor; - } + public YamlAttributesTypeInspector(ITypeInspector innerTypeDescriptor) + { + this.innerTypeDescriptor = innerTypeDescriptor; + } - public override IEnumerable GetProperties(Type type, object container) - { - return innerTypeDescriptor.GetProperties(type, container) - .Where(p => p.GetCustomAttribute() == null) - .Select(p => - { - var descriptor = new PropertyDescriptor(p); + public override IEnumerable GetProperties(Type type, object container) + { + return innerTypeDescriptor.GetProperties(type, container) + .Where(p => p.GetCustomAttribute() == null) + .Select(p => + { + var descriptor = new PropertyDescriptor(p); #pragma warning disable 0618 // 'YamlDotNet.Serialization.YamlAliasAttribute' is obsolete: 'Please use YamlMember instead' - var alias = p.GetCustomAttribute(); - if (alias != null) - { - descriptor.Name = alias.Alias; - } + var alias = p.GetCustomAttribute(); + if (alias != null) + { + descriptor.Name = alias.Alias; + } #pragma warning restore 0618 // 'YamlDotNet.Serialization.YamlAliasAttribute' is obsolete: 'Please use YamlMember instead' - var member = p.GetCustomAttribute(); - if (member != null) - { - if (member.SerializeAs != null) - { - descriptor.TypeOverride = member.SerializeAs; - } + var member = p.GetCustomAttribute(); + if (member != null) + { + if (member.SerializeAs != null) + { + descriptor.TypeOverride = member.SerializeAs; + } - descriptor.Order = member.Order; - descriptor.ScalarStyle = member.ScalarStyle; + descriptor.Order = member.Order; + descriptor.ScalarStyle = member.ScalarStyle; - if (member.Alias != null) - { - if (alias != null) - { - throw new InvalidOperationException("Mixing YamlAlias(...) with YamlMember(Alias = ...) is an error. The YamlAlias attribute is obsolete and should be removed."); - } - descriptor.Name = member.Alias; - } - } + if (member.Alias != null) + { + if (alias != null) + { + throw new InvalidOperationException("Mixing YamlAlias(...) with YamlMember(Alias = ...) is an error. The YamlAlias attribute is obsolete and should be removed."); + } + descriptor.Name = member.Alias; + } + } - return (IPropertyDescriptor)descriptor; - }) - .OrderBy(p => p.Order); - } - } + return (IPropertyDescriptor)descriptor; + }) + .OrderBy(p => p.Order); + } + } } diff --git a/YamlDotNet/Serialization/YamlFormatter.cs b/YamlDotNet/Serialization/YamlFormatter.cs index f9e34c553..eab932913 100644 --- a/YamlDotNet/Serialization/YamlFormatter.cs +++ b/YamlDotNet/Serialization/YamlFormatter.cs @@ -24,42 +24,42 @@ namespace YamlDotNet.Serialization { - internal static class YamlFormatter - { - public static readonly NumberFormatInfo NumberFormat = new NumberFormatInfo - { - CurrencyDecimalSeparator = ".", - CurrencyGroupSeparator = "_", - CurrencyGroupSizes = new[] { 3 }, - CurrencySymbol = string.Empty, - CurrencyDecimalDigits = 99, - NumberDecimalSeparator = ".", - NumberGroupSeparator = "_", - NumberGroupSizes = new[] { 3 }, - NumberDecimalDigits = 99, - NaNSymbol = ".nan", - PositiveInfinitySymbol = ".inf", - NegativeInfinitySymbol = "-.inf", - }; + internal static class YamlFormatter + { + public static readonly NumberFormatInfo NumberFormat = new NumberFormatInfo + { + CurrencyDecimalSeparator = ".", + CurrencyGroupSeparator = "_", + CurrencyGroupSizes = new[] { 3 }, + CurrencySymbol = string.Empty, + CurrencyDecimalDigits = 99, + NumberDecimalSeparator = ".", + NumberGroupSeparator = "_", + NumberGroupSizes = new[] { 3 }, + NumberDecimalDigits = 99, + NaNSymbol = ".nan", + PositiveInfinitySymbol = ".inf", + NegativeInfinitySymbol = "-.inf", + }; - public static string FormatNumber(object number) - { - return Convert.ToString(number, NumberFormat); - } + public static string FormatNumber(object number) + { + return Convert.ToString(number, NumberFormat); + } - public static string FormatBoolean(object boolean) - { - return boolean.Equals(true) ? "true" : "false"; - } + public static string FormatBoolean(object boolean) + { + return boolean.Equals(true) ? "true" : "false"; + } - public static string FormatDateTime(object dateTime) - { - return ((DateTime)dateTime).ToString("o", CultureInfo.InvariantCulture); - } + public static string FormatDateTime(object dateTime) + { + return ((DateTime)dateTime).ToString("o", CultureInfo.InvariantCulture); + } - public static string FormatTimeSpan(object timeSpan) - { - return ((TimeSpan)timeSpan).ToString(); - } - } + public static string FormatTimeSpan(object timeSpan) + { + return ((TimeSpan)timeSpan).ToString(); + } + } } \ No newline at end of file diff --git a/YamlDotNet/Serialization/YamlMember.cs b/YamlDotNet/Serialization/YamlMember.cs index d4fb1a27a..00f373e5e 100644 --- a/YamlDotNet/Serialization/YamlMember.cs +++ b/YamlDotNet/Serialization/YamlMember.cs @@ -24,26 +24,26 @@ namespace YamlDotNet.Serialization { - /// - /// Provides special Yaml serialization instructions. - /// - [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] - public sealed class YamlMemberAttribute : Attribute - { - /// - /// Specifies that this property should be serialized as the given type, rather than using the actual runtime value's type. - /// - public Type SerializeAs { get; set; } + /// + /// Provides special Yaml serialization instructions. + /// + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] + public sealed class YamlMemberAttribute : Attribute + { + /// + /// Specifies that this property should be serialized as the given type, rather than using the actual runtime value's type. + /// + public Type SerializeAs { get; set; } /// /// Specifies the order priority of this property. /// public int Order { get; set; } - /// - /// Instructs the to use a different field name for serialization. - /// - public string Alias { get; set; } + /// + /// Instructs the to use a different field name for serialization. + /// + public string Alias { get; set; } /// /// Specifies the scalar style of the property when serialized. This will only affect the serialization of scalar properties. @@ -58,13 +58,13 @@ public YamlMemberAttribute() ScalarStyle = ScalarStyle.Any; } - /// - /// Initializes a new instance of the class. - /// - /// Specifies that this property should be serialized as the given type, rather than using the actual runtime value's type. - public YamlMemberAttribute(Type serializeAs) : this() - { - SerializeAs = serializeAs; - } - } + /// + /// Initializes a new instance of the class. + /// + /// Specifies that this property should be serialized as the given type, rather than using the actual runtime value's type. + public YamlMemberAttribute(Type serializeAs) : this() + { + SerializeAs = serializeAs; + } + } } diff --git a/YamlDotNet/YamlDotNet.Signed.nuspec b/YamlDotNet/YamlDotNet.Signed.nuspec index c33d9add5..1b69dc3af 100644 --- a/YamlDotNet/YamlDotNet.Signed.nuspec +++ b/YamlDotNet/YamlDotNet.Signed.nuspec @@ -2,27 +2,27 @@ YamlDotNet.Signed - 0.0.1 - Antoine Aubry - A .NET library for YAML. YamlDotNet provides low level parsing and emitting of YAML as well as a high level object model similar to XmlDocument. - This package contains the YAML parser and serializer. This is the signed version of the package. - en-US - http://aaubry.net/pages/license.html - http://aaubry.net/pages/yamldotnet.html - http://aaubry.net/images/yamldotnet.png - yaml parser development library serialization signed strongname + 0.0.1 + Antoine Aubry + A .NET library for YAML. YamlDotNet provides low level parsing and emitting of YAML as well as a high level object model similar to XmlDocument. + This package contains the YAML parser and serializer. This is the signed version of the package. + en-US + http://aaubry.net/pages/license.html + http://aaubry.net/pages/yamldotnet.html + http://aaubry.net/images/yamldotnet.png + yaml parser development library serialization signed strongname - - - + + + - - - + + + - - - - + + + + diff --git a/YamlDotNet/YamlDotNet.Unsigned.nuspec b/YamlDotNet/YamlDotNet.Unsigned.nuspec index 8475b0d29..d9b11e44a 100644 --- a/YamlDotNet/YamlDotNet.Unsigned.nuspec +++ b/YamlDotNet/YamlDotNet.Unsigned.nuspec @@ -1,25 +1,25 @@ - - YamlDotNet - 0.0.1 - Antoine Aubry - A .NET library for YAML. YamlDotNet provides low level parsing and emitting of YAML as well as a high level object model similar to XmlDocument. - This package contains the YAML parser and serializer. - en-US - http://aaubry.net/pages/license.html - http://aaubry.net/pages/yamldotnet.html - http://aaubry.net/images/yamldotnet.png - yaml parser development library serialization - - - - - + + YamlDotNet + 0.0.1 + Antoine Aubry + A .NET library for YAML. YamlDotNet provides low level parsing and emitting of YAML as well as a high level object model similar to XmlDocument. + This package contains the YAML parser and serializer. + en-US + http://aaubry.net/pages/license.html + http://aaubry.net/pages/yamldotnet.html + http://aaubry.net/images/yamldotnet.png + yaml parser development library serialization + + + + + - - - + + + diff --git a/build.ps1 b/build.ps1 index 78e79bf6b..53faff375 100644 --- a/build.ps1 +++ b/build.ps1 @@ -23,15 +23,15 @@ $targets | msbuild YamlDotNet.sln /p:Configuration=$_ } - if($LASTEXITCODE -ne 0) { - throw "Build failed" - } + if($LASTEXITCODE -ne 0) { + throw "Build failed" + } } "Unsigned", "Signed" | % { nuget pack YamlDotNet\YamlDotNet.$_.nuspec -OutputDirectory YamlDotNet\bin - if($LASTEXITCODE -ne 0) { - throw "Build failed" - } + if($LASTEXITCODE -ne 0) { + throw "Build failed" + } } diff --git a/prebuild.ps1 b/prebuild.ps1 index 8d9dc453f..35443196a 100644 --- a/prebuild.ps1 +++ b/prebuild.ps1 @@ -6,7 +6,7 @@ $version = Get-VersionFromTag Update-AppveyorBuild -Version "$version.$buildNumber" if($env:APPVEYOR_REPO_BRANCH -ne "release") { - $version = "$version-pre$buildNumber" + $version = "$version-pre$buildNumber" } Patch-Xml "YamlDotNet\YamlDotNet.Unsigned.nuspec" $version "/package/metadata/version/text()" @{ } From 60a43aeb36eb6edf2c4584685dd978234ef45bc8 Mon Sep 17 00:00:00 2001 From: Antoine Aubry Date: Mon, 1 Feb 2016 16:37:32 +0000 Subject: [PATCH 4/5] Prepare release 3.8.0. --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index bf1663982..8fea450d3 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,30 @@ Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. # Changelog +## Version 3.8.0 + +New features: + +* **Add support for different scalar integer bases.** + Addresses issue [#113](https://github.com/aaubry/YamlDotNet/issues/113). Adds basic support for deserializing scalar integers + written in binary, octal, decimal, hex, and base 60, as allowed in the YAML + specification; see http://yaml.org/type/int.html. Adds unit tests for each + of these bases as well. +* **Add dnx compatibility to the NuGet packages.** +* Do not throw exception if a tag does not contain a valid type name. + +Fixes and improvements: + +* Cache type metadata. +* Fix wrong type when deserializing UInt16. +* Fix handling of special float values, such as NaN, PositiveInfinity and NegativeInfinity. +* Properly quote empty strings. +* Properly handle non-Unicode encodings when emitting scalars. + +## Version 3.7.0 + +This is a minor update that simply adds an overload of YamlStream.Load to be able to specify the EventReader. + ## Version 3.6.1 Bug fixes: From 6c5f252715d2772d30b218f4fc33b6d496b9ab5c Mon Sep 17 00:00:00 2001 From: Antoine Aubry Date: Tue, 2 Feb 2016 13:48:09 +0000 Subject: [PATCH 5/5] Remove branch names from .gitmodules Ensures compatibility with some clients, and 'master' is the default anyway. --- .gitmodules | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index d09e656e9..493011f45 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,8 +1,6 @@ [submodule "BuildUtils"] path = BuildUtils url = https://github.com/aaubry/BuildUtils.git - branch = master [submodule "BuildUtils.UnityPrerequisites"] path = BuildUtils.UnityPrerequisites url = https://github.com/aaubry/BuildUtils.UnityPrerequisites.git - branch = master