Ejemplo n.º 1
0
        private void EmitRowStart()
        {
            var objectName = ValueConventions.CreateName("Row", Settings, TextCase.KeepOriginal);

            queue.Enqueue(new Node {
                Type = NodeType.ObjectStart, Value = objectName
            });
        }
Ejemplo n.º 2
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);
                    }

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

                EmitRowCollectionStart();
                return(true);
            }

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

                cols     = EnumerateCols(rows.Current).GetEnumerator();
                colNames = EmitColName(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);
        }
Ejemplo n.º 3
0
        private IEnumerable <Node> EnumerateNodes()
        {
            if (!settings.IsFragment)
            {
                yield return(new Node {
                    Type = NodeType.DocumentStart
                });

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

            var enumerator = this.readers.Cast <Reader>().GetEnumerator();

            while (enumerator.MoveNext())
            {
                readerCount++;

                if (!settings.IsFragment)
                {
                    var name           = "Document" + readerCount;
                    var conventionName = ValueConventions.CreateName(name, settings, TextCase.KeepOriginal);
                    yield return(new Node {
                        Type = NodeType.PropertyStart, Value = conventionName
                    });
                }

                var reader = enumerator.Current;
                while (reader.Read())
                {
                    var isDocument = (reader.Current.Type & NodeType.Document) != 0;
                    if (!isDocument)
                    {
                        yield return(reader.Current);
                    }
                }

                if (!settings.IsFragment)
                {
                    yield return(new Node {
                        Type = NodeType.PropertyEnd
                    });
                }
            }

            if (!settings.IsFragment)
            {
                yield return(new Node {
                    Type = NodeType.ObjectEnd
                });

                yield return(new Node {
                    Type = NodeType.DocumentEnd
                });
            }
        }
Ejemplo n.º 4
0
        private Node OpenRow()
        {
            rowCount++;
            unnamedFieldCount = 0;
            var name    = "Row" + rowCount;
            var rowName = ValueConventions.CreateName(name, Settings, DefaultCase);

            return(new Node {
                Type = NodeType.ObjectStart, Value = rowName
            });
        }
Ejemplo n.º 5
0
        private IEnumerable <string> CreateColNames()
        {
            var colIndex = 0;

            while (++colIndex <= int.MaxValue)
            {
                var name       = "Field" + colIndex;
                var headerName = ValueConventions.CreateName(name, Settings, TextCase.KeepOriginal);
                yield return(headerName);
            }
        }
Ejemplo n.º 6
0
        private void EmitProperty(string name)
        {
            var propertyName = ValueConventions.CreateName(name, Settings, TextCase.CamelCase);

            Indent();
            writer.Write("\"");
            writer.Write(propertyName);
            writer.Write("\":");
            if (Settings.Indent)
            {
                writer.Write(" ");
            }
        }
Ejemplo n.º 7
0
        protected override void DoWrite(Node node)
        {
            switch (node.Type)
            {
            case NodeType.CollectionStart:
            {
                collectionDepth++;

                if (collectionDepth == 1)
                {
                    string name =
                        (node.Value != null)
                  ? node.Value.ToString()
                  : "Planilha" + (workbook.Sheets.Count + 1);
                    var conventionName = ValueConventions.CreateName(name, Settings, ExcelWriter.DefaultTextCase);

                    sheet = workbook.CreateSheet(conventionName);
                    sheet.StartSheet();
                }
                else if (collectionDepth == 2)
                {
                    sheet.StartRow();
                }

                break;
            }

            case NodeType.CollectionEnd:
            {
                if (collectionDepth == 2)
                {
                    sheet.EndRow();
                }
                else if (collectionDepth == 1)
                {
                    sheet.EndSheet();
                    sheet = null;
                }
                collectionDepth--;
                break;
            }

            case NodeType.Value:
            {
                sheet.Cell(node.Value);
                break;
            }
            }
        }
Ejemplo n.º 8
0
        private void EmitRowCollectionStart()
        {
            var collectionName = ValueConventions.CreateName("Csv", Settings, TextCase.KeepOriginal);

            if (!Settings.IsFragment)
            {
                queue.Enqueue(new Node {
                    Type = NodeType.DocumentStart
                });
            }

            queue.Enqueue(new Node {
                Type = NodeType.CollectionStart, Value = collectionName
            });
        }
Ejemplo n.º 9
0
        private string CreateFieldName()
        {
            if (fieldStack.Count == 0)
            {
                unnamedFieldCount++;

                var field = "Field" + unnamedFieldCount;
                var name  = ValueConventions.CreateName(field, Settings, DefaultCase);
                return(name);
            }
            else
            {
                var name = fieldStack.Peek();
                foreach (var field in fieldStack.Skip(1))
                {
                    name = field + "." + name;
                }
                return(name);
            }
        }
Ejemplo n.º 10
0
        protected override void DoWrite(Node node)
        {
            switch (node.Type)
            {
            case NodeType.CollectionStart:
            {
                collectionDepth++;
                if (collectionDepth == 2)
                {
                    cols = 0;
                }
                break;
            }

            case NodeType.CollectionEnd:
            {
                if (collectionDepth == 2)
                {
                    writer.WriteLine();
                }
                collectionDepth--;
                break;
            }

            case NodeType.Value:
            {
                cols++;
                if (cols > 1)
                {
                    writer.Write(Settings.FieldDelimiter);
                }

                if (node.Value != null)
                {
                    var text = ValueConventions.CreateQuotedText(node.Value, Settings);
                    writer.Write(text);
                }
                break;
            }
            }
        }
Ejemplo n.º 11
0
        protected override void DoWrite(Node node)
        {
            switch (node.Type)
            {
            case NodeType.DocumentStart:
            case NodeType.DocumentEnd:
                // nada a fazer
                break;

            case NodeType.ObjectStart:
            {
                var parentKind       = stack.FirstOrDefault();
                var parentIsProperty = parentKind == NodeType.Property;

                if (!parentIsProperty)
                {
                    var name    = (node.Value ?? "Element").ToString();
                    var tagName = ValueConventions.CreateName(name, Settings, TextCase.PascalCase);

                    writer.WriteStartElement(tagName);
                }

                stack.Push(NodeType.Object);
                break;
            }

            case NodeType.ObjectEnd:
            {
                stack.Pop();

                var parentKind       = stack.FirstOrDefault();
                var parentIsProperty = parentKind == NodeType.Property;

                if (!parentIsProperty)
                {
                    writer.WriteEndElement();
                }
                break;
            }

            case NodeType.CollectionStart:
            {
                var parentKind       = stack.FirstOrDefault();
                var parentIsProperty = parentKind == NodeType.Property;

                if (!parentIsProperty)
                {
                    var name    = (node.Value ?? "Array").ToString();
                    var tagName = ValueConventions.CreateName(name, Settings, TextCase.PascalCase);
                    writer.WriteStartElement(tagName);
                }

                var attName = ValueConventions.CreateName("IsArray", Settings, TextCase.PascalCase);
                writer.WriteAttributeString(attName, "true");

                stack.Push(NodeType.Collection);
                break;
            }

            case NodeType.CollectionEnd:
            {
                stack.Pop();

                var parentKind       = stack.FirstOrDefault();
                var parentIsProperty = parentKind == NodeType.Property;

                if (!parentIsProperty)
                {
                    writer.WriteEndElement();
                }

                break;
            }

            case NodeType.PropertyStart:
            {
                var name    = (node.Value ?? "Property").ToString();
                var tagName = ValueConventions.CreateName(name, Settings, TextCase.PascalCase);
                writer.WriteStartElement(tagName);

                stack.Push(NodeType.Property);
                break;
            }

            case NodeType.PropertyEnd:
            {
                writer.WriteEndElement();
                stack.Pop();
                break;
            }

            case NodeType.Value:
            {
                if (node.Value == null)
                {
                    writer.WriteValue(null);
                }
                else if (node.Value is XContainer)
                {
                    var xml   = (XContainer)node.Value;
                    var cdata = xml.ToString(SaveOptions.DisableFormatting);
                    writer.WriteCData(cdata);
                }
                else
                {
                    var text = ValueConventions.CreateText(node.Value, Settings);
                    writer.WriteValue(text);
                }
                break;
            }

            default:
                throw new SerializationException("Token não esperado: " + node);
            }

            if (Settings.AutoFlush)
            {
                DoFlush();
            }
        }
Ejemplo n.º 12
0
        protected override void DoWrite(Node node)
        {
            switch (node.Type)
            {
            case NodeType.DocumentStart:
            {
                writer.Write("{");
                stack.Push(new Children {
                        Parent = NodeType.Document
                    });
                break;
            }

            case NodeType.DocumentEnd:
            {
                stack.Pop();
                Indent();
                writer.Write("}");
                break;
            }

            case NodeType.ObjectStart:
            {
                if (stack.Any())
                {
                    var children = stack.Peek();
                    if (children.Parent == NodeType.Document)
                    {
                        EmitProperty((node.Value ?? "root").ToString());
                    }
                    else if (children.Parent == NodeType.Collection)
                    {
                        if (children.Count > 0)
                        {
                            writer.Write(",");
                        }
                        children.Count++;

                        Indent();
                    }
                }

                writer.Write("{");
                stack.Push(new Children {
                        Parent = NodeType.Object
                    });
                return;
            }

            case NodeType.ObjectEnd:
            {
                var children = stack.Pop();
                if (children.Count > 0)
                {
                    Indent();
                }
                writer.Write("}");
                return;
            }

            case NodeType.CollectionStart:
            {
                if (stack.Any())
                {
                    var children = stack.Peek();
                    if (children.Parent == NodeType.Document)
                    {
                        EmitProperty((node.Value ?? "root").ToString());
                    }
                    else if (children.Parent == NodeType.Collection)
                    {
                        if (children.Count > 0)
                        {
                            writer.Write(",");
                        }
                        children.Count++;

                        Indent();
                    }
                }

                writer.Write("[");
                stack.Push(new Children {
                        Parent = NodeType.Collection
                    });
                return;
            }

            case NodeType.CollectionEnd:
            {
                var children = stack.Pop();
                if (children.Count > 0)
                {
                    Indent();
                }
                writer.Write("]");
                return;
            }

            case NodeType.PropertyStart:
            {
                var children = stack.Peek();
                if (children.Count > 0)
                {
                    writer.Write(",");
                }
                children.Count++;

                EmitProperty((node.Value ?? "property").ToString());

                return;
            }

            case NodeType.PropertyEnd:
            {
                return;
            }

            case NodeType.Value:
            {
                var children = stack.Peek();
                if (children.Parent == NodeType.Collection)
                {
                    if (children.Count > 0)
                    {
                        writer.Write(",");
                    }
                    children.Count++;

                    Indent();
                }

                var text = ValueConventions.CreateQuotedText(node.Value, Settings, Toolset.Json.Escape);
                writer.Write(text);

                return;
            }
            }
        }
Ejemplo n.º 13
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;
                }
                }
            }
        }
