21 |
* |
* |
22 |
* -------------------------------------------------------------------------- |
* -------------------------------------------------------------------------- |
23 |
*/ |
*/ |
|
using System; |
|
24 |
using System.Collections; |
using System.Collections; |
25 |
using System.IO; |
using System.IO; |
26 |
using System.CodeDom.Compiler; |
using System.Text; |
27 |
using System.Xml; |
using System.Xml; |
28 |
|
|
29 |
namespace DotGNU.XmlRpc |
namespace DotGNU.XmlRpc |
34 |
// Ideally XmlTextWriter should write the tags, but it's indentation |
// Ideally XmlTextWriter should write the tags, but it's indentation |
35 |
// is too broken so that its more human readable and debuggable. |
// is too broken so that its more human readable and debuggable. |
36 |
// Grrr Grrr Grrrrr |
// Grrr Grrr Grrrrr |
37 |
public class XmlRpcWriter |
public class XmlRpcWriter : XmlTextWriter |
38 |
{ |
{ |
39 |
private XmlTextWriter writer; |
|
40 |
|
// TODO: build node tree in memory, then flush this tree at the |
41 |
|
// end which avoids us to do the WriteEndElements and allows us |
42 |
|
// for consistency checking |
43 |
|
|
44 |
private StringWriter sw; |
private StringWriter sw; |
45 |
private XmlRpcMethod m; |
private XmlRpcMethod m; |
46 |
|
|
47 |
|
public XmlRpcWriter( TextWriter w ) : base( w ) |
48 |
|
{ |
49 |
|
} |
50 |
|
|
51 |
|
public XmlRpcWriter( Stream stream, Encoding encoding ) : base( stream, encoding ) |
52 |
|
{ |
53 |
|
} |
54 |
|
|
55 |
|
public XmlRpcWriter( String filename, Encoding encoding ) : base( filename, encoding ) |
56 |
|
{ |
57 |
|
} |
58 |
|
|
59 |
|
public void WriteMethodResponse() |
60 |
|
{ |
61 |
|
WriteStartElement( "methodResponse" ); |
62 |
|
} |
63 |
|
|
64 |
|
public void WriteMethodResponse( object o ) |
65 |
|
{ |
66 |
|
WriteMethodResponse(); |
67 |
|
WriteParams(); |
68 |
|
WriteParam( o ); |
69 |
|
} |
70 |
|
|
71 |
|
public void WriteParams() |
72 |
|
{ |
73 |
|
WriteStartElement( "params" ); |
74 |
|
} |
75 |
|
|
76 |
|
public void WriteParam( object o ) |
77 |
|
{ |
78 |
|
WriteStartElement( "param" ); |
79 |
|
WriteValue( o ); |
80 |
|
WriteEndElement(); |
81 |
|
} |
82 |
|
|
83 |
public XmlRpcWriter() |
public void WriteValue() |
84 |
{ |
{ |
85 |
sw = new StringWriter(); |
WriteStartElement( "value" ); |
|
writer = new XmlTextWriter( sw ); |
|
|
//writer.Formatting = Formatting.Indented; |
|
86 |
} |
} |
87 |
|
|
88 |
private void WriteHead() |
public void WriteInt( int v ) |
89 |
{ |
{ |
90 |
writer.WriteStartDocument(); |
WriteElementString( "i4", XmlConvert.ToString( v ) ); |
91 |
writer.WriteStartElement( "methodResponse" ); |
} |
92 |
writer.WriteStartElement( "params" ); |
|
93 |
writer.WriteStartElement( "param" ); |
public void WriteStringValue( string v) |
94 |
writer.WriteStartElement( "value" ); |
{ |
95 |
|
WriteElementString( "string", v ); |
96 |
|
} |
97 |
|
|
98 |
|
public void WriteDouble( double v ) |
99 |
|
{ |
100 |
|
// XmlConvert is HORRID doing this!!!! Try this with a value |
101 |
|
// of 2.0 and see what i mean |
102 |
|
WriteElementString( "double", v.ToString() ); |
103 |
|
} |
104 |
|
|
105 |
|
public void WriteBoolean( bool v ) |
106 |
|
{ |
107 |
|
WriteElementString( "boolean", XmlConvert.ToString( v ) ); |
108 |
} |
} |
109 |
|
|
110 |
private void WriteTail() |
public void WriteDateTime( DateTime v ) |
111 |
|
{ |
112 |
|
// ensure this is iso compliant |
113 |
|
DateTime dt = (DateTime)v; |
114 |
|
|
115 |
|
// Why has MS got no clue about ISO 8601??? Horrid. All |
116 |
|
// these newbies working on specs. this is as close as it |
117 |
|
// gets but not exactly since the 'T' can be left out |
118 |
|
WriteElementString( "dateTime.iso860", dt.ToString( "s" ) ); |
119 |
|
} |
120 |
|
|
121 |
|
public void WriteBase64( byte[] v ) |
122 |
{ |
{ |
123 |
writer.WriteEndElement(); // value |
WriteStartElement( "base64" ); |
124 |
writer.WriteEndElement(); // param |
WriteBase64( v, 0, v.Length); |
125 |
writer.WriteEndElement(); // params |
WriteEndElement(); |
|
writer.WriteEndElement(); // methodResponse |
|
|
writer.WriteEndDocument(); |
|
126 |
} |
} |
127 |
|
|
128 |
private void Write( object o ) |
public void WriteStruct( XmlRpcStruct v ) |
129 |
{ |
{ |
130 |
|
WriteStartElement( "struct" ); |
131 |
|
|
132 |
|
foreach( DictionaryEntry entry in v ) { |
133 |
|
WriteStartElement( "member" ); |
134 |
|
WriteElementString( "name", (string)entry.Key ); |
135 |
|
WriteValue( entry.Value ); |
136 |
|
WriteEndElement(); // member |
137 |
|
} |
138 |
|
WriteEndElement(); // struct |
139 |
|
} |
140 |
|
|
141 |
|
public void WriteArray( XmlRpcArray v ) |
142 |
|
{ |
143 |
|
WriteStartElement( "array" ); |
144 |
|
WriteStartElement( "data" ); |
145 |
|
foreach( object entry in v ) { |
146 |
|
WriteValue( entry ); |
147 |
|
} |
148 |
|
WriteEndElement(); // data |
149 |
|
WriteEndElement(); // array |
150 |
|
} |
151 |
|
|
152 |
|
public void WriteValue( object o ) |
153 |
|
{ |
154 |
|
WriteStartElement( "value" ); |
155 |
if( o is int ) { |
if( o is int ) { |
156 |
writer.WriteElementString( "i4", XmlConvert.ToString( (int)o ) ); |
WriteInt( (int)o ); |
157 |
} |
} |
158 |
else if( o is double ) { |
else if( o is double ) { |
159 |
// XmlConvert is HORRID doing this!!!! Try this with a value |
WriteDouble( (double)o ); |
|
// of 2.0 and see what i mean |
|
|
writer.WriteElementString( "double", o.ToString() ); |
|
160 |
} |
} |
161 |
else if( o is string ) { |
else if( o is string ) { |
162 |
writer.WriteElementString( "string", (string)o ); |
WriteStringValue( (string)o ); |
163 |
} |
} |
164 |
else if( o is bool ) { |
else if( o is bool ) { |
165 |
writer.WriteElementString( "boolean", XmlConvert.ToString( (bool)o ) ); |
WriteBoolean( (bool)o ); |
166 |
} |
} |
167 |
else if( o is DateTime ) { |
else if( o is DateTime ) { |
168 |
// ensure this is iso compliant |
WriteDateTime( (DateTime)o ); |
|
DateTime dt = (DateTime)o; |
|
|
|
|
|
// Why has MS got no clue about ISO 8601??? Horrid. All |
|
|
// these newbies working on specs. this is as close as it |
|
|
// gets but not exactly since the 'T' can be left out |
|
|
writer.WriteElementString( "dateTime.iso860", dt.ToString( "s" ) ); |
|
169 |
} |
} |
170 |
else if( o is byte[] ) { |
else if( o is byte[] ) { |
171 |
byte[] buf = (byte[])o; |
WriteBase64( (byte[])o ); |
|
writer.WriteStartElement( "base64" ); |
|
|
writer.WriteBase64( buf, 0, buf.Length); |
|
|
writer.WriteEndElement(); // base64 |
|
172 |
} |
} |
173 |
else if( o is XmlRpcStruct ) { |
else if( o is XmlRpcStruct ) { |
174 |
XmlRpcStruct xmlRpcStruct = (XmlRpcStruct)o; |
WriteStruct( (XmlRpcStruct)o ); |
|
writer.WriteStartElement( "struct" ); |
|
|
foreach( DictionaryEntry entry in xmlRpcStruct ) { |
|
|
writer.WriteStartElement( "member" ); |
|
|
writer.WriteElementString( "name", (string)entry.Key ); |
|
|
writer.WriteStartElement( "value" ); |
|
|
Write( entry.Value ); |
|
|
writer.WriteEndElement(); // value |
|
|
writer.WriteEndElement(); // member |
|
|
} |
|
|
writer.WriteEndElement(); // struct |
|
175 |
} |
} |
176 |
else if( o is XmlRpcArray ) { |
else if( o is XmlRpcArray ) { |
177 |
XmlRpcArray xmlRpcArray = (XmlRpcArray)o; |
WriteArray( (XmlRpcArray)o ); |
|
writer.WriteStartElement( "array" ); |
|
|
writer.WriteStartElement( "data" ); |
|
|
foreach( object entry in xmlRpcArray ) { |
|
|
writer.WriteStartElement( "value" ); |
|
|
this.Write( entry ); |
|
|
writer.WriteEndElement(); // value |
|
|
} |
|
|
writer.WriteEndElement(); // data |
|
|
writer.WriteEndElement(); // array |
|
178 |
} |
} |
179 |
} |
WriteEndElement(); |
|
|
|
|
public string Parse( XmlRpcStruct s ) |
|
|
{ |
|
|
WriteHead(); |
|
|
Write( s ); |
|
|
WriteTail(); |
|
|
return sw.ToString(); |
|
180 |
} |
} |
181 |
} |
} |
182 |
} |
} |