00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00042 #include "TclXPCOMPrivate.h"
00043 #include "nsAString.h"
00044 #include "nsReadableUtils.h"
00045
00046
00047
00054 size_t
00055 GetElementTypeSize(
00056 nsXPTType *type
00057 )
00058 {
00059 size_t size;
00060
00061
00062
00063 if (type->IsPointer())
00064 {
00065 size = sizeof(void*);
00066 } else
00067 {
00068 switch (type->TagPart())
00069 {
00070 case nsXPTType::T_I8:
00071 size = sizeof(PRInt8);
00072 break;
00073 case nsXPTType::T_I16:
00074 size = sizeof(PRInt16);
00075 break;
00076 case nsXPTType::T_I32:
00077 size = sizeof(PRInt32);
00078 break;
00079 case nsXPTType::T_I64:
00080 size = sizeof(PRInt64);
00081 break;
00082 case nsXPTType::T_U8:
00083 size = sizeof(PRUint8);
00084 break;
00085 case nsXPTType::T_U16:
00086 size = sizeof(PRUint16);
00087 break;
00088 case nsXPTType::T_U32:
00089 size = sizeof(PRUint32);
00090 break;
00091 case nsXPTType::T_U64:
00092 size = sizeof(PRUint64);
00093 break;
00094 case nsXPTType::T_FLOAT:
00095 size = sizeof(float);
00096 break;
00097 case nsXPTType::T_DOUBLE:
00098 size = sizeof(double);
00099 break;
00100 case nsXPTType::T_BOOL:
00101 size = sizeof(PRBool);
00102 break;
00103 case nsXPTType::T_CHAR:
00104 size = sizeof(char);
00105 break;
00106 case nsXPTType::T_WCHAR:
00107 size = sizeof(PRUnichar);
00108 break;
00109
00110 case nsXPTType::T_VOID:
00111 default:
00112 NS_ERROR("invalid type");
00113 size = 0;
00114 break;
00115 }
00116 }
00117 return size;
00118 }
00119
00120
00127 void
00128 CleanupParam(
00129 void **params,
00130 void *param,
00131 nsXPTType *type,
00132 nsIInterfaceInfo *interfaceinfo,
00133 PRUint16 methodindex,
00134 nsXPTParamInfo *paraminfo
00135 )
00136 {
00137 PRUint32 i, j;
00138 size_t elementsize;
00139 PRUint8 lengthindex;
00140 nsXPTType arraytype;
00141 nsISupports *isupports;
00142
00143 NS_PRECONDITION(params, "null pointer");
00144 NS_PRECONDITION(param, "null pointer");
00145 NS_PRECONDITION(type, "null pointer");
00146 NS_PRECONDITION(interfaceinfo, "null pointer");
00147 NS_PRECONDITION(paraminfo, "null pointer");
00148
00149 if (type->IsPointer() && (*(void **)param != NULL))
00150 {
00151 switch (type->TagPart())
00152 {
00153 case nsXPTType::T_VOID:
00154
00155 break;
00156
00157 case nsXPTType::T_ASTRING:
00158 case nsXPTType::T_DOMSTRING:
00159 delete *(nsAString **)param;
00160 break;
00161
00162 case nsXPTType::T_CSTRING:
00163 case nsXPTType::T_UTF8STRING:
00164 delete *(nsACString **)param;
00165 break;
00166
00167 case nsXPTType::T_INTERFACE:
00168 case nsXPTType::T_INTERFACE_IS:
00169 isupports = *(nsISupports **)param;
00170 NS_RELEASE(isupports);
00171 break;
00172
00173 case nsXPTType::T_ARRAY:
00174 interfaceinfo->GetTypeForParam(methodindex, paraminfo, 1, &arraytype);
00175 interfaceinfo->GetLengthIsArgNumberForParam(methodindex, paraminfo, 0, &lengthindex);
00176 elementsize = GetElementTypeSize(&arraytype);
00177 j = *(PRUint32 *)params[lengthindex];
00178 for (i = 0; i < j; i++)
00179 {
00180 CleanupParam(params, (void *)(*(char **)param + (i * elementsize)), &arraytype, interfaceinfo, methodindex, paraminfo);
00181 }
00182 memmgr->Free(*(void **)param);
00183 break;
00184
00185 default:
00186 if (!paraminfo->IsShared())
00187 {
00188 memmgr->Free(*(void **)param);
00189 }
00190 break;
00191 }
00192 }
00193 }
00194
00195
00203 nsresult
00204 Native2Tcl(
00205 void **params,
00206 void *param,
00207 nsXPTType *type,
00208 nsIInterfaceInfo *interfaceinfo,
00209 PRUint16 methodindex,
00210 nsXPTParamInfo *paraminfo,
00211 Tcl_Obj **result
00212 )
00213 {
00214 nsresult res;
00215 PRUint32 i, j;
00216 PRUint8 lengthindex, iidindex;
00217 size_t elementsize;
00218 Tcl_Obj *listitem;
00219 nsXPTType arraytype;
00220 nsIID *iid;
00221 nsAString *astr;
00222 nsACString *acstr;
00223 char *charPtr;
00224 PRUnichar *wcharPtr;
00225 nsIInterfaceInfo *tempinfo;
00226
00227 NS_PRECONDITION(params, "null pointer");
00228 NS_PRECONDITION(param, "null pointer");
00229 NS_PRECONDITION(type, "null pointer");
00230
00231
00232
00233
00234 NS_PRECONDITION(result, "null pointer");
00235
00236 if (!(type->IsPointer()))
00237 {
00238 switch (type->TagPart())
00239 {
00240 case nsXPTType::T_I8:
00241 *result = Tcl_NewIntObj((int)*(PRInt8 *)param);
00242 break;
00243
00244 case nsXPTType::T_I16:
00245 *result = Tcl_NewIntObj((int)*(PRInt16 *)param);
00246 break;
00247
00248 case nsXPTType::T_I32:
00249 *result = Tcl_NewLongObj((long)*(PRInt32 *)param);
00250 break;
00251
00252 case nsXPTType::T_I64:
00253 *result = TclXPCOM_NewWideIntObj((TclXPCOM_WideInt)*(PRInt64 *)param);
00254 break;
00255
00256 case nsXPTType::T_U8:
00257 *result = Tcl_NewIntObj((int)*(PRUint8 *)param);
00258 break;
00259
00260 case nsXPTType::T_U16:
00261 *result = Tcl_NewIntObj((int)*(PRUint16 *)param);
00262 break;
00263
00264 case nsXPTType::T_U32:
00265 *result = Tcl_NewLongObj((long)*(PRUint32 *)param);
00266 break;
00267
00268 case nsXPTType::T_U64:
00269 *result = TclXPCOM_NewWideIntObj((TclXPCOM_WideInt)*(PRUint64 *)param);
00270 break;
00271
00272 case nsXPTType::T_FLOAT:
00273 *result = Tcl_NewDoubleObj((double)*(float *)param);
00274 break;
00275
00276 case nsXPTType::T_DOUBLE:
00277 *result = Tcl_NewDoubleObj(*(double *)param);
00278 break;
00279
00280 case nsXPTType::T_BOOL:
00281 *result = Tcl_NewBooleanObj((int)*(PRBool *)param);
00282 break;
00283
00284 case nsXPTType::T_CHAR:
00285 *result = Tcl_NewStringObj((char *)param, 1);
00286 break;
00287
00288 case nsXPTType::T_WCHAR:
00289 *result = Tcl_NewUnicodeObj((Tcl_UniChar *)param, 1);
00290 break;
00291
00292 case nsXPTType::T_VOID:
00293 *result = Tcl_NewStringObj("", -1);
00294 break;
00295
00296 default:
00297
00298 *result = NULL;
00299 return NS_ERROR_INVALID_ARG;
00300 break;
00301 }
00302 } else
00303 {
00304 if (*(void **)param == NULL)
00305 {
00306 if (type->IsReference())
00307 {
00308
00309 *result = NULL;
00310 return NS_ERROR_NULL_POINTER;
00311 } else
00312 {
00313 *result = TclXPCOM_NewPointerObj(NULL);
00314 return NS_OK;
00315 }
00316 }
00317
00318 switch (type->TagPart())
00319 {
00320 case nsXPTType::T_ASTRING:
00321 case nsXPTType::T_DOMSTRING:
00322 if ((*(nsAString **)param)->IsVoid())
00323 {
00324 *result = TclXPCOM_NewPointerObj(NULL);
00325 return NS_OK;
00326 }
00327 break;
00328
00329 case nsXPTType::T_CSTRING:
00330 case nsXPTType::T_UTF8STRING:
00331 if ((*(nsACString **)param)->IsVoid())
00332 {
00333 *result = TclXPCOM_NewPointerObj(NULL);
00334 return NS_OK;
00335 }
00336 break;
00337
00338 default:
00339 break;
00340 }
00341
00342 switch (type->TagPart())
00343 {
00344 case nsXPTType::T_I8:
00345 *result = Tcl_NewIntObj((int)**(PRInt8 **)param);
00346 break;
00347
00348 case nsXPTType::T_I16:
00349 *result = Tcl_NewIntObj((int)**(PRInt16 **)param);
00350 break;
00351
00352 case nsXPTType::T_I32:
00353 *result = Tcl_NewLongObj((long)**(PRInt32 **)param);
00354 break;
00355
00356 case nsXPTType::T_I64:
00357 *result = TclXPCOM_NewWideIntObj((TclXPCOM_WideInt)**(PRInt64 **)param);
00358 break;
00359
00360 case nsXPTType::T_U8:
00361 *result = Tcl_NewIntObj((int)**(PRUint8 **)param);
00362 break;
00363
00364 case nsXPTType::T_U16:
00365 *result = Tcl_NewIntObj((int)**(PRUint16 **)param);
00366 break;
00367
00368 case nsXPTType::T_U32:
00369 *result = Tcl_NewLongObj((long)**(PRUint32 **)param);
00370 break;
00371
00372 case nsXPTType::T_U64:
00373 *result = TclXPCOM_NewWideIntObj((TclXPCOM_WideInt)**(PRUint64 **)param);
00374 break;
00375
00376 case nsXPTType::T_FLOAT:
00377 *result = Tcl_NewDoubleObj((double)**(float **)param);
00378 break;
00379
00380 case nsXPTType::T_DOUBLE:
00381 *result = Tcl_NewDoubleObj(**(double **)param);
00382 break;
00383
00384 case nsXPTType::T_BOOL:
00385 *result = Tcl_NewBooleanObj((int)**(PRBool **)param);
00386 break;
00387
00388 case nsXPTType::T_CHAR:
00389 *result = Tcl_NewStringObj(*(char **)param, 1);
00390 break;
00391
00392 case nsXPTType::T_WCHAR:
00393 *result = Tcl_NewUnicodeObj(*(Tcl_UniChar **)param, 1);
00394 break;
00395
00396 case nsXPTType::T_VOID:
00397 *result = TclXPCOM_NewPointerObj(*(void **)param);
00398 break;
00399
00400 case nsXPTType::T_IID:
00401 *result = TclXPCOM_NewNsIDObj(*(nsID **)param);
00402 break;
00403
00404 case nsXPTType::T_ASTRING:
00405 case nsXPTType::T_DOMSTRING:
00406
00407 astr = *(nsAString **)param;
00408 wcharPtr = ToNewUnicode(*astr);
00409 *result = Tcl_NewUnicodeObj((Tcl_UniChar *)wcharPtr, astr->Length());
00410 memmgr->Free(wcharPtr);
00411 break;
00412
00413 case nsXPTType::T_CSTRING:
00414 case nsXPTType::T_UTF8STRING:
00415
00416 acstr = *(nsACString **)param;
00417 charPtr = ToNewCString(*acstr);
00418 *result = Tcl_NewStringObj(charPtr, acstr->Length());
00419 memmgr->Free(charPtr);
00420 break;
00421
00422 case nsXPTType::T_CHAR_STR:
00423 *result = Tcl_NewStringObj(*(char **)param, -1);
00424 break;
00425
00426 case nsXPTType::T_WCHAR_STR:
00427 *result = Tcl_NewUnicodeObj(*(Tcl_UniChar **)param, -1);
00428 break;
00429
00430 case nsXPTType::T_INTERFACE:
00431 res = interfaceinfo->GetInfoForParam(methodindex, paraminfo, &tempinfo);
00432 NS_ASSERTION((NS_SUCCEEDED(res)), "GetInfoForParam failed");
00433
00434 *result = TclXPCOM_NewISupportsObj(*(nsISupports **)param, tempinfo);
00435 NS_RELEASE(tempinfo);
00436 break;
00437
00438 case nsXPTType::T_INTERFACE_IS:
00439 interfaceinfo->GetInterfaceIsArgNumberForParam(methodindex, paraminfo, &iidindex);
00440 iid = *(nsIID **)params[iidindex];
00441
00442
00443 res = manager->GetInfoForIID(iid, &tempinfo);
00444 NS_ASSERTION((NS_SUCCEEDED(res)), "GetInfoForIID failed");
00445
00446 *result = TclXPCOM_NewISupportsObj(*(nsISupports **)param, tempinfo);
00447 NS_RELEASE(tempinfo);
00448 break;
00449
00450 case nsXPTType::T_ARRAY:
00451 interfaceinfo->GetTypeForParam(methodindex, paraminfo, 1, &arraytype);
00452 elementsize = GetElementTypeSize(&arraytype);
00453 interfaceinfo->GetLengthIsArgNumberForParam(methodindex, paraminfo, 0, &lengthindex);
00454 j = *(PRUint32 *)params[lengthindex];
00455 *result = Tcl_NewListObj(0, NULL);
00456 for (i = 0; i < j; i++)
00457 {
00458 res = Native2Tcl(params, (void *)(*(char **)param + (i * elementsize)), &arraytype, interfaceinfo, methodindex, paraminfo, &listitem);
00459 if (NS_FAILED(res))
00460 {
00461 Tcl_DecrRefCount(*result);
00462 *result = NULL;
00463 return res;
00464 }
00465
00466 Tcl_ListObjAppendElement(NULL, *result, listitem);
00467 }
00468 break;
00469
00470 case nsXPTType::T_PSTRING_SIZE_IS:
00471 interfaceinfo->GetLengthIsArgNumberForParam(methodindex, paraminfo, 0, &lengthindex);
00472 *result = Tcl_NewStringObj(*(char **)param, (int)*(PRUint32 *)params[lengthindex]);
00473 break;
00474
00475 case nsXPTType::T_PWSTRING_SIZE_IS:
00476 interfaceinfo->GetLengthIsArgNumberForParam(methodindex, paraminfo, 0, &lengthindex);
00477 *result = Tcl_NewUnicodeObj(*(Tcl_UniChar **)param, (int)*(PRUint32 *)params[lengthindex]);
00478 break;
00479
00480 default:
00481
00482 *result = NULL;
00483 return NS_ERROR_INVALID_ARG;
00484 break;
00485 }
00486 }
00487
00488 return NS_OK;
00489 }
00490
00491
00501 int
00502 Tcl2Native(
00503 Tcl_Interp *interp,
00504 Tcl_Obj *value,
00505 void **params,
00506 void *param,
00507 nsXPTType *type,
00508 int shared,
00509 nsIInterfaceInfo *interfaceinfo,
00510 PRUint16 methodindex,
00511 nsXPTParamInfo *paraminfo
00512 )
00513 {
00514 int rv;
00515 nsresult res;
00516 PRUint32 i, length;
00517 PRUint8 sizeindex, lengthindex, iidindex;
00518 size_t elementsize;
00519 int intVal;
00520 long longVal;
00521 double doubleVal;
00522 TclXPCOM_WideInt wideVal;
00523 nsIID *iidPtr;
00524 char *charPtr, *utf8str;
00525 Tcl_Obj **listPtr;
00526 char str[128];
00527 nsXPTType arraytype;
00528 nsIInterfaceInfo *tempinfo;
00529 nsISupports *isupports;
00530 int numbytes;
00531
00532 NS_PRECONDITION(interp, "null pointer");
00533 NS_PRECONDITION(value, "null pointer");
00534 NS_PRECONDITION(params, "null pointer");
00535 NS_PRECONDITION(param, "null pointer");
00536 NS_PRECONDITION(type, "null pointer");
00537
00538 NS_PRECONDITION(interfaceinfo, "null pointer");
00539 NS_PRECONDITION(paraminfo, "null pointer");
00540
00541 if (!(type->IsPointer()))
00542 {
00543 switch (type->TagPart())
00544 {
00545 case nsXPTType::T_I8:
00546 rv = Tcl_GetIntFromObj(interp, value, &intVal);
00547 if (rv == TCL_OK)
00548 {
00549 *(PRInt8 *)param = (PRInt8)intVal;
00550 }
00551 break;
00552
00553 case nsXPTType::T_I16:
00554 rv = Tcl_GetIntFromObj(interp, value, &intVal);
00555 if (rv == TCL_OK)
00556 {
00557 *(PRInt16 *)param = (PRInt16)intVal;
00558 }
00559 break;
00560
00561 case nsXPTType::T_I32:
00562 rv = Tcl_GetLongFromObj(interp, value, &longVal);
00563 if (rv == TCL_OK)
00564 {
00565 *(PRInt32 *)param = (PRInt32)longVal;
00566 }
00567 break;
00568
00569 case nsXPTType::T_I64:
00570 rv = TclXPCOM_GetWideIntFromObj(interp, value, &wideVal);
00571 if (rv == TCL_OK)
00572 {
00573 *(PRInt64 *)param = (PRInt64)wideVal;
00574 }
00575 break;
00576
00577 case nsXPTType::T_U8:
00578 rv = Tcl_GetIntFromObj(interp, value, &intVal);
00579 if (rv == TCL_OK)
00580 {
00581 *(PRUint8 *)param = (PRUint8)intVal;
00582 }
00583 break;
00584
00585 case nsXPTType::T_U16:
00586 rv = Tcl_GetIntFromObj(interp, value, &intVal);
00587 if (rv == TCL_OK)
00588 {
00589 *(PRUint16 *)param = (PRUint16)intVal;
00590 }
00591 break;
00592
00593 case nsXPTType::T_U32:
00594 rv = Tcl_GetLongFromObj(interp, value, &longVal);
00595 if (rv == TCL_OK)
00596 {
00597 *(PRUint32 *)param = (PRUint32)longVal;
00598 }
00599 break;
00600
00601 case nsXPTType::T_U64:
00602 rv = TclXPCOM_GetWideIntFromObj(interp, value, &wideVal);
00603 if (rv == TCL_OK)
00604 {
00605 *(PRUint64 *)param = (PRUint64)wideVal;
00606 }
00607 break;
00608
00609 case nsXPTType::T_FLOAT:
00610 rv = Tcl_GetDoubleFromObj(interp, value, &doubleVal);
00611 if (rv == TCL_OK)
00612 {
00613 *(float *)param = (float)doubleVal;
00614 }
00615 break;
00616
00617 case nsXPTType::T_DOUBLE:
00618 rv = Tcl_GetDoubleFromObj(interp, value, &doubleVal);
00619 if (rv == TCL_OK)
00620 {
00621 *(double *)param = doubleVal;
00622 }
00623 break;
00624
00625 case nsXPTType::T_BOOL:
00626 rv = Tcl_GetBooleanFromObj(interp, value, &intVal);
00627 if (rv == TCL_OK)
00628 {
00629 *(PRBool *)param = (PRBool)intVal;
00630 }
00631 break;
00632
00633 case nsXPTType::T_CHAR:
00634 if (Tcl_GetCharLength(value) != 1)
00635 {
00636 Tcl_ResetResult(interp);
00637 Tcl_AppendResult(interp, "parameter must be a single character", NULL);
00638 rv = TCL_ERROR;
00639 } else
00640 {
00641 utf8str = Tcl_GetStringFromObj(value, &numbytes);
00642 rv = Tcl_UtfToExternal(interp, ascii_enc, utf8str, numbytes, 0, NULL, str, 2, NULL, NULL, NULL);
00643 if (rv == TCL_OK)
00644 {
00645 *(char *)param = str[0];
00646 }
00647 }
00648 break;
00649
00650 case nsXPTType::T_WCHAR:
00651 if (Tcl_GetCharLength(value) != 1)
00652 {
00653 Tcl_ResetResult(interp);
00654 Tcl_AppendResult(interp, "parameter must be a single character", NULL);
00655 rv = TCL_ERROR;
00656 } else
00657 {
00658 *(PRUnichar *)param = (PRUnichar)*Tcl_GetUnicode(value);
00659 rv = TCL_OK;
00660 }
00661 break;
00662
00663 case nsXPTType::T_VOID:
00664
00665 rv = TCL_OK;
00666 break;
00667
00668 default:
00669
00670 TclXPCOM_SetError(interp, NS_ERROR_INVALID_ARG);
00671 rv = TCL_ERROR;
00672 break;
00673 }
00674 } else
00675 {
00676 if (TclXPCOM_IsNULL(value))
00677 {
00678 switch (type->TagPart())
00679 {
00680 case nsXPTType::T_ASTRING:
00681 case nsXPTType::T_DOMSTRING:
00682 (*(nsAString **)param)->Truncate();
00683 (*(nsAString **)param)->SetIsVoid(PR_TRUE);
00684 rv = TCL_OK;
00685 break;
00686
00687 case nsXPTType::T_CSTRING:
00688 case nsXPTType::T_UTF8STRING:
00689 (*(nsACString **)param)->Truncate();
00690 (*(nsACString **)param)->SetIsVoid(PR_TRUE);
00691 rv = TCL_OK;
00692 break;
00693
00694 default:
00695 if (type->IsReference())
00696 {
00697
00698 Tcl_ResetResult(interp);
00699 Tcl_AppendResult(interp, "reference argument won't accept a NULL value", NULL);
00700 rv = TCL_ERROR;
00701 } else
00702 {
00703 *(void **)param = NULL;
00704 rv = TCL_OK;
00705 }
00706 }
00707
00708 return rv;
00709 }
00710
00711 switch (type->TagPart())
00712 {
00713 case nsXPTType::T_I8:
00714 rv = Tcl_GetIntFromObj(interp, value, &intVal);
00715 if (rv == TCL_OK)
00716 {
00717 *(void **)param = (void *)memmgr->Alloc(sizeof(PRInt8));
00718 **(PRInt8 **)param = (PRInt8)intVal;
00719 }
00720 break;
00721
00722 case nsXPTType::T_I16:
00723 rv = Tcl_GetIntFromObj(interp, value, &intVal);
00724 if (rv == TCL_OK)
00725 {
00726 *(void **)param = (void *)memmgr->Alloc(sizeof(PRInt16));
00727 **(PRInt16 **)param = (PRInt16)intVal;
00728 }
00729 break;
00730
00731 case nsXPTType::T_I32:
00732 rv = Tcl_GetLongFromObj(interp, value, &longVal);
00733 if (rv == TCL_OK)
00734 {
00735 *(void **)param = (void *)memmgr->Alloc(sizeof(PRInt32));
00736 **(PRInt32 **)param = (PRInt32)longVal;
00737 }
00738 break;
00739
00740 case nsXPTType::T_I64:
00741 rv = TclXPCOM_GetWideIntFromObj(interp, value, &wideVal);
00742 if (rv == TCL_OK)
00743 {
00744 *(void **)param = (void *)memmgr->Alloc(sizeof(PRInt64));
00745 **(PRInt64 **)param = (PRInt64)wideVal;
00746 }
00747 break;
00748
00749 case nsXPTType::T_U8:
00750 rv = Tcl_GetIntFromObj(interp, value, &intVal);
00751 if (rv == TCL_OK)
00752 {
00753 *(void **)param = (void *)memmgr->Alloc(sizeof(PRUint8));
00754 **(PRUint8 **)param = (PRUint8)intVal;
00755 }
00756 break;
00757
00758 case nsXPTType::T_U16:
00759 rv = Tcl_GetIntFromObj(interp, value, &intVal);
00760 if (rv == TCL_OK)
00761 {
00762 *(void **)param = (void *)memmgr->Alloc(sizeof(PRUint16));
00763 **(PRUint16 **)param = (PRUint16)intVal;
00764 }
00765 break;
00766
00767 case nsXPTType::T_U32:
00768 rv = Tcl_GetLongFromObj(interp, value, &longVal);
00769 if (rv == TCL_OK)
00770 {
00771 *(void **)param = (void *)memmgr->Alloc(sizeof(PRUint32));
00772 **(PRUint32 **)param = (PRUint32)longVal;
00773 }
00774 break;
00775
00776 case nsXPTType::T_U64:
00777 rv = TclXPCOM_GetWideIntFromObj(interp, value, &wideVal);
00778 if (rv == TCL_OK)
00779 {
00780 *(void **)param = (void *)memmgr->Alloc(sizeof(PRUint64));
00781 **(PRUint64 **)param = (PRUint64)wideVal;
00782 }
00783 break;
00784
00785 case nsXPTType::T_FLOAT:
00786 rv = Tcl_GetDoubleFromObj(interp, value, &doubleVal);
00787 if (rv == TCL_OK)
00788 {
00789 *(void **)param = (void *)memmgr->Alloc(sizeof(float));
00790 **(float **)param = (float)doubleVal;
00791 }
00792 break;
00793
00794 case nsXPTType::T_DOUBLE:
00795 rv = Tcl_GetDoubleFromObj(interp, value, &doubleVal);
00796 if (rv == TCL_OK)
00797 {
00798 *(void **)param = (void *)memmgr->Alloc(sizeof(double));
00799 **(double **)param = doubleVal;
00800 }
00801 break;
00802
00803 case nsXPTType::T_BOOL:
00804 rv = Tcl_GetBooleanFromObj(interp, value, &intVal);
00805 if (rv == TCL_OK)
00806 {
00807 *(void **)param = (void *)memmgr->Alloc(sizeof(PRBool));
00808 **(PRBool **)param = (PRBool)intVal;
00809 }
00810 break;
00811
00812 case nsXPTType::T_CHAR:
00813 if (Tcl_GetCharLength(value) != 1)
00814 {
00815 Tcl_ResetResult(interp);
00816 Tcl_AppendResult(interp, "parameter must be a single character", NULL);
00817 rv = TCL_ERROR;
00818 } else
00819 {
00820 utf8str = Tcl_GetStringFromObj(value, &numbytes);
00821 rv = Tcl_UtfToExternal(interp, ascii_enc, utf8str, numbytes, 0, NULL, str, 2, NULL, NULL, NULL);
00822 if (rv == TCL_OK)
00823 {
00824 *(void **)param = (void *)memmgr->Alloc(sizeof(char));
00825 **(char **)param = str[0];
00826 }
00827 }
00828 break;
00829
00830 case nsXPTType::T_WCHAR:
00831 if (Tcl_GetCharLength(value) != 1)
00832 {
00833 Tcl_ResetResult(interp);
00834 Tcl_AppendResult(interp, "parameter must be a single character", NULL);
00835 rv = TCL_ERROR;
00836 } else
00837 {
00838 *(void **)param = (void *)memmgr->Alloc(sizeof(PRUnichar));
00839 **(PRUnichar **)param = (PRUnichar)*Tcl_GetUnicode(value);
00840 rv = TCL_OK;
00841 }
00842 break;
00843
00844 case nsXPTType::T_VOID:
00845 rv = TclXPCOM_GetPointerFromObj(interp, value, (void **)param);
00846
00847 break;
00848
00849 case nsXPTType::T_IID:
00850 rv = TclXPCOM_GetNsIDFromObj(interp, value, &iidPtr);
00851 if (rv == TCL_OK)
00852 {
00853 *(nsIID **)param = (nsIID *)CloneMemory(iidPtr, sizeof(nsIID));
00854 }
00855 break;
00856
00857 case nsXPTType::T_ASTRING:
00858 case nsXPTType::T_DOMSTRING:
00859 (*(nsAString **)param)->Assign(Tcl_GetUnicode(value), Tcl_GetCharLength(value));
00860 rv = TCL_OK;
00861 break;
00862
00863 case nsXPTType::T_CSTRING:
00864 length = (PRUint32)Tcl_GetCharLength(value);
00865 charPtr = (char *)memmgr->Alloc(sizeof(char) * (length + 1));
00866
00867 utf8str = Tcl_GetStringFromObj(value, &numbytes);
00868 rv = Tcl_UtfToExternal(interp, ascii_enc, utf8str, numbytes, 0, NULL, charPtr, (length + 1), NULL, NULL, NULL);
00869 if (rv == TCL_OK)
00870 {
00871 (*(nsACString **)param)->Assign(charPtr, length);
00872 }
00873
00874 memmgr->Free(charPtr);
00875 break;
00876
00877 case nsXPTType::T_UTF8STRING:
00878 utf8str = Tcl_GetStringFromObj(value, &numbytes);
00879 (*(nsACString **)param)->Assign(utf8str, numbytes);
00880 rv = TCL_OK;
00881 break;
00882
00883 case nsXPTType::T_CHAR_STR:
00884 length = (PRUint32)Tcl_GetCharLength(value);
00885 charPtr = (char *)memmgr->Alloc(sizeof(char) * (length + 1));
00886
00887 utf8str = Tcl_GetStringFromObj(value, &numbytes);
00888 rv = Tcl_UtfToExternal(interp, ascii_enc, utf8str, numbytes, 0, NULL, charPtr, (length + 1), NULL, NULL, NULL);
00889 if (rv == TCL_OK)
00890 {
00891 *(char **)param = charPtr;
00892 } else
00893 {
00894 memmgr->Free(charPtr);
00895 }
00896 break;
00897
00898 case nsXPTType::T_WCHAR_STR:
00899 length = (PRUint32)Tcl_GetCharLength(value);
00900 *(PRUnichar **)param = (PRUnichar *)CloneMemory(Tcl_GetUnicode(value), sizeof(PRUnichar) * (length + 1));
00901 rv = TCL_OK;
00902 break;
00903
00904 case nsXPTType::T_INTERFACE:
00905 res = interfaceinfo->GetInfoForParam(methodindex, paraminfo, &tempinfo);
00906 NS_ASSERTION((NS_SUCCEEDED(res)), "GetInfoForParam failed");
00907
00908 rv = TclXPCOM_QueryISupportsObj(interp, value, tempinfo, &isupports);
00909 NS_RELEASE(tempinfo);
00910
00911 if (rv == TCL_OK)
00912 {
00913 *(nsISupports **)param = isupports;
00914 }
00915 break;
00916
00917 case nsXPTType::T_INTERFACE_IS:
00918 interfaceinfo->GetInterfaceIsArgNumberForParam(methodindex, paraminfo, &iidindex);
00919
00920 if (shared)
00921 {
00922 iidPtr = *(nsIID **)params[iidindex];
00923
00924
00925 res = manager->GetInfoForIID(iidPtr, &tempinfo);
00926 NS_ASSERTION((NS_SUCCEEDED(res)), "GetInfoForIID failed");
00927
00928 rv = TclXPCOM_QueryISupportsObj(interp, value, tempinfo, &isupports);
00929 NS_RELEASE(tempinfo);
00930
00931 if (rv == TCL_OK)
00932 {
00933 *(nsISupports **)param = isupports;
00934 }
00935 } else
00936 {
00937 rv = TclXPCOM_GetISupportsFromObj(interp, value, &isupports, &tempinfo);
00938
00939 if (rv == TCL_OK)
00940 {
00941 tempinfo->GetInterfaceIID(&iidPtr);
00942 *(nsIID **)params[iidindex] = iidPtr;
00943 NS_ADDREF(isupports);
00944 *(nsISupports **)param = isupports;
00945 }
00946 }
00947 break;
00948
00949 case nsXPTType::T_ARRAY:
00950 interfaceinfo->GetSizeIsArgNumberForParam(methodindex, paraminfo, 0, &sizeindex);
00951 interfaceinfo->GetLengthIsArgNumberForParam(methodindex, paraminfo, 0, &lengthindex);
00952
00953 rv = Tcl_ListObjGetElements(interp, value, &intVal, &listPtr);
00954 if (rv != TCL_OK)
00955 {
00956 return rv;
00957 }
00958
00959 length = (PRUint32)intVal;
00960 if (shared)
00961 {
00962 if (*(PRUint32 *)params[lengthindex] != length)
00963 {
00964 sprintf(str, "list parameter must be of length %d", length);
00965 Tcl_ResetResult(interp);
00966 Tcl_AppendResult(interp, str, NULL);
00967 return TCL_ERROR;
00968 }
00969 } else
00970 {
00971 *(PRUint32 *)params[sizeindex] = length;
00972 *(PRUint32 *)params[lengthindex] = length;
00973 }
00974
00975 if (length)
00976 {
00977 interfaceinfo->GetTypeForParam(methodindex, paraminfo, 1, &arraytype);
00978 elementsize = GetElementTypeSize(&arraytype);
00979
00980 charPtr = (char *)memmgr->Alloc(elementsize * length);
00981 memset(charPtr, 0, elementsize * length);
00982
00983 *(void **)param = charPtr;
00984
00985 for (i = 0; i < length; i++)
00986 {
00987 rv = Tcl2Native(interp, listPtr[i], params, (void *)(charPtr + (i * elementsize)), &arraytype, 0, interfaceinfo, methodindex, paraminfo);
00988 if (rv != TCL_OK) {
00989 sprintf(str, "\nwhile reading list element #%d", i);
00990 Tcl_AddObjErrorInfo(interp, str, -1);
00991
00992 break;
00993 }
00994 }
00995 } else
00996 {
00997
00998 *(void **)param = NULL;
00999 }
01000 break;
01001
01002 case nsXPTType::T_PSTRING_SIZE_IS:
01003 interfaceinfo->GetSizeIsArgNumberForParam(methodindex, paraminfo, 0, &sizeindex);
01004 interfaceinfo->GetLengthIsArgNumberForParam(methodindex, paraminfo, 0, &lengthindex);
01005
01006 length = (PRUint32)Tcl_GetCharLength(value);
01007 if (shared)
01008 {
01009 if (*(PRUint32 *)params[lengthindex] != length)
01010 {
01011 sprintf(str, "string parameter must be of length %d", length);
01012 Tcl_ResetResult(interp);
01013 Tcl_AppendResult(interp, str, NULL);
01014 return TCL_ERROR;
01015 }
01016 } else
01017 {
01018 *(PRUint32 *)params[sizeindex] = length;
01019 *(PRUint32 *)params[lengthindex] = length;
01020 }
01021
01022 charPtr = (char *)memmgr->Alloc(sizeof(char) * (length + 1));
01023
01024 utf8str = Tcl_GetStringFromObj(value, &numbytes);
01025 rv = Tcl_UtfToExternal(interp, ascii_enc, utf8str, numbytes, 0, NULL, charPtr, (length + 1), NULL, NULL, NULL);
01026 if (rv == TCL_OK)
01027 {
01028 *(char **)param = charPtr;
01029 } else
01030 {
01031 memmgr->Free(charPtr);
01032 }
01033 break;
01034
01035 case nsXPTType::T_PWSTRING_SIZE_IS:
01036 interfaceinfo->GetSizeIsArgNumberForParam(methodindex, paraminfo, 0, &sizeindex);
01037 interfaceinfo->GetLengthIsArgNumberForParam(methodindex, paraminfo, 0, &lengthindex);
01038
01039 length = (PRUint32)Tcl_GetCharLength(value);
01040 if (shared)
01041 {
01042 if (*(PRUint32 *)params[lengthindex] != length)
01043 {
01044 sprintf(str, "unicode string parameter must be of length %d", length);
01045 Tcl_ResetResult(interp);
01046 Tcl_AppendResult(interp, str, NULL);
01047 return TCL_ERROR;
01048 }
01049 } else
01050 {
01051 *(PRUint32 *)params[sizeindex] = length;
01052 *(PRUint32 *)params[lengthindex] = length;
01053 }
01054
01055 *(PRUnichar **)param = (PRUnichar *)CloneMemory(Tcl_GetUnicode(value), sizeof(PRUnichar) * (length + 1));
01056 rv = TCL_OK;
01057 break;
01058
01059 default:
01060
01061 TclXPCOM_SetError(interp, NS_ERROR_INVALID_ARG);
01062 rv = TCL_ERROR;
01063 break;
01064 }
01065 }
01066 return rv;
01067 }
01068