Ejemplo n.º 14
0
        private Node CreateNode()
        {
            var item = stack.Pop();

            if (item is Node)
            {
                return((Node)item);
            }

            #region Valores simples...

            else if (item == null)
            {
                return(new Node {
                    Type = NodeType.Value
                });
            }
            else if (IsSimpleValue(item))
            {
                return(new Node {
                    Type = NodeType.Value, Value = item
                });
            }

            #endregion

            #region Xmls

            else if (item is XContainer)
            {
                // var xml = (XContainer)item;
                // var text = xml.ToString(SaveOptions.DisableFormatting);
                // return new Node { Type = NodeType.Value, Value = text };
                return(new Node {
                    Type = NodeType.Value, Value = item
                });
            }

            #endregion

            #region Propriedades...

            else if (item is PropertiesHolder)
            {
                var properties = (PropertiesHolder)item;
                var graph      = properties.Graph;
                var enumerator = properties.Enumerator;

                var ready = enumerator.MoveNext();
                if (!ready)
                {
                    return(CreateNode());
                }

                stack.Push(properties);

                var graphInfo = new GraphReaderInfo(graph.GetType());

                var property      = (PropertyInfo)enumerator.Current;
                var propertyValue = property.GetValue(graph, null);

                var ignore = IgnoreValueMethod.Invoke(propertyValue);
                if (ignore)
                {
                    return(CreateNode());
                }

                var name         = graphInfo.GetPropertyLabel(property);
                var propertyName = ValueConventions.CreateName(name, Settings, TextCase.PascalCase);

                stack.Push(new Node {
                    Type = NodeType.PropertyEnd
                });
                stack.Push(propertyValue);
                return(new Node {
                    Type = NodeType.PropertyStart, Value = propertyName
                });
            }

            #endregion

            #region Dicionarios, tratados como objetos...

            else if (Collections.IsDictionary(item))
            {
                var dictionary = (IDictionary)item;
                var enumerator = dictionary.GetEnumerator();

                var name         = item.GetType().Name;
                var propertyName = ValueConventions.CreateName(name, Settings, TextCase.PascalCase);

                stack.Push(new Node {
                    Type = NodeType.ObjectEnd
                });
                stack.Push(enumerator);
                return(new Node {
                    Type = NodeType.ObjectStart, Value = propertyName
                });
            }
            else if (item is DictionaryEntry)
            {
                var entry = (DictionaryEntry)item;
                stack.Push(new Node {
                    Type = NodeType.PropertyEnd
                });
                stack.Push(entry.Value);

                var name         = entry.Key.ToString();
                var propertyName = ValueConventions.CreateName(name, Settings, TextCase.PascalCase);

                return(new Node {
                    Type = NodeType.PropertyStart, Value = name
                });
            }

            #endregion

            #region Listas...

            else if (item is IEnumerable)
            {
                var collection = (IEnumerable)item;
                var enumerator = collection.GetEnumerator();

                var collectionType = collection.GetType();
                var collectionInfo = new GraphReaderInfo(collectionType);

                var name           = collectionInfo.GetLabel();
                var collectionName = ValueConventions.CreateName(name, Settings, TextCase.PascalCase);

                stack.Push(new Node {
                    Type = NodeType.CollectionEnd
                });
                stack.Push(enumerator);
                return(new Node {
                    Type = NodeType.CollectionStart, Value = collectionName
                });
            }
            else if (item is IEnumerator)
            {
                var enumerator = (IEnumerator)item;

                var ready = enumerator.MoveNext();
                if (ready)
                {
                    stack.Push(enumerator);
                    stack.Push(enumerator.Current);
                }

                return(CreateNode());
            }

            #endregion

            #region Objetos...

            else
            {
                var graph     = item;
                var graphType = graph.GetType();
                var graphInfo = new GraphReaderInfo(graphType);

                var properties = graphInfo.GetProperties();
                var enumerator = properties.GetEnumerator();
                var holder     = new PropertiesHolder {
                    Graph = graph, Enumerator = enumerator
                };

                var name         = graphInfo.GetLabel();
                var propertyName = ValueConventions.CreateName(name, Settings, TextCase.PascalCase);

                stack.Push(new Node {
                    Type = NodeType.ObjectEnd
                });
                stack.Push(holder);
                return(new Node {
                    Type = NodeType.ObjectStart, Value = propertyName
                });
            }

            #endregion
        }
