//internal members
 internal XmlRpcAsyncResult(
     XmlRpcClientProtocol ClientProtocol,
     XmlRpcRequest XmlRpcReq,
     Encoding XmlEncoding,
     bool useEmptyParamsTag,
     bool useIndentation,
     int indentation,
     bool UseIntTag,
     bool UseStringTag,
     WebRequest Request,
     AsyncCallback UserCallback,
     object UserAsyncState,
     int retryNumber)
 {
     xmlRpcRequest = XmlRpcReq;
       clientProtocol = ClientProtocol;
       request = Request;
       userAsyncState = UserAsyncState;
       userCallback = UserCallback;
       completedSynchronously = true;
       xmlEncoding = XmlEncoding;
       _useEmptyParamsTag = useEmptyParamsTag;
       _useIndentation = useIndentation;
       _indentation = indentation;
       _useIntTag = UseIntTag;
       _useStringTag = UseStringTag;
 }
 public XmlRpcResponse Invoke(XmlRpcRequest request)
 {
     MethodInfo mi = null;
       if (request.mi != null)
       {
     mi = request.mi;
       }
       else
       {
     mi = this.GetType().GetMethod(request.method);
       }
       // exceptions thrown during an MethodInfo.Invoke call are
       // package as inner of
       Object reto;
       try
       {
     reto = mi.Invoke(this, request.args);
       }
       catch(Exception ex)
       {
     if (ex.InnerException != null)
       throw ex.InnerException;
     throw ex;
       }
       XmlRpcResponse response = new XmlRpcResponse(reto);
       return response;
 }
        public void SerializeRequest(Stream stm, XmlRpcRequest request)
        {
            // JB Change - Android tapatalk client needs the encoding to be uppercased
            if (m_encoding is UTF8Encoding)
            m_encoding = UpperCaseUTF8Encoding.UpperCaseUTF8;

              XmlTextWriter xtw = new XmlTextWriter(stm, m_encoding);
              ConfigureXmlFormat(xtw);
              xtw.WriteStartDocument();
              xtw.WriteStartElement("", "methodCall", "");
            {
              // TODO: use global action setting
              MappingAction mappingAction = MappingAction.Error;
              if (request.xmlRpcMethod == null)
            xtw.WriteElementString("methodName", request.method);
              else
            xtw.WriteElementString("methodName", request.xmlRpcMethod);
              if (request.args.Length > 0 || UseEmptyParamsTag)
              {
            xtw.WriteStartElement("", "params", "");
            try
            {
              if (!IsStructParamsMethod(request.mi))
            SerializeParams(xtw, request, mappingAction);
              else
            SerializeStructParams(xtw, request, mappingAction);
            }
            catch (XmlRpcUnsupportedTypeException ex)
            {
              throw new XmlRpcUnsupportedTypeException(ex.UnsupportedType,
            String.Format("A parameter is of, or contains an instance of, "
            + "type {0} which cannot be mapped to an XML-RPC type",
            ex.UnsupportedType));
            }
            xtw.WriteEndElement();
              }
            }
              xtw.WriteEndElement();
              xtw.Flush();
        }
        public XmlRpcRequest DeserializeRequest(XmlDocument xdoc, Type svcType)
        {
            XmlRpcRequest request = new XmlRpcRequest();
              XmlNode callNode = SelectSingleNode(xdoc, "methodCall");
              if (callNode == null)
              {
            throw new XmlRpcInvalidXmlRpcException(
              "Request XML not valid XML-RPC - missing methodCall element.");
              }
              XmlNode methodNode = SelectSingleNode(callNode, "methodName");
              if (methodNode == null)
              {
            throw new XmlRpcInvalidXmlRpcException(
              "Request XML not valid XML-RPC - missing methodName element.");
              }
              if (methodNode.FirstChild == null)
              {
            throw new XmlRpcInvalidXmlRpcException(
              "Request XML not valid XML-RPC - missing methodName element.");
              }
              request.method = methodNode.FirstChild.Value;
              if (request.method == "")
              {
            throw new XmlRpcInvalidXmlRpcException(
              "Request XML not valid XML-RPC - empty methodName.");
              }
              request.mi = null;
              ParameterInfo[] pis = new ParameterInfo[0];
              if (svcType != null)
              {
            // retrieve info for the method which handles this XML-RPC method
            XmlRpcServiceInfo svcInfo
              = XmlRpcServiceInfo.CreateServiceInfo(svcType);
            request.mi = svcInfo.GetMethodInfo(request.method);
            // if a service type has been specified and we cannot find the requested
            // method then we must throw an exception
            if (request.mi == null)
            {
              string msg = String.Format("unsupported method called: {0}",
                                      request.method);
              throw new XmlRpcUnsupportedMethodException(msg);
            }
            // method must be marked with XmlRpcMethod attribute
            Attribute attr = Attribute.GetCustomAttribute(request.mi,
              typeof(XmlRpcMethodAttribute));
            if (attr == null)
            {
              throw new XmlRpcMethodAttributeException(
            "Method must be marked with the XmlRpcMethod attribute.");
            }
            pis = request.mi.GetParameters();
              }
              XmlNode paramsNode = SelectSingleNode(callNode, "params");
              if (paramsNode == null)
              {
            if (svcType != null)
            {
              if (pis.Length == 0)
              {
            request.args = new object[0];
            return request;
              }
            // JB Change
            // Sometimes tapatalk calls the same method with both parameters and no parameters
            // This allows us to handle that by changing the no parameter case into an empty parameter array
              else if(pis.Length == 1 && pis[0].ParameterType == typeof(object[]))
              {
              paramsNode = xdoc.CreateNode(XmlNodeType.Element, "params", "");
              //var paramNode = xdoc.CreateNode(XmlNodeType.Element, "param", "");
              //paramsNode.AppendChild(paramNode);

             // var valueNode = xdoc.CreateNode(XmlNodeType.Element, "value", "");
              //paramNode.AppendChild(valueNode);

             // var arrayNode = xdoc.CreateNode(XmlNodeType.Element, "string", "");
              //valueNode.AppendChild(arrayNode);

             // var dataNode = xdoc.CreateNode(XmlNodeType.Element, "data", "");
              //arrayNode.AppendChild(dataNode);
              }
              else
              {

            throw new XmlRpcInvalidParametersException(
              "Method takes parameters and params element is missing.");
              }
            }
            else
            {
              request.args = new object[0];
              return request;
            }
              }
              XmlNode[] paramNodes = SelectNodes(paramsNode, "param");
              int paramsPos = GetParamsPos(pis);
              int minParamCount = paramsPos == -1 ? pis.Length : paramsPos;
              if (svcType != null && paramNodes.Length < minParamCount)
              {
            throw new XmlRpcInvalidParametersException(
              "Request contains too few param elements based on method signature.");
              }
              if (svcType != null && paramsPos == -1 && paramNodes.Length > pis.Length)
              {
            throw new XmlRpcInvalidParametersException(
              "Request contains too many param elements based on method signature.");
              }
              ParseStack parseStack = new ParseStack("request");
              // TODO: use global action setting
              MappingAction mappingAction = MappingAction.Error;
              int paramObjCount = (paramsPos == -1 ? paramNodes.Length : paramsPos + 1);
              Object[] paramObjs = new Object[paramObjCount];
              // parse ordinary parameters
              int ordinaryParams = (paramsPos == -1 ? paramNodes.Length : paramsPos);
              for (int i = 0; i < ordinaryParams; i++)
              {
            XmlNode paramNode = paramNodes[i];
            XmlNode valueNode = SelectSingleNode(paramNode, "value");
            if (valueNode == null)
              throw new XmlRpcInvalidXmlRpcException("Missing value element.");
            XmlNode node = SelectValueNode(valueNode);
            if (svcType != null)
            {
              parseStack.Push(String.Format("parameter {0}", i + 1));
              // TODO: why following commented out?
              //          parseStack.Push(String.Format("parameter {0} mapped to type {1}",
              //            i, pis[i].ParameterType.Name));
              paramObjs[i] = ParseValue(node, pis[i].ParameterType, parseStack,
            mappingAction);
            }
            else
            {
              parseStack.Push(String.Format("parameter {0}", i));
              paramObjs[i] = ParseValue(node, null, parseStack, mappingAction);
            }
            parseStack.Pop();
              }
              // parse params parameters
              if (paramsPos != -1)
              {
            Type paramsType = pis[paramsPos].ParameterType.GetElementType();
            Object[] args = new Object[1];
            args[0] = paramNodes.Length - paramsPos;
            Array varargs = (Array)CreateArrayInstance(pis[paramsPos].ParameterType,
              args);
            for (int i = 0; i < varargs.Length; i++)
            {
              XmlNode paramNode = paramNodes[i + paramsPos];
              XmlNode valueNode = SelectSingleNode(paramNode, "value");
              if (valueNode == null)
            throw new XmlRpcInvalidXmlRpcException("Missing value element.");
              XmlNode node = SelectValueNode(valueNode);
              parseStack.Push(String.Format("parameter {0}", i + 1 + paramsPos));
              varargs.SetValue(ParseValue(node, paramsType, parseStack,
            mappingAction), i);
              parseStack.Pop();
            }
            paramObjs[paramsPos] = varargs;
              }
              request.args = paramObjs;
              return request;
        }
 void SerializeStructParams(XmlTextWriter xtw, XmlRpcRequest request,
     MappingAction mappingAction)
 {
     ParameterInfo[] pis = request.mi.GetParameters();
       if (request.args.Length > pis.Length)
     throw new XmlRpcInvalidParametersException("Number of request "
       + "parameters greater than number of proxy method parameters.");
       if (Attribute.IsDefined(pis[request.args.Length - 1],
     typeof(ParamArrayAttribute)))
       {
     throw new XmlRpcInvalidParametersException("params parameter cannot "
       + "be used with StructParams.");
       }
       xtw.WriteStartElement("", "param", "");
       xtw.WriteStartElement("", "value", "");
       xtw.WriteStartElement("", "struct", "");
       for (int i = 0; i < request.args.Length; i++)
       {
     if (request.args[i] == null)
     {
       throw new XmlRpcNullParameterException(String.Format(
     "Null method parameter #{0}", i + 1));
     }
     xtw.WriteStartElement("", "member", "");
     xtw.WriteElementString("name", pis[i].Name);
     Serialize(xtw, request.args[i], mappingAction);
     xtw.WriteEndElement();
       }
       xtw.WriteEndElement();
       xtw.WriteEndElement();
       xtw.WriteEndElement();
 }
 void SerializeParams(XmlTextWriter xtw, XmlRpcRequest request,
     MappingAction mappingAction)
 {
     ParameterInfo[] pis = null;
       if (request.mi != null)
       {
     pis = request.mi.GetParameters();
       }
       for (int i = 0; i < request.args.Length; i++)
       {
     if (pis != null)
     {
       if (i >= pis.Length)
     throw new XmlRpcInvalidParametersException("Number of request "
       + "parameters greater than number of proxy method parameters.");
       if (i == pis.Length - 1
     && Attribute.IsDefined(pis[i], typeof(ParamArrayAttribute)))
       {
     Array ary = (Array)request.args[i];
     foreach (object o in ary)
     {
       if (o == null)
         throw new XmlRpcNullParameterException(
           "Null parameter in params array");
       xtw.WriteStartElement("", "param", "");
       Serialize(xtw, o, mappingAction);
       xtw.WriteEndElement();
     }
     break;
       }
     }
     if (request.args[i] == null)
     {
       throw new XmlRpcNullParameterException(String.Format(
     "Null method parameter #{0}", i + 1));
     }
     xtw.WriteStartElement("", "param", "");
     Serialize(xtw, request.args[i], mappingAction);
     xtw.WriteEndElement();
       }
 }
 XmlRpcResponse ReadResponse(
     XmlRpcRequest req,
     WebResponse webResp,
     Stream respStm,
     Type returnType)
 {
     HttpWebResponse httpResp = (HttpWebResponse)webResp;
       if (httpResp.StatusCode != HttpStatusCode.OK)
       {
     // status 400 is used for errors caused by the client
     // status 500 is used for server errors (not server application
     // errors which are returned as fault responses)
     if (httpResp.StatusCode == HttpStatusCode.BadRequest)
       throw new XmlRpcException(httpResp.StatusDescription);
     else
       throw new XmlRpcServerException(httpResp.StatusDescription);
       }
       XmlRpcSerializer serializer = new XmlRpcSerializer();
       serializer.NonStandard = _nonStandard;
       Type retType = returnType;
       if (retType == null)
     retType = req.mi.ReturnType;
       XmlRpcResponse xmlRpcResp
     = serializer.DeserializeResponse(respStm, retType);
       return xmlRpcResp;
 }
 XmlRpcRequest MakeXmlRpcRequest(WebRequest webReq, MethodInfo mi,
     object[] parameters, object clientObj, string xmlRpcMethod,
     Guid proxyId)
 {
     webReq.Method = "POST";
       webReq.ContentType = "text/xml";
       string rpcMethodName = GetRpcMethodName(clientObj, mi);
       XmlRpcRequest req = new XmlRpcRequest(rpcMethodName, parameters, mi,
     xmlRpcMethod, proxyId);
       return req;
 }
 Header[] GetChannelHeaders(
     ITransportHeaders requestHeaders,
     XmlRpcRequest xmlRpcReq,
     Type svcType)
 {
     string requestUri = (string) requestHeaders["__RequestUri"];
       XmlRpcServiceInfo svcInfo = XmlRpcServiceInfo.CreateServiceInfo(svcType);
       ArrayList hdrList = new ArrayList();
       hdrList.Add(new Header("__Uri", requestUri));
       hdrList.Add(new Header("__TypeName", svcType.AssemblyQualifiedName));
       hdrList.Add(new Header("__MethodName",
     svcInfo.GetMethodName(xmlRpcReq.method)));
       hdrList.Add(new Header("__Args", xmlRpcReq.args));
       return (Header[])hdrList.ToArray(typeof(Header));
 }
        //  private methods
        //
        void SerializeMessage(
            IMethodCallMessage mcm,
            ref ITransportHeaders headers,
            ref Stream stream)
        {
            ITransportHeaders reqHeaders = new TransportHeaders();
              reqHeaders["__Uri"] = mcm.Uri;
              reqHeaders["Content-Type"] = "text/xml; charset=\"utf-8\"";
              reqHeaders["__RequestVerb"] = "POST";

              MethodInfo mi = (MethodInfo) mcm.MethodBase;
              string methodName = GetRpcMethodName(mi);
              XmlRpcRequest xmlRpcReq = new XmlRpcRequest(methodName, mcm.InArgs);
              // TODO: possibly call GetRequestStream from next sink in chain?
              // TODO: SoapClientFormatter sink uses ChunkedStream - check why?
              Stream stm = new MemoryStream();
              XmlRpcSerializer serializer = new XmlRpcSerializer();
              serializer.SerializeRequest(stm, xmlRpcReq);
              stm.Position = 0;

              headers = reqHeaders;
              stream = stm;
        }