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.