Monday, November 08, 2010 at 12:05 AM.

system.verbs.builtins.soap.decode.simpleType

on simpleType (adrmsg, adrelement, typeattrib) {
	<<Changes:
		<<04/01/01; 3:36:00 AM by JES
			<<When decoding floating point numbers, call soap.decode.float, instead of using double (cdata).
		<<04/02/01; 5:40:16 PM by JES
			<<Fixed a bug where decoding a false boolean represented as "0" would return true.
		<<04/03/01; 1:39:38 AM by JES
			<<Added base64Binary as a synonym for base64, and dateTime as a synonym for timeInstant, as support for decoding SOAP messages which are encoded according to the 2001 XML schema.
		<<04/03/01; 7:43:37 PM by JES
			<<When decoding strings, use xml.entityDecode, instead of soap.xmlutils.decodeAmpersands, so that entity-encoded high-ascii characters will be decoded.
		<<04/05/01; 2:24:40 AM by JES
			<<Validate namespace against URIs in subtables of soap.constants.schemaVersions.
		<<04/10/01; 7:03:45 PM by JES
			<<Fixed a bug where " and ' would not be decoded to ' and " when decoding strings.
		<<04/10/01; 11:42:38 PM by JES
			<<Check bounding for integer values. Return a binaryType when decoding binaries, instead of a stringType.
		<<04/12/01; 11:45:22 PM by JES
			<<Fixed a bug in integer bounds-checking, which would cause an error for very large negative numbers.
		<<04/27/01; 6:56:59 PM by JES
			<<Added SOAP-ENC to the supported namespaces list, to fix a bug decoding base64-encoded binaries.
	local (value, typerec = soap.xmlutils.getQualifiedName (adrmsg, typeattrib));
	local (supportedNamespaceURIs = {});
	bundle { //fill in supported schema namespaces list
		local (adrSchemaVersion);
		for adrSchemaVersion in @soap.constants.schemaVersions {
			supportedNamespaceURIs = supportedNamespaceURIs + adrSchemaVersion^.nsDataURI};
		supportedNamespaceURIs = supportedNamespaceURIs + soap.constants.nsEncodingURI};
	if not (supportedNamespaceURIs contains typerec["namespace"]) {
		scripterror ("Can't decode \"" + soap.xmlutils.getElementName (adrelement) + "\" element because the type attribute contained an unsupported namespace.")};
	case typerec["localpart"] {
		"string" {
			value = string (soap.xmlutils.getCharacterData (adrelement));
			value = xml.entityDecode (value); //decode high ascii
			value = soap.xmlutils.decodeAmpersands (value)}; //decode standard entities
		"base64Binary";
		"base64" {
			value = binary (base64.decode (soap.xmlutils.getCharacterData (adrelement)))};
		"boolean" {
			value = boolean (number (soap.xmlutils.getCharacterData (adrelement)))};
		"float";
		"decimal";
		"double" {
			value = soap.decode.float (soap.xmlutils.getCharacterData (adrelement))};
		"unsignedByte";
		"byte" {
			value = char (soap.xmlutils.getCharacterData (adrelement))};
		"unsignedShort";
		"short" {
			value = short (soap.xmlutils.getCharacterData (adrelement))};
		"int";
		"integer";
		"nonPositiveInteger";
		"negativeInteger";
		"long";
		"nonNegativeInteger";
		"unsignedLong";
		"unsignedInt";
		"positiveInteger" {
			local (cdata = soap.xmlutils.getCharacterData (adrelement));
			bundle { //check bounding
				local (compare, maxchars, startchar);
				if cdata[1] == '-' {
					compare = soap.constants.minInt;
					maxchars = 11;
					startchar = 2}
				else {
					compare = soap.constants.maxInt;
					maxchars = 10;
					startchar = 1};
				if sizeOf (cdata) > maxchars {
					scriptError ("Can't decode " + cdata + " as an integer because its size exceeds the maximum size for an integer.")};
				if sizeOf (cdata) == maxchars {
					for i = startchar to maxchars {
						if cdata[i] > compare[i] {
							scriptError ("Can't decode " + cdata + " as an integer because its value exceeds the maximum size for an integer.")};
						if cdata[i] < compare[i] {
							break}}}}; //optimization
			value = number (cdata)};
		"dateTime";
		"timeInstant" {
			local (multiplier = 1, isostring = soap.xmlutils.getCharacterData (adrelement));
			if isostring beginsWith "-" {
				isostring = string.delete (isostring, 1, 1);
				multiplier = -1};
			local (datestring = string.nthField (isostring, "T", 1));
			isostring = string.delete (isostring, 1, string.length (datestring) + 1);
			local (ixplus, ixminus, tzstring, timestring);
			ixplus = string.patternMatch ("+", isostring);
			ixminus = string.patternMatch ("-", isostring);
			if (ixminus > 0) and (ixplus > 0) {
				scripterror ("Can't decode \"" + soap.xmlutils.getElementName (adrelement) + "\" element because the format of the timeInstant was invalid.")};
			if (ixminus > 0) or (ixplus > 0) {
				local (ix = ixminus + ixplus);
				timestring = string.mid (isostring, 1, ix - 1);
				tzstring = string.delete (isostring, 1, ix)}
			else {
				timestring = isostring};
			local (year = multiplier * number (string.nthField (datestring, "-", 1)));
			local (month = number (string.nthField (datestring, "-", 2)));
			local (day = number (string.nthField (datestring, "-", 3)));
			local (hour = number (string.nthField (timestring, ":", 1)));
			local (minute = number (string.nthField (timestring, ":", 2)));
			local (second = number (string.mid (string.nthField (timestring, ":", 3), 1, 2)));
			local (tzoffset = 60 * (60 * number (string.nthField (tzstring, ":", 1)) + number (string.nthField (tzstring, ":", 2))));
			if ixminus {
				tzoffset = -1 * tzoffset};
			value = date.set (day, month, year, hour, minute, second) - tzoffset + date.getCurrentTimeZone ()};
		"date";
		"time";
		"timePeriod";
		"month";
		"year";
		"century";
		"timeDuration";
		"recurringDuration";
		"recurringDate";
		"recurringDay";
		"uriReference";
		"ID";
		"IREF";
		"ENTITY";
		"NOTATION";
		"QName";
		"language";
		"IDREFS";
		"ENTITIES";
		"NMTOKEN";
		"NMTOKENS";
		"Name";
		"NCName" {
			scripterror ("Can't decode SOAP element because support for the '" + type + "' type has not been implemented yet.")}};
	return (value)}



This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.