Ejemplo n.º 15
0
        public IEnumerable <Node> TransformNode(Node node)
        {
            switch (node.Type)
            {
            case NodeType.DocumentStart:
            {
                var name = ValueConventions.CreateName(node.Value, Settings, DefaultCase);
                yield return(new Node {
                        Type = NodeType.DocumentStart, Value = name
                    });

                break;
            }

            case NodeType.DocumentEnd:
            {
                yield return(new Node {
                        Type = NodeType.DocumentEnd
                    });

                break;
            }

            case NodeType.CollectionStart:
            {
                collectionDepth++;

                if (collectionDepth == 1)
                {
                    var name = ValueConventions.CreateName(node.Value, Settings, DefaultCase);
                    yield return(new Node {
                            Type = NodeType.CollectionStart, Value = name
                        });

                    isInsideTable = true;
                }
                else if (collectionDepth > 1)
                {
                    rowDepth++;
                    if (rowDepth == 1)
                    {
                        isInsideTable = true;
                        yield return(OpenRow());
                    }
                    isInsideRow = rowDepth > 0;
                }

                isInsideTable = (collectionDepth == 1) || (rowDepth == 1);
                break;
            }

            case NodeType.CollectionEnd:
            {
                if (collectionDepth > 1)
                {
                    if (rowDepth == 1)
                    {
                        yield return(CloseRow());
                    }
                    rowDepth--;
                    isInsideRow = rowDepth > 0;
                }
                else if (collectionDepth == 1)
                {
                    yield return(new Node {
                            Type = NodeType.CollectionEnd
                        });
                }

                collectionDepth--;
                isInsideTable = (collectionDepth == 1) || (rowDepth == 1);
                break;
            }

            case NodeType.ObjectStart:
            {
                if (isInsideTable)
                {
                    rowDepth++;
                    if (rowDepth == 1)
                    {
                        yield return(OpenRow());
                    }
                    isInsideRow = rowDepth > 0;
                }
                break;
            }

            case NodeType.ObjectEnd:
            {
                if (isInsideTable)
                {
                    if (rowDepth == 1)
                    {
                        yield return(CloseRow());
                    }
                    rowDepth--;
                    isInsideRow = rowDepth > 0;
                }
                break;
            }

            case NodeType.PropertyStart:
            {
                if (isInsideTable)
                {
                    var fieldName = ValueConventions.CreateName(node.Value, Settings, DefaultCase);
                    fieldStack.Push(fieldName);
                }
                break;
            }

            case NodeType.PropertyEnd:
            {
                if (isInsideTable)
                {
                    fieldStack.Pop();
                }
                break;
            }

            case NodeType.Value:
            {
                if (isInsideTable)
                {
                    if (!isInsideRow)
                    {
                        rowCount++;
                        var name    = "Row" + rowCount;
                        var rowName = ValueConventions.CreateName(name, Settings, DefaultCase);
                        yield return(new Node {
                                Type = NodeType.ObjectStart, Value = rowName
                            });
                    }

                    var fieldName = CreateFieldName();
                    yield return(new Node {
                            Type = NodeType.PropertyStart, Value = fieldName
                        });

                    yield return(node);

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

                    if (!isInsideRow)
                    {
                        yield return(new Node {
                                Type = NodeType.ObjectEnd
                            });
                    }
                }
                break;
            }
            }
        }
