public override bool Read () { if (source.IsEmpty) { node = default (XamlNodeInfo); return false; } node = source.Queue.Dequeue (); return true; }
public override bool Read() { position++; if (position >= source.Count) { return(false); } node = source.GetNode(position); return(true); }
public XamlNodeInfo Copy() { var node = new XamlNodeInfo(); node.NodeType = NodeType; node.Value = Value; var obj = node.Value as XamlObject; if (obj != null) { node.Value = new XamlObject(obj.Type, obj.Value); } return(node); }
IEnumerable <XamlNodeInfo> GetDeferredNodes(XamlMember xm, object val) { var node = new XamlNodeInfo(); var reader = xm.DeferringLoader.ConverterInstance.Save(val, value_serializer_ctx); var xobj = new XamlObject(); while (reader.Read()) { var nodeType = reader.NodeType; switch (nodeType) { case XamlNodeType.StartObject: case XamlNodeType.GetObject: xobj.Set(reader.Type, reader.Value); yield return(node.Set(nodeType, xobj)); break; case XamlNodeType.EndObject: yield return(XamlNodeInfo.EndObject); break; case XamlNodeType.StartMember: yield return(node.Set(nodeType, reader.Member)); break; case XamlNodeType.EndMember: yield return(XamlNodeInfo.EndMember); break; case XamlNodeType.Value: yield return(node.Set(reader.Value)); break; case XamlNodeType.NamespaceDeclaration: yield return(node.Set(reader.Namespace)); break; default: break; } } }
IEnumerable <XamlNodeInfo> GetKeyNodes(object ikey, XamlType keyType) { var node = new XamlNodeInfo(); var en = GetNodes(XamlLanguage.Key, new XamlObject(GetType(ikey), ikey), keyType, false, node: node).GetEnumerator(); if (en.MoveNext()) { yield return(new XamlNodeInfo(XamlNodeType.StartMember, XamlLanguage.Key)); do { yield return(en.Current); } while (en.MoveNext()); yield return(XamlNodeInfo.EndMember); } }
public XamlNodeLineInfo(XamlNodeInfo node, int line, int column) { Node = node; LineNumber = line; LinePosition = column; }
IEnumerable <XamlNodeInfo> GetItemsNodes(XamlMember xm, XamlObject xobj) { var obj = xobj.Value; if (obj == null) { yield break; } var ie = xobj.Type.Invoker.GetItems(obj); var node = new XamlNodeInfo(); var xiobj = new XamlObject(); while (ie.MoveNext()) { var iobj = ie.Current; // If it is dictionary, then retrieve the key, and rewrite the item as the Value part. object ikey = null; if (xobj.Type.IsDictionary) { Type kvpType = iobj.GetType(); bool isNonGeneric = kvpType == typeof(DictionaryEntry); var kp = isNonGeneric ? null : kvpType.GetRuntimeProperty("Key"); var vp = isNonGeneric ? null : kvpType.GetRuntimeProperty("Value"); ikey = isNonGeneric ? ((DictionaryEntry)iobj).Key : kp.GetValue(iobj, null); iobj = isNonGeneric ? ((DictionaryEntry)iobj).Value : vp.GetValue(iobj, null); } var wobj = TypeExtensionMethods.GetExtensionWrapped(iobj); xiobj.Set(GetType(wobj), wobj); if (ikey != null) { // TODO: do this without copying the XamlNodeInfo somehow? var en = GetNodes(null, xiobj).Select(c => c.Copy()).GetEnumerator(); en.MoveNext(); yield return(en.Current); // StartObject //var nodes1 = en.Skip (1).Take (en.Count - 2); var nodes1 = new List <XamlNodeInfo>(); while (en.MoveNext()) { nodes1.Add(en.Current); } var nodes2 = GetKeyNodes(ikey, xobj.Type.KeyType); // group the members then sort to put the key nodes in the correct order var grouped = GroupMemberNodes(nodes1.Take(nodes1.Count - 1).Concat(nodes2)).OrderBy(r => r.Item1, TypeExtensionMethods.MemberComparer); foreach (var item in grouped) { foreach (var n in item.Item2) { yield return(n); } } yield return(nodes1[nodes1.Count - 1]); // EndObject } else { foreach (var xn in GetNodes(null, xiobj, node: node)) { yield return(xn); } } } }
IEnumerable <XamlNodeInfo> GetNodes(XamlMember xm, XamlObject xobj, XamlType overrideMemberType = null, bool partOfPositionalParameters = false, XamlNodeInfo node = null) { //If the item is invisible for the serialization then we must just skip it and return empty nodes info if (!xobj.Type.ShouldSerialize(xobj.Value)) { yield break; } object val; // Value - only for non-top-level node (thus xm != null) if (xm != null) { // collection items: each item is exposed as a standalone object that has StartObject, EndObject and contents. if (ReferenceEquals(xm, XamlLanguage.Items)) { foreach (var xn in GetItemsNodes(xm, xobj)) { yield return(xn); } yield break; } // Arguments: each argument is written as a standalone object if (ReferenceEquals(xm, XamlLanguage.Arguments)) { var xarg = new XamlObject(); foreach (var argm in xobj.Type.GetSortedConstructorArguments()) { var argv = argm.Invoker.GetValue(xobj.Value); xarg.Set(argm.Type, argv); foreach (var cn in GetNodes(null, xarg)) { yield return(cn); } } yield break; } // PositionalParameters: items are from constructor arguments, written as Value node sequentially. Note that not all of them are in simple string value. Also, null values are not written as NullExtension if (ReferenceEquals(xm, XamlLanguage.PositionalParameters)) { var xarg = new XamlObject(); foreach (var argm in xobj.Type.GetSortedConstructorArguments()) { foreach (var cn in GetNodes(argm, xarg.Set(argm.Type, xobj.GetMemberValue(argm)), null, true)) { yield return(cn); } } yield break; } node = node ?? new XamlNodeInfo(); if (ReferenceEquals(xm, XamlLanguage.Initialization)) { yield return(node.Set(TypeExtensionMethods.GetStringValue(xobj.Type, xm, xobj.Value, value_serializer_ctx))); yield break; } val = xobj.Value; if (xm.DeferringLoader != null) { foreach (var xn in GetDeferredNodes(xm, val)) { yield return(xn); } yield break; } // don't serialize default values if one is explicitly specified using the DefaultValueAttribute if (!partOfPositionalParameters) { if (xm.Invoker.IsDefaultValue(val)) { yield break; } if (settings.IgnoreDefaultValues && xm.DefaultValue == null) { if (xm.Type?.UnderlyingType?.GetTypeInfo().IsValueType == true) { if (Equals(val, Activator.CreateInstance(xm.Type.UnderlyingType))) { yield break; } } else if (ReferenceEquals(val, null)) { yield break; } } } // overrideMemberType is (so far) used for XamlLanguage.Key. var xtt = overrideMemberType ?? xm.Type; if (!xtt.IsMarkupExtension && // this condition is to not serialize MarkupExtension whose type has TypeConverterAttribute (e.g. StaticExtension) as a string. (xtt.IsContentValue(value_serializer_ctx) || xm.IsContentValue(value_serializer_ctx))) { // though null value is special: it is written as a standalone object. if (val == null) { if (!partOfPositionalParameters) { foreach (var xn in GetNodes(null, null_object, node: node)) { yield return(xn); } } else { yield return(node.Set(String.Empty)); } } else if (!NameResolver.IsCollectingReferences) // for perf, getting string value can be expensive { yield return(node.Set(TypeExtensionMethods.GetStringValue(xtt, xm, val, value_serializer_ctx))); } else if (val is Type) { LookupType((Type)val); } //new XamlTypeName(xtt.SchemaContext.GetXamlType((Type)val)).ToString(value_serializer_ctx?.GetService(typeof(INamespacePrefixLookup)) as INamespacePrefixLookup); yield break; } // collection items: return GetObject and Items. if ((xm.Type.IsCollection || xm.Type.IsDictionary) && !xm.IsWritePublic) { yield return(XamlNodeInfo.GetObject); // Write Items member only when there are items (i.e. do not write it if it is empty). var itemsValue = xobj.GetMemberObjectValue(XamlLanguage.Items); var en = GetItemsNodes(XamlLanguage.Items, itemsValue).GetEnumerator(); if (en.MoveNext()) { yield return(node.Set(XamlNodeType.StartMember, XamlLanguage.Items)); do { yield return(en.Current); } while (en.MoveNext()); yield return(XamlNodeInfo.EndMember); } yield return(XamlNodeInfo.EndObject); yield break; } if (xm.Type.IsXData) { var sw = new StringWriter(); var xw = XmlWriter.Create(sw, new XmlWriterSettings { OmitXmlDeclaration = true, ConformanceLevel = ConformanceLevel.Auto }); #if NETSTANDARD1_0 if (!ReflectionHelpers.IXmlSerializableType?.GetTypeInfo().IsAssignableFrom(val?.GetType().GetTypeInfo()) ?? false) { yield break; // do not output anything } ReflectionHelpers.IXmlSerializableWriteXmlMethod?.Invoke(val, new object[] { xw }); #else var val3 = val as IXmlSerializable; if (val3 == null) { yield break; // do not output anything } val3.WriteXml(xw); #endif xw.Dispose(); var obj = new XData { Text = sw.ToString() }; foreach (var xn in GetNodes(null, new XamlObject(XamlLanguage.XData, obj), node: node)) { yield return(xn); } yield break; } } else { node = node ?? new XamlNodeInfo(); val = xobj.Value; } // Object - could become Reference if (val != null && !ReferenceEquals(xobj.Type, XamlLanguage.Reference)) { if (xm != null && !xm.IsReadOnly && !IsPublicOrVisible(val.GetType())) { throw new XamlObjectReaderException($"Cannot read from internal type {xobj.Type}"); } if (!xobj.Type.IsContentValue(value_serializer_ctx)) { string refName = NameResolver.GetReferenceName(xobj, val); if (refName != null) { // The target object is already retrieved, so we don't return the same object again. NameResolver.SaveAsReferenced(val); // Record it as named object. // Then return Reference object instead. var xref = new XamlObject(XamlLanguage.Reference, new Reference(refName)); yield return(node.Set(XamlNodeType.StartObject, xref)); yield return(node.Set(XamlNodeType.StartMember, XamlLanguage.PositionalParameters)); yield return(node.Set(refName)); yield return(XamlNodeInfo.EndMember); yield return(XamlNodeInfo.EndObject); yield break; } else { // The object appeared in the xaml tree for the first time. So we store the reference with a unique name so that it could be referenced later. NameResolver.SetNamedObject(val, true); // probably fullyInitialized is always true here. } } yield return(node.Set(XamlNodeType.StartObject, xobj)); // If this object is referenced and there is no [RuntimeNameProperty] member, then return Name property in addition. if (!NameResolver.IsCollectingReferences && xobj.Type.GetAliasedProperty(XamlLanguage.Name) == null) { string name = NameResolver.GetReferencedName(xobj, val); if (name != null) { yield return(node.Set(XamlNodeType.StartMember, XamlLanguage.Name)); yield return(node.Set(name)); yield return(XamlNodeInfo.EndMember); } } } else { yield return(node.Set(XamlNodeType.StartObject, xobj)); } // get all object member nodes var xce = GetNodeMembers(xobj, value_serializer_ctx).GetEnumerator(); var xobject = new XamlObject(); var startNode = new XamlNodeInfo(); while (xce.MoveNext()) { var xnm = xce.Current; var en = GetNodes(xnm.Member, xnm.GetValue(xobject), node: node).GetEnumerator(); if (en.MoveNext()) { if (!xnm.Member.IsWritePublic && xnm.Member.Type != null && (xnm.Member.Type.IsCollection || xnm.Member.Type.IsDictionary)) { // if we are a collection or dictionary without a setter, check to see if its empty first var node1 = en.Current.Copy(); // getObject if (!en.MoveNext()) { continue; } var node2 = en.Current.Copy(); // possibly endObject if (!en.MoveNext()) // we have one more, so it's not empty! { continue; } // if we have three nodes, then it isn't empty yield return(startNode.Set(XamlNodeType.StartMember, xnm.Member)); yield return(node1); yield return(node2); } else { yield return(startNode.Set(XamlNodeType.StartMember, xnm.Member)); } do { yield return(en.Current); } while (en.MoveNext()); yield return(XamlNodeInfo.EndMember); } } yield return(XamlNodeInfo.EndObject); }
public XamlNodeLineInfo (XamlNodeInfo node, int line, int column) { Node = node; LineNumber = line; LinePosition = column; }
internal void Enqueue (XamlNodeInfo info) { var nli = (LineInfoProvider != null && LineInfoProvider.HasLineInfo) ? new XamlNodeLineInfo (info, LineInfoProvider.LineNumber, LineInfoProvider.LinePosition) : new XamlNodeLineInfo (info, 0, 0); queue.Enqueue (nli); }
internal void Enqueue(XamlNodeInfo info) { var nli = (LineInfoProvider != null && LineInfoProvider.HasLineInfo) ? new XamlNodeLineInfo(info, LineInfoProvider.LineNumber, LineInfoProvider.LinePosition) : new XamlNodeLineInfo(info, 0, 0); queue.Enqueue(nli); }
internal void Add(XamlNodeInfo node) { nodes.Add(node); }
public XamlNodeQueueReader (XamlNodeQueue source) { this.source = source; node = default (XamlNodeInfo); }