886
case nsXPTType::T_PSTRING_SIZE_IS:
887
case nsXPTType::T_PWSTRING_SIZE_IS:
889
NS_PRECONDITION(!aIsArrayElement, "sized string array not supported");
891
LOG(("Sized string\n"));
892
jstring data = nsnull;
893
if (!aIsOut) { // 'in'
894
data = (jstring) aParam;
895
} else if (aParam) { // 'inout'
896
data = (jstring) env->GetObjectArrayElement((jobjectArray) aParam,
902
if (aType == nsXPTType::T_PSTRING_SIZE_IS) {
903
length = env->GetStringUTFLength(data);
905
length = env->GetStringLength(data);
907
if (length > aArraySize) {
908
rv = NS_ERROR_ILLEGAL_VALUE;
913
PRUint32 size_of_char = (aType == nsXPTType::T_PSTRING_SIZE_IS) ?
914
sizeof(char) : sizeof(jchar);
915
PRUint32 allocLength = (aArraySize + 1) * size_of_char;
916
void* buf = nsMemory::Alloc(allocLength);
918
rv = NS_ERROR_OUT_OF_MEMORY;
923
if (aType == nsXPTType::T_PSTRING_SIZE_IS) {
924
const char* str = env->GetStringUTFChars(data, nsnull);
927
rv = NS_ERROR_OUT_OF_MEMORY;
930
memcpy(buf, str, length);
931
env->ReleaseStringUTFChars(data, str);
933
jchar* jchar_str = NS_STATIC_CAST(jchar*, buf);
934
env->GetStringRegion(data, 0, length, jchar_str);
938
aVariant.val.p = buf;
939
if (aIsOut) { // 'inout'
940
aVariant.ptr = &aVariant.val;
941
aVariant.SetPtrIsData();
887
948
NS_WARNING("unexpected parameter type");
888
949
return NS_ERROR_UNEXPECTED;
1235
1296
// If this is not an out param or if the invokeResult is a failure case,
1236
1297
// then the array elements have not been cleaned up. Do so now.
1237
if (!aParamInfo.IsOut() || NS_FAILED(aInvokeResult)) {
1298
if (!aParamInfo.IsOut() || (NS_FAILED(aInvokeResult) && aVariant.val.p)) {
1238
1299
nsXPTCVariant var;
1239
1300
for (PRUint32 i = 0; i < aArraySize; i++) {
1240
1301
rv = GetNativeArrayElement(aArrayType, aVariant.val.p, i, &var);
1312
case nsXPTType::T_PSTRING_SIZE_IS:
1313
case nsXPTType::T_PWSTRING_SIZE_IS:
1315
NS_PRECONDITION(!aIsArrayElement, "sized string array not supported");
1317
if ((aParamInfo.IsOut()) && NS_SUCCEEDED(aInvokeResult))
1319
// create new string from data
1320
jstring str = nsnull;
1321
if (aVariant.val.p) {
1322
if (aType == nsXPTType::T_PSTRING_SIZE_IS) {
1323
PRUint32 len = (aArraySize + 1) * sizeof(char);
1324
char* buf = (char*) nsMemory::Alloc(len);
1326
memcpy(buf, aVariant.val.p, len);
1327
buf[aArraySize] = '\0';
1328
str = env->NewStringUTF((const char*) buf);
1329
nsMemory::Free(buf);
1332
str = env->NewString((const jchar*) aVariant.val.p, aArraySize);
1335
rv = NS_ERROR_OUT_OF_MEMORY;
1340
if (aParamInfo.IsRetval()) {
1342
} else if (*aParam) {
1343
// put new string into output array
1344
env->SetObjectArrayElement((jobjectArray) *aParam, aIndex, str);
1350
nsMemory::Free(aVariant.val.p);
1252
1355
NS_WARNING("unexpected parameter type");
1253
1356
return NS_ERROR_UNEXPECTED;
1406
1509
memset(params, 0, paramCount * sizeof(nsXPTCVariant));
1511
PRBool foundDependentParam = PR_FALSE;
1408
1512
for (PRUint8 i = 0; i < paramCount && NS_SUCCEEDED(rv); i++)
1410
1514
LOG(("\t Param %d: ", i));
1411
1515
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(i);
1412
1516
params[i].type = paramInfo.GetType();
1518
if (params[i].type.IsDependent() && paramInfo.IsIn()) {
1519
foundDependentParam = PR_TRUE;
1414
1523
if (paramInfo.IsIn()) {
1415
1524
PRUint8 type = params[i].type.TagPart();
1417
// is paramater an array?
1418
PRUint8 arrayType = 0;
1419
PRUint32 arraySize = 0;
1420
if (type == nsXPTType::T_ARRAY) {
1423
rv = iinfo->GetTypeForParam(methodIndex, ¶mInfo, 1, &xpttype);
1426
arrayType = xpttype.TagPart();
1428
// get size of array
1430
rv = iinfo->GetSizeIsArgNumberForParam(methodIndex, ¶mInfo, 0,
1434
arraySize = params[argnum].val.u32;
1437
1526
// get IID for interface params
1439
if (type == nsXPTType::T_INTERFACE ||
1440
type == nsXPTType::T_INTERFACE_IS ||
1441
type == nsXPTType::T_ARRAY &&
1442
(arrayType == nsXPTType::T_INTERFACE ||
1443
arrayType == nsXPTType::T_INTERFACE_IS))
1445
PRUint8 paramType = type == nsXPTType::T_ARRAY ? arrayType : type;
1446
rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, paramType,
1528
if (type == nsXPTType::T_INTERFACE) {
1529
rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, type,
1447
1530
methodIndex, params, PR_TRUE, iid);
1452
1535
if (aParams && !paramInfo.IsRetval()) {
1453
1536
param = env->GetObjectArrayElement(aParams, i);
1455
rv = SetupParams(env, param, type, paramInfo.IsOut(), iid, arrayType,
1456
arraySize, PR_FALSE, 0, params[i]);
1538
rv = SetupParams(env, param, type, paramInfo.IsOut(), iid, 0, 0,
1539
PR_FALSE, 0, params[i]);
1459
1542
LOG(("out/retval\n"));
1461
1544
params[i].SetPtrIsData();
1548
// Handle any dependent params by doing a second pass
1549
if (foundDependentParam) {
1551
for (PRUint8 j = 0; j < paramCount && NS_SUCCEEDED(rv); j++) {
1553
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(j);
1554
params[j].type = paramInfo.GetType();
1556
if (!params[j].type.IsDependent())
1559
if (paramInfo.IsIn()) {
1560
PRUint8 type = params[j].type.TagPart();
1562
// is paramater an array or sized string?
1563
PRUint8 arrayType = 0;
1564
PRUint32 arraySize = 0;
1565
PRBool isArray = params[j].type.IsArray();
1566
PRBool isSizedString = isArray ? PR_FALSE :
1567
type == nsXPTType::T_PSTRING_SIZE_IS ||
1568
type == nsXPTType::T_PWSTRING_SIZE_IS;
1573
rv = iinfo->GetTypeForParam(methodIndex, ¶mInfo, 1, &xpttype);
1576
arrayType = xpttype.TagPart();
1577
// IDL 'octet' arrays are not 'promoted' to short, but kept as 'byte';
1578
// therefore, treat as a signed 8bit value
1579
if (arrayType == nsXPTType::T_U8)
1580
arrayType = nsXPTType::T_I8;
1583
if (isArray || isSizedString) {
1584
// get size of array or string
1586
rv = iinfo->GetSizeIsArgNumberForParam(methodIndex, ¶mInfo, 0,
1590
arraySize = params[argnum].val.u32;
1593
// get IID for interface params
1595
if (type == nsXPTType::T_INTERFACE_IS ||
1596
type == nsXPTType::T_ARRAY &&
1597
(arrayType == nsXPTType::T_INTERFACE ||
1598
arrayType == nsXPTType::T_INTERFACE_IS))
1600
PRUint8 paramType = type == nsXPTType::T_ARRAY ? arrayType : type;
1601
rv = GetIIDForMethodParam(iinfo, methodInfo, paramInfo, paramType,
1602
methodIndex, params, PR_TRUE, iid);
1605
if (NS_SUCCEEDED(rv)) {
1606
jobject param = nsnull;
1607
if (aParams && !paramInfo.IsRetval()) {
1608
param = env->GetObjectArrayElement(aParams, j);
1610
rv = SetupParams(env, param, type, paramInfo.IsOut(), iid, arrayType,
1611
arraySize, PR_FALSE, 0, params[j]);
1464
1617
if (NS_FAILED(rv)) {
1465
1618
ThrowException(env, rv, "SetupParams failed");
1487
1640
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(i);
1488
1641
PRUint8 type = paramInfo.GetType().TagPart();
1490
// is paramater an array?
1643
// is paramater an array or sized string?
1491
1644
PRUint8 arrayType = 0;
1492
1645
PRUint32 arraySize = 0;
1493
if (type == nsXPTType::T_ARRAY) {
1646
PRBool isArray = params[i].type.IsArray();
1647
PRBool isSizedString = isArray ? PR_FALSE :
1648
type == nsXPTType::T_PSTRING_SIZE_IS ||
1649
type == nsXPTType::T_PWSTRING_SIZE_IS;
1494
1652
// get array type
1495
1653
nsXPTType array_xpttype;
1496
1654
rv = iinfo->GetTypeForParam(methodIndex, ¶mInfo, 1, &array_xpttype);
1497
1655
if (NS_FAILED(rv))
1499
1657
arrayType = array_xpttype.TagPart();
1658
// IDL 'octet' arrays are not 'promoted' to short, but kept as 'byte';
1659
// therefore, treat as a signed 8bit value
1660
if (arrayType == nsXPTType::T_U8)
1661
arrayType = nsXPTType::T_I8;
1664
if (isArray || isSizedString) {
1501
1665
// get size of array
1502
1666
PRUint8 argnum;
1503
1667
rv = iinfo->GetSizeIsArgNumberForParam(methodIndex, ¶mInfo, 0,
1530
1694
rv = FinalizeParams(env, paramInfo, type, params[i], iid, PR_FALSE,
1531
1695
arrayType, arraySize, 0, invokeResult, javaElement);
1533
if (NS_FAILED(rv)) {
1534
ThrowException(env, rv, "FinalizeParams failed");
1538
1698
// Normally, we would delete any created nsID object in the above loop.
1539
1699
// However, GetIIDForMethodParam may need some of the nsID params when it's
1540
1700
// looking for the IID of an INTERFACE_IS. Therefore, we can't delete it
1541
1701
// until we've gone through the 'Finalize' loop once and created the result.
1542
for (PRUint8 j = 0; j < paramCount && NS_SUCCEEDED(rv); j++)
1702
for (PRUint8 j = 0; j < paramCount; j++)
1544
1704
const nsXPTParamInfo ¶mInfo = methodInfo->GetParam(j);
1545
1705
const nsXPTType &type = paramInfo.GetType();
1561
1721
message.AppendLiteral("\" returned an error condition");
1562
1722
ThrowException(env, invokeResult, message.get());
1724
if (NS_FAILED(rv)) {
1725
ThrowException(env, rv, "FinalizeParams failed");
1565
1729
LOG(("<=== (XPCOM) %s::%s()\n", ifaceName, methodInfo->GetName()));