Exemple #1
0
        /// <summary>
        ///   Test for the value's nan, NaN and NAN in the stream. If
        ///   found then it is placed inside the content.
        ///   There is no more data excepted behind it
        /// </summary>
        private void ParseNaN(ParseStream stream)
        {
            // Read the first 8 chars
            char[] chars = new char[8];

            int length = 0;
            for (int i = 0; i < chars.Length && !stream.EOF; i++)
            {
                chars[i] = stream.Char;
                length++;
                stream.Next(true);
            }

            // Compare
            if (length == 3)
            {
                string s = "" + chars[0] + chars[1] + chars[2];

                if (s == "NAN" || s == "NaN" || s == "nan")
                {
                    content = double.NaN;
                    return;
                }
            }

            throw new ParseException(stream, "No valid NaN");
        }
Exemple #2
0
        /// <summary> Hexadecimal string </summary>
        private static long Parse16(ParseStream stream, short sign)
        {
            uint output = 0;

            while (!stream.EOF)
            {
                // 0 .. 9
                if (stream.Char >= '0' && stream.Char <= '9')
                {
                    output = (output * 16) + (uint)(stream.Char - '0');
                    OverflowTest(output, sign);
                }
                // a .. f
                else if (stream.Char >= 'a' && stream.Char <= 'f')
                {
                    output = (output * 16) + (uint)(stream.Char - 'a') + 10;
                    OverflowTest(output, sign);
                }
                // A .. F
                else if (stream.Char >= 'A' && stream.Char <= 'F')
                {
                    output = (output * 16) + (uint)(stream.Char - 'A') + 10;
                    OverflowTest(output, sign);
                }
                // Ignore underscores, other chars are not allowed
                else if (stream.Char != '_')
                {
                    throw new Exception("Unknown char in base 16");
                }

                stream.Next();
            }

            return((long)(sign * output));
        }
Exemple #3
0
        /// <summary>
        ///   Parse the time (hours, minutes, seconds)
        /// </summary>
        private void ParseTime(ParseStream stream,
                               out int hour, out int minutes, out int seconds)
        {
            if (stream.Char == 't' || stream.Char == 'T')
            {
                stream.Next(true);
            }
            else
            {
                SkipWhitespace(stream);
            }

            // Parse hour
            // Note: A hour can be represented by one or two digits.
            string hulp = "";

            while (stream.Char >= '0' && stream.Char <= '9' &&
                   !stream.EOF && hulp.Length <= 2)
            {
                hulp += stream.Char;
                stream.Next(true);
            }
            hour = Int32.Parse(hulp);

            SkipChar(stream, ':');

            // Parse minutes
            minutes = ParseNumber(stream, 2);
            SkipChar(stream, ':');

            // Parse seconds
            seconds = ParseNumber(stream, 2);
        }
Exemple #4
0
 /// <summary>
 ///   Skips the spaces * and tabs * in the current stream
 /// </summary>
 private void SkipWhitespace(ParseStream stream)
 {
     while ((stream.Char == ' ' || stream.Char == '\t') && !stream.EOF)
     {
         stream.Next(true);
     }
 }
Exemple #5
0
        /// <summary> Parses a string with a given base (maximum 10) </summary>
        /// <remarks>
        ///   This is not completly correct. For base10 the first char may not be a '_'
        ///   The other bases allow this...
        /// </remarks>
        private static long ParseBase(ParseStream stream, uint basis, short sign)
        {
            // Base must be <= 10
            if (basis > 10)
            {
                throw new Exception("Base to large. Maximum 10");
            }

            ulong output = 0;
            char  max    = (char)((basis - 1) + (int)'0');

            // Parse
            while (!stream.EOF)
            {
                // Decimal
                if (stream.Char >= '0' && stream.Char <= max)
                {
                    output = (output * basis) + (uint)(stream.Char - '0');
                    OverflowTest(output, sign);
                }
                // Ignore underscores, but other chars are not allowed
                // see remarks
                else if (stream.Char != '_')
                {
                    throw new Exception("Unknown char in base " + basis);
                }

                stream.Next();
            }
            return(sign * (long)output);
        }
Exemple #6
0
        /// <summary>
        ///   Test for the value's nan, NaN and NAN in the stream. If
        ///   found then it is placed inside the content.
        ///   There is no more data excepted behind it
        /// </summary>
        private void ParseNaN(ParseStream stream)
        {
            // Read the first 8 chars
            char[] chars = new char[8];

            int length = 0;

            for (int i = 0; i < chars.Length && !stream.EOF; i++)
            {
                chars[i] = stream.Char;
                length++;
                stream.Next(true);
            }

            // Compare
            if (length == 3)
            {
                string s = "" + chars[0] + chars[1] + chars[2];

                if (s == "NAN" || s == "NaN" || s == "nan")
                {
                    content = double.NaN;
                    return;
                }
            }

            throw new ParseException(stream, "No valid NaN");
        }
Exemple #7
0
        /// <summary> Parse a DateTime </summary>
        public Timestamp(ParseStream stream) :
            base("tag:yaml.org,2002:timestamp", NodeType.Timestamp)
        {
            int year    = 0;
            int month   = 0;
            int day     = 0;
            int hour    = 0;
            int minutes = 0;
            int seconds = 0;
            int ms      = 0;

            try
            {
                // Parse year
                year = ParseNumber(stream, 4);
                SkipChar(stream, '-');

                // Parse month
                month = ParseNumber(stream, 2);
                SkipChar(stream, '-');

                // Parse day
                day = ParseNumber(stream, 2);

                // Additional, the time
                if (!stream.EOF)
                {
                    ParseTime(stream, out hour, out minutes, out seconds);
                }

                // Additional, milliseconds
                if (!stream.EOF)
                {
                    ms = ParseMilliSeconds(stream);
                }

                // Additional, the timezone
                if (!stream.EOF)
                {
                    timezone = ParseTimezone(stream);
                }

                // If there is more, then a format exception
                if (!stream.EOF)
                {
                    throw new Exception("More data then excepted");
                }

                content = new DateTime(year, month, day, hour, minutes, seconds, ms);
            }
            catch (Exception ex)
            {
                throw new ParseException(stream, ex.ToString());
            }
        }
Exemple #8
0
 /// <summary>
 ///   Skips a specified char, and throws an exception when
 ///   another char was found.
 /// </summary>
 private void SkipChar(ParseStream stream, char toSkip)
 {
     if (stream.Char == toSkip)
     {
         stream.Next(true);
     }
     else
     {
         throw new Exception("Unexpected character");
     }
 }
Exemple #9
0
 /// <summary> Parse a binary node </summary>
 public Binary(ParseStream stream) :
     base("tag:yaml.org,2002:binary", NodeType.Binary)
 {
     try
     {
         content = Parse(stream);
     }
     catch (FormatException e)
     {
         throw new ParseException(stream, e);
     }
 }
Exemple #10
0
 /// <summary> Parse a binary node </summary>
 public Binary(ParseStream stream) :
     base("tag:yaml.org,2002:binary", NodeType.Binary)
 {
     try
     {
         content = Parse(stream);
     }
     catch (FormatException e)
     {
         throw new ParseException(stream, e);
     }
 }
Exemple #11
0
        /// <summary>
        ///   Parse a Yaml string from a textfile and return a Yaml tree
        /// </summary>
        public static Node FromFile(string filename)
        {
            // Open YAML file
            StreamReader reader      = File.OpenText(filename);
            ParseStream  parsestream = new ParseStream(reader);

            // Parse
            Node node = Parse(parsestream);

            // Close YAML file
            reader.Close();
            return(node);
        }
Exemple #12
0
        /// <summary>
        ///   Parses a String surrounded with single quotes
        /// </summary>
        private string ParseSingleQuoted(ParseStream stream)
        {
            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            // Start literal parsing
            stream.StartLiteral();

            // Skip '''
            stream.Next(true);

            while (!stream.EOF)
            {
                if (stream.Char == '\'')
                {
                    stream.Next();

                    // Escaped single quote
                    if (stream.Char == '\'')
                    {
                        builder.Append(stream.Char);
                    }

                    // End of string
                    else
                    {
                        break;
                    }
                }
                else
                {
                    builder.Append(stream.Char);
                }

                stream.Next();

                // Skip \'
                if (stream.EOF)
                {
                    stream.StopLiteral();
                    throw new ParseException(stream,
                                             "Single quoted string not closed");
                }
            }

            // Stop literal parsing
            stream.StopLiteral();

            return(builder.ToString());
        }
Exemple #13
0
        /// <summary> Parses a binairy node. </summary>
        /// <remarks>
        ///   This is not an efficient method. First the stream is placed
        ///   in a string. And after that the string is converted in a byte[].
        ///   If there is a fault in the binairy string then that will only be detected
        ///   after reading the whole stream and after coneverting.
        /// </remarks>
        public static new byte[] Parse(ParseStream stream)
        {
            bool quoted = false;
            bool block  = false;

            System.Text.StringBuilder input = new System.Text.StringBuilder();

            if (stream.EOF)
            {
                throw new ParseException(stream, "Empty node");
            }

            // Detect block scalar
            stream.SkipSpaces();
            if (stream.Char == '|')
            {
                block = true;
                stream.Next();
                stream.SkipSpaces();
            }

            while (!stream.EOF)
            {
                // Detect quotes
                if (stream.Char == '\"')
                {
                    if (quoted)
                    {
                        break; //End of stream
                    }
                    else
                    {
                        quoted = true; //Start of quoted stream
                    }
                }
                // Detect and ignore newline char's
                else if (!(stream.Char == '\n' && block))
                {
                    input.Append(stream.Char);
                }

                stream.Next();
            }

            //Console.WriteLine("convert [" + input.ToString() + "]");

            return(System.Convert.FromBase64String(input.ToString()));
        }
