summaryrefslogtreecommitdiff
path: root/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs
blob: 4365d699897ae5d9b2fcf55f3321f447b9e335f7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GodotTools.IdeConnection
{
    public static class MessageParser
    {
        public static bool TryParse(string messageLine, out Message message)
        {
            var arguments = new List<string>();
            var stringBuilder = new StringBuilder();

            bool expectingArgument = true;

            for (int i = 0; i < messageLine.Length; i++)
            {
                char @char = messageLine[i];

                if (@char == ',')
                {
                    if (expectingArgument)
                        arguments.Add(string.Empty);

                    expectingArgument = true;
                    continue;
                }

                bool quoted = false;

                if (messageLine[i] == '"')
                {
                    quoted = true;
                    i++;
                }

                while (i < messageLine.Length)
                {
                    @char = messageLine[i];

                    if (quoted && @char == '"')
                    {
                        i++;
                        break;
                    }

                    if (@char == '\\')
                    {
                        i++;
                        if (i < messageLine.Length)
                            break;

                        stringBuilder.Append(messageLine[i]);
                    }
                    else if (!quoted && @char == ',')
                    {
                        break; // We don't increment the counter to allow the colon to be parsed after this
                    }
                    else
                    {
                        stringBuilder.Append(@char);
                    }

                    i++;
                }

                arguments.Add(stringBuilder.ToString());
                stringBuilder.Clear();

                expectingArgument = false;
            }

            if (arguments.Count == 0)
            {
                message = new Message();
                return false;
            }

            message = new Message
            {
                Id = arguments[0],
                Arguments = arguments.Skip(1).ToArray()
            };

            return true;
        }
    }
}