/* * 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 #include #include #include #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; }