Exemple #14
0
        /// <summary> Parse a DateTime </summary>
        public Timestamp(ParseStream stream) :
            base("tag:yaml.org,2002:timestamp", NodeType.Timestamp)
        {
            int year = 0;
            int month = 0;
            int day = 0;
            int hour = 0;
            int minutes = 0;
            int seconds = 0;
            int ms = 0;

            try
            {
                // Parse year
                year = ParseNumber(stream, 4);
                SkipChar(stream, '-');

                // Parse month
                month = ParseNumber(stream, 2);
                SkipChar(stream, '-');

                // Parse day
                day = ParseNumber(stream, 2);

                // Additional, the time
                if (!stream.EOF)
                    ParseTime(stream, out hour, out minutes, out seconds);

                // Additional, milliseconds
                if (!stream.EOF)
                    ms = ParseMilliSeconds(stream);

                // Additional, the timezone
                if (!stream.EOF)
                    timezone = ParseTimezone(stream);

                // If there is more, then a format exception
                if (!stream.EOF)
                    throw new Exception("More data then excepted");

                content = new DateTime(year, month, day, hour, minutes, seconds, ms);
            }
            catch (Exception ex)
            {
                throw new ParseException(stream, ex.ToString());
            }
        }
Exemple #15
0
        /// <summary> Parse a null node </summary>
        public Null(ParseStream stream) :
            base("tag:yaml.org,2002:null", NodeType.Null)
        {
            // An empty string is a valid null node
            if (stream.EOF)
            {
                return;
            }

            else
            {
                // Read the first 4 chars
                char[] chars  = new char[8];
                int    length = 0;
                for (int i = 0; i < chars.Length && !stream.EOF; i++)
                {
                    chars[i] = stream.Char;
                    length++;
                    stream.Next();
                }

                // Compare
                if (length == 1)
                {
                    string s = "" + chars[0];

                    // Canonical notation
                    if (s == "~")
                    {
                        return;
                    }
                }
                if (length == 4)
                {
                    string s = "" + chars[0] + chars[1] + chars[2] + chars[3];

                    // null, Null, NULL
                    if (s == "NULL" || s == "Null" || s == "null")
                    {
                        return;
                    }
                }

                throw new ParseException(stream, "Not NULL");
            }
        }
Exemple #16
0
        /// <summary>
        ///   Parse the milliseconds
        /// </summary>
        private int ParseMilliSeconds(ParseStream stream)
        {
            int ms = 0;

            // Look for fraction
            if (stream.Char == '.')
            {
                stream.Next(true);

                // Parse fraction, can consists of an
                // unlimited sequence of numbers, we only
                // look to the first three (max 1000)
                int count = 0;

                while (stream.Char >= '0' && stream.Char <= '9' &&
                       count < 3 && !stream.EOF)
                {
                    ms *= 10;
                    ms += stream.Char - '0';

                    stream.Next(true);
                    count++;
                }

                if (count == 1)
                {
                    ms *= 100;
                }
                if (count == 2)
                {
                    ms *= 10;
                }
                if (count == 3)
                {
                    ms *= 1;
                }

                // Ignore the rest
                while (stream.Char >= '0' && stream.Char <= '9' &&
                       !stream.EOF)
                {
                    stream.Next(true);
                }
            }
            return(ms);
        }
Exemple #17
0
        /// <summary> Parse float </summary>
        public Float(ParseStream stream) :
            base("tag:yaml.org,2002:float", NodeType.Float)
        {
            // NaN
            if (stream.Char == '.')
            {
                stream.Next(true);
                ParseNaN(stream);
            }
            else
            {
                // By default positief
                int sign = 1;

                // Negative sign
                if (stream.Char == '-')
                {
                    sign = -1;
                    stream.Next(true);
                }
                // Positive sign
                else if (stream.Char == '+')
                {
                    stream.Next(true);
                }

                // Test for inf, Inf and INF
                if (!stream.EOF && stream.Char == '.')
                {
                    stream.Next(true);
                    ParseInf(stream, sign);
                }
                // Parse the numbers
                else if (!stream.EOF)
                {
                    ParseNumber(stream, sign);
                }

                else
                {
                    throw new ParseException(stream,
                                             "No valid float, no data behind the sign");
                }
            }
        }
Exemple #18
0
        /// <summary>
        ///   Parse an integer
        /// </summary>
        /// <param name="length">
        ///   The number of characters that the integer is expected to be.
        /// </param>
        /// <param name="stream"> The stream that will be parsed </param>
        private int ParseNumber(ParseStream stream, int length)
        {
            System.Text.StringBuilder hulp = new System.Text.StringBuilder();

            int i;

            for (i = 0; i < length && !stream.EOF; i++)
            {
                hulp.Append(stream.Char);
                stream.Next(true);
            }
            if (i == length)
            {
                return(Int32.Parse(hulp.ToString()));
            }
            else
            {
                throw new Exception("Can't parse number");
            }
        }
Exemple #19
0
        /// <summary> Parse a null node </summary>
        public Null(ParseStream stream) :
            base("tag:yaml.org,2002:null", NodeType.Null)
        {
            // An empty string is a valid null node
            if (stream.EOF)
                return;

            else
            {
                // Read the first 4 chars
                char[] chars = new char[8];
                int length = 0;
                for (int i = 0; i < chars.Length && !stream.EOF; i++)
                {
                    chars[i] = stream.Char;
                    length++;
                    stream.Next();
                }

                // Compare
                if (length == 1)
                {
                    string s = "" + chars[0];

                    // Canonical notation
                    if (s == "~")
                        return;
                }
                if (length == 4)
                {
                    string s = "" + chars[0] + chars[1] + chars[2] + chars[3];

                    // null, Null, NULL
                    if (s == "NULL" || s == "Null" || s == "null")
                        return;
                }

                throw new ParseException(stream, "Not NULL");
            }
        }
Exemple #20
0
        /// <summary> Parse float </summary>
        public Float(ParseStream stream) :
            base("tag:yaml.org,2002:float", NodeType.Float)
        {
            // NaN
            if (stream.Char == '.')
            {
                stream.Next(true);
                ParseNaN(stream);
            }
            else
            {
                // By default positief
                int sign = 1;

                // Negative sign
                if (stream.Char == '-')
                {
                    sign = -1;
                    stream.Next(true);
                }
                // Positive sign
                else if (stream.Char == '+')
                    stream.Next(true);

                // Test for inf, Inf and INF
                if (!stream.EOF && stream.Char == '.')
                {
                    stream.Next(true);
                    ParseInf(stream, sign);
                }
                // Parse the numbers
                else if (!stream.EOF)
                    ParseNumber(stream, sign);

                else
                    throw new ParseException(stream,
                        "No valid float, no data behind the sign");
            }
        }
Exemple #21
0
        /// <summary>
        ///   Parses a String surrounded without nothing
        /// </summary>
        private string ParseUnQuoted(ParseStream stream)
        {
            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            while (!stream.EOF)
            {
                builder.Append(NextUnescapedChar(stream));
            }

            // Trimming left
            int count = 0;

            while (count < builder.Length &&
                   (builder[count] == ' ' || builder[count] == '\t'))
            {
                count++;
            }

            if (count >= 0)
            {
                builder.Remove(0, count);
            }

            // Trimming right
            count = 0;
            while (count < builder.Length &&
                   (builder[builder.Length - count - 1] == ' ' ||
                    builder[builder.Length - count - 1] == '\t'))
            {
                count++;
            }

            if (count >= 0)
            {
                builder.Remove(builder.Length - count, count);
            }

            return(builder.ToString());
        }
Exemple #22
0
        /// <summary> Parses the exponential part of the float </summary>
        private static long ParseScient(ParseStream stream)
        {
            ulong output = 0;
            short sign;

            if (stream.Char == '-')
            {
                sign = -1;
            }
            else if (stream.Char == '+')
            {
                sign = 1;
            }
            else
            {
                throw new ParseException(stream,
                                         "Excepted + or - for the exponential part");
            }

            stream.Next(true);

            while (!stream.EOF)
            {
                if (stream.Char >= '0' && stream.Char <= '9')
                {
                    output = (10 * output) + (uint)stream.Char - '0';
                }
                else
                {
                    throw new ParseException(stream,
                                             "Unexepted char in exponential part: >" +
                                             stream.Char + "<");
                }

                stream.Next(true);
            }

            return(sign * (long)output);
        }
Exemple #23
0
        /// <summary>
        ///   Parses a String surrounded with double quotes
        /// </summary>
        private string ParseDoubleQuoted(ParseStream stream)
        {
            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            // Skip '"'
            stream.Next();

            // Stop at "
            stream.StopAt(new char[] { '\"' });

            while (!stream.EOF)
            {
                if (stream.Char == '\n')
                {
                    builder.Append(' ');
                    stream.Next();
                }
                else
                {
                    builder.Append(NextUnescapedChar(stream));
                }
            }

            // Don't stop at "
            stream.DontStop();

            // Skip '"'
            if (stream.Char != '\"')
            {
                throw new ParseException(stream,
                                         "Double quoted string not closed");
            }
            else
            {
                stream.Next(true);
            }

            return(builder.ToString());
        }
