aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Common/XmlRpcCS/XmlRpcDeserializer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Common/XmlRpcCS/XmlRpcDeserializer.cs')
-rw-r--r--Common/XmlRpcCS/XmlRpcDeserializer.cs195
1 files changed, 195 insertions, 0 deletions
diff --git a/Common/XmlRpcCS/XmlRpcDeserializer.cs b/Common/XmlRpcCS/XmlRpcDeserializer.cs
new file mode 100644
index 0000000..bd736c0
--- /dev/null
+++ b/Common/XmlRpcCS/XmlRpcDeserializer.cs
@@ -0,0 +1,195 @@
1namespace Nwc.XmlRpc
2{
3 using System;
4 using System.Collections;
5 using System.IO;
6 using System.Xml;
7 using System.Globalization;
8
9 /// <summary>Parser context, we maintain contexts in a stack to avoiding recursion. </summary>
10 struct Context
11 {
12 public String Name;
13 public Object Container;
14 }
15
16 /// <summary>Basic XML-RPC data deserializer.</summary>
17 /// <remarks>Uses <c>XmlTextReader</c> to parse the XML data. This level of the class
18 /// only handles the tokens common to both Requests and Responses. This class is not useful in and of itself
19 /// but is designed to be subclassed.</remarks>
20 public class XmlRpcDeserializer : XmlRpcXmlTokens
21 {
22 private static DateTimeFormatInfo _dateFormat = new DateTimeFormatInfo();
23
24 private Object _container;
25 private Stack _containerStack;
26
27 /// <summary>Protected reference to last text.</summary>
28 protected String _text;
29 /// <summary>Protected reference to last deserialized value.</summary>
30 protected Object _value;
31 /// <summary>Protected reference to last name field.</summary>
32 protected String _name;
33
34
35 /// <summary>Basic constructor.</summary>
36 public XmlRpcDeserializer()
37 {
38 Reset();
39 _dateFormat.FullDateTimePattern = ISO_DATETIME;
40 }
41
42 /// <summary>Static method that parses XML data into a response using the Singleton.</summary>
43 /// <param name="xmlData"><c>StreamReader</c> containing an XML-RPC response.</param>
44 /// <returns><c>Object</c> object resulting from the deserialization.</returns>
45 virtual public Object Deserialize(TextReader xmlData)
46 {
47 return null;
48 }
49
50 /// <summary>Protected method to parse a node in an XML-RPC XML stream.</summary>
51 /// <remarks>Method deals with elements common to all XML-RPC data, subclasses of
52 /// this object deal with request/response spefic elements.</remarks>
53 /// <param name="reader"><c>XmlTextReader</c> of the in progress parsing data stream.</param>
54 protected void DeserializeNode(XmlTextReader reader)
55 {
56 switch (reader.NodeType)
57 {
58 case XmlNodeType.Element:
59 if (Logger.Delegate != null)
60 Logger.WriteEntry("START " + reader.Name, LogLevel.Information);
61 switch (reader.Name)
62 {
63 case VALUE:
64 _value = null;
65 _text = null;
66 break;
67 case STRUCT:
68 PushContext();
69 _container = new Hashtable();
70 break;
71 case ARRAY:
72 PushContext();
73 _container = new ArrayList();
74 break;
75 }
76 break;
77 case XmlNodeType.EndElement:
78 if (Logger.Delegate != null)
79 Logger.WriteEntry("END " + reader.Name, LogLevel.Information);
80 switch (reader.Name)
81 {
82 case BASE64:
83 _value = Convert.FromBase64String(_text);
84 break;
85 case BOOLEAN:
86 int val = Int16.Parse(_text);
87 if (val == 0)
88 _value = false;
89 else if (val == 1)
90 _value = true;
91 break;
92 case STRING:
93 _value = _text;
94 break;
95 case DOUBLE:
96 _value = Double.Parse(_text);
97 break;
98 case INT:
99 case ALT_INT:
100 _value = Int32.Parse(_text);
101 break;
102 case DATETIME:
103#if __MONO__
104 _value = DateParse(_text);
105#else
106 _value = DateTime.ParseExact(_text, "F", _dateFormat);
107#endif
108 break;
109 case NAME:
110 _name = _text;
111 break;
112 case VALUE:
113 if (_value == null)
114 _value = _text; // some kits don't use <string> tag, they just do <value>
115
116 if ((_container != null) && (_container is IList)) // in an array? If so add value to it.
117 ((IList)_container).Add(_value);
118 break;
119 case MEMBER:
120 if ((_container != null) && (_container is IDictionary)) // in an struct? If so add value to it.
121 ((IDictionary)_container).Add(_name, _value);
122 break;
123 case ARRAY:
124 case STRUCT:
125 _value = _container;
126 PopContext();
127 break;
128 }
129 break;
130 case XmlNodeType.Text:
131 if (Logger.Delegate != null)
132 Logger.WriteEntry("Text " + reader.Value, LogLevel.Information);
133 _text = reader.Value;
134 break;
135 default:
136 break;
137 }
138 }
139
140 /// <summary>Static method that parses XML in a <c>String</c> into a
141 /// request using the Singleton.</summary>
142 /// <param name="xmlData"><c>String</c> containing an XML-RPC request.</param>
143 /// <returns><c>XmlRpcRequest</c> object resulting from the parse.</returns>
144 public Object Deserialize(String xmlData)
145 {
146 StringReader sr = new StringReader(xmlData);
147 return Deserialize(sr);
148 }
149
150 /// <summary>Pop a Context of the stack, an Array or Struct has closed.</summary>
151 private void PopContext()
152 {
153 Context c = (Context)_containerStack.Pop();
154 _container = c.Container;
155 _name = c.Name;
156 }
157
158 /// <summary>Push a Context on the stack, an Array or Struct has opened.</summary>
159 private void PushContext()
160 {
161 Context context;
162
163 context.Container = _container;
164 context.Name = _name;
165
166 _containerStack.Push(context);
167 }
168
169 /// <summary>Reset the internal state of the deserializer.</summary>
170 protected void Reset()
171 {
172 _text = null;
173 _value = null;
174 _name = null;
175 _container = null;
176 _containerStack = new Stack();
177 }
178
179#if __MONO__
180 private DateTime DateParse(String str)
181 {
182 int year = Int32.Parse(str.Substring(0,4));
183 int month = Int32.Parse(str.Substring(4,2));
184 int day = Int32.Parse(str.Substring(6,2));
185 int hour = Int32.Parse(str.Substring(9,2));
186 int min = Int32.Parse(str.Substring(12,2));
187 int sec = Int32.Parse(str.Substring(15,2));
188 return new DateTime(year,month,day,hour,min,sec);
189 }
190#endif
191
192 }
193}
194
195