OpenLiveWriter/utilities/BlogServer/XmlRpc/XmlRpcFormatter.cs

128 lines
3.9 KiB
C#

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.Xml;
namespace BlogServer.XmlRpc
{
class XmlRpcFormatter
{
public static XmlDocument EncodeRequest(string methodName, params object[] parameters)
{
XmlDocument doc = new XmlDocument();
XmlElement methodCall = CreateElement(doc, "methodCall");
XmlElement methodNameEl = CreateElement(methodCall, "methodName");
methodNameEl.InnerText = methodName;
XmlElement paramsEl = CreateElement(methodCall, "params");
foreach (object o in parameters)
{
XmlElement paramEl = CreateElement(paramsEl, "param", "value");
EncodeValue(paramEl, o);
}
return doc;
}
public static XmlDocument EncodeResponse(object val)
{
XmlDocument doc = new XmlDocument();
XmlElement param = CreateElement(doc, "methodResponse", "params", "param", "value");
EncodeValue(param, val);
return doc;
}
public static XmlDocument EncodeFault(int faultCode, string faultString)
{
XmlDocument doc = new XmlDocument();
XmlElement faultStruct = CreateElement(doc, "methodResponse", "fault", "value");
ListDictionary faultDict = new ListDictionary();
faultDict["faultCode"] = faultCode;
faultDict["faultString"] = faultString;
EncodeStruct(faultStruct, faultDict);
return doc;
}
private static void EncodeValue(XmlElement parent, object val)
{
if (val == null)
throw new ArgumentNullException("val");
else if (val is int)
EncodeScalarValue(parent, "i4", ((int) val).ToString(CultureInfo.InvariantCulture));
else if (val is bool)
EncodeScalarValue(parent, "boolean", (bool) val ? "1" : "0");
else if (val is string)
EncodeScalarValue(parent, "string", val.ToString());
else if (val is double)
EncodeScalarValue(parent, "double", ((double) val).ToString(CultureInfo.InvariantCulture));
else if (val is DateTime)
EncodeScalarValue(parent, "dateTime.iso8601",
((DateTime) val).ToString("yyyyMMdd'T'HH:mm:ss", CultureInfo.InvariantCulture));
else if (val is byte[])
EncodeScalarValue(parent, "base64", Convert.ToBase64String((byte[]) val));
else if (val is IDictionary)
EncodeStruct(parent, (IDictionary) val);
else if (val is Array)
EncodeArray(parent, (Array) val);
else
throw new ArgumentException("Don't know how to encode object of type " + val.GetType());
}
private static void EncodeScalarValue(XmlElement parent, string typeName, string val)
{
XmlElement leaf = parent.OwnerDocument.CreateElement(typeName);
parent.AppendChild(leaf);
leaf.InnerText = val;
}
private static void EncodeStruct(XmlElement parent, IDictionary val)
{
XmlElement structEl = CreateElement(parent, "struct");
foreach (DictionaryEntry entry in val)
{
// HACK: deal with empty values
if (entry.Value == null || (entry.Value is DateTime && entry.Value.Equals(DateTime.MinValue)))
continue;
XmlElement memberEl = CreateElement(structEl, "member");
XmlElement nameEl = CreateElement(memberEl, "name");
nameEl.InnerText = (string) entry.Key;
XmlElement valueEl = CreateElement(memberEl, "value");
EncodeValue(valueEl, entry.Value);
}
}
private static void EncodeArray(XmlElement parent, Array val)
{
XmlElement dataEl = CreateElement(parent, "array", "data");
foreach (object o in val)
{
XmlElement valueEl = CreateElement(dataEl, "value");
EncodeValue(valueEl, o);
}
}
private static XmlElement CreateElement(XmlNode parent, params string[] elementNames)
{
XmlDocument ownerDoc = parent is XmlDocument ? (XmlDocument) parent : parent.OwnerDocument;
XmlNode currentNode = parent;
foreach (string elName in elementNames)
{
XmlElement el = ownerDoc.CreateElement(elName);
currentNode.AppendChild(el);
currentNode = el;
}
return (XmlElement) currentNode;
}
}
}