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()); } }