gecko-dev/java/xpcom/test/xptest.cpp

424 lines
10 KiB
C++

/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Frank
* Mitchell. Portions created by Frank Mitchell are
* Copyright (C) 1999 Frank Mitchell. All
* Rights Reserved.
*
* Contributor(s):
* Frank Mitchell (frank.mitchell@sun.com)
*/
#include <iostream.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "nscore.h"
#include "nsIFactory.h"
#include "nsIComponentManager.h"
#include "nsIInterfaceInfo.h"
#include "nsIInterfaceInfoManager.h"
#include "xptinfo.h"
#include "xptcall.h"
#include "xpt_struct.h"
#include "nsIAllocator.h"
#include "JSISample.h"
#include "JSSample.h"
#include "nsSpecialSystemDirectory.h"
static NS_DEFINE_IID(kISampleIID, JSISAMPLE_IID);
static NS_DEFINE_CID(kSampleCID, JS_SAMPLE_CID);
#ifdef XP_PC
#define SAMPLE_DLL "xpjtest.dll"
#else
#ifdef XP_MAC
#define SAMPLE_DLL "XPJTEST_DLL"
#else
#define SAMPLE_DLL "libxpjtest.so"
#endif
#endif
static void ParamsFromArgv(nsXPTCVariant *result,
const nsXPTMethodInfo *mi,
int argi, int argc, char **argv) {
uint8 paramcount = mi->GetParamCount();
memset(result, 0, sizeof(nsXPTCVariant) * paramcount);
for (int i = 0; i < paramcount; i++) {
nsXPTParamInfo param = mi->GetParam(i);
result[i].ptr = 0;
result[i].type = param.GetType().TagPart();
result[i].flags = 0;
if (param.IsIn()) {
assert(argi < argc);
cerr << "Consuming " << argv[argi] << endl;
switch(result[i].type) {
case nsXPTType::T_I8:
result[i].val.i8 = atoi(argv[argi]);
break;
case nsXPTType::T_I16:
result[i].val.i16 = atoi(argv[argi]);
break;
case nsXPTType::T_I32:
result[i].val.i32 = atol(argv[argi]);
break;
case nsXPTType::T_I64:
result[i].val.i64 = atol(argv[argi]); //s.b. conversion to long long
break;
case nsXPTType::T_U8:
result[i].val.u8 = atoi(argv[argi]);
break;
case nsXPTType::T_U16:
result[i].val.u16 = atoi(argv[argi]);
break;
case nsXPTType::T_U32:
result[i].val.u32 = atol(argv[argi]);
break;
case nsXPTType::T_U64:
result[i].val.u64 = atol(argv[argi]); //s.b. conversion to long long
break;
case nsXPTType::T_FLOAT:
result[i].val.f = atof(argv[argi]);
break;
case nsXPTType::T_DOUBLE:
result[i].val.d = atof(argv[argi]);
break;
case nsXPTType::T_BOOL:
switch (argv[argi][0]) {
case '1':
case 't':
case 'T':
result[i].val.b = 1;
break;
default:
result[i].val.b = 0;
break;
}
break;
case nsXPTType::T_CHAR:
result[i].val.c = argv[argi][0];
break;
case nsXPTType::T_WCHAR:
result[i].val.wc = argv[argi][0]; // PENDING: not wide
break;
case nsXPTType::T_CHAR_STR:
result[i].val.p = argv[argi];
// Copying every time would be wasteful
if (param.IsOut()) {
char *tmpstr = new char[strlen(argv[argi]) + 1];
strcpy(tmpstr, argv[argi]);
result[i].val.p = tmpstr;
result[i].flags |= nsXPTCVariant::VAL_IS_OWNED;
}
break;
case nsXPTType::T_VOID:
case nsXPTType::T_IID:
case nsXPTType::T_BSTR:
case nsXPTType::T_WCHAR_STR:
case nsXPTType::T_INTERFACE:
case nsXPTType::T_INTERFACE_IS:
// Ignore for now
break;
}
// VAL_IS_OWNED: val.p holds alloc'd ptr that must be freed
// VAL_IS_IFACE: val.p holds interface ptr that must be released
argi++;
}
if (param.IsOut()) {
// PTR_IS_DATA: ptr points to 'real' data in val
result[i].flags |= nsXPTCVariant::PTR_IS_DATA;
switch(result[i].type) {
case nsXPTType::T_I8:
result[i].ptr = &result[i].val.i8;
break;
case nsXPTType::T_I16:
result[i].ptr = &result[i].val.i16;
break;
case nsXPTType::T_I32:
result[i].ptr = &result[i].val.i32;
break;
case nsXPTType::T_I64:
result[i].ptr = &result[i].val.i64;
break;
case nsXPTType::T_U8:
result[i].ptr = &result[i].val.u8;
break;
case nsXPTType::T_U16:
result[i].ptr = &result[i].val.u16;
break;
case nsXPTType::T_U32:
result[i].ptr = &result[i].val.u32;
break;
case nsXPTType::T_U64:
result[i].ptr = &result[i].val.u64;
break;
case nsXPTType::T_FLOAT:
result[i].ptr = &result[i].val.f;
break;
case nsXPTType::T_DOUBLE:
result[i].ptr = &result[i].val.d;
break;
case nsXPTType::T_BOOL:
result[i].ptr = &result[i].val.b;
break;
case nsXPTType::T_CHAR:
result[i].ptr = &result[i].val.c;
break;
case nsXPTType::T_WCHAR:
result[i].ptr = &result[i].val.wc;
break;
default:
result[i].ptr = &result[i].val.p;
break;
}
}
}
}
static void xpjd_PrintParams(const nsXPTCVariant params[], int paramcount) {
for (int i = 0; i < paramcount; i++) {
cerr << i << ") ";
switch(params[i].type) {
case nsXPTType::T_I8:
cerr << params[i].val.i8;
break;
case nsXPTType::T_I16:
cerr << params[i].val.i16;
break;
case nsXPTType::T_I32:
cerr << params[i].val.i32;
break;
case nsXPTType::T_I64:
cerr << params[i].val.i64;
break;
case nsXPTType::T_U8:
cerr << params[i].val.u8;
break;
case nsXPTType::T_U16:
cerr << params[i].val.u16;
break;
case nsXPTType::T_U32:
cerr << params[i].val.u32;
break;
case nsXPTType::T_U64:
cerr << params[i].val.u64;
break;
case nsXPTType::T_FLOAT:
cerr << params[i].val.f;
break;
case nsXPTType::T_DOUBLE:
cerr << params[i].val.d;
break;
case nsXPTType::T_BOOL:
cerr << (params[i].val.b ? "true" : "false");
break;
case nsXPTType::T_CHAR:
cerr << "'" << params[i].val.c << "'";
break;
case nsXPTType::T_WCHAR:
cerr << "'" << params[i].val.wc << "'";
break;
case nsXPTType::T_CHAR_STR:
cerr << params[i].val.p << ' '
<< '"' << (char *)params[i].val.p << '"';
break;
default:
// Ignore for now
break;
}
cerr << " : type " << (int)(params[i].type)
<< ", ptr=" << params[i].ptr
<< (params[i].IsPtrData() ? ", data" : "")
<< (params[i].IsValOwned() ? ", owned" : "")
<< (params[i].IsValInterface() ? ", interface" : "")
<< endl;
}
}
static nsresult GetMethodInfoByName(const nsID *iid,
const char *methodname,
PRBool wantSetter,
const nsXPTMethodInfo **miptr,
int *_retval) {
nsresult res;
nsIInterfaceInfoManager *iim;
nsIInterfaceInfo *info = nsnull;
// Get info
iim = XPTI_GetInterfaceInfoManager();
if (!iim) {
cerr << "Failed to find InterfaceInfoManager" << endl;
return NS_ERROR_NOT_INITIALIZED;
}
res = iim->GetInfoForIID(iid, &info);
if (NS_FAILED(res)) {
cerr << "Failed to find info for " << iid->ToString() << endl;
return res;
}
// Find info for command
uint16 methodcount;
info->GetMethodCount(&methodcount);
int i;
for (i = 0; i < methodcount; i++) {
const nsXPTMethodInfo *mi;
info->GetMethodInfo(i, &mi);
// PENDING(frankm): match against name, get/set, *AND* param types
if (strcmp(methodname, mi->GetName()) == 0) {
PRBool setter = mi->IsSetter();
PRBool getter = mi->IsGetter();
if ((!getter && !setter)
|| (setter && wantSetter)
|| (getter && !wantSetter)) {
*miptr = mi;
*_retval = i;
break;
}
}
}
if (i >= methodcount) {
cerr << "Failed to find " << methodname << endl;
*miptr = NULL;
*_retval = -1;
return NS_ERROR_FAILURE;
}
return res;
}
int main(int argc, char **argv)
{
JSISample *sample;
nsresult res;
char *commandName;
cout << "Starting ..." << endl;
// Get options
// Get command vector
if (argc > 1) {
commandName = argv[1];
}
else {
commandName = "PrintStats";
}
// Initialize XPCOM
nsComponentManager::AutoRegister(nsIComponentManager::NS_Startup, nsnull);
// Create Instance
res = nsComponentManager::CreateInstance(kSampleCID,
nsnull,
kISampleIID,
(void **) &sample);
if (NS_FAILED(res)) {
cerr << "Failed to create instance" << endl;
return 1;
}
// Get info
int index;
const nsXPTMethodInfo *mi;
res = GetMethodInfoByName(&kISampleIID, commandName, PR_FALSE,
&mi, &index);
if (NS_FAILED(res)) {
cerr << "Failed to find " << commandName << endl;
return 1;
}
uint8 paramcount = mi->GetParamCount();
cerr << mi->GetName()
<< ":" << endl;
for (int i = 0; i < paramcount; i++) {
nsXPTParamInfo param = mi->GetParam(i);
nsXPTType type = param.GetType();
cerr << '\t' << i << ": "
<< " type = " << (int)type.TagPart()
<< (type.IsUniquePointer() ? " UNIQUE" : "")
<< (type.IsReference() ? " REF" : "")
<< (type.IsPointer() ? " POINTER" : "")
<< (param.IsIn() ? ", in" : "")
<< (param.IsOut() ? ", out" : "")
<< (param.IsRetval() ? ", retval" : "")
<< (param.IsShared() ? ", shared" : "")
<< endl;
}
// Translate and marshall arguments
nsXPTCVariant params[32];
if (paramcount > (sizeof(params)/sizeof(nsXPTCVariant))) {
cerr << "Too Many Params" << endl;
return 1;
}
ParamsFromArgv(params, mi, 2, argc, argv);
cerr << "Arguments are: " << endl;
xpjd_PrintParams(params, paramcount);
// Invoke command
cerr << "Calling XPTC_InvokeByIndex( " << sample
<< ", " << (int)index
<< ", " << (int)paramcount
<< ", " << params
<< ")" << endl;
res = XPTC_InvokeByIndex(sample,
(PRUint32)index,
(PRUint32)paramcount,
params);
// Get result
cerr << "Results are: " << endl;
xpjd_PrintParams(params, paramcount);
// Release Instance
NS_RELEASE(sample);
return 0;
}