Ejemplo n.º 16
0
        public IEnumerable <Node> TransformNode(Node node)
        {
            if (!initialized)
            {
                collectingHeaders = Settings.Get <bool>("HasHeaders");
                initialized       = true;
            }

            var emittedNodes = tableTransform.TransformNode(node);

            foreach (var emittedNode in emittedNodes)
            {
                switch (emittedNode.Type)
                {
                case NodeType.CollectionStart:
                {
                    headers.Clear();
                    collectingHeaders = Settings.Get <bool>("HasHeaders");
                    yield return(emittedNode);

                    break;
                }

                case NodeType.CollectionEnd:
                {
                    collectingHeaders = false;
                    yield return(emittedNode);

                    break;
                }

                case NodeType.ObjectStart:
                {
                    queue.Clear();
                    queue.Enqueue(new Node {
                            Type = NodeType.CollectionStart, Value = emittedNode.Value
                        });
                    break;
                }

                case NodeType.ObjectEnd:
                {
                    queue.Enqueue(new Node {
                            Type = NodeType.CollectionEnd, Value = emittedNode.Value
                        });

                    if (collectingHeaders)
                    {
                        var name = ValueConventions.CreateName("Header", Settings, TableTransform.DefaultCase);
                        yield return(new Node {
                                Type = NodeType.CollectionStart, Value = name
                            });

                        foreach (var header in headers)
                        {
                            yield return(new Node {
                                    Type = NodeType.Value, Value = header.Value
                                });
                        }
                        yield return(new Node {
                                Type = NodeType.CollectionEnd
                            });

                        collectingHeaders = false;
                    }

                    foreach (var queueNode in queue)
                    {
                        yield return(queueNode);
                    }

                    break;
                }

                case NodeType.PropertyStart:
                {
                    if (collectingHeaders)
                    {
                        headers.Enqueue(emittedNode);
                    }

                    // omitindo...
                    break;
                }

                case NodeType.PropertyEnd:
                {
                    // omitindo...
                    break;
                }

                case NodeType.Value:
                {
                    queue.Enqueue(emittedNode);
                    break;
                }

                default:
                {
                    yield return(emittedNode);

                    break;
                }
                }
            }
        }
Ejemplo n.º 17
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())
        }