void WriteElement(Variant element) { WriteStartTag(m_stack.Peek().m_name); switch(element.Type) { case VariantBase.EnumType.None: { WriteAttributes(m_stack.Peek().m_attributes); break; } case VariantBase.EnumType.Any: case VariantBase.EnumType.String: case VariantBase.EnumType.Float: case VariantBase.EnumType.Double: case VariantBase.EnumType.Int32: case VariantBase.EnumType.UInt32: case VariantBase.EnumType.Int64: case VariantBase.EnumType.UInt64: case VariantBase.EnumType.Boolean: case VariantBase.EnumType.Date: case VariantBase.EnumType.Time: case VariantBase.EnumType.DateTime: { WriteAttributes(m_stack.Peek().m_attributes); WriteText(element); break; } case VariantBase.EnumType.Dictionary: case VariantBase.EnumType.Bag: { WriteAttributes(m_stack.Peek().m_attributes); if ((m_mode & XmlMode.Preserve)!=0) { if (element.ContainsKey(XmlConst.Attributes)) { WriteAttributes(element[XmlConst.Attributes]); } foreach(VariantItem item in element) { if (item.Key==XmlConst.Attributes) { continue; } else if (item.Key==XmlConst.Text) { WriteText(item.Value); } else if (item.Key==XmlConst.Instruction) { WriteInstruction(item.Value); } else if (item.Key==XmlConst.Comment) { WriteComment(item.Value); } else { Push(item.Key); WriteElement(item.Value); Pop(); } } } else { foreach (VariantItem item in element) { Push(item.Key); WriteVariant(item.Value); Pop(); } } break; } case VariantBase.EnumType.List: { WriteAttributes(m_stack.Peek().m_attributes); foreach(VariantItem item in element) { Push(); WriteVariant(item.Value); Pop(); } break; } case VariantBase.EnumType.Tuple: { m_stack.Peek().m_attributes.Add("size", new Variant(element.Count)); WriteAttributes(m_stack.Peek().m_attributes); foreach(VariantItem item in element) { Push(); WriteVariant(item.Value); Pop(); } break; } case VariantBase.EnumType.TimeSeries: { WriteAttributes(m_stack.Peek().m_attributes); foreach(VariantItem item in element) { Push().Add("time", new Variant(item.Time)); WriteVariant(item.Value); Pop(); } break; } case VariantBase.EnumType.Buffer: { WriteAttributes(m_stack.Peek().m_attributes); m_writer.WriteBase64(element.AsBuffer(), 0, element.AsBuffer().Length); break; } case VariantBase.EnumType.Object: { IVariantObject obj = element.AsObject(); // write class name m_stack.Peek().m_attributes.Add("class", new Variant(obj.Class)); m_stack.Peek().m_attributes.Add("version", new Variant(obj.Version)); WriteAttributes(m_stack.Peek().m_attributes); // write parameter dictionary Push("params"); WriteVariant(obj.Deflate()); Pop(); break; } case VariantBase.EnumType.Exception: { WriteAttributes(m_stack.Peek().m_attributes); VariantExceptionInfo e = element.AsException(); Push("type"); WriteElement(new Variant(e.Class)); Pop(); Push("message"); WriteElement(new Variant(e.Message)); Pop(); if (e.Source.Length!=0) { Push("source"); WriteElement(new Variant(e.Source)); Pop(); } if (e.Stack.Length!=0) { Push("stack"); WriteElement(new Variant(e.Stack)); Pop(); } break; } case VariantBase.EnumType.Array: { TypedArray array = element.AsArray(); m_stack.Peek().m_attributes.Add("size", new Variant(array.Count)); m_stack.Peek().m_attributes.Add("elementType", new Variant(array.ElementType.ToString())); WriteAttributes(m_stack.Peek().m_attributes); WriteDelegate writer = null; switch (array.ElementType) { case VariantBase.EnumType.Float: writer = o => m_writer.WriteString(VariantBase.ToString((float) o)); break; case VariantBase.EnumType.Double: writer = o => m_writer.WriteString(VariantBase.ToString((double) o)); break; case VariantBase.EnumType.String: writer = o => m_writer.WriteString((string) o); break; case VariantBase.EnumType.Boolean: writer = o => m_writer.WriteString(VariantBase.ToString((bool) o)); break; case VariantBase.EnumType.Int32: writer = o => m_writer.WriteString(VariantBase.ToString((int) o)); break; case VariantBase.EnumType.UInt32: writer = o => m_writer.WriteString(VariantBase.ToString((uint) o)); break; case VariantBase.EnumType.Int64: writer = o => m_writer.WriteString(VariantBase.ToString((long) o)); break; case VariantBase.EnumType.UInt64: writer = o => m_writer.WriteString(VariantBase.ToString((ulong) o)); break; case VariantBase.EnumType.Time: writer = o => m_writer.WriteString(VariantBase.ToString((TimeSpan) o)); break; case VariantBase.EnumType.DateTime: writer = o => m_writer.WriteString(VariantBase.ToString((DateTime) o)); break; default: throw new VariantException("Case exhaustion: " + array.ElementType); } for (int i=0; i<array.Count; ++i) { m_writer.WriteStartElement(XmlConst.Default); writer(array[i]); m_writer.WriteEndElement(); } break; } case VariantBase.EnumType.DataTable: { #if !DISABLE_DATATABLE DataTable dataTable = element.AsDataTable(); m_stack.Peek().m_attributes.Add("rows", new Variant(dataTable.Rows.Count)); m_stack.Peek().m_attributes.Add("columns", new Variant(dataTable.Columns.Count)); WriteAttributes(m_stack.Peek().m_attributes); foreach (DataColumn col in dataTable.Columns) { Push("Column"); m_stack.Peek().m_attributes.Add("name", new Variant(col.ColumnName)); m_stack.Peek().m_attributes.Add("type", new Variant(VariantPrimitiveBase.TypeToEnum(col.DataType).ToString())); WriteElement(new Variant()); Pop(); } foreach (DataColumn col in dataTable.Columns) { Action<object> writer; switch (VariantPrimitiveBase.TypeToEnum(col.DataType)) { case VariantBase.EnumType.Float: writer = o => m_writer.WriteString(VariantBase.ToString((float)o)); break; case VariantBase.EnumType.Double: writer = o => m_writer.WriteString(VariantBase.ToString((double)o)); break; case VariantBase.EnumType.String: writer = o => m_writer.WriteString((string)o); break; case VariantBase.EnumType.Boolean: writer = o => m_writer.WriteString(VariantBase.ToString((bool)o)); break; case VariantBase.EnumType.Int32: writer = o => m_writer.WriteString(VariantBase.ToString((int)o)); break; case VariantBase.EnumType.UInt32: writer = o => m_writer.WriteString(VariantBase.ToString((uint)o)); break; case VariantBase.EnumType.Int64: writer = o => m_writer.WriteString(VariantBase.ToString((long)o)); break; case VariantBase.EnumType.UInt64: writer = o => m_writer.WriteString(VariantBase.ToString((ulong)o)); break; case VariantBase.EnumType.Time: writer = o => m_writer.WriteString(VariantBase.ToString((TimeSpan)o)); break; case VariantBase.EnumType.DateTime: writer = o => m_writer.WriteString(VariantBase.ToString((DateTime)o)); break; default: throw new VariantException("Case exhaustion: " + VariantPrimitiveBase.TypeToEnum(col.DataType)); } Push("Column").Add("name", new Variant(col.ColumnName)); WriteStartTag("s"); WriteAttributes(m_stack.Peek().m_attributes); foreach (DataRow row in dataTable.Rows) { m_writer.WriteStartElement(XmlConst.Default); writer(row[col]); m_writer.WriteEndElement(); } WriteEndTag(); Pop(); } break; #else throw new NotSupportedException("Datatables are not supported on this platform."); #endif } default: throw new VariantException("Case exhaustion: " + element.Type); } WriteEndTag(); }
protected void WriteVariant(Variant v) { VariantBase.EnumType type = v.Type; Write((Int32)type); switch (type) { case VariantBase.EnumType.None: break; case VariantBase.EnumType.String: case VariantBase.EnumType.Any: Write(v.As<string>()); break; case VariantBase.EnumType.Float: Write(v.As<float>()); break; case VariantBase.EnumType.Double: Write(v.As<double>()); break; case VariantBase.EnumType.Int32: Write(v.As<Int32>()); break; case VariantBase.EnumType.UInt32: Write(v.As<UInt32>()); break; case VariantBase.EnumType.Int64: Write(v.As<Int64>()); break; case VariantBase.EnumType.UInt64: Write(v.As<UInt64>()); break; case VariantBase.EnumType.Boolean: Write(v.As<bool>()); break; case VariantBase.EnumType.Time: Write(v.As<TimeSpan>()); break; case VariantBase.EnumType.DateTime: Write(v.As<DateTime>()); break; case VariantBase.EnumType.List: case VariantBase.EnumType.Tuple: Write(v.Count); foreach (VariantItem item in v) { WriteVariant(item.Value); } break; case VariantBase.EnumType.Dictionary: case VariantBase.EnumType.Bag: Write(v.Count); foreach (VariantItem item in v) { Write(item.Key); WriteVariant(item.Value); } break; case VariantBase.EnumType.TimeSeries: Write(v.Count); foreach (VariantItem item in v) { Write(item.Time); WriteVariant(item.Value); } break; case VariantBase.EnumType.Object: IVariantObject o = v.AsObject(); Write(o.Class); Write(o.Version); WriteVariant(o.Deflate()); break; case VariantBase.EnumType.Exception: VariantExceptionInfo x = v.AsException(); Write(x.Class); Write(x.Message); Write(x.Source); Write(x.Stack); break; case VariantBase.EnumType.Buffer: Write(v.AsBuffer().Length); Write(v.AsBuffer(), true); break; case VariantBase.EnumType.DataTable: Write(v.AsDataTable()); break; case VariantBase.EnumType.Array: Write(v.AsArray()); break; default: throw new VariantException("Case exhaustion: " + type.ToString()); } }