Example #1
0
		/// <summary>
		/// Loads the specified event.
		/// </summary>
		/// <param name="yamlEvent">The event.</param>
		/// <param name="state">The state of the document.</param>
		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;
		}
		/// <summary>
		/// Gets the node with the specified anchor.
		/// </summary>
		/// <param name="anchor">The anchor.</param>
		/// <param name="throwException">if set to <c>true</c>, the method should throw an exception if there is no node with that anchor.</param>
		/// <param name="start">The start position.</param>
		/// <param name="end">The end position.</param>
		/// <returns></returns>
		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;
			}
		}
Example #3
0
		/// <summary>
		/// Scan a tag handle.
		/// </summary>

		private string ScanTagHandle(bool isDirective, Mark start)
		{

			// Check the initial '!' character.

			if (!analyzer.Check('!'))
			{
				throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a tag, did not find expected '!'.");
			}

			// Copy the '!' character.

			StringBuilder tagHandle = new StringBuilder();
			tagHandle.Append(ReadCurrentCharacter());

			// Copy all subsequent alphabetical and numerical characters.

			while (analyzer.IsAlphaNumericDashOrUnderscore())
			{
				tagHandle.Append(ReadCurrentCharacter());
			}

			// Check if the trailing character is '!' and copy it.

			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.


				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();
		}
Example #4
0
		/// <summary>
		/// Decode an URI-escape sequence corresponding to a single UTF-8 character.
		/// </summary>

		private char ScanUriEscapes(Mark start)
		{
			// Decode the required number of characters.

			List<byte> charBytes = new List<byte>();
			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.");
				}

				// Get the octet.

				int octet = (analyzer.AsHex(1) << 4) + analyzer.AsHex(2);

				// 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)
					{
						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.");
					}
				}

				// Copy the octet and move the pointers.

				charBytes.Add((byte)octet);

				Skip();
				Skip();
				Skip();
			}
			while (--width > 0);

			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.");
			}

			return characters[0];
		}
Example #5
0
		/// <summary>
		/// Scan a tag.
		/// </summary>

		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.

			// The set of characters that may appear in URI is as follows:

			//      '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
			//      '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
			//      '%'.


			while (analyzer.IsAlphaNumericDashOrUnderscore() || analyzer.Check(";/?:@&=+$,.!~*'()[]%"))
			{
				// Check if it is a URI-escape sequence.

				if (analyzer.Check('%'))
				{
					tag.Append(ScanUriEscapes(start));
				}
				else
				{
					tag.Append(ReadCurrentCharacter());
				}
			}

			// 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.");
			}

			return tag.ToString();
		}
Example #6
0
		/// <summary>
		/// Scan the value of a TAG-DIRECTIVE token.
		///
		/// Scope:
		///      %TAG    !yaml!  tag:yaml.org,2002:  \n
		///          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
		/// </summary>
		private Token ScanTagDirectiveValue(Mark start)
		{
			SkipWhitespaces();

			// Scan a handle.

			string handle = ScanTagHandle(true, start);

			// Expect a whitespace.

			if (!analyzer.IsWhite())
			{
				throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a %TAG directive, did not find expected whitespace.");
			}

			SkipWhitespaces();

			// Scan a prefix.

			string prefix = ScanTagUri(null, start);

			// 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.");
			}

			return new TagDirective(handle, prefix, start, start);
		}
Example #7
0
		/// <summary>
		/// Scan the value of VERSION-DIRECTIVE.
		///
		/// Scope:
		///      %YAML   1.1     # a comment \n
		///           ^^^^^^
		/// </summary>
		private Token ScanVersionDirectiveValue(Mark start)
		{
			SkipWhitespaces();

			// Consume the major version number.

			int major = ScanVersionDirectiveNumber(start);

			// Eat '.'.

			if (!analyzer.Check('.'))
			{
				throw new SyntaxErrorException(start, cursor.Mark(), "While scanning a %YAML directive, did not find expected digit or '.' character.");
			}

			Skip();

			// Consume the minor version number.

			int minor = ScanVersionDirectiveNumber(start);

			return new VersionDirective(new Version(major, minor), start, start);
		}
