public void Operation(string opName) { wsdlParser.portTypeOperation pto = null; wsdlParser.operation bo = null; foreach (wsdlParser.portTypeOperation pto2 in m_portType.operations) { if (pto2.Name == opName) { pto = pto2; break; } } foreach (wsdlParser.operation bo2 in m_binding.operations) { if (bo2.Name == opName) { bo = bo2; break; } } // check for doc/literal or rpc/enc bool isEnc, isRpc; isEnc = bo.inputBody.use != "literal"; // remember that rpc/document can be set at the binding level, but overriden at the operation level if ((bo.style != null) && (bo.style.Length > 0)) { isRpc = (bo.style == "rpc"); } else { isRpc = (m_binding.bindingStyle == "rpc"); } if (isRpc && !isEnc) { throw new Exception("Sorry only encoded is supported for RPC style operations"); } if (!isRpc && isEnc) { throw new Exception("Sorry only literal messages are supported for document style operations"); } if (isRpc) { GenerateRpcEncOperation(opName, pto, bo); } else { GenerateDocLitOperation(opName, pto, bo); } m_proxyFileHeader.Flush(); m_proxyFileCpp.Flush(); }
private void GenerateDocLitOperation(string opName, wsdlParser.portTypeOperation pto, wsdlParser.operation bo) { // todo }
private void GenerateRpcEncOperation(string opName, wsdlParser.portTypeOperation pto, wsdlParser.operation bo) { wsdlParser.message msgIn, msgOut = null; msgIn = m_wsdl.findMessage(pto.inputMessage.msg.localname, pto.inputMessage.msg.@namespace); if (pto.outputMessage.Name.Length > 0) { msgOut = m_wsdl.findMessage(pto.outputMessage.msg.localname, pto.outputMessage.msg.@namespace); } // serializerFactory setup goo string ln = string.Format("// type mappings for operation {0}", opName); m_factory.Add(""); m_factory.Add(ln); string opIn = m_factory.IdForString(opName, IdType.Localname); string opOut = m_factory.IdForString(opName + "Response", IdType.Localname); string opInNS = m_factory.IdForString(bo.inputBody.@namespace, IdType.Namespace); string opOutNS = m_factory.IdForString(bo.outputBody.@namespace, IdType.Namespace); ln = string.Format("m_sf->ElementMapping({0}, {1}, {0}, {1});", opIn, opInNS); m_factory.Add(ln); ln = string.Format("m_sf->ElementMapping({0}, {1}, {0}, {1});", opOut, opOutNS); m_factory.Add(ln); // work out all the parameters ArrayList parameters = new ArrayList(); // first the body parameters foreach (wsdlParser.part p in msgIn.parts) { CppType type = mapType(p.XmlType); // add type mappings string pn = m_factory.IdForString(p.Name, IdType.Localname); string nons = m_factory.IdForString("", IdType.Namespace); string xmlln = m_factory.IdForString(type.XmlType.localname, IdType.Type); string xmlns = m_factory.IdForString(type.XmlType.@namespace, IdType.Namespace); ln = string.Format("m_sf->LocalTypeMapping({0}, {1}, {2}, {3}, {4}, {5});", opIn, opInNS, pn, nons, xmlln, xmlns); m_factory.Add(ln); parameters.Add(new Parameter(type, p.Name, p.XmlType, false, IdlDirection.In)); } // now the headers foreach (wsdlParser.soapHeader header in bo.inputHeaders) { wsdlParser.message hdrMsg = m_wsdl.findMessage(header.message.localname, header.message.@namespace); foreach (wsdlParser.part hdrPart in hdrMsg.parts) { if (hdrPart.Name == header.part) { CppType type = mapPart(hdrPart); parameters.Add(new Parameter(type, hdrPart.Name, hdrPart.XmlType, true, IdlDirection.In)); } } } // finally, any return parameter ? Parameter retParam = null; if (msgOut != null) { if (msgOut.parts.Count() > 0) { object idxOne = 1; wsdlParser.part p = (wsdlParser.part)msgOut.parts.Item(ref idxOne); CppType type = mapType(p.XmlType); // add type mappings string pn = m_factory.IdForString(p.Name, IdType.Localname); string nons = m_factory.IdForString("", IdType.Namespace); string xmlln = m_factory.IdForString(type.XmlType.localname, IdType.Type); string xmlns = m_factory.IdForString(type.XmlType.@namespace, IdType.Namespace); ln = string.Format("m_sf->LocalTypeMapping({0}, {1}, {2}, {3}, {4}, {5});", opOut, opOutNS, pn, nons, xmlln, xmlns); m_factory.Add(ln); retParam = new Parameter(type, p.Name, p.XmlType, false, IdlDirection.Out | IdlDirection.Retval); parameters.Add(retParam); } } // now generate the stub m_proxyFileHeader.Write("\tSTDMETHOD({0})(", opName); m_proxyFileCpp.Write("STDMETHODIMP {0}::{1}(", m_className, opName); bool first = true; foreach (Parameter p in parameters) { string prm = string.Format("{0}{1} {2} {3}", first ? "" : ", ", p.cppType.CPPParameterName, p.IsOutParam ? "*" : "", p.cppName); m_proxyFileHeader.Write(prm); m_proxyFileCpp.Write(prm); first = false; } m_proxyFileHeader.WriteLine(");"); m_proxyFileCpp.WriteLine(")\n{"); // update the interface m_interface.AddMethod("HRESULT " + opName, parameters); // generate the stub body m_proxyFileCpp.WriteLine("\tHRESULT hr;"); m_proxyFileCpp.WriteLine("\tCComPtr<ISOAPEnvelope> env = newEnvelope(CComBSTR(OLESTR(\"{0}\")), CComBSTR(OLESTR(\"{1}\")), hr);", opName, bo.inputBody.@namespace); m_proxyFileCpp.WriteLine("\tif (FAILED(hr)) return hr;"); bool gotParams = false, gotHeader = false; foreach (Parameter p in parameters) { if (p.IsOutParam) { continue; } if (p.isHeader) { if (!gotHeader) { m_proxyFileCpp.WriteLine("\tCComPtr<ISOAPNodes> headers;"); m_proxyFileCpp.WriteLine("\tenv->get_Headers(&headers);"); gotHeader = true; } m_proxyFileCpp.WriteLine("\tif({0} != null)"); m_proxyFileCpp.WriteLine(p.cppType.ConstructVariant(1, "v" + p.cppName, p.cppName)); m_proxyFileCpp.WriteLine("\t\theaders->Create(CComBSTR(OLESTR(\"{0}\")), v{1}, NULL, NULL, NULL, NULL);", p.xmlName.localname, p.cppName); } else { if (!gotParams) { m_proxyFileCpp.WriteLine("\tCComPtr<ISOAPNodes> params;"); m_proxyFileCpp.WriteLine("\tenv->get_Parameters(¶ms);"); gotParams = true; } m_proxyFileCpp.WriteLine(p.cppType.ConstructVariant(1, "v" + p.cppName, p.cppName)); m_proxyFileCpp.WriteLine("\tparams->Create(CComBSTR(OLESTR(\"{0}\")), v{1}, NULL, NULL, NULL, NULL);", p.cppName, p.cppName); } } m_proxyFileCpp.WriteLine("\thr = SendRecv( env, CComBSTR(OLESTR(\"{0}\")));", bo.inputBody.encodingStyle); m_proxyFileCpp.WriteLine("\tif (FAILED(hr)) return hr;"); // decode the return parameter if (retParam != null) { m_proxyFileCpp.WriteLine("\thr = extractRetVal{3}(env, CComBSTR(\"{0}\"), CComBSTR(\"{1}\"), {2});", retParam.xmlName.localname, retParam.xmlName.@namespace, retParam.cppName, retParam.cppType.ExtracRetValSuffix); } m_proxyFileCpp.WriteLine("\treturn hr;"); m_proxyFileCpp.WriteLine("}\n"); }