| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 | /* This file is part of OpenSubtitles Handler   A library that handle OpenSubtitles.org XML-RPC methods.   Copyright © Ala Ibrahim Hadid 2013   This program is free software: you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation, either version 3 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program.  If not, see <http://www.gnu.org/licenses/>. */using System;using System.Globalization;using System.Text;using System.Collections.Generic;using System.IO;using System.Xml;using OpenSubtitlesHandler;namespace XmlRpcHandler{    /// <summary>    /// A class for making XML-RPC requests. The requests then can be sent directly as http request.    /// </summary>    public class XmlRpcGenerator    {        /// <summary>        /// Generate XML-RPC request using method call.        /// </summary>        /// <param name="method">The method call</param>        /// <returns>The request in xml.</returns>        public static byte[] Generate(XmlRpcMethodCall method)        { return Generate(new XmlRpcMethodCall[] { method }); }        /// <summary>        /// Generate XML-RPC request using method calls array.        /// </summary>        /// <param name="methods">The method calls array</param>        /// <returns>The request in utf8 xml string as buffer</returns>        public static byte[] Generate(XmlRpcMethodCall[] methods)        {            if (methods == null)                throw new Exception("No method to write !");            if (methods.Length == 0)                throw new Exception("No method to write !");            // Create xml            XmlWriterSettings sett = new XmlWriterSettings();            sett.Indent = true;            sett.Encoding = Encoding.UTF8;            using (var ms = new MemoryStream())            {                using (XmlWriter XMLwrt = XmlWriter.Create(ms, sett))                {                    // Let's write the methods                    foreach (XmlRpcMethodCall method in methods)                    {                        XMLwrt.WriteStartElement("methodCall");//methodCall                        XMLwrt.WriteStartElement("methodName");//methodName                        XMLwrt.WriteString(method.Name);                        XMLwrt.WriteEndElement();//methodName                        XMLwrt.WriteStartElement("params");//params                                                           // Write values                        foreach (IXmlRpcValue p in method.Parameters)                        {                            XMLwrt.WriteStartElement("param");//param                            if (p is XmlRpcValueBasic)                            {                                WriteBasicValue(XMLwrt, (XmlRpcValueBasic)p);                            }                            else if (p is XmlRpcValueStruct)                            {                                WriteStructValue(XMLwrt, (XmlRpcValueStruct)p);                            }                            else if (p is XmlRpcValueArray)                            {                                WriteArrayValue(XMLwrt, (XmlRpcValueArray)p);                            }                            XMLwrt.WriteEndElement();//param                        }                        XMLwrt.WriteEndElement();//params                        XMLwrt.WriteEndElement();//methodCall                    }                    XMLwrt.Flush();                    return ms.ToArray();                }            }        }        /// <summary>        /// Decode response then return the values        /// </summary>        /// <param name="xmlResponse">The response xml string as provided by server as methodResponse</param>        /// <returns></returns>        public static XmlRpcMethodCall[] DecodeMethodResponse(string xmlResponse)        {            List<XmlRpcMethodCall> methods = new List<XmlRpcMethodCall>();            XmlReaderSettings sett = new XmlReaderSettings();            sett.DtdProcessing = DtdProcessing.Ignore;            sett.IgnoreWhitespace = true;            MemoryStream str;            if (xmlResponse.Contains(@"encoding=""utf-8"""))            {                str = new MemoryStream(Encoding.UTF8.GetBytes(xmlResponse));            }            else            {                str = new MemoryStream(Utilities.GetASCIIBytes(xmlResponse));            }            using (str)            {                using (XmlReader XMLread = XmlReader.Create(str, sett))                {                    XmlRpcMethodCall call = new XmlRpcMethodCall("methodResponse");                    // Read parameters                    while (XMLread.Read())                    {                        if (XMLread.Name == "param" && XMLread.IsStartElement())                        {                            IXmlRpcValue val = ReadValue(XMLread);                            if (val != null)                                call.Parameters.Add(val);                        }                    }                    methods.Add(call);                    return methods.ToArray();                }            }        }        private static void WriteBasicValue(XmlWriter XMLwrt, XmlRpcValueBasic val)        {            XMLwrt.WriteStartElement("value");//value            switch (val.ValueType)            {                case XmlRpcBasicValueType.String:                    XMLwrt.WriteStartElement("string");                    if (val.Data != null)                        XMLwrt.WriteString(val.Data.ToString());                    XMLwrt.WriteEndElement();                    break;                case XmlRpcBasicValueType.Int:                    XMLwrt.WriteStartElement("int");                    if (val.Data != null)                        XMLwrt.WriteString(val.Data.ToString());                    XMLwrt.WriteEndElement();                    break;                case XmlRpcBasicValueType.Boolean:                    XMLwrt.WriteStartElement("boolean");                    if (val.Data != null)                        XMLwrt.WriteString(((bool)val.Data) ? "1" : "0");                    XMLwrt.WriteEndElement();                    break;                case XmlRpcBasicValueType.Double:                    XMLwrt.WriteStartElement("double");                    if (val.Data != null)                        XMLwrt.WriteString(val.Data.ToString());                    XMLwrt.WriteEndElement();                    break;                case XmlRpcBasicValueType.dateTime_iso8601:                    XMLwrt.WriteStartElement("dateTime.iso8601");                    // Get date time format                    if (val.Data != null)                    {                        DateTime time = (DateTime)val.Data;                        string dt = time.Year + time.Month.ToString("D2") + time.Day.ToString("D2") +                            "T" + time.Hour.ToString("D2") + ":" + time.Minute.ToString("D2") + ":" +                            time.Second.ToString("D2");                        XMLwrt.WriteString(dt);                    }                    XMLwrt.WriteEndElement();                    break;                case XmlRpcBasicValueType.base64:                    XMLwrt.WriteStartElement("base64");                    if (val.Data != null)                        XMLwrt.WriteString(Convert.ToBase64String(BitConverter.GetBytes((long)val.Data)));                    XMLwrt.WriteEndElement();                    break;            }            XMLwrt.WriteEndElement();//value        }        private static void WriteStructValue(XmlWriter XMLwrt, XmlRpcValueStruct val)        {            XMLwrt.WriteStartElement("value");//value            XMLwrt.WriteStartElement("struct");//struct            foreach (XmlRpcStructMember member in val.Members)            {                XMLwrt.WriteStartElement("member");//member                XMLwrt.WriteStartElement("name");//name                XMLwrt.WriteString(member.Name);                XMLwrt.WriteEndElement();//name                if (member.Data is XmlRpcValueBasic)                {                    WriteBasicValue(XMLwrt, (XmlRpcValueBasic)member.Data);                }                else if (member.Data is XmlRpcValueStruct)                {                    WriteStructValue(XMLwrt, (XmlRpcValueStruct)member.Data);                }                else if (member.Data is XmlRpcValueArray)                {                    WriteArrayValue(XMLwrt, (XmlRpcValueArray)member.Data);                }                XMLwrt.WriteEndElement();//member            }            XMLwrt.WriteEndElement();//struct            XMLwrt.WriteEndElement();//value        }        private static void WriteArrayValue(XmlWriter XMLwrt, XmlRpcValueArray val)        {            XMLwrt.WriteStartElement("value");//value            XMLwrt.WriteStartElement("array");//array            XMLwrt.WriteStartElement("data");//data            foreach (IXmlRpcValue o in val.Values)            {                if (o is XmlRpcValueBasic)                {                    WriteBasicValue(XMLwrt, (XmlRpcValueBasic)o);                }                else if (o is XmlRpcValueStruct)                {                    WriteStructValue(XMLwrt, (XmlRpcValueStruct)o);                }                else if (o is XmlRpcValueArray)                {                    WriteArrayValue(XMLwrt, (XmlRpcValueArray)o);                }            }            XMLwrt.WriteEndElement();//data            XMLwrt.WriteEndElement();//array            XMLwrt.WriteEndElement();//value        }        private static readonly CultureInfo UsCulture = new CultureInfo("en-US");        private static string ReadString(XmlReader reader)        {            if (reader.NodeType == XmlNodeType.Element)            {                return reader.ReadElementContentAsString();            }            return reader.ReadContentAsString();        }                private static IXmlRpcValue ReadValue(XmlReader xmlReader, bool skipRead = false)        {            while (skipRead || xmlReader.Read())            {                if (xmlReader.Name == "value" && xmlReader.IsStartElement())                {                    xmlReader.Read();                    if (xmlReader.Name == "string" && xmlReader.IsStartElement())                    {                        return new XmlRpcValueBasic(ReadString(xmlReader), XmlRpcBasicValueType.String);                    }                    else if (xmlReader.Name == "int" && xmlReader.IsStartElement())                    {                        return new XmlRpcValueBasic(int.Parse(ReadString(xmlReader), UsCulture), XmlRpcBasicValueType.Int);                    }                    else if (xmlReader.Name == "boolean" && xmlReader.IsStartElement())                    {                        return new XmlRpcValueBasic(ReadString(xmlReader) == "1", XmlRpcBasicValueType.Boolean);                    }                    else if (xmlReader.Name == "double" && xmlReader.IsStartElement())                    {                        return new XmlRpcValueBasic(double.Parse(ReadString(xmlReader), UsCulture), XmlRpcBasicValueType.Double);                    }                    else if (xmlReader.Name == "dateTime.iso8601" && xmlReader.IsStartElement())                    {                        string date = ReadString(xmlReader);                        int year = int.Parse(date.Substring(0, 4), UsCulture);                        int month = int.Parse(date.Substring(4, 2), UsCulture);                        int day = int.Parse(date.Substring(6, 2), UsCulture);                        int hour = int.Parse(date.Substring(9, 2), UsCulture);                        int minute = int.Parse(date.Substring(12, 2), UsCulture);//19980717T14:08:55                        int sec = int.Parse(date.Substring(15, 2), UsCulture);                        DateTime time = new DateTime(year, month, day, hour, minute, sec);                        return new XmlRpcValueBasic(time, XmlRpcBasicValueType.dateTime_iso8601);                    }                    else if (xmlReader.Name == "base64" && xmlReader.IsStartElement())                    {                        return new XmlRpcValueBasic(BitConverter.ToInt64(Convert.FromBase64String(ReadString(xmlReader)), 0)                            , XmlRpcBasicValueType.Double);                    }                    else if (xmlReader.Name == "struct" && xmlReader.IsStartElement())                    {                        XmlRpcValueStruct strct = new XmlRpcValueStruct(new List<XmlRpcStructMember>());                        // Read members...                        while (xmlReader.Read())                        {                            if (xmlReader.Name == "member" && xmlReader.IsStartElement())                            {                                XmlRpcStructMember member = new XmlRpcStructMember("", null);                                xmlReader.Read();// read name                                member.Name = ReadString(xmlReader);                                IXmlRpcValue val = ReadValue(xmlReader, true);                                if (val != null)                                {                                    member.Data = val;                                    strct.Members.Add(member);                                }                            }                            else if (xmlReader.Name == "struct" && !xmlReader.IsStartElement())                            {                                return strct;                            }                        }                        return strct;                    }                    else if (xmlReader.Name == "array" && xmlReader.IsStartElement())                    {                        XmlRpcValueArray array = new XmlRpcValueArray();                        // Read members...                        while (xmlReader.Read())                        {                            if (xmlReader.Name == "array" && !xmlReader.IsStartElement())                            {                                return array;                            }                            else                            {                                IXmlRpcValue val = ReadValue(xmlReader);                                if (val != null)                                    array.Values.Add(val);                            }                        }                        return array;                    }                }                else break;                if (skipRead)                {                    return null;                }            }            return null;        }    }}
 |