Beispiel #1
0
        private static DataNode ReadNode(string contents, ref int index, string name)
        {
            DataNode result = null;

            var  state = State.Type;
            char c;
            var  mode = InputMode.None;

            StringBuilder name_content  = new StringBuilder();
            StringBuilder value_content = new StringBuilder();

            int rewind_index = index;

            bool is_escaped = false;

            do
            {
                bool isWhiteSpace;
                bool next = false;
                do
                {
                    if (index >= contents.Length)
                    {
                        if (state == State.Next)
                        {
                            return(result);
                        }

                        throw new Exception($"JSON parsing exception, unexpected end of data");
                    }

                    c            = contents[index];
                    isWhiteSpace = Char.IsWhiteSpace(c);

                    if (!isWhiteSpace)
                    {
                        rewind_index = index;
                    }

                    index++;


                    next = (mode == InputMode.None) ? isWhiteSpace : false;
                } while (next);

                switch (state)
                {
                case State.Type:
                {
                    switch (c)
                    {
                    case '{':
                    {
                        result = DataNode.CreateObject(name);
                        state  = State.Name;
                        break;
                    }

                    case '[':
                    {
                        result = DataNode.CreateArray(name);
                        state  = State.Value;
                        break;
                    }


                    default:
                    {
                        throw new Exception($"JSON parsing exception at {ParserUtils.GetOffsetError(contents, index)}, unexpected character");
                    }
                    }
                    break;
                }

                case State.Name:
                {
                    if (c == '}' && result.Kind == NodeKind.Object)
                    {
                        return(result);
                    }

                    switch (c)
                    {
                    case '"':
                    {
                        if (mode == InputMode.None)
                        {
                            mode = InputMode.Text;
                            name_content.Length = 0;
                        }
                        else
                        {
                            mode  = InputMode.None;
                            state = State.Colon;
                        }
                        break;
                    }

                    default:
                    {
                        if (mode == InputMode.Text)
                        {
                            name_content.Append(c);
                        }
                        else
                        {
                            throw new Exception($"JSON parsing exception at {ParserUtils.GetOffsetError(contents, index)}, unexpected character");
                        }
                        break;
                    }
                    }
                    break;
                }

                case State.Colon:
                {
                    switch (c)
                    {
                    case ':':
                    {
                        state = State.Value;
                        break;
                    }

                    default:
                    {
                        throw new Exception($"JSON parsing exception at {ParserUtils.GetOffsetError(contents, index)}, expected collon");
                    }
                    }
                    break;
                }

                case State.Value:
                {
                    if (c == '\\' && !is_escaped)
                    {
                        is_escaped = true;
                    }
                    else
                    if (is_escaped)
                    {
                        is_escaped = false;

                        if (c == 'u')
                        {
                            var hex = "";
                            for (int i = 0; i < 4; i++)
                            {
                                if (index >= contents.Length)
                                {
                                    throw new Exception($"JSON parsing exception, unexpected end of data");
                                }
                                hex += contents[index]; index++;
                            }

                            ushort unicode_val;
                            unicode_val = ushort.Parse(hex, System.Globalization.NumberStyles.HexNumber);

                            c = (char)unicode_val;
                        }

                        value_content.Append(c);
                    }
                    else
                    if (c == 'n' && mode == InputMode.None)
                    {
                        ReadString("null", contents, ref index);
                        result.AddField(name_content.Length == 0 ? null : name_content.ToString(), null);
                        state = State.Next;
                    }
                    else
                    if (c == 'f' && mode == InputMode.None)
                    {
                        ReadString("false", contents, ref index);
                        result.AddField(name_content.Length == 0 ? null : name_content.ToString(), false);
                        state = State.Next;
                    }
                    else
                    if (c == 't' && mode == InputMode.None)
                    {
                        ReadString("true", contents, ref index);
                        result.AddField(name_content.Length == 0 ? null : name_content.ToString(), true);
                        state = State.Next;
                    }
                    else
                    if (c == ']' && mode == InputMode.None && result.Kind == NodeKind.Array)
                    {
                        return(result);
                    }
                    else
                    {
                        switch (c)
                        {
                        case '"':
                        {
                            if (mode == InputMode.None)
                            {
                                mode = InputMode.Text;
                                value_content.Length = 0;
                            }
                            else
                            {
                                object value;

                                var str = value_content.ToString();

                                if (mode == InputMode.Number)
                                {
                                    if (str.Contains("e"))
                                    {
                                        // TODO
                                    }
                                    value = str;
                                }
                                else
                                {
                                    value = str;
                                }
                                mode = InputMode.None;

                                result.AddField(name_content.Length == 0 ? null : name_content.ToString(), value);
                                state = State.Next;
                            }
                            break;
                        }

                        case '[':
                        case '{':
                        {
                            if (mode == InputMode.Text)
                            {
                                value_content.Append(c);
                            }
                            else
                            {
                                index = rewind_index;
                                var node = ReadNode(contents, ref index, name_content.Length == 0 ? null : name_content.ToString());
                                result.AddNode(node);

                                state = State.Next;
                            }

                            break;
                        }

                        default:
                        {
                            if (mode == InputMode.Text)
                            {
                                value_content.Append(c);
                            }
                            else
                            if (char.IsNumber(c) || (c == '.' || c == 'e' || c == 'E' || c == '-' || c == '+'))
                            {
                                if (mode != InputMode.Number)
                                {
                                    value_content.Length = 0;
                                    mode = InputMode.Number;
                                }

                                if (c == 'E')
                                {
                                    c = 'e';
                                }

                                value_content.Append(c);
                            }
                            else
                            {
                                if (mode == InputMode.Number)
                                {
                                    mode = InputMode.None;

                                    var numStr = value_content.ToString();
                                    if (numStr.Contains("e"))
                                    {
                                        var num = double.Parse(numStr, NumberStyles.Any, CultureInfo.InvariantCulture);
                                        result.AddField(name_content.Length == 0 ? null : name_content.ToString(), num);
                                    }
                                    else
                                    {
                                        var num = decimal.Parse(numStr, NumberStyles.Any, CultureInfo.InvariantCulture);
                                        result.AddField(name_content.Length == 0 ? null : name_content.ToString(), num);
                                    }
                                    state = State.Next;

                                    if (c == ',' || c == ']' || c == '}')
                                    {
                                        index = rewind_index;
                                    }
                                }
                                else
                                {
                                    throw new Exception($"JSON parsing exception at {ParserUtils.GetOffsetError(contents, index)}, unexpected character");
                                }
                            }
                            break;
                        }
                        }
                    }
                    break;
                }

                case State.Next:
                {
                    switch (c)
                    {
                    case ',':
                    {
                        state = result.Kind == NodeKind.Array ? State.Value : State.Name;
                        break;
                    }

                    case '}':
                    {
                        if (result.Kind != NodeKind.Object)
                        {
                            throw new Exception($"JSON parsing exception at {ParserUtils.GetOffsetError(contents, index)}, unexpected }}");
                        }

                        return(result);
                    }

                    case ']':
                    {
                        if (result.Kind != NodeKind.Array)
                        {
                            throw new Exception($"JSON parsing exception at {ParserUtils.GetOffsetError(contents, index)}, unexpected ]");
                        }

                        return(result);
                    }

                    default:
                    {
                        throw new Exception($"JSON parsing exception at {ParserUtils.GetOffsetError(contents, index)}, expected collon");
                    }
                    }
                    break;
                }
                }
            } while (true);
        }