Exemple #24
0
        /// <summary> Parses a binairy node. </summary>
        /// <remarks>
        ///   This is not an efficient method. First the stream is placed
        ///   in a string. And after that the string is converted in a byte[].
        ///   If there is a fault in the binairy string then that will only be detected
        ///   after reading the whole stream and after coneverting.
        /// </remarks>
        public static new byte[] Parse(ParseStream stream)
        {
            bool quoted = false;
            bool block = false;
            System.Text.StringBuilder input = new System.Text.StringBuilder();

            if (stream.EOF)
                throw new ParseException(stream, "Empty node");

            // Detect block scalar
            stream.SkipSpaces();
            if (stream.Char == '|')
            {
                block = true;
                stream.Next();
                stream.SkipSpaces();
            }

            while (!stream.EOF)
            {
                // Detect quotes
                if (stream.Char == '\"')
                    if (quoted)
                        break; //End of stream
                    else
                        quoted = true; //Start of quoted stream
                // Detect and ignore newline char's
                else if (!(stream.Char == '\n' && block))
                    input.Append(stream.Char);

                stream.Next();
            }

            //Console.WriteLine("convert [" + input.ToString() + "]");

            return System.Convert.FromBase64String(input.ToString());
        }
Exemple #25
0
        /// <summary>
        ///   Test for the value's inf, Inf and INF in the stream. If
        ///   found then it 'merged' with the sign and placed in the content.
        ///   There is no more data excepted behind it.
        /// </summary>
        private void ParseInf(ParseStream stream, int sign)
        {
            // Read the first 8 chars
            char[] chars = new char[8];

            int length = 0;

            for (int i = 0; i < chars.Length && !stream.EOF; i++)
            {
                chars[i] = stream.Char;
                length++;
                stream.Next(true);
            }

            // Compare
            if (length == 3)
            {
                string s = "" + chars[0] + chars[1] + chars[2];

                if (s == "INF" || s == "Inf" || s == "inf")
                {
                    if (sign < 0)
                    {
                        content = double.NegativeInfinity;
                    }
                    else
                    {
                        content = double.PositiveInfinity;
                    }

                    return;
                }
            }

            throw new ParseException(stream, "No valid infinity");
        }
Exemple #26
0
 /// <summary>
 ///   Skips a specified char, and throws an exception when
 ///   another char was found.
 /// </summary>
 private void SkipChar(ParseStream stream, char toSkip)
 {
     if (stream.Char == toSkip)
         stream.Next(true);
     else
         throw new Exception("Unexpected character");
 }
Exemple #27
0
        /// <summary>
        ///   Parse the time (hours, minutes, seconds)
        /// </summary>
        private void ParseTime(ParseStream stream,
                out int hour, out int minutes, out int seconds)
        {
            if (stream.Char == 't' || stream.Char == 'T')
                stream.Next(true);
            else
                SkipWhitespace(stream);

            // Parse hour
            // Note: A hour can be represented by one or two digits.
            string hulp = "";
            while (stream.Char >= '0' && stream.Char <= '9' &&
                    !stream.EOF && hulp.Length <= 2)
            {
                hulp += stream.Char;
                stream.Next(true);
            }
            hour = Int32.Parse(hulp);

            SkipChar(stream, ':');

            // Parse minutes
            minutes = ParseNumber(stream, 2);
            SkipChar(stream, ':');

            // Parse seconds
            seconds = ParseNumber(stream, 2);
        }
Exemple #28
0
        /// <summary> Parses a string with a given base (maximum 10) </summary>
        /// <remarks>
        ///   This is not completly correct. For base10 the first char may not be a '_'
        ///   The other bases allow this...
        /// </remarks>
        private static long ParseBase(ParseStream stream, uint basis, short sign)
        {
            // Base must be <= 10
            if (basis > 10)
                throw new Exception("Base to large. Maximum 10");

            ulong output = 0;
            char max = (char)((basis - 1) + (int)'0');

            // Parse
            while (!stream.EOF)
            {
                // Decimal
                if (stream.Char >= '0' && stream.Char <= max)
                {
                    output = (output * basis) + (uint)(stream.Char - '0');
                    OverflowTest(output, sign);
                }
                // Ignore underscores, but other chars are not allowed
                // see remarks
                else if (stream.Char != '_')
                    throw new Exception("Unknown char in base " + basis);

                stream.Next();
            }
            return sign * (long)output;
        }
Exemple #29
0
        /// <summary> Parse an integer </summary>
        public Integer(ParseStream stream) :
            base("tag:yaml.org,2002:int", NodeType.Integer)
        {
            short sign = 1; // Positive sign by default

            // Negative sign
            if (stream.Char == '-')
            {
                sign = -1;
                stream.Next();
            }
            // Positive sign
            else if (stream.Char == '+')
                stream.Next();

            try
            {
                // Determine base
                if (stream.Char == '0')
                {
                    stream.Next();

                    // Base 2
                    if (stream.Char == 'b')
                    {
                        stream.Next();
                        content = ParseBase(stream, 2, sign);
                        return;
                    }
                    // Base 16
                    else if (stream.Char == 'x')
                    {
                        stream.Next();
                        content = Parse16(stream, sign);
                        return;
                    }
                    // Base 8
                    else
                    {
                        content = ParseBase(stream, 8, sign);
                        return;
                    }
                }

                // Other base
                stream.BuildLookaheadBuffer();

                // First, try to parse with base 10
                try
                {
                    content = ParseBase(stream, 10, sign);
                    stream.DestroyLookaheadBuffer();
                    return;
                }
                catch { }

                // If not parseable with base 10, then try base 60
                stream.RewindLookaheadBuffer();
                stream.DestroyLookaheadBuffer();

                content = Parse60(stream, sign);
            }
            catch (Exception ex)
            {
                throw new ParseException(stream, ex.ToString());
            }
        }
Exemple #30
0
        /// <summary> Parse a sequence </summary>
        public Sequence(ParseStream stream) :
            base("tag:yaml.org,2002:seq", NodeType.Sequence)
        {
            // Is this really a sequence?
            if (stream.Char == '-')
            {
                // Parse recursively
                do
                {
                    // Override the parent's stop chars, never stop
                    stream.StopAt(new char[] { });

                    // Skip over '-'
                    stream.Next();

                    // Parse recursively
                    stream.Indent();
                    AddNode(Parse(stream));
                    stream.UnIndent();

                    // Re-accept the parent's stop chars
                    stream.DontStop();
                }while (!stream.EOF && stream.Char == '-');
            }
            // Or inline Sequence
            else if (stream.Char == '[')
            {
                // Override the parent's stop chars, never stop
                stream.StopAt(new char[] { });

                // Skip '['
                stream.Next();

                do
                {
                    stream.StopAt(new char[] { ']', ',' });
                    stream.Indent();
                    AddNode(Parse(stream, false));
                    stream.UnIndent();
                    stream.DontStop();

                    // Skip ','
                    if (stream.Char != ']' && stream.Char != ',')
                    {
                        stream.DontStop();
                        throw new ParseException(stream, "Comma expected in inline sequence");
                    }

                    if (stream.Char == ',')
                    {
                        stream.Next();
                        stream.SkipSpaces();
                    }
                }while (!stream.EOF && stream.Char != ']');

                // Re-accept the parent's stop chars
                stream.DontStop();

                // Skip ']'
                if (stream.Char == ']')
                {
                    stream.Next(true);
                }
                else
                {
                    throw new ParseException(stream, "Inline sequence not closed");
                }
            }
            // Throw an exception when not
            else
            {
                throw new Exception("This is not a sequence");
            }
        }
