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.