Monday, November 08, 2010 at 12:05 AM.
system.verbs.builtins.soap.decode.array
on array (adrmsg, adrelement, arraytype, flEnforceSimpleTypes=true) { <<Changes: <<03/19/01; 3:23:07 PM by JES <<Added support for decoding arrays of structs. <<03/25/01; 10:01:48 PM by JES <<Fixed a problem with decoding simple arrays, which was caused by changes for decoding arrays of structs. <<04/05/01; 6:53:36 PM by JES <<When decoding an array of structs, decode using soap.decode.main, instead of soap.decode.struct. Allows elements to be decoded by reference, as well as in-place. New optional parameter, flEnforceSimpleTypes, specifies whether to fault on elements whose type is not specified. This is passed to soap.decode.main. <<04/10/01; 5:27:24 PM by JES <<Bug fix: one of the calls to soap.decode.simpleType was passing in too many parameters. <<04/30/01; 5:16:19 PM by JES <<Fixed a bug decoding mixed-type arrays, where the type of the array is specified as ur-type or anyType. local (rank = 1, size, flsizeknown = false, fltypeknown = true, resultlist = {}); bundle { //extract size local (ix = string.length (arraytype)); while (--ix > 0) { if arraytype[ix] == "[" { size = number (string.popTrailing (string.popLeading (string.delete (arraytype, 1, ix-1), "["), "]")); flsizeknown = true; arraytype = string.mid (arraytype, 1, ix-1); break}}; if ix == 0 { scripterror ("Can't decode the array \"" + soap.xmlutils.getElementName (adrelement) + "\" because the size could not be determined.")}}; bundle { //extract rank local (s, ix = string.length (arraytype)); while (--ix > 0) { if arraytype[ix] == "[" { s = string.popTrailing (string.popLeading (string.delete (arraytype, 1, ix-1), "["), "]"); arraytype = string.mid (arraytype, 1, ix-1); break}}; if ix > 0 { for ix = 1 to sizeof (s) { if s[ix] == "," { rank++}}}; if rank > 1 { scripterror ("Can't decode array \"" + soap.xmlutils.getElementName (adrelement) + "\" because multi-dimensional arrays are not supported by this implementation.")}}; bundle { //pre-fill the list local (ix); for ix = 1 to size { resultlist = resultlist + nil}}; if arraytype == soap.xmlutils.setQualifiedName (adrmsg, "ur-type", soap.constants.nsSchemaDataURI) { fltypeknown = false}; local (offset = soap.xmlutils.getAttributeValue (adrelement, soap.xmlutils.setQualifiedName (adrmsg, "offset", soap.constants.nsEncodingURI))); if offset { offset = number (string.popTrailing (string.popLeading (offset, "["), "]"))} else { offset = 0}; local (ix = 1, nomad = soap.xmlutils.getFirstChildElement (adrelement)); while nomad { local (adrarrayelement = soap.xmlutils.resolveHref (adrmsg, nomad)); local (position = soap.xmlutils.getAttributeValue (adrarrayelement, soap.xmlutils.setQualifiedName (adrmsg, "position", soap.constants.nsEncodingURI))); if position { position = number (string.popTrailing (string.popLeading (position, "["), "]"))} else { position = offset + (ix++)}; if position > size { scripterror ("Can't decode the array \"" + soap.xmlutils.getElementName (adrelement) + "\" because the specified array size is smaller than the actual size.")}; if fltypeknown { if system.verbs.builtins.soap.xmlutils.hasChildren (adrarrayelement) { //complex type if typeOf (resultlist) == listType { new (tableType, @resultlist)}; local (name = string.nthField (arrayType, ":", 2) + string.padWithZeros (position, 7)); resultlist.[name] = soap.decode.main (adrmsg, adrarrayelement, flEnforceSimpleTypes)} else { //simpleType case arrayType { //call soap.decode.main for mixed-type arrays "ur-type"; "anyType" { resultlist[position] = soap.decode.main (adrmsg, adrarrayelement, flEnforceSimpleTypes)}} else { //call soap.decode.simpleType, for single-type arrays resultlist[position] = soap.decode.simpleType (adrmsg, adrarrayelement, arraytype)}}} <<bundle //old code for dealing with arrays of structs <<try //simple type <<resultlist[position] = soap.decode.simpleType (adrmsg, adrarrayelement, arraytype) <<else //03/25/2001 JES: simple-type decoding failed -- assume it's an array of structs <<if typeOf (resultlist) == listType <<new (tableType, @resultlist) <<local (name = string.nthField (arrayType, ":", 2) + string.padWithZeros (position, 7)) <<resultlist.[name] = soap.decode.struct (adrmsg, adrarrayelement, flEnforceSimpleTypes) <<resultlist.[name] = soap.decode.main (adrmsg, adrarrayelement, flEnforceSimpleTypes) else { local (type = soap.xmlutils.getAttributeValue (adrarrayelement, soap.xmlutils.setQualifiedName (adrmsg, "type", soap.constants.nsSchemaURI))); if type { resultlist[position] = soap.decode.simpleType (adrmsg, adrarrayelement, type)} else { scripterror ("Can't decode an element of array \"" + soap.xmlutils.getElementName (adrelement) + "\" because no type was specified.")}}; nomad = soap.xmlutils.getNextSiblingElement (nomad)}; return (resultlist)}
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.