2 // Parser.cs - instantiate an object according to a Xaml file
5 // Iain McCoy (iain@mccoy.id.au)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System.Reflection;
32 using System.Collections;
34 using System.CodeDom.Compiler;
35 using System.ComponentModel;
36 using System.Diagnostics;
38 using Mono.Windows.Serialization;
41 namespace System.Windows.Serialization {
44 public static object LoadXml(Stream s)
46 return LoadXml(new XmlTextReader(s));
48 // TODO: this should take a XmlReader in order to be same as MSFT
49 public static object LoadXml(XmlTextReader reader)
51 Consumer r = new Consumer();
55 private class Consumer : ParserConsumerBase {
57 public object instance;
58 ArrayList objects = new ArrayList();
60 Hashtable keys = new Hashtable();
62 public override void CreateTopLevel(Type parent, string className)
64 instance = Activator.CreateInstance(parent);
68 public override void CreateObject(Type type, string varName, string key)
70 Object o = Activator.CreateInstance(type);
71 ((IAddChild)peek()).AddChild(o);
78 public override void CreateProperty(PropertyInfo property)
83 // top of stack is a reference to an object
84 // pushes a reference to the event
85 public override void CreateEvent(EventInfo evt)
90 public override void CreateDependencyProperty(Type attachedTo, string propertyName, Type propertyType)
96 public override void EndDependencyProperty()
99 string propertyName = (string)pop();
100 Type attachedTo = (Type)pop();
103 MethodInfo setter = attachedTo.GetMethod("Set" + propertyName);
104 setter.Invoke(null, new object[] { peek(), value});
107 public override void CreateObjectText(string text)
109 ((IAddChild)peek()).AddText(text);
112 // top of stack is reference to an event
113 public override void CreateEventDelegate(string functionName, Type eventDelegateType)
115 EventInfo e = (EventInfo)peek();
117 e.AddEventHandler(o, Delegate.CreateDelegate(o.GetType(), o, functionName));
119 // top of stack is reference to a property
120 public override void CreatePropertyDelegate(string functionName, Type propertyType)
122 PropertyInfo p = (PropertyInfo)peek();
124 p.SetValue(o, Delegate.CreateDelegate(o.GetType(), o, functionName), null);
127 public override void CreatePropertyText(string text, Type propertyType)
129 object value = convertText(propertyType, text);
130 storeToProperty(value);
133 public override void CreatePropertyObject(Type type, string name, string key)
135 object value = Activator.CreateInstance(type);
136 Debug.WriteLine("ObjectWriter CREATING PROPERTY OBJECT of type" + type);
142 public override void CreatePropertyReference(string key)
146 public override void CreateDependencyPropertyReference(string key)
150 public override void EndPropertyObject(Type destType)
152 object value = convertPropertyObjectValue(destType, pop());
153 storeToProperty(value);
155 private void storeToProperty(object value)
157 PropertyInfo p = (PropertyInfo)peek();
159 p.SetValue(o, value, null);
161 private object convertPropertyObjectValue(Type destType, object value)
163 Type sourceType = value.GetType();
164 if (destType != sourceType && !sourceType.IsSubclassOf(destType)) {
165 TypeConverter tc = TypeDescriptor.GetConverter(sourceType);
166 value = tc.ConvertTo(value, destType);
170 private object convertText(Type propertyType, string text)
172 if (propertyType != typeof(string)) {
173 TypeConverter tc = TypeDescriptor.GetConverter(propertyType);
174 return tc.ConvertFromString(text);
180 public override void CreateDependencyPropertyObject(Type type, string name, string key)
182 CreatePropertyObject(type, name, key);
184 public override void EndDependencyPropertyObject(Type finalType)
186 push(convertPropertyObjectValue(finalType, pop()));
189 // top of stack is reference to an attached property
190 public override void CreateDependencyPropertyText(string text, Type propertyType)
192 object value = convertText(propertyType, text);
196 public override void EndObject()
201 public override void EndProperty()
206 public override void EndEvent()
211 public override void Finish()
215 public override void CreateCode(string code)
217 throw new NotImplementedException();
220 private object peek()
224 private object peek(int i)
226 return objects[objects.Count - 1 - i];
230 object v = objects[objects.Count - 1];
231 objects.RemoveAt(objects.Count - 1);
232 Debug.WriteLine("ObjectWriter: POPPING");
235 private void push(object v)
237 Debug.WriteLine("ObjectWriter: PUSHING " + v);