Exemple #31
0
        /// <summary> Internal parse method </summary>
        /// <param name="parseImplicitMappings">
        ///   Avoids ethernal loops while parsing implicit mappings. Implicit mappings are
        ///   not rocognized by a leading character. So while trying to parse the key of
        ///   something we think that could be a mapping, we're sure that if it is a mapping,
        ///   the key of this implicit mapping is not a mapping itself.
        ///
        ///   NOTE: Implicit mapping still belong to unstable code and require the UNSTABLE and
        ///         IMPLICIT_MAPPINGS preprocessor flags.
        /// </param>
        /// <param name="stream"></param>
        protected static Node Parse(ParseStream stream, bool parseImplicitMappings)
        {
            // ----------------
            // Skip Whitespace
            // ----------------
            if (!stream.EOF)
            {
                // Move the firstindentation pointer after the whitespaces of this line
                stream.SkipSpaces();
                while (stream.Char == '\n' && !stream.EOF)
                {
                    // Skip newline and next whitespaces
                    stream.Next();
                    stream.SkipSpaces();
                }
            }

            // -----------------
            // No remaining chars (Null/empty stream)
            // -----------------
            if (stream.EOF)
                return new Null();

            // -----------------
            // Explicit type
            // -----------------

#if SUPPORT_EXPLICIT_TYPES
			stream.BuildLookaheadBuffer ();

			char a = '\0', b = '\0';

			a = stream.Char; stream.Next ();
			b = stream.Char; stream.Next ();

			// Starting with !!
			if (a == '!' && b == '!' && ! stream.EOF)
			{
				stream.DestroyLookaheadBuffer ();

				// Read the tagname
				string tag = "";

				while (stream.Char != ' ' && stream.Char != '\n' && ! stream.EOF)
				{
					tag += stream.Char;
					stream.Next ();
				}

				// Skip Whitespace
				if (! stream.EOF)
				{
					stream.SkipSpaces ();
					while (stream.Char == '\n' && ! stream.EOF)
					{
						stream.Next ();
						stream.SkipSpaces ();
					}
				}

				// Parse
				Node n;
				switch (tag)
				{
					// Mappings and sequences
					// NOTE:
					// - sets are mappings without values
					// - Ordered maps are ordered sequence of key: value
					//   pairs without duplicates.
					// - Pairs are ordered sequence of key: value pairs
					//   allowing duplicates.

					// TODO: Create new datatypes for omap and pairs
					//   derived from sequence with a extra duplicate
					//   checking.

					case "seq":       n = new Sequence  (stream); break;
					case "map":       n = new Mapping   (stream); break;
					case "set":       n = new Mapping   (stream); break;
					case "omap":      n = new Sequence  (stream); break;
					case "pairs":     n = new Sequence  (stream); break;

					// Scalars
					//
					// TODO: do we have to move this to Scalar.cs
					// in order to get the following working:
					//
					// !!str "...": "..."
					// !!str "...": "..."

					case "timestamp": n = new Timestamp (stream); break;
					case "binary":    n = new Binary    (stream); break;
					case "null":      n = new Null      (stream); break;
					case "float":     n = new Float     (stream); break;
					case "int":       n = new Integer   (stream); break;
					case "bool":      n = new Boolean   (stream); break;
					case "str":       n = new String    (stream); break;

					// Unknown data type
					default:
						throw  new Exception ("Incorrect tag '!!" + tag + "'");
				}

				return n;
			}
			else
			{
				stream.RewindLookaheadBuffer ();
				stream.DestroyLookaheadBuffer ();
			}
#endif
            // -----------------
            // Sequence
            // -----------------

            if (stream.Char == '-' || stream.Char == '[')
                return new Sequence(stream);

            // -----------------
            // Mapping
            // -----------------

            if (stream.Char == '?' || stream.Char == '{')
                return new Mapping(stream);

            // -----------------
            // Try implicit mapping
            // -----------------

            // This are mappings which are not preceded by a question
            // mark. The keys have to be scalars.

#if (UNSTABLE && SUPPORT_IMPLICIT_MAPPINGS)

			// NOTE: This code can't be included in Mapping.cs
			// because of the way we are using to rewind the buffer.

			Node key, val;

			if (parseImplicitMappings)
			{
				// First Key/value pair

				stream.BuildLookaheadBuffer ();

				stream.StopAt (new char [] {':'});

				// Keys of implicit mappings can't be sequences, or other mappings
				// just look for scalars
				key = Scalar.Parse (stream, false); 
				stream.DontStop ();

Console.WriteLine ("key: " + key);

				// Followed by a colon, so this is a real mapping
				if (stream.Char == ':')
				{
					stream.DestroyLookaheadBuffer ();

					Mapping mapping = new Mapping ();

					// Skip colon and spaces
					stream.Next ();
					stream.SkipSpaces ();

					// Parse the value
Console.Write ("using  buffer: " + stream.UsingBuffer ());
					stream.Indent ();
Console.Write ("using  buffer: " + stream.UsingBuffer ());
//					val = Parse (stream, false);
Console.Write ("<<");
while (!stream.EOF) {Console.Write (stream.Char);stream.Next (true);}
Console.Write (">>");

val = new  String (stream);


Console.Write ("using  buffer: " + stream.UsingBuffer ());
					stream.UnIndent ();
Console.Write ("using  buffer: " + stream.UsingBuffer ());

Console.Write ("<<");
while (!stream.EOF) {Console.Write (stream.Char);stream.Next (true);}
Console.Write (">>");




Console.WriteLine ("val: " + val);
					mapping.AddMappingNode (key, val);

					// Skip possible newline
					// NOTE: this can't be done by the drop-newline
					// method since this is not the end of a block
					while (stream.Char == '\n')
						stream.Next (true);

					// Other key/value pairs
					while (! stream.EOF)
					{
						stream.StopAt (new char [] {':'} );
						stream.Indent ();
						key = Scalar.Parse (stream);
						stream.UnIndent ();
						stream.DontStop ();

Console.WriteLine ("key 2: " + key);
						if (stream.Char == ':')
						{
							// Skip colon and spaces
							stream.Next ();
							stream.SkipSpaces ();

							// Parse the value
							stream.Indent ();
							val = Parse (stream);
							stream.UnIndent ();

Console.WriteLine ("val 2: " + val);
							mapping.AddMappingNode (key, val);
						}
						else // TODO: Is this an error?
						{
							// NOTE: We can't recover from this error,
							// the last buffer has been destroyed, so
							// rewinding is impossible.
							throw new ParseException (stream,
								"Implicit mapping without value node");
						}

						// Skip possible newline
						while (stream.Char == '\n')
							stream.Next ();
					}

					return mapping;
				}

				stream.RewindLookaheadBuffer ();
				stream.DestroyLookaheadBuffer ();
			}

#endif
            // -----------------
            // No known data structure, assume this is a scalar
            // -----------------

            Scalar scalar = Scalar.Parse(stream);

            // Skip trash
            while (!stream.EOF)
                stream.Next();


            return scalar;
        }
Exemple #32
0
        /// <summary> Parses the exponential part of the float </summary>
        private static long ParseScient(ParseStream stream)
        {
            ulong output = 0;
            short sign;

            if (stream.Char == '-')
                sign = -1;
            else if (stream.Char == '+')
                sign = 1;
            else
                throw new ParseException(stream,
                        "Excepted + or - for the exponential part");

            stream.Next(true);

            while (!stream.EOF)
            {
                if (stream.Char >= '0' && stream.Char <= '9')
                    output = (10 * output) + (uint)stream.Char - '0';
                else
                    throw new ParseException(stream,
                            "Unexepted char in exponential part: >" +
                            stream.Char + "<");

                stream.Next(true);
            }

            return sign * (long)output;
        }
Exemple #33
0
 /// <summary> Constructor </summary>
 /// <param name="stream"> The parse stream (contains the line number where it went wrong) </param>
 /// <param name="message"> Info about the exception </param>
 public ParseException(ParseStream stream, string message) :
     base("Parse error near line " + stream.CurrentLine + ": " + message)
 {
     this.linenr = stream.CurrentLine;
 }
Exemple #34
0
        /// <summary>
        ///   Parse the time zone
        /// </summary>
        private double ParseTimezone(ParseStream stream)
        {
            double timezone = 0;

            SkipWhitespace(stream);

            // Timezone = UTC, use by default 0
            if (stream.Char == 'Z')
                stream.Next(true);
            else
            {
                // Find the sign of the offset
                int sign = 0;

                if (stream.Char == '-')
                    sign = -1;

                else if (stream.Char == '+')
                    sign = +1;

                else
                    throw new Exception("Invalid time zone: " +
                            "unexpected character");

                // Read next char and test for more chars
                stream.Next(true);
                if (stream.EOF)
                    throw new Exception("Invalid time zone");

                // Parse hour offset
                // Note: A hour can be represented by one or two digits.
                string hulp = "";
                while (stream.Char >= '0' &&
                        stream.Char <= '9' &&
                        !stream.EOF && hulp.Length <= 2)
                {
                    hulp += (stream.Char);
                    stream.Next(true);
                }
                timezone = sign * Double.Parse(hulp);

                // Parse the minutes of the timezone
                // when there is still more to parse
                if (!stream.EOF)
                {
                    SkipChar(stream, ':');
                    int temp = ParseNumber(stream, 2);

                    timezone += (temp / 60.0);
                }
            }

            return timezone;
        }
Exemple #35
0
        /// <summary>
        ///   Test for the value's inf, Inf and INF in the stream. If
        ///   found then it 'merged' with the sign and placed in the content.
        ///   There is no more data excepted behind it.
        /// </summary>
        private void ParseInf(ParseStream stream, int sign)
        {
            // Read the first 8 chars
            char[] chars = new char[8];

            int length = 0;
            for (int i = 0; i < chars.Length && !stream.EOF; i++)
            {
                chars[i] = stream.Char;
                length++;
                stream.Next(true);
            }

            // Compare
            if (length == 3)
            {
                string s = "" + chars[0] + chars[1] + chars[2];

                if (s == "INF" || s == "Inf" || s == "inf")
                {
                    if (sign < 0)
                        content = double.NegativeInfinity;
                    else
                        content = double.PositiveInfinity;

                    return;
                }
            }

            throw new ParseException(stream, "No valid infinity");
        }
Exemple #36
0
        /// <summary> Parse boolean </summary>
        public Boolean(ParseStream stream) :
            base("tag:yaml.org,2002:bool", NodeType.Boolean)
        {
            // Read the first 8 chars
            char[] chars = new char[8];

            int length = 0;

            for (int i = 0; i < chars.Length && !stream.EOF; i++)
            {
                chars[i] = stream.Char;
                length++;
                stream.Next(true);
            }

            // Compare
            if (length == 1)
            {
                if (chars[0] == 'Y' || chars[0] == 'y')
                {
                    content = true; return;
                }

                if (chars[0] == 'N' || chars[0] == 'n')
                {
                    content = false; return;
                }
            }
            if (length == 2)
            {
                string s = "" + chars[0] + chars[1];

                if (s == "ON" || s == "On" || s == "on")
                {
                    content = true; return;
                }

                if (s == "NO" || s == "No" || s == "no")
                {
                    content = false; return;
                }
            }
            if (length == 3)
            {
                string s = "" + chars[0] + chars[1] + chars[2];

                if (s == "YES" || s == "Yes" || s == "yes")
                {
                    content = true; return;
                }

                if (s == "OFF" || s == "Off" || s == "off")
                {
                    content = false; return;
                }
            }
            if (length == 4)
            {
                string s = "" + chars[0] + chars[1] + chars[2] + chars[3];

                if (s == "TRUE" || s == "True" || s == "true")
                {
                    content = true; return;
                }
            }
            if (length == 5)
            {
                string s = "" + chars[0] + chars[1] + chars[2] + chars[3] + chars[4];

                if (s == "FALSE" || s == "False" || s == "false")
                {
                    content = false; return;
                }
            }

            // No boolean
            throw new Exception("No valid boolean");
        }
