Example #1
0
        Expression ArrayContainer(ContainerItemHandler handler)
        {
            Debug.Assert(schemaType.IsBondContainer());

            var count = Expression.Variable(typeof(int), "count");
            var index = Expression.Variable(typeof(int), "index");
            var item  = Expression.ArrayAccess(value, new Expression[] { index });
            var next  = Expression.LessThan(Expression.PreIncrementAssign(index), count);

            return(Expression.Block(
                       new[] { index, count },
                       Expression.Assign(index, Expression.Constant(-1)),
                       Expression.Assign(count, Expression.ArrayLength(value)),
                       handler(item, next, count)));
        }
Example #2
0
        Expression EnumerableContainer(ContainerItemHandler handler)
        {
            Debug.Assert(schemaType.IsBondContainer());

            var methodGetEnumerator = value.Type.GetMethod(typeof(IEnumerable <>), "GetEnumerator");

            Debug.Assert(methodGetEnumerator != null, "Container must provide GetEnumerator method");

            var enumerator = Expression.Variable(methodGetEnumerator.ReturnType, "enumerator");
            var item       = Expression.Property(enumerator, "Current");
            var next       = Expression.Call(enumerator, moveNext);

            return(Expression.Block(
                       new[] { enumerator },
                       Expression.Assign(enumerator, Expression.Call(value, methodGetEnumerator)),
                       handler(item, next, ContainerCount(value))));
        }
Example #3
0
        Expression LinkedListContainer(ContainerItemHandler handler)
        {
            Debug.Assert(schemaType.IsBondContainer());

            var nodeType = typeof(LinkedListNode <>).MakeGenericType(value.Type.GetGenericArguments()[0]);
            var node     = Expression.Variable(nodeType, "node");
            var item     = Expression.Property(node, "Value");
            var next     = Expression.NotEqual(
                Expression.Condition(
                    Expression.Equal(node, Expression.Constant(null)),
                    Expression.Assign(node, Expression.Property(value, "First")),
                    Expression.Assign(node, Expression.Property(node, "Next"))),
                Expression.Constant(null));

            return(Expression.Block(
                       new[] { node },
                       Expression.Assign(node, Expression.Constant(null, nodeType)),
                       handler(item, next, ContainerCount(value))));
        }
Example #4
0
        Expression Items(ContainerItemHandler handler)
        {
            // If the list is an empty element we won't read anything
            var isEmpty = Expression.Variable(typeof(bool), "isEmpty");

            // Generate the following code for the "next" expression:
            //  if (isEmpty)
            //  {
            //      return false;
            //  }
            //  else
            //  {
            //      while (reader.NodeType == XmlNodeType.Whitespace) reader.Read;
            //      do { reader.Read(); } while (reader.NodeType == XmlNodeType.Whitespace;
            //
            //      if (reader.NodeType == XmlNodeType.Element) &&
            //          reader.LocalName != "Item")
            //      {
            //          throw new InvalidDataException();
            //      }
            //
            //      return reader.XmlNode != XmlNodeType.EndElement;
            //  }

            var whitespace = Expression.Equal(Reader.NodeType, Expression.Constant(XmlNodeType.Whitespace));

            var next = Expression.Condition(isEmpty,
                                            Expression.Constant(false),
                                            Expression.Block(
                                                ControlExpression.While(whitespace, Reader.Read()),
                                                ControlExpression.DoWhile(Reader.Read(), whitespace),
                                                Expression.IfThen(
                                                    Expression.AndAlso(
                                                        Expression.Equal(Reader.NodeType, Expression.Constant(XmlNodeType.Element)),
                                                        Expression.NotEqual(Reader.LocalName, Expression.Constant("Item"))),
                                                    ParsingError()),
                                                Expression.NotEqual(Reader.NodeType, Expression.Constant(XmlNodeType.EndElement))));

            return(Expression.Block(
                       new[] { isEmpty },
                       Expression.Assign(isEmpty, Reader.IsEmptyElement),
                       handler(next)));
        }
Example #5
0
        public Expression Container(BondDataType?expectedType, ContainerHandler handler)
        {
            if (schemaType.IsBondNullable())
            {
                return(Nullable(handler));
            }

            if (schemaType.IsBondBlob())
            {
                return(BlobContainer(handler));
            }

            var itemType = schemaType.GetValueType();

            ContainerItemHandler itemHandler = (item, next, count) => handler(
                new ObjectParser(this, item, itemType),
                Expression.Constant(itemType.GetBondDataType()),
                next,
                count,
                null);

            if (value.Type.IsArray)
            {
                return(ArrayContainer(itemHandler));
            }

            if (value.Type.IsGenericType())
            {
                if (typeof(IList <>).MakeGenericType(value.Type.GetTypeInfo().GenericTypeArguments[0]).IsAssignableFrom(value.Type))
                {
                    return(ListContainer(itemHandler));
                }

                if (typeof(LinkedList <>) == value.Type.GetGenericTypeDefinition())
                {
                    return(LinkedListContainer(itemHandler));
                }
            }

            return(EnumerableContainer(itemHandler));
        }
        Expression LinkedListContainer(ContainerItemHandler handler)
        {
            Debug.Assert(schemaType.IsBondContainer());

            var nodeType = typeof(LinkedListNode<>).MakeGenericType(value.Type.GetGenericArguments()[0]);
            var node = Expression.Variable(nodeType, "node");
            var item = Expression.Property(node, "Value");
            var next = Expression.NotEqual(
                Expression.Condition(
                    Expression.Equal(node, Expression.Constant(null)),
                    Expression.Assign(node, Expression.Property(value, "First")),
                    Expression.Assign(node, Expression.Property(node, "Next"))),
                Expression.Constant(null));

            return Expression.Block(
                new[] { node },
                Expression.Assign(node, Expression.Constant(null, nodeType)),
                handler(item, next, ContainerCount(value)));
        }
        Expression ArrayContainer(ContainerItemHandler handler)
        {
            Debug.Assert(schemaType.IsBondContainer());

            var count = Expression.Variable(typeof(int), "count");
            var index = Expression.Variable(typeof(int), "index");
            var item = Expression.ArrayAccess(value, new Expression[] { index });
            var next = Expression.LessThan(Expression.PreIncrementAssign(index), count);

            return Expression.Block(
                new[] { index, count },
                Expression.Assign(index, Expression.Constant(-1)),
                Expression.Assign(count, Expression.ArrayLength(value)),
                handler(item, next, count));
        }
        Expression EnumerableContainer(ContainerItemHandler handler)
        {
            Debug.Assert(schemaType.IsBondContainer());

            var methodGetEnumerator = value.Type.GetMethod(typeof(IEnumerable<>), "GetEnumerator");
            Debug.Assert(methodGetEnumerator != null, "Container must provide GetEnumerator method");

            var enumerator = Expression.Variable(methodGetEnumerator.ReturnType, "enumerator");
            var item = Expression.Property(enumerator, "Current");
            var next = Expression.Call(enumerator, moveNext);

            return Expression.Block(
                new[] { enumerator },
                Expression.Assign(enumerator, Expression.Call(value, methodGetEnumerator)),
                handler(item, next, ContainerCount(value)));
        }