Beispiel #2
0
        public static DataNode ReadFromString(string contents)
        {
            var root = DataNode.CreateArray(null);

            var header = new List <string>();

            int  index = 0;
            var  state = State.Header;
            char c;
            int  fieldIndex = 0;

            bool isEscaped = false;

            var content = new StringBuilder();

            DataNode currentNode = null;

            while (index < contents.Length)
            {
                c = contents[index];

                index++;

                switch (state)
                {
                case State.Header:
                {
                    if (c == ',' || c == '\n')
                    {
                        header.Add(content.ToString().Trim());
                        content.Length = 0;
                    }

                    switch (c)
                    {
                    case ',': { break; }

                    case '\n':
                    {
                        state = State.Content;
                        break;
                    }

                    default:
                    {
                        content.Append(c);
                        break;
                    }
                    }
                    break;
                }

                case State.Content:
                {
                    if (!isEscaped && (c == ',' || c == '\n'))
                    {
                        if (fieldIndex < header.Count)
                        {
                            currentNode.AddField(header[fieldIndex], content.ToString());
                        }

                        content.Length = 0;

                        fieldIndex++;

                        if (c == '\n')
                        {
                            fieldIndex  = 0;
                            currentNode = null;
                        }

                        break;
                    }

                    if (c == '"')
                    {
                        if (isEscaped && index < contents.Length && contents[index] == '"')
                        {
                            index++;
                        }
                        else
                        {
                            isEscaped = !isEscaped;
                            break;
                        }
                    }

                    if (currentNode == null)
                    {
                        currentNode = DataNode.CreateObject(null);
                        root.AddNode(currentNode);
                    }

                    content.Append(c);

                    break;
                }
                }
            }

            if (currentNode != null && fieldIndex < header.Count)
            {
                currentNode.AddField(header[fieldIndex], content.ToString());
            }

            return(root);
        }
