void UniversalWriterSubnodes(SerializationWriterContext ctx, object instance, IEnumerable <Element> elements) { // PROPERTY as SUBNODE: // composite not null // collection foreach (var element in elements.OrderBy(x => x.Name)) { var subObj = element.GetValue(instance); if (!IsInAttrib(subObj)) { var subList = subObj as IList; if (subObj != null && (subList == null || subList.Count > 0)) // subList == null - this is composite { ctx.Write($"{Indentation(ctx.Indentation)}<{instance.GetType().Name}.{element.Name}>"); ctx.Indentation++; if (subList != null) { ctx.Result.AppendLine(); for (int index = 0; index < subList.Count; index++) { var item = subList[index]; GetWriter(item.GetType())(ctx, item); } } else { UniversalWriter(ctx, subObj); } ctx.Indentation--; ctx.WriteLine($"{Indentation(ctx.Indentation)}</{instance.GetType().Name}.{element.Name}>"); } } } }
public void Save(TextWriter stream, object instance) { var ctx = new SerializationWriterContext(); Write(ctx, instance); stream.Write(ctx.Result.ToString()); }
private void WriteMembers(SerializationWriterContext context, HashSet <object> stack) { var target = context.Value; var members = new List <MemberInfo>(); members.AddRange(target.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)); members.AddRange(target.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)); int index = 0; foreach (var member in members) { object value = null; try { if (member.IsField()) { value = ((FieldInfo)member).GetValue(target); } else if (member.IsProperty()) { value = ((PropertyInfo)member).GetValue(target, null); } } catch { continue; } this.Write(this.CreateWriterContext(stack, context, value, member, index++), stack); } }
protected override void OnWrite(SerializationWriterContext context) { var writer = this.GetWriter(context); if (writer == null) { throw new System.Runtime.Serialization.SerializationException("Can not obtain a text writer."); } if (context.Index >= 0) { writer.WriteLine(); } var indentText = this.GetIndentText(context.Depth); writer.Write(indentText); if (context.Member != null) { writer.Write(context.MemberName + " : "); } if (context.Value == null) { writer.Write("<NULL>"); return; } if (context.IsCircularReference) { writer.Write("<Circular Reference>"); return; } var directedValue = string.Empty; var isDirectedValue = this.GetDirectedValue(context.Value, out directedValue); if (isDirectedValue) { writer.Write(directedValue); writer.Write(" (" + this.GetFriendlyTypeName(context.Value.GetType()) + ")"); } else { writer.Write(this.GetFriendlyTypeName(context.Value.GetType())); if (context.IsCollection) { writer.Write(writer.NewLine + indentText + "["); } else { writer.Write(writer.NewLine + indentText + "{"); } } context.Terminated = isDirectedValue; }
protected virtual void Write(SerializationWriterContext context, HashSet <object> stack) { try { //调用序列化写入器的写入方法,以进行实际的序列化写入 _writer.Write(context); //如果当前序列化的成员是循环引用或者被强制终止则退出 if (context.IsCircularReference || context.Terminated) { return; } //判断该是否已经达到允许的序列化的层次 if (context.Settings.MaximumDepth > -1 && context.Depth >= context.Settings.MaximumDepth) { return; } //判断该是否需要继续序列化当前对象 if (context.Value == null || this.IsTermination(context)) { return; } //表示当前序列化对象是否已经序列化过 bool exists = false; if (!context.Value.GetType().IsValueType()) { exists = stack.Add(context.Value); } if (context.IsCollection) { int index = 0; foreach (var item in (System.Collections.IEnumerable)context.Value) { this.Write(this.CreateWriterContext(stack, context, item, null, index++), stack); } } else { this.WriteMembers(context, stack); } if (stack.Count > 0 && exists) { stack.Remove(context.Value); } } finally { //通知序列化写入器,本轮写入操作完成。 _writer.OnWrote(context); } }
protected TextWriter GetWriter(SerializationWriterContext context) { if (context == null) { return(null); } return(this.GetWriter(context.SerializationContext)); }
public SerializationWroteEventArgs(SerializationWriterContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } _context = context; }
private bool OnWriting(SerializationWriterContext context) { //创建事件参数对象 var args = new SerializationWritingEventArgs(context); //激发“Writing”事件 this.OnWriting(args); return(args.Cancel); }
protected virtual bool IsTermination(SerializationWriterContext context) { if (context.Terminated || context.Value == null) { return(true); } var type = context.Value.GetType(); return(type.IsPrimitive() || type.IsEnum() || type == typeof(decimal) || type == typeof(DateTime) || type == typeof(DBNull) || type == typeof(Guid) || type == typeof(object) || type == typeof(string) || TypeExtension.IsAssignableFrom(typeof(Type), type)); }
public void Write(SerializationWriterContext context) { //激发“Writing”事件 if (this.OnWriting(context)) { return; } //执行写入操作 this.OnWrite(context); //激发“Wrote”事件 this.OnWrote(new SerializationWroteEventArgs(context)); }
protected override void OnWrote(SerializationWriterContext context) { if (context.Terminated || context.IsCircularReference) { return; } var writer = this.GetWriter(context); if (writer == null) { return; } if (context.IsCollection) { writer.Write(writer.NewLine + this.GetIndentText(context.Depth) + "]"); } else { writer.Write(writer.NewLine + this.GetIndentText(context.Depth) + "}"); } }
void UniversalWriterAttributes(SerializationWriterContext ctx, object instance, IEnumerable <Element> elements) { // PROPERTY as ATTRIBUTE: // primitive // composite null foreach (var element in elements.OrderBy(x => x.Name)) { var val = element.GetValue(instance); if (IsInAttrib(val)) { if (element.DefaultValueAttribute == null || !Equals(element.DefaultValueAttribute.Value, val)) { if (ReferenceEquals(null, val)) { var x = ctx.GetAliasFor("http://schemas.microsoft.com/winfx/2006/xaml"); val = $"{{{x}:Null}}"; } val = ConvertToString(val); ctx.Write($@" {element.Name}=""{val}"""); } } } }
private void PrecompiledWriter(SerializationWriterContext ctx, object obj) { var sample = (Sample)obj; ctx.Write($@"<Sample Prop1=""{sample.Prop1}"" Prop2=""{sample.Prop2}"" xmlns=""test"" />"); }
private SerializationWriterContext CreateWriterContext(HashSet <object> stack, SerializationWriterContext context, object value, MemberInfo member, int index) { return(new SerializationWriterContext( context.Writer, context.SerializationContext, context.Value, value, member, index, context.Depth + 1, this.IsCircularReference(value, stack), this.IsCollection(value))); }
public SerializationWritingEventArgs(SerializationWriterContext context, bool cancel) : base(context) { _cancel = cancel; }
void Write(SerializationWriterContext ctx, object instance) { var type = instance.GetType(); ObjectWriterFor(type)(ctx, instance); }
void ISerializationWriter.OnWrote(SerializationWriterContext context) { this.OnWrote(context); }
protected virtual void OnWrote(SerializationWriterContext context) { }
void UniversalWriter(SerializationWriterContext ctx, object instance) { var type = instance.GetType(); var meta = GetTypeMetada(type); var elements = meta.Elements; ctx.NamespacesUsed.Add(meta.XmlNamespace); string alias; if (ctx.Indentation > 0 && meta.XmlNamespace != ctx.RootNamespace || meta.IsX()) { alias = ctx.GetAliasFor(meta.XmlNamespace) + ':'; } else { alias = null; ctx.RootNamespace = meta.XmlNamespace; } if (ctx.Indentation != 0 && ctx.Result[ctx.Result.Length - 1] != '\n') { ctx.Result.AppendLine(); } ctx.Write($"{Indentation(ctx.Indentation)}<{alias}{type.Name}"); UniversalWriterAttributes(ctx, instance, elements); // <nested in new builder> var subCtx = ctx.Nested(); UniversalWriterSubnodes(subCtx, instance, elements); // </nested in new builder> if (!ctx.XmlnsEmited && ctx.Indentation == 0) { if (!string.IsNullOrEmpty(ctx.RootNamespace)) { ctx.Write($" xmlns=\"{ctx.RootNamespace}\""); } foreach (var ns in ctx.NamespacesUsed) { if (ns != ctx.RootNamespace) { ctx.Write($" xmlns:{ctx.GetAliasFor(ns)}=\"{ns}\""); } } ctx.XmlnsEmited = true; } // <body> string body = null; if (meta.IsBody()) { body = string.Format(CultureInfo.InvariantCulture, "{0}", instance); } // </body> if (subCtx.Result.Length > 0) { ctx.WriteLine(">"); ctx.Write(subCtx.Result.ToString()); ctx.Write($"{Indentation(ctx.Indentation)}</{alias}{type.Name}>"); } else if (body != null) { ctx.Write(">"); ctx.Write(body); ctx.Write($"</{alias}{type.Name}>"); } else { ctx.Write(" />"); } if (ctx.Indentation != 0) { ctx.Result.AppendLine(); } }
protected abstract void OnWrite(SerializationWriterContext context);
public SerializationWritingEventArgs(SerializationWriterContext context) : this(context, false) { }