Example #8
0
		/// <summary>
		/// Initializes a new instance of the <see cref="YamlException"/> class.
		/// </summary>
		public YamlException(Mark start, Mark end, string message)
			: this(start, end, message, null)
		{
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="SyntaxErrorException"/> class.
		/// </summary>
		public SyntaxErrorException(Mark start, Mark end, string message)
			: base(start, end, message)
		{
		}
Example #10
0
		/// <summary>
		/// 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.
		/// </summary>
		private void RollIndent(int column, int number, bool isSequence, Mark position)
		{
			// In the flow context, do nothing.

			if (flowLevel > 0)
			{
				return;
			}

			if (indent < column)
			{

				// Push the current indentation level to the stack and set the new
				// indentation level.


				indents.Push(indent);

				indent = column;

				// Create a token and insert it into the queue.

				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);
				}
			}
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="AnchorNotFoundException"/> class.
		/// </summary>
		public AnchorNotFoundException(Mark start, Mark end, string message)
			: base(start, end, message)
		{
		}
Example #12
0
		/// <summary>
		/// Generate an empty scalar event.
		/// </summary>
		private static ParsingEvent ProcessEmptyScalar(Mark position)
		{
			return new Events.Scalar(null, null, string.Empty, ScalarStyle.Plain, true, false, position, position);
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="DuplicateAnchorException"/> class.
		/// </summary>
		public DuplicateAnchorException(Mark start, Mark end, string message)
			: base(start, end, message)
		{
		}
Example #14
0
		/// <summary>
		/// Initializes a new instance of the <see cref="YamlException"/> class.
		/// </summary>
		/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> that holds the serialized object data about the exception being thrown.</param>
		/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"/> that contains contextual information about the source or destination.</param>
		/// <exception cref="T:System.ArgumentNullException">The <paramref name="info"/> parameter is null. </exception>
		/// <exception cref="T:System.Runtime.Serialization.SerializationException">The class name is null or <see cref="P:System.Exception.HResult"/> is zero (0). </exception>
		protected YamlException(SerializationInfo info, StreamingContext context)
			: base(info, context)
		{
			Start = (Mark)info.GetValue("Start", typeof(Mark));
			End = (Mark)info.GetValue("End", typeof(Mark));
		}
Example #15
0
		/// <summary>
		/// Initializes a new instance of the <see cref="YamlException"/> class.
		/// </summary>
		public YamlException(Mark start, Mark end, string message, Exception innerException)
			: base(string.Format("({0}) - ({1}): {2}", start, end, message), innerException)
		{
			Start = start;
			End = end;
		}
Example #16
0
		/// <summary>
		/// Scan the version number of VERSION-DIRECTIVE.
		///
		/// Scope:
		///      %YAML   1.1     # a comment \n
		///              ^
		///      %YAML   1.1     # a comment \n
		///                ^
		/// </summary>
		private int ScanVersionDirectiveNumber(Mark start)
		{
			int value = 0;
			int length = 0;

			// Repeat while the next character is digit.

			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.");
				}

				value = value * 10 + analyzer.AsDigit();

				Skip();
			}

			// 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.");
			}

			return value;
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="AnchorNotFoundException"/> class.
		/// </summary>
		public ForwardAnchorNotSupportedException(Mark start, Mark end, string message)
			: base(start, end, message)
		{
		}
Example #18
0
		/// <summary>
		/// Scan intendation spaces and line breaks for a block scalar.  Determine the
		/// intendation level if needed.
		/// </summary>

		private int ScanBlockScalarBreaks(int currentIndent, StringBuilder breaks, Mark start, ref Mark end)
		{
			int maxIndent = 0;

			end = cursor.Mark();

			// Eat the intendation spaces and line breaks.

			for (; ;)
			{
				// Eat the intendation spaces.

				while ((currentIndent == 0 || cursor.LineOffset < currentIndent) && analyzer.IsSpace())
				{
					Skip();
				}

				if (cursor.LineOffset > maxIndent)
				{
					maxIndent = cursor.LineOffset;
				}

				// 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.");
				}

				// Have we find a non-empty line?

				if (!analyzer.IsBreak())
				{
					break;
				}

				// Consume the line break.

				breaks.Append(ReadLine());

				end = cursor.Mark();
			}

			// Determine the indentation level if needed.

			if (currentIndent == 0)
			{
				currentIndent = Math.Max(maxIndent, Math.Max(indent + 1, 1));
			}

			return currentIndent;
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="SemanticErrorException"/> class.
		/// </summary>
		public SemanticErrorException(Mark start, Mark end, string message)
			: base(start, end, message)
		{
		}
Example #20
0
		/// <summary>
		/// Scan the directive name.
		///
		/// Scope:
		///      %YAML   1.1     # a comment \n
		///       ^^^^
		///      %TAG    !yaml!  tag:yaml.org,2002:  \n
		///       ^^^
		/// </summary>
		private string ScanDirectiveName(Mark start)
		{
			StringBuilder name = new StringBuilder();

			// 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();
		}