Esempio n. 1
0
        private bool FetchNodes()
        {
            if (done)
            {
                return(false);
            }

            if (rows == null)
            {
                rows = EnumerateRows(textReader).GetEnumerator();
                if (Settings.HasHeaders)
                {
                    var hasMoreRows = rows.MoveNext();
                    if (!hasMoreRows)
                    {
                        done = true;
                        EmitRowCollectionEnd();
                        return(true);
                    }

                    var colNames = EnumerateCols(rows.Current).ToArray();
                    this.colNamesAlgorithm = colNames;
                }

                EmitRowCollectionStart();
                return(true);
            }

            if (cols == null)
            {
                var hasMoreRows = rows.MoveNext();
                if (!hasMoreRows)
                {
                    done = true;
                    EmitRowCollectionEnd();
                    return(true);
                }

                cols     = EnumerateCols(rows.Current).GetEnumerator();
                colNames = this.colNamesAlgorithm.GetEnumerator();

                EmitRowStart();
                return(true);
            }

            var hasMoreCols = cols.MoveNext();

            if (!hasMoreCols)
            {
                cols = null;
                EmitRowEnd();
                return(true);
            }

            var colValue = ValueConventions.CreateValue(cols.Current, Settings);

            EmitCol(colValue);
            return(true);
        }
Esempio n. 2
0
        private IEnumerable <Node> EnumerateNodes()
        {
            var    tokenEnumerator = EnumerateTokens().GetEnumerator();
            var    stack           = new Stack <NodeType>();
            string suggestedName   = null;

            var ready = tokenEnumerator.MoveNext();

            while (ready)
            {
                var token = tokenEnumerator.Current;

                switch (token)
                {
                case ",":
                {
                    var type = stack.FirstOrDefault();
                    if (type == NodeType.Property)
                    {
                        stack.Pop();
                        yield return(new Node {
                                Type = NodeType.PropertyEnd
                            });
                    }
                    ready = tokenEnumerator.MoveNext();
                    break;
                }

                case "{":
                {
                    var depth      = stack.Count;
                    var isDocument = (!Settings.IsFragment && depth == 0);

                    if (isDocument)
                    {
                        stack.Push(NodeType.Document);
                        var name = ValueConventions.CreateName("document", Settings, TextCase.CamelCase);
                        yield return(new Node {
                                Type = NodeType.DocumentStart, Value = name
                            });

                        //
                        // a proxima propriedade deve ser tratada como o nome do objeto ou coleção
                        // exemplo:
                        //   {
                        //     "tipo": { ... }
                        //   }
                        //

                        // nome da propriedade
                        ready = tokenEnumerator.MoveNext();
                        if (!ready)
                        {
                            throw new SerializationException("Fim inesperado de arquivo.");
                        }
                        var propertyName = tokenEnumerator.Current;

                        // dois pontos
                        ready = tokenEnumerator.MoveNext();
                        if (!ready)
                        {
                            throw new SerializationException("Fim inesperado de arquivo.");
                        }
                        var delimiter = tokenEnumerator.Current;
                        if (delimiter != ":")
                        {
                            throw new SerializationException("Token não esperado: " + delimiter);
                        }

                        suggestedName = propertyName;
                    }
                    else
                    {
                        stack.Push(NodeType.Object);
                        var name = ValueConventions.CreateName(suggestedName ?? "object", Settings, TextCase.CamelCase);
                        yield return(new Node {
                                Type = NodeType.ObjectStart, Value = name
                            });

                        suggestedName = null;
                    }

                    ready = tokenEnumerator.MoveNext();
                    break;
                }

                case "[":
                {
                    stack.Push(NodeType.Collection);
                    var name = ValueConventions.CreateName(suggestedName ?? "collection", Settings, TextCase.CamelCase);
                    yield return(new Node {
                            Type = NodeType.CollectionStart, Value = name
                        });

                    ready         = tokenEnumerator.MoveNext();
                    suggestedName = null;
                    break;
                }

                case "]":
                case "}":
                {
                    NodeType type;

                    type = stack.FirstOrDefault();
                    if (type == NodeType.Property)
                    {
                        stack.Pop();
                        yield return(new Node {
                                Type = NodeType.PropertyEnd
                            });
                    }

                    type = stack.Pop();
                    yield return(new Node {
                            Type = type | NodeType.End
                        });

                    type = stack.FirstOrDefault();
                    if (type == NodeType.Property)
                    {
                        stack.Pop();
                        yield return(new Node {
                                Type = NodeType.PropertyEnd
                            });
                    }

                    ready = tokenEnumerator.MoveNext();
                    break;
                }

                default:
                {
                    ready = tokenEnumerator.MoveNext();
                    if (!ready)
                    {
                        throw new SerializationException("Fim inesperado de arquivo.");
                    }

                    var nextToken = tokenEnumerator.Current;
                    if (nextToken == ":")
                    {
                        stack.Push(NodeType.Property);

                        var name = ValueConventions.CreateName(token, Settings, TextCase.CamelCase);
                        yield return(new Node {
                                Type = NodeType.PropertyStart, Value = name
                            });

                        ready = tokenEnumerator.MoveNext();
                    }
                    else
                    {
                        if (token.StartsWith("'"))
                        {
                            token = token.Substring(1, token.Length - 2);
                        }

                        var value = ValueConventions.CreateValue(token, Settings, Toolset.Json.Unescape);
                        yield return(new Node {
                                Type = NodeType.Value, Value = value
                            });
                    }
                    break;
                }
                }
            }
        }
