diff options
Diffstat (limited to 'mcs/class/PresentationFramework/Mono.Windows.Serialization/ObjectWriter.cs')
-rw-r--r-- | mcs/class/PresentationFramework/Mono.Windows.Serialization/ObjectWriter.cs | 143 |
1 files changed, 118 insertions, 25 deletions
diff --git a/mcs/class/PresentationFramework/Mono.Windows.Serialization/ObjectWriter.cs b/mcs/class/PresentationFramework/Mono.Windows.Serialization/ObjectWriter.cs index f8c283cfbfc..c078cb0763e 100644 --- a/mcs/class/PresentationFramework/Mono.Windows.Serialization/ObjectWriter.cs +++ b/mcs/class/PresentationFramework/Mono.Windows.Serialization/ObjectWriter.cs @@ -33,42 +33,120 @@ using System.Collections; using System.CodeDom; using System.CodeDom.Compiler; using System.ComponentModel; +using System.Diagnostics; +using System.Windows; using System.Windows.Serialization; +using System.Xml; namespace Mono.Windows.Serialization { - public class ObjectWriter : IXamlWriter { + public class ObjectWriter { public object instance; ArrayList objects = new ArrayList(); + + public static object Parse(XmlTextReader reader) + { + ObjectWriter ow = new ObjectWriter(reader); + return ow.instance; + } + private ObjectWriter(XmlTextReader reader) + { + XamlParser p = new XamlParser(reader); + XamlNode n; + while (true) { + n = p.GetNextNode(); + if (n == null) + break; + Debug.WriteLine("ObjectWriter: INCOMING " + n.GetType()); + if (n is XamlDocumentStartNode) { + Debug.WriteLine("ObjectWriter: document begins"); + // do nothing + } else if (n is XamlElementStartNode && n.Depth == 0) { + Debug.WriteLine("ObjectWriter: element begins as top-level"); + CreateTopLevel(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name); + } else if (n is XamlElementStartNode && peek() is PropertyInfo) { + Debug.WriteLine("ObjectWriter: element begins as property value"); + CreatePropertyObject(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name); + } else if (n is XamlElementStartNode) { + Debug.WriteLine("ObjectWriter: element begins"); + CreateObject(((XamlElementStartNode)n).ElementType, ((XamlElementStartNode)n).name); + } else if (n is XamlPropertyNode && ((XamlPropertyNode)n).PropInfo != null) { + Debug.WriteLine("ObjectWriter: normal property begins"); + CreateProperty(((XamlPropertyNode)n).PropInfo); + } else if (n is XamlPropertyNode && ((XamlPropertyNode)n).DP != null) { + Debug.WriteLine("ObjectWriter: dependency property begins"); + DependencyProperty dp = ((XamlPropertyNode)n).DP; + Type typeAttachedTo = dp.OwnerType; + string propertyName = ((XamlPropertyNode)n).PropertyName; + + CreateDependencyProperty(typeAttachedTo, propertyName, dp.PropertyType); + } else if (n is XamlClrEventNode) { + Debug.WriteLine("ObjectWriter: event"); + CreateEvent((EventInfo)((XamlClrEventNode)n).EventMember); + CreateEventDelegate(((XamlClrEventNode)n).Value, ((EventInfo)((XamlClrEventNode)n).EventMember).EventHandlerType); + EndEvent(); + + } else if (n is XamlTextNode && ((XamlTextNode)n).mode == XamlParseMode.Object){ + Debug.WriteLine("ObjectWriter: text for object"); + CreateObjectText(((XamlTextNode)n).TextContent); + } else if (n is XamlTextNode && ((XamlTextNode)n).mode == XamlParseMode.Property){ + Debug.WriteLine("ObjectWriter: text for property"); + Debug.WriteLine("THINGTYPE = " + peek().GetType()); + CreatePropertyText(((XamlTextNode)n).TextContent, ((PropertyInfo)peek()).PropertyType); + EndProperty(); + } else if (n is XamlTextNode && ((XamlTextNode)n).mode == XamlParseMode.DependencyProperty){ + Debug.WriteLine("ObjectWriter: text for dependency property"); + string propertyName = (string)peek(); + Type attachedTo = (Type)peek(1); + CreateDependencyPropertyText(((XamlTextNode)n).TextContent, ((DependencyProperty)attachedTo.GetField(propertyName + "Property").GetValue(null)).PropertyType); + EndDependencyProperty(); + } else if (n is XamlPropertyComplexEndNode) { + Debug.WriteLine("ObjectWriter: end complex property"); + Debug.WriteLine("ObjectWriter: final type is " + ((XamlPropertyComplexEndNode)n).finalType); + EndPropertyObject(((XamlPropertyComplexEndNode)n).finalType); + EndProperty(); + } else if (n is XamlElementEndNode) { + Debug.WriteLine("ObjectWriter: end element"); + if (!((XamlElementEndNode)n).propertyObject) + EndObject(); + } else if (n is XamlDocumentEndNode) { + Debug.WriteLine("ObjectWriter: end document"); + Finish(); + } else { + throw new Exception("Unknown node " + n.GetType()); + } + } + } + public void CreateTopLevel(Type parent, string className) { instance = Activator.CreateInstance(parent); - objects.Add(instance); + push(instance); } public void CreateObject(Type type, string varName) { Object o = Activator.CreateInstance(type); - ((IAddChild)objects[objects.Count - 1]).AddChild(o); - objects.Add(o); + ((IAddChild)peek()).AddChild(o); + push(o); } public void CreateProperty(PropertyInfo property) { - objects.Add(property); + push(property); } // top of stack is a reference to an object // pushes a reference to the event public void CreateEvent(EventInfo evt) { - objects.Add(evt); + push(evt); } public void CreateDependencyProperty(Type attachedTo, string propertyName, Type propertyType) { - objects.Add(attachedTo); - objects.Add(propertyName); + push(attachedTo); + push(propertyName); } public void EndDependencyProperty() @@ -78,26 +156,26 @@ namespace Mono.Windows.Serialization { Type attachedTo = (Type)pop(); MethodInfo setter = attachedTo.GetMethod("Set" + propertyName); - setter.Invoke(null, new object[] { objects[objects.Count - 1], value}); + setter.Invoke(null, new object[] { peek(), value}); } public void CreateObjectText(string text) { - ((IAddChild)objects[objects.Count - 1]).AddText(text); + ((IAddChild)peek()).AddText(text); } // top of stack is reference to an event public void CreateEventDelegate(string functionName, Type eventDelegateType) { - EventInfo e = (EventInfo)objects[objects.Count-1]; - object o = objects[objects.Count-2]; + EventInfo e = (EventInfo)peek(); + object o = peek(1); e.AddEventHandler(o, Delegate.CreateDelegate(o.GetType(), o, functionName)); } // top of stack is reference to a property public void CreatePropertyDelegate(string functionName, Type propertyType) { - PropertyInfo p = (PropertyInfo)objects[objects.Count-1]; - object o = objects[objects.Count-2]; + PropertyInfo p = (PropertyInfo)peek(); + object o = peek(1); p.SetValue(o, Delegate.CreateDelegate(o.GetType(), o, functionName), null); } @@ -108,27 +186,28 @@ namespace Mono.Windows.Serialization { TypeConverter tc = TypeDescriptor.GetConverter(propertyType); value = tc.ConvertFromString(text); } - PropertyInfo p = (PropertyInfo)objects[objects.Count-1]; - object o = objects[objects.Count-2]; + PropertyInfo p = (PropertyInfo)peek(); + object o = peek(1); p.SetValue(o, value, null); } public void CreatePropertyObject(Type type, string name) { object value = Activator.CreateInstance(type); - objects.Add(value); + Debug.WriteLine("ObjectWriter CREATING PROPERTY OBJECT of type" + type); + push(value); } public void EndPropertyObject(Type destType) { - object value = objects[objects.Count - 1]; - objects.RemoveAt(objects.Count - 1); + object value = pop(); Type sourceType = value.GetType(); + Debug.WriteLine("ObjectWriter: EndPropertyObject has a " + value + value.GetType() + ", needs a " + destType); if (destType != sourceType && !sourceType.IsSubclassOf(destType)) { TypeConverter tc = TypeDescriptor.GetConverter(destType); value = tc.ConvertFrom(value); } - PropertyInfo p = (PropertyInfo)objects[objects.Count-1]; - object o = objects[objects.Count-2]; + PropertyInfo p = (PropertyInfo)peek(); + object o = peek(1); p.SetValue(o, value, null); } @@ -140,22 +219,22 @@ namespace Mono.Windows.Serialization { TypeConverter tc = TypeDescriptor.GetConverter(propertyType); value = tc.ConvertFromString(text); } - objects.Add(value); + push(value); } public void EndObject() { - objects.RemoveAt(objects.Count - 1); + pop(); } public void EndProperty() { - objects.RemoveAt(objects.Count - 1); + pop(); } public void EndEvent() { - objects.RemoveAt(objects.Count - 1); + pop(); } public void Finish() @@ -167,11 +246,25 @@ namespace Mono.Windows.Serialization { throw new NotImplementedException(); } + private object peek() + { + return peek(0); + } + private object peek(int i) + { + return objects[objects.Count - 1 - i]; + } private object pop() { object v = objects[objects.Count - 1]; objects.RemoveAt(objects.Count - 1); + Debug.WriteLine("ObjectWriter POPPING"); return v; } + private void push(object v) + { + Debug.WriteLine("ObjectWriter PUSHING " + v); + objects.Add(v); + } } } |