Beispiel #3
0
        public DataNode SendRequest(Logger logger, string url, string method, params object[] parameters)
        {
            Throw.IfNull(logger, nameof(logger));

            DataNode paramData = DataNode.CreateArray("params");

            if (parameters != null && parameters.Length > 0)
            {
                foreach (var obj in parameters)
                {
                    paramData.AddField(null, obj);
                }
            }

            var jsonRpcData = DataNode.CreateObject(null);

            jsonRpcData.AddField("jsonrpc", "2.0");
            jsonRpcData.AddField("method", method);
            jsonRpcData.AddField("id", "1");

            jsonRpcData.AddNode(paramData);

            int    retries  = 5;
            string contents = null;

            int retryDelay = 500;

            while (retries > 0)
            {
                try
                {
                    client.Headers.Add("Content-Type", "application/json-rpc");
                    var json = JSONWriter.WriteToString(jsonRpcData);
                    contents = client.UploadString(url, json);
                }
                catch (Exception e)
                {
                    retries--;
                    if (retries <= 0)
                    {
                        logger.Error(e.ToString());
                        return(null);
                    }
                    else
                    {
                        logger.Warning($"Retrying connection to {url} after {retryDelay}ms...");
                        Thread.Sleep(retryDelay);
                        retryDelay *= 2;
                        continue;
                    }
                }

                break;
            }

            if (string.IsNullOrEmpty(contents))
            {
                return(null);
            }

            //File.WriteAllText("response.json", contents);

            var root = JSONReader.ReadFromString(contents);

            if (root == null)
            {
                return(null);
            }

            if (root.HasNode("result"))
            {
                return(root["result"]);
            }

            return(root);
        }
