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.