values[i]->Release();
NS_RELEASE(values[i]);
static nsresult EncodeArray(nsISOAPEncoding* aEncoding, nsIVariant* aSource, nsISchemaType* aSchemaType,  nsISOAPAttachments* aAttachments, nsIDOMElement* aArray, PRUint32 aDimensionCount, PRUint32* aDimensionSizes){  nsresult rc;  PRUint16 type;  nsIID iid;  PRUint32 count;  void *array;  if (aSource != nsnull) {    rc = aSource->GetAsArray(&type, &iid, &count, &array);        // First, get the array, if any.    if (NS_FAILED(rc))      return rc;  }  else {  //  If the source is null, then just add a bunch of nulls to the array.    count = (PRUint32)aDimensionSizes[--aDimensionCount];    while (aDimensionCount)      count *= (PRUint32)aDimensionSizes[--aDimensionCount];    if (count) {      nsAutoString ns;      nsCOMPtr<nsIDOMElement> cloneable;      rc = aEncoding->GetExternalSchemaURI(nsSOAPUtils::kXSIURI, ns);      if (NS_FAILED(rc))        return rc;      rc = EncodeSimpleValue(aEncoding, kEmpty, kEmpty,         kNull, nsnull, aArray, getter_AddRefs(cloneable));      if (NS_FAILED(rc))        return rc;      rc = cloneable->SetAttributeNS(ns, kNull, nsSOAPUtils::kTrueA);      if (NS_FAILED(rc))        return rc;      nsCOMPtr<nsIDOMNode> clone;      nsCOMPtr<nsIDOMNode> dummy;      for (;--count;) {        rc = cloneable->CloneNode(PR_TRUE, getter_AddRefs(clone));// No children so deep == shallow        if (NS_FAILED(rc))          return rc;        rc = aArray->AppendChild(clone, getter_AddRefs(dummy));        if (NS_FAILED(rc))          return rc;      }    }  }  nsCOMPtr<nsIDOMElement> dummy;  PRBool freeptrs = PR_FALSE;  PRUint32 i;//  The more-robust way of encoding is to construct variants and call the encoder directly,//  but for now, we short-circuit it for simple types.#define ENCODE_SIMPLE_ARRAY(XPType, VType, Source) \      {\        XPType* values = NS_STATIC_CAST(XPType*, array);\        nsCOMPtr < nsIWritableVariant > p =\           do_CreateInstance(NS_VARIANT_CONTRACTID, &rc);\        for (i = 0; i < count; i++) {\          if (NS_FAILED(rc))\            break;\          rc = p->SetAs##VType(Source);\          if (NS_FAILED(rc))\            break;\          rc = aEncoding->Encode(p,\                       kEmpty,\                       kEmpty,\                       aSchemaType,\                       aAttachments,\                       aArray,\                       getter_AddRefs(dummy));\          if (NS_FAILED(rc)) break;\        }\        break;\      }  if (aDimensionCount > 1) {    switch (type) {      case nsIDataType::VTYPE_INTERFACE_IS:        {          nsIVariant** values = NS_STATIC_CAST(nsIVariant**, array);//  If not truly a variant, we only release.          if (iid.Equals(NS_GET_IID(nsIVariant))) {  //  Only do variants for now.            for (i = 0; i < count; i++) {              rc = EncodeArray(aEncoding, values[i],                             aSchemaType,                             aAttachments,                             aArray,                             aDimensionCount - 1,                             aDimensionSizes + 1);              if (NS_FAILED(rc)) break;            }          }          for (i = 0; i < count; i++)          values[i]->Release();          break;        }      case nsIDataType::VTYPE_WCHAR_STR:      case nsIDataType::VTYPE_CHAR_STR:        freeptrs = PR_TRUE;      default:        rc = SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE,"SOAP_ARRAY_OBJECTS","When encoding as an array, an array of array objects is required");    }  } else switch (type) {    case nsIDataType::VTYPE_INT8:      ENCODE_SIMPLE_ARRAY(PRUint8, Int8,                      (PRInt16) (signed char) values[i]);    case nsIDataType::VTYPE_INT16:      ENCODE_SIMPLE_ARRAY(PRInt16, Int16, values[i]);    case nsIDataType::VTYPE_INT32:      ENCODE_SIMPLE_ARRAY(PRInt32, Int32, values[i]);    case nsIDataType::VTYPE_INT64:      ENCODE_SIMPLE_ARRAY(PRInt64, Int64, values[i]);    case nsIDataType::VTYPE_UINT8:      ENCODE_SIMPLE_ARRAY(PRUint8, Uint8, (PRUint16) values[i]);    case nsIDataType::VTYPE_UINT16:      ENCODE_SIMPLE_ARRAY(PRUint16, Uint16, values[i]);    case nsIDataType::VTYPE_UINT32:      ENCODE_SIMPLE_ARRAY(PRUint32, Uint32, values[i]);    case nsIDataType::VTYPE_UINT64:      ENCODE_SIMPLE_ARRAY(PRUint64, Uint64, values[i]);    case nsIDataType::VTYPE_FLOAT:      ENCODE_SIMPLE_ARRAY(float, Float, values[i]);    case nsIDataType::VTYPE_DOUBLE:      ENCODE_SIMPLE_ARRAY(double, Double, values[i]);    case nsIDataType::VTYPE_BOOL:      ENCODE_SIMPLE_ARRAY(PRBool, Bool, (PRUint16) values[i]);    case nsIDataType::VTYPE_ID:    case nsIDataType::VTYPE_CHAR_STR:      freeptrs = PR_TRUE;      ENCODE_SIMPLE_ARRAY(char *, String, values[i]);    case nsIDataType::VTYPE_WCHAR_STR:      freeptrs = PR_TRUE;      ENCODE_SIMPLE_ARRAY(PRUnichar *, WString, values[i]);    case nsIDataType::VTYPE_CHAR:      ENCODE_SIMPLE_ARRAY(char, Char, values[i]);    case nsIDataType::VTYPE_WCHAR:      ENCODE_SIMPLE_ARRAY(PRUnichar, WChar, values[i]);    case nsIDataType::VTYPE_INTERFACE_IS:      {        nsIVariant** values = NS_STATIC_CAST(nsIVariant**, array);//  If not truly a variant, we only use as nsISupports        if (iid.Equals(NS_GET_IID(nsIVariant))) {  //  Only do variants for now.          for (i = 0; i < count; i++) {            rc = aEncoding->Encode(values[i],                           kEmpty,                           kEmpty,                           aSchemaType,                           aAttachments,                           aArray,                           getter_AddRefs(dummy));            if (NS_FAILED(rc)) break;          }        }        else {          nsCOMPtr < nsIWritableVariant > p =            do_CreateInstance(NS_VARIANT_CONTRACTID, &rc);          for (i = 0; i < count; i++) {            if (NS_FAILED(rc))              break;            rc = p->SetAsInterface(iid, values[i]);            if (NS_FAILED(rc))              break;            rc = aEncoding->Encode(p,                           kEmpty,                           kEmpty,                           aSchemaType,                           aAttachments,                           aArray,                           getter_AddRefs(dummy));            if (NS_FAILED(rc)) break;          }        }        for (i = 0; i < count; i++)          values[i]->Release();        break;      }      case nsIDataType::VTYPE_EMPTY:      break;  //  I think an empty array needs no elements?  //  Don't support these array types, as they seem meaningless.    case nsIDataType::VTYPE_ASTRING:    case nsIDataType::VTYPE_VOID:    case nsIDataType::VTYPE_INTERFACE:    case nsIDataType::VTYPE_ARRAY:      rc = SOAP_EXCEPTION(NS_ERROR_ILLEGAL_VALUE,"SOAP_ARRAY_TYPES","When encoding an array, unable to handle array elements");  }  if (freeptrs) {    void** ptrs = NS_STATIC_CAST(void**,array);    for (i = 0; i < count; i++) {      nsMemory::Free(ptrs[i]);    }    nsMemory::Free(array);  }//  We know that count does not exceed size of dimension, but it may be less  return rc;}