Exemple #37
0
        /// <summary> Parse a string </summary>
        public String(ParseStream stream) :
            base("tag:yaml.org,2002:str", NodeType.String)
        {
            // set flags for folded or block scalar
            if (stream.Char == '>')  // TODO: '+' and '-' chomp chars
                folded = true;

            else if (stream.Char == '|')
                block = true;

            if (block || folded)
            {
                stream.Next();
                stream.SkipSpaces();
            }

            // -----------------
            // Folded Scalar
            // -----------------
            if (folded)
            {
                System.Text.StringBuilder builder = new System.Text.StringBuilder();

                // First line (the \n after the first line is always ignored,
                // not replaced with a whitespace)
                while (!stream.EOF && stream.Char != '\n')
                {
                    builder.Append(stream.Char);
                    stream.Next();
                }

                // Skip the first newline
                stream.Next();

                // Next lines (newlines will be replaced by spaces in folded scalars)
                while (!stream.EOF)
                {
                    if (stream.Char == '\n')
                        builder.Append(' ');
                    else
                        builder.Append(stream.Char);

                    stream.Next(true);
                }
                content = builder.ToString();
            }

            // -----------------
            // Block Scalar (verbatim block without folding)
            // -----------------
            else if (block)
            {
                /*
                Console.Write(">>");
                while (! stream.EOF)
                {
                    Console.Write (stream.Char);
                    stream.Next();
                }
                Console.Write("<<");
                // */

                System.Text.StringBuilder builder = new System.Text.StringBuilder();
                while (!stream.EOF)
                {
                    builder.Append(stream.Char);
                    stream.Next(true);
                }
                content = builder.ToString();
            }

            // String between double quotes
            if (stream.Char == '\"')
                content = ParseDoubleQuoted(stream);

            // Single quoted string
            else if (stream.Char == '\'')
                content = ParseSingleQuoted(stream);

            // String without quotes
            else
                content = ParseUnQuoted(stream);
        }
Exemple #38
0
 /// <summary>
 ///   Skips the spaces * and tabs * in the current stream
 /// </summary>
 private void SkipWhitespace(ParseStream stream)
 {
     while ((stream.Char == ' ' || stream.Char == '\t') && !stream.EOF)
         stream.Next(true);
 }
Exemple #39
0
        /// <summary>
        ///   Parse a Yaml string from a textfile and return a Yaml tree
        /// </summary>
        public static Node FromFile(string filename)
        {
            // Open YAML file
            StreamReader reader = File.OpenText(filename);
            ParseStream parsestream = new ParseStream(reader);

            // Parse
            Node node = Parse(parsestream);

            // Close YAML file
            reader.Close();
            return node;
        }
Exemple #40
0
        /// <summary>
        ///   Parses a String surrounded with single quotes
        /// </summary>
        private string ParseSingleQuoted(ParseStream stream)
        {
            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            // Start literal parsing
            stream.StartLiteral();

            // Skip '''
            stream.Next(true);

            while (!stream.EOF)
            {
                if (stream.Char == '\'')
                {
                    stream.Next();

                    // Escaped single quote
                    if (stream.Char == '\'')
                        builder.Append(stream.Char);

                        // End of string
                    else
                        break;
                }
                else
                    builder.Append(stream.Char);

                stream.Next();

                // Skip \'
                if (stream.EOF)
                {
                    stream.StopLiteral();
                    throw new ParseException(stream,
                        "Single quoted string not closed");
                }
            }

            // Stop literal parsing
            stream.StopLiteral();

            return builder.ToString();
        }
Exemple #41
0
        /// <summary> Parse a sequence </summary>
        public Sequence(ParseStream stream) :
            base("tag:yaml.org,2002:seq", NodeType.Sequence)
        {
            // Is this really a sequence?
            if (stream.Char == '-')
            {
                // Parse recursively
                do
                {
                    // Override the parent's stop chars, never stop
                    stream.StopAt(new char[] { });

                    // Skip over '-'
                    stream.Next();

                    // Parse recursively
                    stream.Indent();
                    AddNode(Parse(stream));
                    stream.UnIndent();

                    // Re-accept the parent's stop chars
                    stream.DontStop();
                }
                while (!stream.EOF && stream.Char == '-');
            }
            // Or inline Sequence
            else if (stream.Char == '[')
            {
                // Override the parent's stop chars, never stop
                stream.StopAt(new char[] { });

                // Skip '['
                stream.Next();

                do
                {
                    stream.StopAt(new char[] { ']', ',' });
                    stream.Indent();
                    AddNode(Parse(stream, false));
                    stream.UnIndent();
                    stream.DontStop();

                    // Skip ','
                    if (stream.Char != ']' && stream.Char != ',')
                    {
                        stream.DontStop();
                        throw new ParseException(stream, "Comma expected in inline sequence");
                    }

                    if (stream.Char == ',')
                    {
                        stream.Next();
                        stream.SkipSpaces();
                    }
                }
                while (!stream.EOF && stream.Char != ']');

                // Re-accept the parent's stop chars
                stream.DontStop();

                // Skip ']'
                if (stream.Char == ']')
                    stream.Next(true);
                else
                    throw new ParseException(stream, "Inline sequence not closed");

            }
            // Throw an exception when not
            else
                throw new Exception("This is not a sequence");
        }
Exemple #42
0
        /// <summary>
        ///   Parses a String surrounded without nothing
        /// </summary>
        private string ParseUnQuoted(ParseStream stream)
        {
            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            while (!stream.EOF)
                builder.Append(NextUnescapedChar(stream));

            // Trimming left
            int count = 0;
            while (count < builder.Length &&
                (builder[count] == ' ' || builder[count] == '\t'))
                count++;

            if (count >= 0)
                builder.Remove(0, count);

            // Trimming right
            count = 0;
            while (count < builder.Length &&
                (builder[builder.Length - count - 1] == ' ' ||
                builder[builder.Length - count - 1] == '\t'))
                count++;

            if (count >= 0)
                builder.Remove(builder.Length - count, count);

            return builder.ToString();
        }
Exemple #43
0
 /// <summary> Constructor </summary>
 /// <param name="stream"> The parse stream (contains the line number where it went wrong) </param>
 /// <param name="child"> The exception that is for example throwed again </param>
 public ParseException(ParseStream stream, Exception child) :
     base("Parse error near line " + stream.CurrentLine, child)
 {
     this.linenr = stream.CurrentLine;
 }
Exemple #44
0
 /// <summary> Parse function </summary>
 protected static Node Parse(ParseStream stream) { return Parse(stream, true); }
Exemple #45
0
        /// <summary>
        ///   Parses a scalar
        ///   <list type="bullet">
        ///     <item>Integer</item>
        ///     <item>String</item>
        ///     <item>Boolean</item>
        ///     <item>Null</item>
        ///     <item>Timestamp</item>
        ///     <item>Float</item>
        ///     <item>Binary</item>
        ///   </list>
        /// </summary>
        /// <remarks>
        ///   Binary is only parsed behind an explicit !!binary tag (in Node.cs)
        /// </remarks>
        public static new Scalar Parse(ParseStream stream)
        {
            // -----------------
            // Parse scalars
            // -----------------

            stream.BuildLookaheadBuffer();

            // Try Null
#if SUPPORT_NULL_NODES
            try
            {
                Scalar s = new Null(stream);
                stream.DestroyLookaheadBuffer();
                return(s);
            } catch { }
#endif
            // Try boolean
#if SUPPORT_BOOLEAN_NODES
            stream.RewindLookaheadBuffer();
            try
            {
                Scalar scalar = new Boolean(stream);
                stream.DestroyLookaheadBuffer();
                return(scalar);
            }
            catch { }
#endif
            // Try integer
#if SUPPORT_INTEGER_NODES
            stream.RewindLookaheadBuffer();
            try
            {
                Scalar scalar = new Integer(stream);
                stream.DestroyLookaheadBuffer();
                return(scalar);
            } catch { }
#endif
            // Try Float
#if SUPPORT_FLOAT_NODES
            stream.RewindLookaheadBuffer();
            try
            {
                Scalar scalar = new Float(stream);
                stream.DestroyLookaheadBuffer();
                return(scalar);
            }
            catch { }
#endif
            // Try timestamp
#if SUPPORT_TIMESTAMP_NODES
            stream.RewindLookaheadBuffer();
            try {
                Scalar scalar = new Timestamp(stream);
                stream.DestroyLookaheadBuffer();
                return(scalar);
            } catch { }
#endif
            // Other scalars are strings
            stream.RewindLookaheadBuffer();
            stream.DestroyLookaheadBuffer();

            return(new String(stream));
        }
