case nsIDataType::TYPE_WCHAR_STR:
case nsIDataType::VTYPE_WCHAR_STR:
static nsresult CloneArray(PRUint16 inType, const nsIID* inIID,                            PRUint32 inCount, void* inValue,                           PRUint16* outType, nsIID* outIID,                            PRUint32* outCount, void** outValue){    NS_ASSERTION(inCount, "bad param");    NS_ASSERTION(inValue, "bad param");    NS_ASSERTION(outType, "bad param");    NS_ASSERTION(outCount, "bad param");    NS_ASSERTION(outValue, "bad param");    PRUint32 allocatedValueCount = 0;    nsresult rv = NS_OK;    PRUint32 i;    // First we figure out the size of the elements for the new array.        size_t elementSize;    size_t allocSize;    switch(inType)    {        case nsIDataType::TYPE_INT8:                    elementSize = sizeof(PRInt8);             break;        case nsIDataType::TYPE_INT16:                    elementSize = sizeof(PRInt16);             break;        case nsIDataType::TYPE_INT32:                    elementSize = sizeof(PRInt32);             break;        case nsIDataType::TYPE_INT64:                    elementSize = sizeof(PRInt64);             break;        case nsIDataType::TYPE_UINT8:                    elementSize = sizeof(PRUint8);             break;        case nsIDataType::TYPE_UINT16:                    elementSize = sizeof(PRUint16);             break;        case nsIDataType::TYPE_UINT32:                    elementSize = sizeof(PRUint32);             break;        case nsIDataType::TYPE_UINT64:                    elementSize = sizeof(PRUint64);             break;        case nsIDataType::TYPE_FLOAT:                    elementSize = sizeof(float);             break;        case nsIDataType::TYPE_DOUBLE:                    elementSize = sizeof(double);             break;        case nsIDataType::TYPE_BOOL:                    elementSize = sizeof(PRBool);             break;        case nsIDataType::TYPE_CHAR:                    elementSize = sizeof(char);             break;        case nsIDataType::TYPE_WCHAR:                    elementSize = sizeof(PRUnichar);             break;        // XXX We ASSUME that "array of nsID" means "array of pointers to nsID".        case nsIDataType::TYPE_ID:                case nsIDataType::TYPE_CHAR_STR:                case nsIDataType::TYPE_WCHAR_STR:                case nsIDataType::TYPE_INTERFACE:                case nsIDataType::TYPE_INTERFACE_IS:                    elementSize = sizeof(void*);             break;        // The rest are illegal.        case nsIDataType::TYPE_ASTRING:                case nsIDataType::TYPE_STRING_SIZE_IS:                case nsIDataType::TYPE_WSTRING_SIZE_IS:                case nsIDataType::TYPE_VOID:                case nsIDataType::TYPE_ARRAY:        case nsIDataType::TYPE_EMPTY:        default:            NS_ERROR("bad type in array!");            return NS_ERROR_CANNOT_CONVERT_DATA;    }        // Alloc the array.    allocSize = inCount * elementSize;    *outValue = nsMemory::Alloc(allocSize);    if(!*outValue)        return NS_ERROR_OUT_OF_MEMORY;    // Clone the elements.    switch(inType)    {        case nsIDataType::TYPE_INT8:                case nsIDataType::TYPE_INT16:                case nsIDataType::TYPE_INT32:                case nsIDataType::TYPE_INT64:                case nsIDataType::TYPE_UINT8:                case nsIDataType::TYPE_UINT16:                case nsIDataType::TYPE_UINT32:                case nsIDataType::TYPE_UINT64:                case nsIDataType::TYPE_FLOAT:                case nsIDataType::TYPE_DOUBLE:                case nsIDataType::TYPE_BOOL:                case nsIDataType::TYPE_CHAR:                case nsIDataType::TYPE_WCHAR:                    memcpy(*outValue, inValue, allocSize);            break;        case nsIDataType::TYPE_INTERFACE_IS:                    if(outIID)                *outIID = *inIID;            // fall through...        case nsIDataType::TYPE_INTERFACE:                {            memcpy(*outValue, inValue, allocSize);                        nsISupports** p = (nsISupports**) *outValue;            for(i = inCount; i > 0; p++, i--)                if(*p)                    (*p)->AddRef();            break;        }        // XXX We ASSUME that "array of nsID" means "array of pointers to nsID".        case nsIDataType::TYPE_ID:        {            nsID** inp  = (nsID**) inValue;            nsID** outp = (nsID**) *outValue;            for(i = inCount; i > 0; i--)            {                nsID* idp = *(inp++);                if(idp)                {                    if(nsnull == (*(outp++) = (nsID*)                       nsMemory::Clone((char*)idp, sizeof(nsID))))                        goto bad;                }                else                    *(outp++) = nsnull;                allocatedValueCount++;            }            break;        }            case nsIDataType::TYPE_CHAR_STR:                {            char** inp  = (char**) inValue;            char** outp = (char**) *outValue;            for(i = inCount; i > 0; i--)            {                char* str = *(inp++);                if(str)                {                    if(nsnull == (*(outp++) = (char*)                       nsMemory::Clone(str, (strlen(str)+1)*sizeof(char))))                        goto bad;                }                else                    *(outp++) = nsnull;                allocatedValueCount++;            }            break;        }        case nsIDataType::TYPE_WCHAR_STR:                {            PRUnichar** inp  = (PRUnichar**) inValue;            PRUnichar** outp = (PRUnichar**) *outValue;            for(i = inCount; i > 0; i--)            {                PRUnichar* str = *(inp++);                if(str)                {                    if(nsnull == (*(outp++) = (PRUnichar*)                       nsMemory::Clone(str,                         (nsCRT::strlen(str)+1)*sizeof(PRUnichar))))                        goto bad;                }                else                    *(outp++) = nsnull;                allocatedValueCount++;            }            break;        }        // The rest are illegal.        case nsIDataType::TYPE_VOID:                case nsIDataType::TYPE_ARRAY:        case nsIDataType::TYPE_EMPTY:        case nsIDataType::TYPE_ASTRING:                case nsIDataType::TYPE_STRING_SIZE_IS:                case nsIDataType::TYPE_WSTRING_SIZE_IS:                default:            NS_ERROR("bad type in array!");            return NS_ERROR_CANNOT_CONVERT_DATA;    }    *outType = inType;    *outCount = inCount;    return NS_OK;bad:    if(*outValue)    {        char** p = (char**) *outValue;        for(i = allocatedValueCount; i > 0; p++, i--)            if(*p)                nsMemory::Free(*p);        nsMemory::Free((char*)*outValue);        *outValue = nsnull;    }    return rv;}