Beispiel #4
0
        private static DataNode ReadNode(string contents, ref int index)
        {
            DataNode result = null;

            var  state     = State.Next;
            var  prevState = State.Next;
            char c;

            StringBuilder name_content  = new StringBuilder();
            StringBuilder value_content = new StringBuilder();

            int rewind_index = index;

            do
            {
                bool isWhiteSpace;
                bool next   = false;
                bool inside = state == State.Content || state == State.TagOpen || state == State.TagClose ||
                              state == State.AttributeName || state == State.AttributeValue || state == State.CData;

                do
                {
                    if (index >= contents.Length)
                    {
                        if (state == State.Next) // no useful data
                        {
                            return(null);
                        }
                        throw new Exception($"XML parsing exception, unexpected end of data");
                    }

                    c            = contents[index];
                    isWhiteSpace = Char.IsWhiteSpace(c);

                    if (!isWhiteSpace)
                    {
                        rewind_index = index;
                    }

                    index++;
                    next = isWhiteSpace && !inside;
                } while (next);

                switch (state)
                {
                case State.Next:
                {
                    switch (c)
                    {
                    case '<':
                    {
                        state = State.TagOpen;
                        name_content.Length = 0;
                        break;
                    }

                    default:
                    {
                        throw new Exception($"XML parsingexception at {ParserUtils.GetOffsetError(contents, index)}, unexpected character");
                    }
                    }
                    break;
                }

                case State.TagOpen:
                {
                    switch (c)
                    {
                    case '?':
                    {
                        if (contents[index - 2] == '<')
                        {
                            state = State.Prolog;
                        }
                        else
                        {
                            name_content.Append(c);
                        }
                        break;
                    }

                    case '!':
                    {
                        if (index < contents.Length - 3 && contents[index - 2] == '<' && contents[index] == '-' && contents[index + 1] == '-')
                        {
                            state     = State.Comment;
                            prevState = State.Next;
                        }
                        else
                        {
                            name_content.Append(c);
                        }
                        break;
                    }

                    case '/':
                    {
                        result = DataNode.CreateObject(name_content.ToString());
                        state  = State.TagClose;
                        break;
                    }

                    case '>':
                    {
                        result = DataNode.CreateObject(name_content.ToString());
                        state  = State.Content;
                        break;
                    }

                    case ' ':
                    {
                        result = DataNode.CreateObject(name_content.ToString());
                        name_content.Length = 0;
                        state = State.AttributeName;
                        break;
                    }

                    default:
                    {
                        name_content.Append(c);
                        break;
                    }
                    }
                    break;
                }

                case State.TagClose:
                {
                    switch (c)
                    {
                    case '>':
                    {
                        // previously created:
                        // result = DataNode.CreateObject(name_content.ToString());
                        return(result);
                    }

                    default:
                    {
                        // TODO: verify that the close tag matches the open tag
                        // name_content.Append(c);
                        break;
                    }
                    }
                    break;
                }

                case State.AttributeName:
                {
                    switch (c)
                    {
                    case '/':
                    {
                        state = State.TagClose;
                        break;
                    }

                    case '=':
                    {
                        state = State.AttributeQuote;
                        break;
                    }

                    default:
                    {
                        if (name_content.Length > 0 || !char.IsWhiteSpace(c))
                        {
                            name_content.Append(c);
                        }
                        break;
                    }
                    }
                    break;
                }

                case State.AttributeQuote:
                {
                    if (c == '"')
                    {
                        state = State.AttributeValue;
                        value_content.Length = 0;
                    }
                    else
                    {
                        throw new Exception($"XML parsingexception at {ParserUtils.GetOffsetError(contents, index)}, unexpected character");
                    }
                    break;
                }

                case State.AttributeValue:
                {
                    switch (c)
                    {
                    case '"':
                    {
                        result.AddField(name_content.ToString(), value_content.ToString());
                        value_content.Length = 0;
                        state = State.NextAttribute;
                        break;
                    }

                    default:
                    {
                        value_content.Append(c);
                        break;
                    }
                    }

                    break;
                }

                case State.NextAttribute:
                {
                    switch (c)
                    {
                    case '/':
                    {
                        break;
                    }

                    case '>':
                    {
                        if (contents[index - 2] == '/')
                        {
                            return(result);
                        }

                        state = State.Content;

                        break;
                    }

                    default:
                    {
                        if (char.IsLetter(c))
                        {
                            name_content.Length = 0;
                            name_content.Append(c);
                            state = State.AttributeName;
                        }
                        else
                        {
                            throw new Exception($"XML parsingexception at {ParserUtils.GetOffsetError(contents, index)}, unexpected character");
                        }

                        break;
                    }
                    }

                    break;
                }

                case State.Prolog:
                {
                    if (c == '>')
                    {
                        state = State.Next;
                    }
                    break;
                }

                case State.Comment:
                {
                    switch (c)
                    {
                    case '>':
                    {
                        if (contents[index - 2] == '-' && contents[index - 3] == '-')
                        {
                            state = prevState;
                        }
                        break;
                    }
                    }
                    break;
                }

                case State.CData:
                {
                    if (c == ']' && contents[index - 2] == c && index < contents.Length && contents[index] == '>')
                    {
                        state = State.Content;
                        value_content.Length--;
                        index++;
                    }
                    else
                    {
                        value_content.Append(c);
                    }

                    break;
                }

                case State.Content:
                {
                    switch (c)
                    {
                    case '<':
                    {
                        if (CDataAt(contents, index))
                        {
                            state  = State.CData;
                            index += 8;
                        }
                        else
                        if (index < contents.Length && contents[index] == '/')
                        {
                            state         = State.TagClose;
                            result.Value += value_content.ToString();
                        }
                        else if (index < contents.Length - 3 && contents[index] == '!' && contents[index + 1] == '-' && contents[index + 2] == '-')
                        {
                            state     = State.Comment;
                            prevState = State.Content;
                            index    += 2;
                        }
                        else
                        {
                            index--;
                            var child = ReadNode(contents, ref index);
                            if (child == null)                 // only valid at top-level. Here must be an input error
                            {
                                throw new Exception("XML parsing exception, unexpected end of data");
                            }
                            result.AddNode(child);
                        }
                        break;
                    }

                    default:
                    {
                        value_content.Append(c);
                        break;
                    }
                    }
                    break;
                }
                }
            } while (true);
        }