Exemple #46
0
        /// <summary>
        ///   Parse the milliseconds
        /// </summary>
        private int ParseMilliSeconds(ParseStream stream)
        {
            int ms = 0;

            // Look for fraction
            if (stream.Char == '.')
            {
                stream.Next(true);

                // Parse fraction, can consists of an
                // unlimited sequence of numbers, we only
                // look to the first three (max 1000)
                int count = 0;

                while (stream.Char >= '0' && stream.Char <= '9' &&
                        count < 3 && !stream.EOF)
                {
                    ms *= 10;
                    ms += stream.Char - '0';

                    stream.Next(true);
                    count++;
                }

                if (count == 1) ms *= 100;
                if (count == 2) ms *= 10;
                if (count == 3) ms *= 1;

                // Ignore the rest
                while (stream.Char >= '0' && stream.Char <= '9' &&
                        !stream.EOF)
                    stream.Next(true);
            }
            return ms;
        }
Exemple #47
0
        /// <summary> Parse a mapping </summary>
        public Mapping(ParseStream stream) :
            base("tag:yaml.org,2002:map", NodeType.Mapping)
        {
            // Mapping with eplicit key, (implicit mappings are threaded
            // in Node.cs)
            if (stream.Char == '?')
            {
                // Parse recursively
                do
                {
                    Node key, val;

                    // Skip over '?'
                    stream.Next();
                    stream.SkipSpaces();

                    // Parse recursively. The false param avoids
                    // looking recursively for implicit mappings.
                    stream.StopAt(new char[] { ':' });
                    stream.Indent();
                    key = Parse(stream, false);
                    stream.UnIndent();
                    stream.DontStop();

                    // Parse recursively. The false param avoids
                    // looking for implit nodes
                    if (stream.Char == ':')
                    {
                        // Skip over ':'
                        stream.Next();
                        stream.SkipSpaces();

                        // Parse recursively
                        stream.Indent();
                        val = Parse(stream);
                        stream.UnIndent();
                    }
                    else
                    {
                        val = new Null();
                    }

                    AddMappingNode(key, val);

                    // Skip possible newline
                    // NOTE: this can't be done by the drop-newline
                    // method since this is not the end of a block
                    if (stream.Char == '\n')
                    {
                        stream.Next();
                    }
                }while (!stream.EOF && stream.Char == '?');
            }
            // Inline mapping
            else if (stream.Char == '{')
            {
                // Override the parent's stop chars, never stop
                stream.StopAt(new char[] { });

                // Skip '{'
                stream.Next();

                do
                {
                    Node key, val;

                    // Skip '?'
                    // (NOTE: it's not obligated to use this '?',
                    // especially because this is an inline mapping)
                    if (stream.Char == '?')
                    {
                        stream.Next();
                        stream.SkipSpaces();
                    }

                    // Parse recursively the key
                    stream.StopAt(new char[] { ':', ',', '}' });
                    stream.Indent();
                    key = Parse(stream, false);
                    stream.UnIndent();
                    stream.DontStop();

                    // Value
                    if (stream.Char == ':')
                    {
                        // Skip colon
                        stream.Next();
                        stream.SkipSpaces();

                        // Parse recursively the value
                        stream.StopAt(new char[] { '}', ',' });
                        stream.Indent();
                        val = Parse(stream, false);
                        stream.UnIndent();
                        stream.DontStop();
                    }
                    else
                    {
                        val = new Null();
                    }

                    AddMappingNode(key, val);

                    // Skip comma (key sepatator)
                    if (stream.Char != '}' && stream.Char != ',')
                    {
                        stream.DontStop();
                        throw new ParseException(stream, "Comma expected in inline sequence");
                    }

                    if (stream.Char == ',')
                    {
                        stream.Next();
                        stream.SkipSpaces();
                    }
                }while (!stream.EOF && stream.Char != '}');

                // Re-accept the parent's stop chars
                stream.DontStop();

                // Skip '}'
                if (stream.Char == '}')
                {
                    stream.Next();
                }
                else
                {
                    throw new ParseException(stream, "Inline mapping not closed");
                }
            }
        }
Exemple #48
0
        /// <summary>
        ///   If it is not Infinity or NaN, then parse as a number
        /// </summary>
        private void ParseNumber(ParseStream stream, int sign)
        {
            bool base60 = false; // Base 60 with ':'
            bool afterDecimal = false; // Before or after the decimal point

            double factor = 0.1;
            double part; // If base60 different parts, else output value

            // Set sign
            content = sign >= 0 ? 1 : -1;

            // First char must 0-9
            if (stream.Char >= '0' && stream.Char <= '9')
            {
                part = (uint)(stream.Char - '0');
                stream.Next(true);
            }
            else
                throw new ParseException(stream,
                    "No valid float: Invalid first character of float: " + stream.Char);

            while (!stream.EOF)
            {
                // Decimal
                if (stream.Char >= '0' && stream.Char <= '9')
                    if (afterDecimal)
                    {
                        part += (uint)(stream.Char - '0') * factor;
                        factor *= 0.1;
                    }
                    else
                        part = (part * 10) + (uint)(stream.Char - '0');

                // Base60 detected
                else if (stream.Char == ':')
                {
                    if (!base60) // First time
                    {
                        content *= part; // Multiply to get sign
                        part = 0;
                        base60 = true; // We are now sure base 60
                    }
                    else
                    {
                        if (part > 59)
                            throw new ParseException(stream,
                                "Part of base 60 can't be larger then 59");
                        content = (60 * content) + part;
                        part = 0;
                    }
                }
                // If first '.', then after decimal, else it is ignored if not in Base60
                else if ((!base60 || (base60 && !afterDecimal)) && stream.Char == '.')
                    afterDecimal = true;

                // Determine scientific notation
                else if ((stream.Char == 'E' || stream.Char == 'e') && !base60)
                {
                    stream.Next(true);
                    content *= Math.Pow(10, ParseScient(stream));
                }
                // Ignore underscores if before the decimal point, special case if base 60
                else if ((!afterDecimal || (afterDecimal && base60)) && stream.Char != '_')
                    throw new ParseException(stream, "Unknown char");

                stream.Next(true);
            }

            // Add last part of base to content
            if (base60)
                content = (60 * content) + part;
            else
                content *= part; // Multiply to get sign
        }
Exemple #49
0
        /// <summary> Parses a string with base 60, without sign </summary>
        private static long Parse60(ParseStream stream, short sign)
        {
            ulong output = 0;

            // Parse
            ulong part = 0;
            bool firstPart = true; // Only the first part can be larger then 59

            while (!stream.EOF)
            {
                // Decimal
                if (stream.Char >= '0' && stream.Char <= '9')
                    part = (part * 10) + (uint)(stream.Char - '0');

                // New part
                else if (stream.Char == ':')
                {
                    // Only the first part can be largen then 60
                    if (!firstPart)
                        if (part >= 60)
                            throw new
                Exception("Part of base 60 scalar is too large (max. 59)");
                        else
                            firstPart = false;

                    output = (output * 60) + part;
                    OverflowTest(output, sign);
                    part = 0;
                }

                // Ignore underscores, other chars are not allowed
                else if (stream.Char != '_')
                    throw new Exception("Unknown char in base 16");

                stream.Next();
            }

            // Add last part to the output
            if (!firstPart)
                if (part >= 60)
                    throw new Exception(
                        "Part of base 60 scalar is too large (max. 59)");
                else
                    firstPart = false;

            output = (output * 60) + part;
            OverflowTest(output, sign);

            return sign * (long)output;
        }
Exemple #50
0
        /// <summary> Parse an integer </summary>
        public Integer(ParseStream stream) :
            base("tag:yaml.org,2002:int", NodeType.Integer)
        {
            short sign = 1; // Positive sign by default

            // Negative sign
            if (stream.Char == '-')
            {
                sign = -1;
                stream.Next();
            }
            // Positive sign
            else if (stream.Char == '+')
            {
                stream.Next();
            }

            try
            {
                // Determine base
                if (stream.Char == '0')
                {
                    stream.Next();

                    // Base 2
                    if (stream.Char == 'b')
                    {
                        stream.Next();
                        content = ParseBase(stream, 2, sign);
                        return;
                    }
                    // Base 16
                    else if (stream.Char == 'x')
                    {
                        stream.Next();
                        content = Parse16(stream, sign);
                        return;
                    }
                    // Base 8
                    else
                    {
                        content = ParseBase(stream, 8, sign);
                        return;
                    }
                }

                // Other base
                stream.BuildLookaheadBuffer();

                // First, try to parse with base 10
                try
                {
                    content = ParseBase(stream, 10, sign);
                    stream.DestroyLookaheadBuffer();
                    return;
                }
                catch { }

                // If not parseable with base 10, then try base 60
                stream.RewindLookaheadBuffer();
                stream.DestroyLookaheadBuffer();

                content = Parse60(stream, sign);
            }
            catch (Exception ex)
            {
                throw new ParseException(stream, ex.ToString());
            }
        }
Exemple #51
0
        /// <summary> Hexadecimal string </summary>
        private static long Parse16(ParseStream stream, short sign)
        {
            uint output = 0;

            while (!stream.EOF)
            {
                // 0 .. 9
                if (stream.Char >= '0' && stream.Char <= '9')
                {
                    output = (output * 16) + (uint)(stream.Char - '0');
                    OverflowTest(output, sign);
                }
                // a .. f
                else if (stream.Char >= 'a' && stream.Char <= 'f')
                {
                    output = (output * 16) + (uint)(stream.Char - 'a') + 10;
                    OverflowTest(output, sign);
                }
                // A .. F
                else if (stream.Char >= 'A' && stream.Char <= 'F')
                {
                    output = (output * 16) + (uint)(stream.Char - 'A') + 10;
                    OverflowTest(output, sign);
                }
                // Ignore underscores, other chars are not allowed
                else if (stream.Char != '_')
                    throw new Exception("Unknown char in base 16");

                stream.Next();
            }

            return (long)(sign * output);
        }
