// Released under the MIT/X11 license // http://www.opensource.org/licenses/mit-license.php "use strict"; /* * * xmlrpc.js beta version 1 Tool for creating XML-RPC formatted requests in * JavaScript * * Copyright 2001 Scott Andrew LePera scott@scottandrew.com * http://www.scottandrew.com/xml-rpc * * License: You are granted the right to use and/or redistribute this code only * if this license and the copyright notice are included and you accept that no * warranty of any kind is made or implied by the author. * */ exports.XMLRPCMessage = function XMLRPCMessage(methodname) { this.method = methodname || "system.listMethods"; this.params = []; return this; } XMLRPCMessage.prototype.setMethod = function(methodName) { if (!methodName) return; this.method = methodName; }; XMLRPCMessage.prototype.addParameter = function(data) { if (arguments.length == 0) return; this.params[this.params.length] = data; }; XMLRPCMessage.prototype.xml = function() { let method = this.method; // assemble the XML message header let xml = ""; xml += "\n"; xml += "\n"; xml += "" + method + "\n"; xml += "\n"; // do individual parameters for ( let i = 0; i < this.params.length; i++) { let data = this.params[i]; xml += "\n"; xml += "" + this.getParamXML(this.dataTypeOf(data), data) + "\n"; xml += "\n"; } xml += "\n"; xml += ""; return xml; // for now }; XMLRPCMessage.prototype.dataTypeOf = function(o) { // identifies the data type let type = typeof (o); type = type.toLowerCase(); switch (type) { case "number": if (Math.round(o) == o) type = "i4"; else type = "double"; break; case "object": let con = o.constructor; if (con == Date) type = "date"; else if (con == Array) type = "array"; else type = "struct"; break; } return type; }; XMLRPCMessage.prototype.doValueXML = function(type, data) { let xml = "<" + type + ">" + data + ""; return xml; }; XMLRPCMessage.prototype.doBooleanXML = function(data) { let value = (data == true) ? 1 : 0; let xml = "" + value + ""; return xml; }; XMLRPCMessage.prototype.doDateXML = function(data) { let leadingZero = function (n) { // pads a single number with a leading zero. Heh. if (n.length == 1) n = "0" + n; return n; }; let dateToISO8601 = function(date) { // wow I hate working with the Date object let year = new String(date.getYear()); let month = this.leadingZero(new String(date.getMonth())); let day = this.leadingZero(new String(date.getDate())); let time = this.leadingZero(new String(date.getHours())) + ":" + this.leadingZero(new String(date.getMinutes())) + ":" + this.leadingZero(new String(date.getSeconds())); let converted = year + month + day + "T" + time; return converted; }; let xml = ""; xml += dateToISO8601(data); xml += ""; return xml; }; XMLRPCMessage.prototype.doArrayXML = function(data) { let xml = "\n"; for ( let i = 0; i < data.length; i++) { xml += "" + this.getParamXML(this.dataTypeOf(data[i]), data[i]) + "\n"; } xml += "\n"; return xml; }; XMLRPCMessage.prototype.doStructXML = function(data) { let xml = "\n"; for ( let i in data) { xml += "\n"; xml += "" + i + "\n"; xml += "" + this.getParamXML(this.dataTypeOf(data[i]), data[i]) + "\n"; xml += "\n"; } xml += "\n"; return xml; }; XMLRPCMessage.prototype.getParamXML = function(type, data) { let xml; switch (type) { case "date": xml = this.doDateXML(data); break; case "array": xml = this.doArrayXML(data); break; case "struct": xml = this.doStructXML(data); break; case "boolean": xml = this.doBooleanXML(data); break; default: xml = this.doValueXML(type, data); break; } return xml; };