Beispiel #5
0
        private static void ReadNodes(string[] lines, ref int index, int baseIndents, DataNode parent)
        {
            int expectedIdents = -1;

            DataNode currentNode = null;

            do
            {
                if (index >= lines.Length)
                {
                    return;
                }

                int identCount = 0;
                var content    = lines[index].TrimEnd();

                if (content.StartsWith("---"))
                {
                    index++;
                    continue;
                }

                for (int i = 0; i < content.Length; i++)
                {
                    char c = content[i];
                    if (c == ' ')
                    {
                        identCount++;
                    }
                    else
                    {
                        content = content.Substring(i);
                        break;
                    }
                }

                if (identCount < baseIndents)
                {
                    return;
                }

                index++;

                identCount -= baseIndents;

                if (expectedIdents == -1)
                {
                    expectedIdents = identCount;
                }
                else
                if (identCount != expectedIdents)
                {
                    throw new Exception($"YAML parsing exception, unexpected ammount of identation");
                }

                var temp = content.Split(':');

                if (temp.Length != 2)
                {
                    throw new Exception($"YAML parsing exception, bad formed line");
                }

                var name = temp[0].Trim();
                var val  = temp[1].Trim();

                if (val.StartsWith("&"))
                {
                    val = null;
                }

                if (val == ">" || val == "|")
                {
                    bool preserveLineBreaks = val == "|";

                    var sb = new StringBuilder();
                    while (index < lines.Length)
                    {
                        var line = lines[index].TrimStart();
                        if (line.Contains(":"))
                        {
                            break;
                        }

                        sb.Append(line);
                        if (preserveLineBreaks)
                        {
                            sb.Append('\n');
                        }
                        index++;
                    }
                    sb.Append('\n'); // TODO is adding this at the end necessary?
                    val = sb.ToString();
                }

                if (!string.IsNullOrEmpty(val))
                {
                    parent.AddField(name, val);
                }
                else
                {
                    currentNode = DataNode.CreateObject(name);
                    parent.AddNode(currentNode);

                    ReadNodes(lines, ref index, baseIndents + 1, currentNode);
                }
            } while (true);
        }