Exemple #52
0
        /// <summary>
        ///   Parse an integer
        /// </summary>
        /// <param name="length">
        ///   The number of characters that the integer is expected to be.
        /// </param>
        /// <param name="stream"> The stream that will be parsed </param>
        private int ParseNumber(ParseStream stream, int length)
        {
            System.Text.StringBuilder hulp = new System.Text.StringBuilder();

            int i;
            for (i = 0; i < length && !stream.EOF; i++)
            {
                hulp.Append(stream.Char);
                stream.Next(true);
            }
            if (i == length)
                return Int32.Parse(hulp.ToString());
            else
                throw new Exception("Can't parse number");

        }
Exemple #53
0
        /// <summary>
        ///   Parses a String surrounded with double quotes
        /// </summary>
        private string ParseDoubleQuoted(ParseStream stream)
        {
            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            // Skip '"'
            stream.Next();

            // Stop at "
            stream.StopAt(new char[] { '\"' });

            while (!stream.EOF)
            {
                if (stream.Char == '\n')
                {
                    builder.Append(' ');
                    stream.Next();
                }
                else
                    builder.Append(NextUnescapedChar(stream));
            }

            // Don't stop at "
            stream.DontStop();

            // Skip '"'
            if (stream.Char != '\"')
                throw new ParseException(stream,
                    "Double quoted string not closed");
            else
                stream.Next(true);

            return builder.ToString();
        }
Exemple #54
0
        /// <summary>
        ///   Parse the time zone
        /// </summary>
        private double ParseTimezone(ParseStream stream)
        {
            double timezone = 0;

            SkipWhitespace(stream);

            // Timezone = UTC, use by default 0
            if (stream.Char == 'Z')
            {
                stream.Next(true);
            }
            else
            {
                // Find the sign of the offset
                int sign = 0;

                if (stream.Char == '-')
                {
                    sign = -1;
                }

                else if (stream.Char == '+')
                {
                    sign = +1;
                }

                else
                {
                    throw new Exception("Invalid time zone: " +
                                        "unexpected character");
                }

                // Read next char and test for more chars
                stream.Next(true);
                if (stream.EOF)
                {
                    throw new Exception("Invalid time zone");
                }

                // Parse hour offset
                // Note: A hour can be represented by one or two digits.
                string hulp = "";
                while (stream.Char >= '0' &&
                       stream.Char <= '9' &&
                       !stream.EOF && hulp.Length <= 2)
                {
                    hulp += (stream.Char);
                    stream.Next(true);
                }
                timezone = sign * Double.Parse(hulp);

                // Parse the minutes of the timezone
                // when there is still more to parse
                if (!stream.EOF)
                {
                    SkipChar(stream, ':');
                    int temp = ParseNumber(stream, 2);

                    timezone += (temp / 60.0);
                }
            }

            return(timezone);
        }
Exemple #55
0
        /// <summary>
        ///   Reads a character from the stream, unescapes it,
        ///   and moves to the next character.
        /// </summary>
        private char NextUnescapedChar(ParseStream stream)
        {
            char c = stream.Char;

            // If escaped
            if (c == '\\')
            {
                // Never stop, every special character
                // looses its meaning behind a backslash.
                stream.StopAt(new Char[] { });

                stream.Next(true);
                c = stream.Char;

                // ASCII null
                if (c == '0') c = '\0';

                // ASCII bell
                else if (c == 'a') c = (char)0x7;

                // ASCII backspace
                else if (c == 'b') c = (char)0x8;

                // ASCII horizontal tab
                else if (c == 't') c = (char)0x9;

                // ASCII newline
                else if (c == 'n') c = (char)0xA;

                // ASCII vertical tab
                else if (c == 'v') c = (char)0xB;

                // ASCII form feed
                else if (c == 'f') c = (char)0xC;

                // ASCII carriage return
                else if (c == 'r') c = (char)0xD;

                // ASCII escape
                else if (c == 'e') c = (char)0x1D;

                // Unicode next line
                else if (c == 'N') c = (char)0x85;

                // Unicode non breaking space
                else if (c == '_') c = (char)0xA0;

                // TODO larger unicode characters

                // Unicode line separator
                // else if (c == 'L')     c = (char) 0x20282028;

                // 8 bit hexadecimal
                else if (c == 'x')
                {
                    int c_int = (char)0;

                    for (int i = 0; i < 2; i++)
                    {
                        c_int *= 16;

                        stream.Next();
                        char d = stream.Char;

                        if (d >= '0' && d <= '9')
                            c_int += d - '0';

                        else if (d >= 'a' && d <= 'f')
                            c_int += d - 'a';

                        else if (d >= 'A' && d <= 'F')
                            c_int += d - 'A';
                        else
                        {
                            stream.DontStop();
                            throw new ParseException(stream,
                                "Invalid escape sequence");
                        }
                    }
                    c = (char)c_int;
                }

                stream.Next(true);

                // Restore last stop settings
                stream.DontStop();
            }
            else
                stream.Next(true);

            return c;
        }
Exemple #56
0
        /// <summary>
        ///   If it is not Infinity or NaN, then parse as a number
        /// </summary>
        private void ParseNumber(ParseStream stream, int sign)
        {
            bool base60       = false; // Base 60 with ':'
            bool afterDecimal = false; // Before or after the decimal point

            double factor = 0.1;
            double part; // If base60 different parts, else output value

            // Set sign
            content = sign >= 0 ? 1 : -1;

            // First char must 0-9
            if (stream.Char >= '0' && stream.Char <= '9')
            {
                part = (uint)(stream.Char - '0');
                stream.Next(true);
            }
            else
            {
                throw new ParseException(stream,
                                         "No valid float: Invalid first character of float: " + stream.Char);
            }

            while (!stream.EOF)
            {
                // Decimal
                if (stream.Char >= '0' && stream.Char <= '9')
                {
                    if (afterDecimal)
                    {
                        part   += (uint)(stream.Char - '0') * factor;
                        factor *= 0.1;
                    }
                    else
                    {
                        part = (part * 10) + (uint)(stream.Char - '0');
                    }
                }

                // Base60 detected
                else if (stream.Char == ':')
                {
                    if (!base60)         // First time
                    {
                        content *= part; // Multiply to get sign
                        part     = 0;
                        base60   = true; // We are now sure base 60
                    }
                    else
                    {
                        if (part > 59)
                        {
                            throw new ParseException(stream,
                                                     "Part of base 60 can't be larger then 59");
                        }
                        content = (60 * content) + part;
                        part    = 0;
                    }
                }
                // If first '.', then after decimal, else it is ignored if not in Base60
                else if ((!base60 || (base60 && !afterDecimal)) && stream.Char == '.')
                {
                    afterDecimal = true;
                }

                // Determine scientific notation
                else if ((stream.Char == 'E' || stream.Char == 'e') && !base60)
                {
                    stream.Next(true);
                    content *= Math.Pow(10, ParseScient(stream));
                }
                // Ignore underscores if before the decimal point, special case if base 60
                else if ((!afterDecimal || (afterDecimal && base60)) && stream.Char != '_')
                {
                    throw new ParseException(stream, "Unknown char");
                }

                stream.Next(true);
            }

            // Add last part of base to content
            if (base60)
            {
                content = (60 * content) + part;
            }
            else
            {
                content *= part; // Multiply to get sign
            }
        }
Exemple #57
0
        /// <summary>
        ///   Parses a scalar
        ///   <list type="bullet">
        ///     <item>Integer</item>
        ///     <item>String</item>
        ///     <item>Boolean</item>
        ///     <item>Null</item>
        ///     <item>Timestamp</item>
        ///     <item>Float</item>
        ///     <item>Binary</item>
        ///   </list>
        /// </summary>
        /// <remarks>
        ///   Binary is only parsed behind an explicit !!binary tag (in Node.cs)
        /// </remarks>
        public static new Scalar Parse(ParseStream stream)
        {
            // -----------------
            // Parse scalars
            // -----------------

            stream.BuildLookaheadBuffer();

            // Try Null
#if SUPPORT_NULL_NODES
			try
			{
				Scalar s = new Null (stream);
				stream.DestroyLookaheadBuffer ();
				return s;
			} catch { }
#endif
            // Try boolean
#if SUPPORT_BOOLEAN_NODES
			stream.RewindLookaheadBuffer ();
			try
			{
				Scalar scalar = new Boolean (stream);
				stream.DestroyLookaheadBuffer ();
				return scalar;
			} 
			catch { }
#endif
            // Try integer
#if SUPPORT_INTEGER_NODES
			stream.RewindLookaheadBuffer ();
			try
			{
				Scalar scalar = new Integer (stream);
				stream.DestroyLookaheadBuffer ();
				return scalar;
			} catch { }
#endif
            // Try Float
#if SUPPORT_FLOAT_NODES
			stream.RewindLookaheadBuffer ();
			try
			{
				Scalar scalar = new Float (stream);
				stream.DestroyLookaheadBuffer ();
				return scalar;
			} 
			catch { }
#endif
            // Try timestamp
#if SUPPORT_TIMESTAMP_NODES
			stream.RewindLookaheadBuffer ();
			try {
				Scalar scalar = new Timestamp (stream);
				stream.DestroyLookaheadBuffer ();
				return scalar;
			} catch { }
#endif
            // Other scalars are strings
            stream.RewindLookaheadBuffer();
            stream.DestroyLookaheadBuffer();

            return new String(stream);
        }
