summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/java/tools/genifaces/GenerateJavaInterfaces.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/libs/xpcom18a4/java/tools/genifaces/GenerateJavaInterfaces.cpp952
1 files changed, 952 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/java/tools/genifaces/GenerateJavaInterfaces.cpp b/src/libs/xpcom18a4/java/tools/genifaces/GenerateJavaInterfaces.cpp
new file mode 100644
index 00000000..60648beb
--- /dev/null
+++ b/src/libs/xpcom18a4/java/tools/genifaces/GenerateJavaInterfaces.cpp
@@ -0,0 +1,952 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * 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 Java XPCOM Bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * IBM Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2005
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Javier Pedemonte (jhpedemonte@gmail.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsXPCOM.h"
+#include "nsString.h"
+#include "nsILocalFile.h"
+#include "nsIInterfaceInfoManager.h"
+#include "xptinfo.h"
+#include "nsCOMPtr.h"
+#include "prmem.h"
+#include "xptcall.h"
+#ifdef VBOX
+#include "nsFileStreams.h"
+static nsresult
+NS_NewLocalFileInputStream(nsIInputStream **aResult,
+ nsIFile *aFile,
+ PRInt32 aIOFlags = -1,
+ PRInt32 aPerm = -1,
+ PRInt32 aBehaviorFlags = 0)
+{
+ nsFileInputStream* in = new nsFileInputStream();
+ nsresult rv;
+
+ rv = in->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
+ if (NS_SUCCEEDED(rv))
+ NS_ADDREF(*aResult = in);
+
+ return rv;
+}
+
+inline nsresult
+NS_NewLocalFileOutputStream(nsIOutputStream **aResult,
+ nsIFile *aFile,
+ PRInt32 aIOFlags = -1,
+ PRInt32 aPerm = -1,
+ PRInt32 aBehaviorFlags = 0)
+{
+ nsFileOutputStream* in = new nsFileOutputStream();
+ nsresult rv;
+
+ rv = in->Init(aFile, aIOFlags, aPerm, aBehaviorFlags);
+ if (NS_SUCCEEDED(rv))
+ NS_ADDREF(*aResult = in);
+
+ return rv;
+}
+
+
+#else
+#include "nsNetUtil.h"
+#endif
+#include "nsHashSets.h"
+#include "nsIWeakReference.h"
+#include <stdio.h>
+
+#ifdef WIN32
+#define snprintf _snprintf
+#endif
+
+#define WRITE_NOSCRIPT_METHODS
+
+
+class TypeInfo
+{
+public:
+ static nsresult GetParentInfo(nsIInterfaceInfo* aIInfo,
+ nsIInterfaceInfo** aParentInfo,
+ PRUint16* aParentMethodCount,
+ PRUint16* aParentConstCount)
+ {
+ nsCOMPtr<nsIInterfaceInfo> parent;
+ nsresult rv = aIInfo->GetParent(getter_AddRefs(parent));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (!parent) {
+ *aParentInfo = nsnull;
+ *aParentMethodCount = 0;
+ return NS_OK;
+ }
+
+ rv = parent->GetMethodCount(aParentMethodCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = parent->GetConstantCount(aParentConstCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ *aParentInfo = parent;
+ NS_ADDREF(*aParentInfo);
+ return rv;
+ }
+
+ static nsresult GetInterfaceName(nsIInterfaceInfo* aIInfo,
+ PRUint16 aMethodIndex,
+ const nsXPTParamInfo* aParamInfo,
+ char** aResult)
+ {
+ static const char isupp_str[] = "nsISupports";
+
+ nsIID* iid;
+ nsresult rv = aIInfo->GetIIDForParam(aMethodIndex, aParamInfo, &iid);
+ if (NS_FAILED(rv)) {
+ // GetIIDForParam will sometimes fail to find an interface, particularly
+ // if that interface is not defined in an IDL file. In those cases, just
+ // return |nsISupports|.
+ //
+ // For example, the |onStreamComplete| method for the interface
+ // |nsIUnicharStreamLoaderObserver| takes a param of
+ // |nsIUnicharInputStream|, which is defined in a simple header file, not
+ // an IDL file.
+ *aResult = (char*) nsMemory::Clone(isupp_str, sizeof(isupp_str));
+ rv = (*aResult == nsnull) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
+
+ } else {
+
+ // In Javaconnect, we handle weak references internally; no need for the
+ // |nsIWeakReference| interface. So just return |nsISupports|.
+ if (iid->Equals(NS_GET_IID(nsIWeakReference))) {
+ *aResult = (char*) nsMemory::Clone(isupp_str, sizeof(isupp_str));
+ rv = (*aResult == nsnull) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
+
+ } else {
+
+ // Some methods take parameters of non-scriptable interfaces. But we
+ // only output scriptable interfaces. So if one of the param types is
+ // a non-scriptable interface, output |nsISupports| instead of the
+ // interface name.
+ nsCOMPtr<nsIInterfaceInfo> info;
+ nsCOMPtr<nsIInterfaceInfoManager> iim =
+ getter_AddRefs(XPTI_GetInterfaceInfoManager());
+ NS_ASSERTION(iim, "could not get interface info manager");
+ rv = iim->GetInfoForIID(iid, getter_AddRefs(info));
+ NS_ENSURE_SUCCESS(rv, rv);
+ PRBool scriptable;
+ if (NS_SUCCEEDED(rv)) {
+ info->IsScriptable(&scriptable);
+ }
+ if (NS_FAILED(rv) || !scriptable) {
+ *aResult = (char*) nsMemory::Clone(isupp_str, sizeof(isupp_str));
+ rv = (*aResult == nsnull) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
+ } else {
+
+ // If is scriptable, get name for given IID
+ rv = iim->GetNameForIID(iid, aResult);
+ }
+ }
+
+ nsMemory::Free(iid);
+ }
+
+ return rv;
+ }
+};
+
+
+static const char* kJavaKeywords[] = {
+ "abstract", "default", "if" , "private" , "this" ,
+ "boolean" , "do" , "implements", "protected" , "throw" ,
+ "break" , "double" , "import", "public" , "throws" ,
+ "byte" , "else" , "instanceof", "return" , "transient",
+ "case" , "extends", "int" , "short" , "try" ,
+ "catch" , "final" , "interface" , "static" , "void" ,
+ "char" , "finally", "long" , "strictfp" , "volatile" ,
+ "class" , "float" , "native" , "super" , "while" ,
+ "const" , "for" , "new" , "switch" ,
+ "continue", "goto" , "package" , "synchronized",
+ "assert" , /* added in Java 1.4 */
+ "enum" , /* added in Java 5.0 */
+ "clone" , /* clone is a member function of java.lang.Object */
+ "finalize" /* finalize is a member function of java.lang.Object */
+};
+
+#ifdef WRITE_NOSCRIPT_METHODS
+// SWT uses [noscript] methods of the following interfaces, so we need to
+// output the [noscript] methods for these interfaces.
+static const char* kNoscriptMethodIfaces[] = {
+ "nsIBaseWindow", "nsIEmbeddingSiteWindow"
+};
+#endif
+
+
+class Generate
+{
+ nsILocalFile* mOutputDir;
+ nsCStringHashSet mIfaceTable;
+ nsCStringHashSet mJavaKeywords;
+#ifdef WRITE_NOSCRIPT_METHODS
+ nsCStringHashSet mNoscriptMethodsTable;
+#endif
+
+public:
+ Generate(nsILocalFile* aOutputDir)
+ : mOutputDir(aOutputDir)
+ {
+ mIfaceTable.Init(100);
+
+ PRUint32 size = NS_ARRAY_LENGTH(kJavaKeywords);
+ mJavaKeywords.Init(size);
+ for (PRUint32 i = 0; i < size; i++) {
+ mJavaKeywords.Put(nsDependentCString(kJavaKeywords[i]));
+ }
+
+#ifdef WRITE_NOSCRIPT_METHODS
+ size = NS_ARRAY_LENGTH(kNoscriptMethodIfaces);
+ mNoscriptMethodsTable.Init(size);
+ for (PRUint32 j = 0; j < size; j++) {
+ mNoscriptMethodsTable.Put(nsDependentCString(kNoscriptMethodIfaces[j]));
+ }
+#endif
+ }
+
+ ~Generate()
+ {
+ }
+
+ nsresult GenerateInterfaces()
+ {
+ nsresult rv;
+
+ nsCOMPtr<nsIInterfaceInfoManager> iim =
+ getter_AddRefs(XPTI_GetInterfaceInfoManager());
+ NS_ASSERTION(iim, "could not get interface info manager");
+ nsCOMPtr<nsIEnumerator> etor;
+ rv = iim->EnumerateInterfaces(getter_AddRefs(etor));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // loop over interfaces
+ etor->First();
+ do {
+ // get current interface
+ nsCOMPtr<nsISupports> item;
+ rv = etor->CurrentItem(getter_AddRefs(item));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIInterfaceInfo> iface(do_QueryInterface(item));
+ if (!iface)
+ break;
+
+ // we only care about scriptable interfaces, so skip over those
+ // that aren't
+ PRBool scriptable;
+ iface->IsScriptable(&scriptable);
+ if (!scriptable) {
+ // XXX SWT uses non-scriptable interface 'nsIAppShell' (bug 270892), so
+ // include that one.
+ const char* iface_name;
+ iface->GetNameShared(&iface_name);
+ if (strcmp("nsIAppShell", iface_name) != 0)
+ continue;
+ }
+
+ rv = WriteOneInterface(iface);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ } while (NS_SUCCEEDED(etor->Next()));
+
+ return NS_OK;
+ }
+
+ nsresult WriteOneInterface(nsIInterfaceInfo* aIInfo)
+ {
+ nsresult rv;
+
+ // write each interface only once
+ const char* iface_name;
+ aIInfo->GetNameShared(&iface_name);
+ if (mIfaceTable.Contains(nsDependentCString(iface_name)))
+ return NS_OK;
+
+ // write any parent interface
+ nsCOMPtr<nsIInterfaceInfo> parentInfo;
+ PRUint16 parentMethodCount, parentConstCount;
+ rv = TypeInfo::GetParentInfo(aIInfo, getter_AddRefs(parentInfo),
+ &parentMethodCount, &parentConstCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (parentInfo)
+ WriteOneInterface(parentInfo);
+
+ mIfaceTable.Put(nsDependentCString(iface_name));
+
+ // create file for interface
+ nsCOMPtr<nsIOutputStream> out;
+ rv = OpenIfaceFileStream(iface_name, getter_AddRefs(out));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // write contents to file
+ rv = WriteHeader(out, iface_name);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = WriteInterfaceStart(out, aIInfo, parentInfo);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = WriteIID(out, aIInfo);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = WriteConstants(out, aIInfo, parentConstCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = WriteMethods(out, aIInfo, parentMethodCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = WriteInterfaceEnd(out);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = CloseIfaceFileStream(out);
+
+ return rv;
+ }
+
+ nsresult OpenIfaceFileStream(const char* aIfaceName,
+ nsIOutputStream** aResult)
+ {
+ nsresult rv;
+
+ // create interface file in output dir
+ nsCOMPtr<nsIFile> iface_file;
+ rv = mOutputDir->Clone(getter_AddRefs(iface_file));
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsAutoString filename;
+ filename.AppendASCII(aIfaceName);
+ filename.AppendLiteral(".java");
+ rv = iface_file->Append(filename);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // create interface file
+ PRBool exists;
+ iface_file->Exists(&exists);
+ if (exists)
+ iface_file->Remove(PR_FALSE);
+ rv = iface_file->Create(nsIFile::NORMAL_FILE_TYPE, 0644);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // create output stream for writing to file
+ nsCOMPtr<nsIOutputStream> out;
+ rv = NS_NewLocalFileOutputStream(getter_AddRefs(out), iface_file);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ *aResult = out;
+ NS_ADDREF(*aResult);
+ return NS_OK;
+ }
+
+ nsresult CloseIfaceFileStream(nsIOutputStream* out)
+ {
+ return out->Close();
+ }
+
+ nsresult WriteHeader(nsIOutputStream* out, const char* aIfaceName)
+ {
+ static const char kHeader1[] =
+ "/**\n"
+ " * NOTE: THIS IS A GENERATED FILE. PLEASE CONSULT THE ORIGINAL IDL FILE\n"
+ " * FOR THE FULL DOCUMENTION AND LICENSE.\n"
+ " *\n"
+ " * @see <a href=\"http://lxr.mozilla.org/mozilla/search?string=";
+ static const char kHeader2[]= "\">\n **/\n\n";
+ static const char kPackage[] = "package org.mozilla.interfaces;\n\n";
+
+ PRUint32 count;
+ nsresult rv = out->Write(kHeader1, sizeof(kHeader1) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCAutoString searchTerm;
+ searchTerm.AppendLiteral("interface+");
+ searchTerm.AppendASCII(aIfaceName);
+ // LXR limits to 29 chars
+ rv = out->Write(searchTerm.get(), PR_MIN(29, searchTerm.Length()), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = out->Write(kHeader2, sizeof(kHeader2) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(kPackage, sizeof(kPackage) - 1, &count);
+ return rv;
+ }
+
+ nsresult WriteInterfaceStart(nsIOutputStream* out, nsIInterfaceInfo* aIInfo,
+ nsIInterfaceInfo* aParentInfo)
+ {
+ static const char kIfaceDecl1[] = "public interface ";
+ static const char kParentDecl[] = " extends ";
+ static const char kIfaceDecl2[] = "\n{\n";
+
+ const char* iface_name;
+ aIInfo->GetNameShared(&iface_name);
+ PRUint32 count;
+ nsresult rv = out->Write(kIfaceDecl1, sizeof(kIfaceDecl1) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(iface_name, strlen(iface_name), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (aParentInfo) {
+ const char* parent_name;
+ aParentInfo->GetNameShared(&parent_name);
+ rv = out->Write(kParentDecl, sizeof(kParentDecl) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(parent_name, strlen(parent_name), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ rv = out->Write(kIfaceDecl2, sizeof(kIfaceDecl2) - 1, &count);
+ return rv;
+ }
+
+ nsresult WriteInterfaceEnd(nsIOutputStream* out)
+ {
+ PRUint32 count;
+ return out->Write("}\n", 2, &count);
+ }
+
+ nsresult WriteIID(nsIOutputStream* out, nsIInterfaceInfo* aIInfo)
+ {
+ static const char kIIDDecl1[] = " public static final String ";
+ static const char kIIDDecl2[] = " =\n \"";
+ static const char kIIDDecl3[] = "\";\n\n";
+
+ nsIID* iid = nsnull;
+ aIInfo->GetInterfaceIID(&iid);
+ if (!iid)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ // create iid field name
+ nsCAutoString iid_name;
+ const char* iface_name;
+ aIInfo->GetNameShared(&iface_name);
+ if (strncmp("ns", iface_name, 2) == 0) {
+ iid_name.AppendLiteral("NS_");
+ iid_name.Append(iface_name + 2);
+ } else {
+ iid_name.Append(iface_name);
+ }
+ iid_name.AppendLiteral("_IID");
+ ToUpperCase(iid_name);
+
+ // get iid string
+ char* iid_str = iid->ToString();
+ if (!iid_str)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ PRUint32 count;
+ nsresult rv = out->Write(kIIDDecl1, sizeof(kIIDDecl1) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(iid_name.get(), iid_name.Length(), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(kIIDDecl2, sizeof(kIIDDecl2) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(iid_str, strlen(iid_str), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(kIIDDecl3, sizeof(kIIDDecl3) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // cleanup
+ PR_Free(iid_str);
+ nsMemory::Free(iid);
+ return NS_OK;
+ }
+
+ nsresult WriteConstants(nsIOutputStream* out, nsIInterfaceInfo* aIInfo,
+ PRUint16 aParentConstCount)
+ {
+ static const char kConstDecl1[] = " public static final ";
+ static const char kConstDecl2[] = " = ";
+ static const char kConstDecl3[] = ";\n\n";
+
+ PRUint16 constCount;
+ nsresult rv = aIInfo->GetConstantCount(&constCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ for (PRUint16 i = aParentConstCount; i < constCount; i++) {
+ const nsXPTConstant* constInfo;
+ rv = aIInfo->GetConstant(i, &constInfo);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PRUint32 count;
+ rv = out->Write(kConstDecl1, sizeof(kConstDecl1) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ const nsXPTType &type = constInfo->GetType();
+ rv = WriteType(out, &type, aIInfo, nsnull, nsnull);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(" ", 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ const char* name = constInfo->GetName();
+ rv = out->Write(name, strlen(name), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(kConstDecl2, sizeof(kConstDecl2) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = WriteConstantValue(out, &type, constInfo->GetValue());
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(kConstDecl3, sizeof(kConstDecl3) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+ }
+
+ nsresult WriteConstantValue(nsIOutputStream* out, const nsXPTType* aType,
+ const nsXPTCMiniVariant* aValue)
+ {
+ char buf[32];
+ switch (aType->TagPart()) {
+ case nsXPTType::T_I8:
+ snprintf(buf, sizeof(buf), "%d", aValue->val.i8);
+ break;
+
+ case nsXPTType::T_U8:
+ snprintf(buf, sizeof(buf), "%u", aValue->val.u8);
+ break;
+
+ case nsXPTType::T_I16:
+ snprintf(buf, sizeof(buf), "%d", aValue->val.i16);
+ break;
+
+ case nsXPTType::T_U16:
+ snprintf(buf, sizeof(buf), "%u", aValue->val.u16);
+ break;
+
+ case nsXPTType::T_I32:
+ snprintf(buf, sizeof(buf), "%d", aValue->val.i32);
+ break;
+
+ case nsXPTType::T_U32:
+ snprintf(buf, sizeof(buf), "%uL", aValue->val.u32);
+ break;
+
+ case nsXPTType::T_I64:
+ snprintf(buf, sizeof(buf), "%lldL", aValue->val.i64);
+ break;
+
+ case nsXPTType::T_U64:
+ snprintf(buf, sizeof(buf), "%lluL", aValue->val.u64);
+ break;
+
+ case nsXPTType::T_FLOAT:
+ snprintf(buf, sizeof(buf), "%f", aValue->val.f);
+ break;
+
+ case nsXPTType::T_DOUBLE:
+ snprintf(buf, sizeof(buf), "%f", aValue->val.d);
+ break;
+
+ case nsXPTType::T_BOOL:
+ if (aValue->val.b)
+ sprintf(buf, "true");
+ else
+ sprintf(buf, "false");
+ break;
+
+ case nsXPTType::T_CHAR:
+ snprintf(buf, sizeof(buf), "%c", aValue->val.c);
+ break;
+
+ case nsXPTType::T_WCHAR:
+ snprintf(buf, sizeof(buf), "%c", aValue->val.wc);
+ break;
+
+ default:
+ NS_WARNING("unexpected constant type");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ PRUint32 count;
+ return out->Write(buf, strlen(buf), &count);
+ }
+
+ nsresult WriteMethods(nsIOutputStream* out, nsIInterfaceInfo* aIInfo,
+ PRUint16 aParentMethodCount)
+ {
+ PRUint16 methodCount;
+ nsresult rv = aIInfo->GetMethodCount(&methodCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+#ifdef DEBUG_bird /* attributes first, then method. For making diffing easier. */
+ for (int pass = 0; pass < 2; pass++)
+#endif
+ for (PRUint16 i = aParentMethodCount; i < methodCount; i++) {
+ const nsXPTMethodInfo* methodInfo;
+ rv = aIInfo->GetMethodInfo(i, &methodInfo);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+#ifdef WRITE_NOSCRIPT_METHODS
+ // XXX
+ // SWT makes use of [noscript] methods in some classes, so output them
+ // for those classes.
+
+ // skip [notxpcom] methods
+ if (methodInfo->IsNotXPCOM())
+ continue;
+
+ // skip most hidden ([noscript]) methods
+ if (methodInfo->IsHidden()) {
+ const char* iface_name;
+ aIInfo->GetNameShared(&iface_name);
+ if (!mNoscriptMethodsTable.Contains(nsDependentCString(iface_name)))
+ continue;
+ }
+#else
+ // skip hidden ([noscript]) or [notxpcom] methods
+ if (methodInfo->IsHidden() || methodInfo->IsNotXPCOM())
+ continue;
+#endif
+#ifdef DEBUG_bird /* attributes first, then method. For making diffing easier. */
+ if ((methodInfo->IsSetter() || methodInfo->IsGetter()) == pass)
+ continue;
+#endif
+
+ rv = WriteOneMethod(out, aIInfo, methodInfo, i);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+ }
+
+ nsresult WriteOneMethod(nsIOutputStream* out, nsIInterfaceInfo* aIInfo,
+ const nsXPTMethodInfo* aMethodInfo,
+ PRUint16 aMethodIndex)
+ {
+ static const char kMethodDecl1[] = " public ";
+ static const char kVoidReturn[] = "void";
+ static const char kParamSeparator[] = ", ";
+ static const char kMethodDecl2[] = ");\n\n";
+
+ PRUint32 count;
+ nsresult rv = out->Write(kMethodDecl1, sizeof(kMethodDecl1) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // write return type
+ PRUint8 paramCount = aMethodInfo->GetParamCount();
+ const nsXPTParamInfo* resultInfo = nsnull;
+ for (PRUint8 i = 0; i < paramCount; i++) {
+ const nsXPTParamInfo &paramInfo = aMethodInfo->GetParam(i);
+ if (paramInfo.IsRetval()) {
+ resultInfo = &paramInfo;
+ break;
+ }
+ }
+ if (resultInfo) {
+ rv = WriteParam(out, aIInfo, aMethodIndex, resultInfo, 0);
+ } else {
+ rv = out->Write(kVoidReturn, sizeof(kVoidReturn) - 1, &count);
+ }
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // write method name string
+ nsCAutoString method_name;
+ const char* name = aMethodInfo->GetName();
+ if (aMethodInfo->IsGetter() || aMethodInfo->IsSetter()) {
+ if (aMethodInfo->IsGetter())
+ method_name.AppendLiteral("get");
+ else
+ method_name.AppendLiteral("set");
+ method_name.Append(toupper(name[0]));
+ method_name.AppendASCII(name + 1);
+ } else {
+ method_name.Append(tolower(name[0]));
+ method_name.AppendASCII(name + 1);
+ // don't use Java keywords as method names
+ if (mJavaKeywords.Contains(method_name))
+ method_name.Append('_');
+ }
+ rv = out->Write(" ", 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write(method_name.get(), method_name.Length(), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = out->Write("(", 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // write parameters
+ for (PRUint8 j = 0; j < paramCount; j++) {
+ const nsXPTParamInfo &paramInfo = aMethodInfo->GetParam(j);
+ if (paramInfo.IsRetval())
+ continue;
+
+ if (j != 0) {
+ rv = out->Write(kParamSeparator, sizeof(kParamSeparator) - 1, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ rv = WriteParam(out, aIInfo, aMethodIndex, &paramInfo, j + 1);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ rv = out->Write(kMethodDecl2, sizeof(kMethodDecl2) - 1, &count);
+ return rv;
+ }
+
+ nsresult WriteParam(nsIOutputStream* out, nsIInterfaceInfo* aIInfo,
+ PRUint16 aMethodIndex, const nsXPTParamInfo* aParamInfo,
+ PRUint8 aIndex)
+ {
+ const nsXPTType &type = aParamInfo->GetType();
+ nsresult rv = WriteType(out, &type, aIInfo, aMethodIndex, aParamInfo);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // if parameter is 'out' or 'inout', make it a Java array
+ PRUint32 count;
+ if (aParamInfo->IsOut() && !aParamInfo->IsRetval()) {
+ rv = out->Write("[]", 2, &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // write name for parameter (but not for 'retval' param)
+ if (aIndex) {
+ char buf[10];
+ snprintf(buf, sizeof(buf), " arg%d", aIndex);
+ rv = out->Write(buf, strlen(buf), &count);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+ }
+
+ /**
+ * Write out the Java type for the given XPIDL type.
+ *
+ * NOTE: Java doesn't support unsigned types. So for any unsigned XPIDL type,
+ * we move up to the next largest Java type. This way we ensure that we don't
+ * lose any info.
+ */
+ nsresult WriteType(nsIOutputStream* out, const nsXPTType* aType,
+ nsIInterfaceInfo* aIInfo, PRUint16 aMethodIndex,
+ const nsXPTParamInfo* aParamInfo)
+ {
+ nsresult rv;
+ PRUint32 count;
+ switch (aType->TagPart()) {
+ case nsXPTType::T_I8:
+ rv = out->Write("byte", 4, &count);
+ break;
+
+ case nsXPTType::T_I16:
+ case nsXPTType::T_U8:
+ rv = out->Write("short", 5, &count);
+ break;
+
+ case nsXPTType::T_I32:
+ case nsXPTType::T_U16:
+ rv = out->Write("int", 3, &count);
+ break;
+
+ case nsXPTType::T_I64:
+ case nsXPTType::T_U32:
+ rv = out->Write("long", 4, &count);
+ break;
+
+ case nsXPTType::T_FLOAT:
+ rv = out->Write("float", 5, &count);
+ break;
+
+ // XXX how should we handle 64-bit values?
+ case nsXPTType::T_U64:
+ case nsXPTType::T_DOUBLE:
+ rv = out->Write("double", 6, &count);
+ break;
+
+ case nsXPTType::T_BOOL:
+ rv = out->Write("boolean", 7, &count);
+ break;
+
+ case nsXPTType::T_CHAR:
+ case nsXPTType::T_WCHAR:
+ rv = out->Write("char", 4, &count);
+ break;
+
+ case nsXPTType::T_CHAR_STR:
+ case nsXPTType::T_WCHAR_STR:
+ case nsXPTType::T_IID:
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING:
+ case nsXPTType::T_UTF8STRING:
+ case nsXPTType::T_CSTRING:
+ case nsXPTType::T_PSTRING_SIZE_IS:
+ case nsXPTType::T_PWSTRING_SIZE_IS:
+ rv = out->Write("String", 6, &count);
+ break;
+
+ case nsXPTType::T_INTERFACE:
+ {
+ char* iface_name = nsnull;
+ rv = TypeInfo::GetInterfaceName(aIInfo, aMethodIndex, aParamInfo,
+ &iface_name);
+ if (NS_FAILED(rv) || !iface_name) {
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+
+ rv = out->Write(iface_name, strlen(iface_name), &count);
+ nsMemory::Free(iface_name);
+ break;
+ }
+
+ case nsXPTType::T_INTERFACE_IS:
+ rv = out->Write("nsISupports", 11, &count);
+ break;
+
+ case nsXPTType::T_VOID:
+ rv = out->Write("int", 3, &count);
+ break;
+
+ case nsXPTType::T_ARRAY:
+ {
+ // get array type
+ nsXPTType xpttype;
+ rv = aIInfo->GetTypeForParam(aMethodIndex, aParamInfo, 1, &xpttype);
+ if (NS_FAILED(rv))
+ break;
+
+ rv = WriteType(out, &xpttype, aIInfo, aMethodIndex, aParamInfo);
+ if (NS_FAILED(rv))
+ break;
+
+ rv = out->Write("[]", 2, &count);
+ break;
+ }
+
+ default:
+ fprintf(stderr, "WARNING: unexpected parameter type %d\n",
+ aType->TagPart());
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return rv;
+ }
+};
+
+void PrintUsage(char** argv)
+{
+ static const char usage_str[] =
+ "Usage: %s -d path\n"
+ " -d output directory for Java interface files\n";
+ fprintf(stderr, usage_str, argv[0]);
+}
+#ifdef VBOX
+#include <VBox/com/com.h>
+using namespace com;
+
+#include <iprt/initterm.h>
+#include <iprt/string.h>
+#include <iprt/alloca.h>
+#include <iprt/stream.h>
+#endif
+
+int main(int argc, char** argv)
+{
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsILocalFile> output_dir;
+
+#ifdef VBOX
+#if defined(VBOX_PATH_APP_PRIVATE_ARCH) && defined(VBOX_PATH_SHARED_LIBS)
+ rv = RTR3InitExe(argc, &argv, 0);
+#else
+ const char *pszHome = getenv("VBOX_PROGRAM_PATH");
+ if (pszHome) {
+ size_t cchHome = strlen(pszHome);
+ char *pszExePath = (char *)alloca(cchHome + 32);
+ memcpy(pszExePath, pszHome, cchHome);
+ memcpy(pszExePath + cchHome, "/pythonfake", sizeof("/pythonfake"));
+ rc = RTR3InitEx(RTR3INIT_VER_CUR, 0, argc, &argv, pszExePath);
+ } else {
+ rv = RTR3InitExe(argc, &argv, 0);
+ }
+#endif
+#endif
+
+ // handle command line arguments
+ for (int i = 1; i < argc; i++) {
+ if (argv[i][0] != '-') {
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+
+ switch (argv[i][1]) {
+ case 'd': {
+ if (i + 1 == argc) {
+ fprintf(stderr, "ERROR: missing output directory after -d\n");
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+
+ // see if given path exists
+ rv = NS_NewNativeLocalFile(nsDependentCString(argv[++i]), PR_TRUE,
+ getter_AddRefs(output_dir));
+ PRBool val;
+ if (NS_FAILED(rv) || NS_FAILED(output_dir->Exists(&val)) || !val ||
+ NS_FAILED(output_dir->IsDirectory(&val)) || !val)
+ {
+ fprintf(stderr,
+ "ERROR: output directory doesn't exist / isn't a directory\n");
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+
+ break;
+ }
+
+ default: {
+ fprintf(stderr, "ERROR: unknown option %s\n", argv[i]);
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+ }
+ }
+
+ if (NS_FAILED(rv)) {
+ PrintUsage(argv);
+ return 1;
+ }
+
+#ifdef VBOX
+ rv = com::Initialize();
+#else
+ rv = NS_InitXPCOM2(nsnull, nsnull, nsnull);
+#endif
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ Generate gen(output_dir);
+ rv = gen.GenerateInterfaces();
+
+#ifdef VBOX
+ // very short-living XPCOM processes trigger problem on shutdown - ignoring it not a big deal anyway
+ //com::Shutdown();
+#else
+ NS_ShutdownXPCOM(nsnull);
+#endif
+ return rv;
+}