Esempio n. 1
0
        public override void StartElement(string name, Variant attributes, Variant.EnumType variantType)
        {
            ElementInfo context = new ElementInfo(name, attributes, variantType);

            if (m_stack.Count != 0)
            {
                ElementInfo parentContext = m_stack.Peek();

                switch (parentContext.m_type)
                {
                case Variant.EnumType.Any:
                    if (!parentContext.m_isTyped)
                    {
                        // Untyped elements with children are converted to Bags
                        parentContext.m_type    = Variant.EnumType.Bag;
                        parentContext.m_element = new Variant(parentContext.m_type);
                    }
                    break;

                case Variant.EnumType.None:
                case Variant.EnumType.String:
                case Variant.EnumType.Int32:
                case Variant.EnumType.UInt32:
                case Variant.EnumType.Int64:
                case Variant.EnumType.UInt64:
                case Variant.EnumType.Float:
                case Variant.EnumType.Double:
                case Variant.EnumType.Boolean:
                case Variant.EnumType.Date:
                case Variant.EnumType.Time:
                case Variant.EnumType.DateTime:
                case Variant.EnumType.Buffer:
                    throw new VariantException("Unexpected start element");

                case Variant.EnumType.TimeSeries:
                    if (context.m_attributes.ContainsKey("time"))
                    {
                        context.m_time = context.m_attributes["time"].As <DateTime>();
                        context.m_attributes.Remove("time");
                    }
                    else
                    {
                        throw new VariantException("Missing 'time' attribute for TimeSeries element");
                    }
                    break;
                }
            }

            m_stack.Push(context);

            // infer type from 'variant' attribute
            if (context.m_attributes.ContainsKey("variant"))
            {
                context.m_type    = Variant.StringToEnum(context.m_attributes["variant"].As <string>());
                context.m_isTyped = true;
                context.m_attributes.Remove("variant");
            }

            switch (context.m_type)
            {
            case Variant.EnumType.Any:
                if (!context.m_isTyped && !context.m_attributes.Empty)
                {
                    // untyped elements with attributes are assumed
                    // to be bags
                    context.m_type    = Variant.EnumType.Bag;
                    context.m_element = new Variant(context.m_type);
                }
                break;

            case Variant.EnumType.None:
            case Variant.EnumType.String:
            case Variant.EnumType.Int32:
            case Variant.EnumType.UInt32:
            case Variant.EnumType.Int64:
            case Variant.EnumType.UInt64:
            case Variant.EnumType.Float:
            case Variant.EnumType.Double:
            case Variant.EnumType.Boolean:
            case Variant.EnumType.Date:
            case Variant.EnumType.Time:
            case Variant.EnumType.DateTime:
            case Variant.EnumType.Buffer:
                break;

            case Variant.EnumType.List:
            case Variant.EnumType.Dictionary:
            case Variant.EnumType.Bag:
            case Variant.EnumType.TimeSeries:
                context.m_element = new Variant(context.m_type);
                break;

            case Variant.EnumType.Exception:
            case Variant.EnumType.Object:
                // Exception and Object are parsed via a dictionary for convenience.
                context.m_element = new Variant(Variant.EnumType.Dictionary);
                break;

            case Variant.EnumType.Tuple:
            {
                if (context.m_attributes.ContainsKey("size"))
                {
                    context.m_element = new Variant(Variant.EnumType.Tuple, context.m_attributes["size"].As <int>());
                    context.m_attributes.Remove("size");
                }
                else
                {
                    throw new VariantException("Missing 'size' attribute for Tuple variant");
                }
                break;
            }

            default:
                throw new VariantException("Case exhaustion: " + context.m_type.ToString());
            }
        }