Esempio n. 3
0
        private IEnumerable <Node> EmitNodes(XmlReader reader)
        {
            // Propriedade sem EndElement é considerada nula: <tag/>
            // Propriedade com EndElement e sem conteúdo é considerada vazia: <tag></tag>
            // Tag nula é identificada por IsEmptyElement.
            // Tag vazia é identificada por esta variável, que estoca o último tipo de nodo encontrdo.
            // Se este último nodo foi um abre propriedade e estamos fechando esta propriedade então
            // não vimos valor algum.
            Node emitted = null;

            while (reader.Read())
            {
                var nodeType       = reader.NodeType;
                var nodeName       = reader.Name;
                var nodeValue      = reader.Value;
                var isEmptyElement = reader.IsEmptyElement;

                switch (nodeType)
                {
                case XmlNodeType.Element:
                {
                    var isCollection = IsCollection();

                    var parentKind       = stack.FirstOrDefault();
                    var parentIsProperty = (parentKind == NodeType.Property);
                    if (parentIsProperty)
                    {
                        var name           = "Object";
                        var conventionName = ValueConventions.CreateName(name, Settings, TextCase.KeepOriginal);
                        stack.Push(NodeType.Object);
                        yield return(emitted = new Node {
                                Type = NodeType.ObjectStart, Value = conventionName
                            });

                        parentKind = stack.FirstOrDefault();
                    }

                    var isProperty = (parentKind == NodeType.Object);
                    if (isProperty)
                    {
                        var name           = nodeName ?? "Property";
                        var conventionName = ValueConventions.CreateName(name, Settings, TextCase.KeepOriginal);

                        yield return(emitted = new Node {
                                Type = NodeType.PropertyStart, Value = conventionName
                            });

                        if (reader.IsEmptyElement)
                        {
                            // tags vazias não tem um EndElement correspondente, como em: <tag/>
                            // por isto vamos emitir um aqui e com um valor padrao.
                            if (isCollection)
                            {
                                yield return(emitted = new Node {
                                        Type = NodeType.CollectionStart, Value = "Collection"
                                    });

                                yield return(emitted = new Node {
                                        Type = NodeType.CollectionEnd
                                    });

                                // Como estamos fechando a coleção para forçar uma coleção vazia como
                                // valor padrão vamos também abortar a interpretação da coleção na continuidade.
                                // A propriedade foi detectada em uma tag vazia como <Xml IsArray="true"/> e
                                // portanto não há realmente coleção para interpretar
                                isCollection = false;
                            }
                            else
                            {
                                yield return(emitted = new Node {
                                        Type = NodeType.Value, Value = null
                                    });
                            }

                            yield return(emitted = new Node {
                                    Type = NodeType.PropertyEnd
                                });
                        }
                        else
                        {
                            stack.Push(NodeType.Property);
                        }
                    }

                    if (isCollection)
                    {
                        var name           = nodeName ?? "Collection";
                        var conventionName = ValueConventions.CreateName(name, Settings, TextCase.KeepOriginal);
                        stack.Push(NodeType.Collection);
                        yield return(emitted = new Node {
                                Type = NodeType.CollectionStart, Value = conventionName
                            });

                        if (reader.IsEmptyElement)
                        {
                            yield return(emitted = new Node {
                                    Type = NodeType.CollectionEnd
                                });
                        }
                    }

                    else if (!isProperty && !isCollection)
                    {
                        var name           = nodeName ?? "Object";
                        var conventionName = ValueConventions.CreateName(name, Settings, TextCase.KeepOriginal);
                        stack.Push(NodeType.Object);
                        yield return(emitted = new Node {
                                Type = NodeType.ObjectStart, Value = conventionName
                            });

                        if (reader.IsEmptyElement)
                        {
                            yield return(emitted = new Node {
                                    Type = NodeType.ObjectEnd
                                });
                        }
                    }

                    break;
                }

                case XmlNodeType.EndElement:
                {
                    var kind       = stack.Pop();
                    var parentKind = stack.FirstOrDefault();

                    if (kind == NodeType.Property)
                    {
                        // se o nodo emitido anteriormente tiver sido abre propriedade então não vimos
                        // um valor e devemos tratar a propriedade como vazia
                        if (emitted.Type == NodeType.PropertyStart)
                        {
                            yield return emitted = new Node {
                                       Type = NodeType.Value, Value = string.Empty
                            }
                        }
                        ;
                    }

                    yield return(emitted = new Node {
                            Type = kind | NodeType.End
                        });

                    if (kind == NodeType.Collection)
                    {
                        var isProperty = (parentKind == NodeType.Property);
                        if (isProperty)
                        {
                            kind = stack.Pop();

                            yield return(emitted = new Node {
                                    Type = kind | NodeType.End
                                });
                        }
                    }
                    else if (parentKind == NodeType.Property)
                    {
                        kind = stack.Pop();
                        yield return(emitted = new Node {
                                Type = kind | NodeType.End
                            });
                    }

                    break;
                }

                case XmlNodeType.CDATA:
                case XmlNodeType.Text:
                {
                    var value = ValueConventions.CreateValue(nodeValue, Settings);
                    yield return(emitted = new Node {
                            Type = NodeType.Value, Value = value
                        });

                    break;
                }
                }
            } // while (reader.Read())
        }