Exemple #58
0
 /// <summary> Parse function </summary>
 protected static Node Parse(ParseStream stream)
 {
     return(Parse(stream, true));
 }
Exemple #59
0
        /// <summary> Parse boolean </summary>
        public Boolean(ParseStream stream) :
            base("tag:yaml.org,2002:bool", NodeType.Boolean)
        {
            // Read the first 8 chars
            char[] chars = new char[8];

            int length = 0;
            for (int i = 0; i < chars.Length && !stream.EOF; i++)
            {
                chars[i] = stream.Char;
                length++;
                stream.Next(true);
            }

            // Compare
            if (length == 1)
            {
                if (chars[0] == 'Y' || chars[0] == 'y')
                { content = true; return; }

                if (chars[0] == 'N' || chars[0] == 'n')
                { content = false; return; }
            }
            if (length == 2)
            {
                string s = "" + chars[0] + chars[1];

                if (s == "ON" || s == "On" || s == "on")
                { content = true; return; }

                if (s == "NO" || s == "No" || s == "no")
                { content = false; return; }
            }
            if (length == 3)
            {
                string s = "" + chars[0] + chars[1] + chars[2];

                if (s == "YES" || s == "Yes" || s == "yes")
                { content = true; return; }

                if (s == "OFF" || s == "Off" || s == "off")
                { content = false; return; }
            }
            if (length == 4)
            {
                string s = "" + chars[0] + chars[1] + chars[2] + chars[3];

                if (s == "TRUE" || s == "True" || s == "true")
                { content = true; return; }
            }
            if (length == 5)
            {
                string s = "" + chars[0] + chars[1] + chars[2] + chars[3] + chars[4];

                if (s == "FALSE" || s == "False" || s == "false")
                { content = false; return; }
            }

            // No boolean
            throw new Exception("No valid boolean");
        }
Exemple #60
0
        /// <summary> Internal parse method </summary>
        /// <param name="parseImplicitMappings">
        ///   Avoids ethernal loops while parsing implicit mappings. Implicit mappings are
        ///   not rocognized by a leading character. So while trying to parse the key of
        ///   something we think that could be a mapping, we're sure that if it is a mapping,
        ///   the key of this implicit mapping is not a mapping itself.
        ///
        ///   NOTE: Implicit mapping still belong to unstable code and require the UNSTABLE and
        ///         IMPLICIT_MAPPINGS preprocessor flags.
        /// </param>
        /// <param name="stream"></param>
        protected static Node Parse(ParseStream stream, bool parseImplicitMappings)
        {
            // ----------------
            // Skip Whitespace
            // ----------------
            if (!stream.EOF)
            {
                // Move the firstindentation pointer after the whitespaces of this line
                stream.SkipSpaces();
                while (stream.Char == '\n' && !stream.EOF)
                {
                    // Skip newline and next whitespaces
                    stream.Next();
                    stream.SkipSpaces();
                }
            }

            // -----------------
            // No remaining chars (Null/empty stream)
            // -----------------
            if (stream.EOF)
            {
                return(new Null());
            }

            // -----------------
            // Explicit type
            // -----------------

#if SUPPORT_EXPLICIT_TYPES
            stream.BuildLookaheadBuffer();

            char a = '\0', b = '\0';

            a = stream.Char; stream.Next();
            b = stream.Char; stream.Next();

            // Starting with !!
            if (a == '!' && b == '!' && !stream.EOF)
            {
                stream.DestroyLookaheadBuffer();

                // Read the tagname
                string tag = "";

                while (stream.Char != ' ' && stream.Char != '\n' && !stream.EOF)
                {
                    tag += stream.Char;
                    stream.Next();
                }

                // Skip Whitespace
                if (!stream.EOF)
                {
                    stream.SkipSpaces();
                    while (stream.Char == '\n' && !stream.EOF)
                    {
                        stream.Next();
                        stream.SkipSpaces();
                    }
                }

                // Parse
                Node n;
                switch (tag)
                {
                // Mappings and sequences
                // NOTE:
                // - sets are mappings without values
                // - Ordered maps are ordered sequence of key: value
                //   pairs without duplicates.
                // - Pairs are ordered sequence of key: value pairs
                //   allowing duplicates.

                // TODO: Create new datatypes for omap and pairs
                //   derived from sequence with a extra duplicate
                //   checking.

                case "seq":       n = new Sequence(stream); break;

                case "map":       n = new Mapping(stream); break;

                case "set":       n = new Mapping(stream); break;

                case "omap":      n = new Sequence(stream); break;

                case "pairs":     n = new Sequence(stream); break;

                // Scalars
                //
                // TODO: do we have to move this to Scalar.cs
                // in order to get the following working:
                //
                // !!str "...": "..."
                // !!str "...": "..."

                case "timestamp": n = new Timestamp(stream); break;

                case "binary":    n = new Binary(stream); break;

                case "null":      n = new Null(stream); break;

                case "float":     n = new Float(stream); break;

                case "int":       n = new Integer(stream); break;

                case "bool":      n = new Boolean(stream); break;

                case "str":       n = new String(stream); break;

                // Unknown data type
                default:
                    throw  new Exception("Incorrect tag '!!" + tag + "'");
                }

                return(n);
            }
            else
            {
                stream.RewindLookaheadBuffer();
                stream.DestroyLookaheadBuffer();
            }
#endif
            // -----------------
            // Sequence
            // -----------------

            if (stream.Char == '-' || stream.Char == '[')
            {
                return(new Sequence(stream));
            }

            // -----------------
            // Mapping
            // -----------------

            if (stream.Char == '?' || stream.Char == '{')
            {
                return(new Mapping(stream));
            }

            // -----------------
            // Try implicit mapping
            // -----------------

            // This are mappings which are not preceded by a question
            // mark. The keys have to be scalars.

#if (UNSTABLE && SUPPORT_IMPLICIT_MAPPINGS)
            // NOTE: This code can't be included in Mapping.cs
            // because of the way we are using to rewind the buffer.

            Node key, val;

            if (parseImplicitMappings)
            {
                // First Key/value pair

                stream.BuildLookaheadBuffer();

                stream.StopAt(new char [] { ':' });

                // Keys of implicit mappings can't be sequences, or other mappings
                // just look for scalars
                key = Scalar.Parse(stream, false);
                stream.DontStop();

                Console.WriteLine("key: " + key);

                // Followed by a colon, so this is a real mapping
                if (stream.Char == ':')
                {
                    stream.DestroyLookaheadBuffer();

                    Mapping mapping = new Mapping();

                    // Skip colon and spaces
                    stream.Next();
                    stream.SkipSpaces();

                    // Parse the value
                    Console.Write("using  buffer: " + stream.UsingBuffer());
                    stream.Indent();
                    Console.Write("using  buffer: " + stream.UsingBuffer());
//					val = Parse (stream, false);
                    Console.Write("<<");
                    while (!stream.EOF)
                    {
                        Console.Write(stream.Char); stream.Next(true);
                    }
                    Console.Write(">>");

                    val = new  String(stream);


                    Console.Write("using  buffer: " + stream.UsingBuffer());
                    stream.UnIndent();
                    Console.Write("using  buffer: " + stream.UsingBuffer());

                    Console.Write("<<");
                    while (!stream.EOF)
                    {
                        Console.Write(stream.Char); stream.Next(true);
                    }
                    Console.Write(">>");



                    Console.WriteLine("val: " + val);
                    mapping.AddMappingNode(key, val);

                    // Skip possible newline
                    // NOTE: this can't be done by the drop-newline
                    // method since this is not the end of a block
                    while (stream.Char == '\n')
                    {
                        stream.Next(true);
                    }

                    // Other key/value pairs
                    while (!stream.EOF)
                    {
                        stream.StopAt(new char [] { ':' });
                        stream.Indent();
                        key = Scalar.Parse(stream);
                        stream.UnIndent();
                        stream.DontStop();

                        Console.WriteLine("key 2: " + key);
                        if (stream.Char == ':')
                        {
                            // Skip colon and spaces
                            stream.Next();
                            stream.SkipSpaces();

                            // Parse the value
                            stream.Indent();
                            val = Parse(stream);
                            stream.UnIndent();

                            Console.WriteLine("val 2: " + val);
                            mapping.AddMappingNode(key, val);
                        }
                        else                         // TODO: Is this an error?
                        {
                            // NOTE: We can't recover from this error,
                            // the last buffer has been destroyed, so
                            // rewinding is impossible.
                            throw new ParseException(stream,
                                                     "Implicit mapping without value node");
                        }

                        // Skip possible newline
                        while (stream.Char == '\n')
                        {
                            stream.Next();
                        }
                    }

                    return(mapping);
                }

                stream.RewindLookaheadBuffer();
                stream.DestroyLookaheadBuffer();
            }
#endif
            // -----------------
            // No known data structure, assume this is a scalar
            // -----------------

            Scalar scalar = Scalar.Parse(stream);

            // Skip trash
            while (!stream.EOF)
            {
                stream.Next();
            }


            return(scalar);
        }