summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/python
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/libs/xpcom18a4/python/.cvsignore4
-rw-r--r--src/libs/xpcom18a4/python/Makefile.kmk789
-rw-r--r--src/libs/xpcom18a4/python/README.vbox5
-rwxr-xr-xsrc/libs/xpcom18a4/python/__init__.py173
-rw-r--r--src/libs/xpcom18a4/python/client/.cvsignore2
-rwxr-xr-xsrc/libs/xpcom18a4/python/client/__init__.py539
-rwxr-xr-xsrc/libs/xpcom18a4/python/components.py248
-rw-r--r--src/libs/xpcom18a4/python/doc/advanced.html176
-rw-r--r--src/libs/xpcom18a4/python/doc/architecture.html116
-rw-r--r--src/libs/xpcom18a4/python/doc/configure.html196
-rw-r--r--src/libs/xpcom18a4/python/doc/credits.html86
-rw-r--r--src/libs/xpcom18a4/python/doc/tutorial.html286
-rwxr-xr-xsrc/libs/xpcom18a4/python/file.py318
-rwxr-xr-xsrc/libs/xpcom18a4/python/gen_python_deps.py147
-rwxr-xr-xsrc/libs/xpcom18a4/python/nsError.py166
-rwxr-xr-xsrc/libs/xpcom18a4/python/primitives.py39
-rw-r--r--src/libs/xpcom18a4/python/readme.html121
-rw-r--r--src/libs/xpcom18a4/python/server/.cvsignore2
-rwxr-xr-xsrc/libs/xpcom18a4/python/server/__init__.py88
-rwxr-xr-xsrc/libs/xpcom18a4/python/server/enumerator.py58
-rwxr-xr-xsrc/libs/xpcom18a4/python/server/factory.py68
-rwxr-xr-xsrc/libs/xpcom18a4/python/server/loader.py227
-rwxr-xr-xsrc/libs/xpcom18a4/python/server/module.py108
-rwxr-xr-xsrc/libs/xpcom18a4/python/server/policy.py398
-rw-r--r--src/libs/xpcom18a4/python/src/ErrorUtils.cpp483
-rw-r--r--src/libs/xpcom18a4/python/src/PyGBase.cpp852
-rw-r--r--src/libs/xpcom18a4/python/src/PyGInputStream.cpp173
-rw-r--r--src/libs/xpcom18a4/python/src/PyGModule.cpp297
-rw-r--r--src/libs/xpcom18a4/python/src/PyGStub.cpp180
-rw-r--r--src/libs/xpcom18a4/python/src/PyGWeakReference.cpp112
-rw-r--r--src/libs/xpcom18a4/python/src/PyIClassInfo.cpp181
-rw-r--r--src/libs/xpcom18a4/python/src/PyIComponentManager.cpp138
-rw-r--r--src/libs/xpcom18a4/python/src/PyIComponentManagerObsolete.cpp203
-rw-r--r--src/libs/xpcom18a4/python/src/PyIEnumerator.cpp235
-rw-r--r--src/libs/xpcom18a4/python/src/PyIID.cpp410
-rw-r--r--src/libs/xpcom18a4/python/src/PyIInputStream.cpp190
-rw-r--r--src/libs/xpcom18a4/python/src/PyIInterfaceInfo.cpp431
-rw-r--r--src/libs/xpcom18a4/python/src/PyIInterfaceInfoManager.cpp206
-rw-r--r--src/libs/xpcom18a4/python/src/PyISimpleEnumerator.cpp202
-rw-r--r--src/libs/xpcom18a4/python/src/PyISupports.cpp621
-rw-r--r--src/libs/xpcom18a4/python/src/PyIVariant.cpp231
-rw-r--r--src/libs/xpcom18a4/python/src/PyXPCOM.h1036
-rw-r--r--src/libs/xpcom18a4/python/src/PyXPCOM_std.h56
-rw-r--r--src/libs/xpcom18a4/python/src/Pyxpt_info.cpp197
-rw-r--r--src/libs/xpcom18a4/python/src/TypeObject.cpp457
-rw-r--r--src/libs/xpcom18a4/python/src/VariantUtils.cpp3112
-rw-r--r--src/libs/xpcom18a4/python/src/dllmain.cpp352
-rw-r--r--src/libs/xpcom18a4/python/src/loader/pyloader.cpp435
-rw-r--r--src/libs/xpcom18a4/python/src/module/_xpcom.cpp950
-rw-r--r--src/libs/xpcom18a4/python/src/readme.html99
-rw-r--r--src/libs/xpcom18a4/python/test/.cvsignore2
-rw-r--r--src/libs/xpcom18a4/python/test/output/test_com_exceptions8
-rw-r--r--src/libs/xpcom18a4/python/test/output/test_comfile7
-rw-r--r--src/libs/xpcom18a4/python/test/output/test_components4
-rw-r--r--src/libs/xpcom18a4/python/test/output/test_isupports_primitives2
-rw-r--r--src/libs/xpcom18a4/python/test/output/test_streams1
-rw-r--r--src/libs/xpcom18a4/python/test/output/test_test_component4
-rw-r--r--src/libs/xpcom18a4/python/test/output/test_weakreferences2
-rwxr-xr-xsrc/libs/xpcom18a4/python/test/pyxpcom_test_tools.py126
-rw-r--r--src/libs/xpcom18a4/python/test/regrtest.py91
-rwxr-xr-xsrc/libs/xpcom18a4/python/test/test_com_exceptions.py124
-rwxr-xr-xsrc/libs/xpcom18a4/python/test/test_comfile.py49
-rw-r--r--src/libs/xpcom18a4/python/test/test_component/_xpidlgen/.done0
-rw-r--r--src/libs/xpcom18a4/python/test/test_component/_xpidlgen/py_test_component.h1411
-rw-r--r--src/libs/xpcom18a4/python/test/test_component/py_test_component.html182
-rw-r--r--src/libs/xpcom18a4/python/test/test_component/py_test_component.idl231
-rwxr-xr-xsrc/libs/xpcom18a4/python/test/test_component/py_test_component.py421
-rwxr-xr-xsrc/libs/xpcom18a4/python/test/test_components.py109
-rwxr-xr-xsrc/libs/xpcom18a4/python/test/test_isupports_primitives.py207
-rwxr-xr-xsrc/libs/xpcom18a4/python/test/test_misc.py236
-rwxr-xr-xsrc/libs/xpcom18a4/python/test/test_streams.py96
-rw-r--r--src/libs/xpcom18a4/python/test/test_test_component.js138
-rwxr-xr-xsrc/libs/xpcom18a4/python/test/test_test_component.py575
-rwxr-xr-xsrc/libs/xpcom18a4/python/test/test_weakreferences.py114
-rwxr-xr-xsrc/libs/xpcom18a4/python/tools/regxpcom.py68
-rwxr-xr-xsrc/libs/xpcom18a4/python/tools/tracer_demo.py113
-rwxr-xr-xsrc/libs/xpcom18a4/python/vboxxpcom.py83
-rw-r--r--src/libs/xpcom18a4/python/xpcom_consts.py272
-rwxr-xr-xsrc/libs/xpcom18a4/python/xpt.py471
79 files changed, 21346 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/python/.cvsignore b/src/libs/xpcom18a4/python/.cvsignore
new file mode 100644
index 00000000..9d5da30c
--- /dev/null
+++ b/src/libs/xpcom18a4/python/.cvsignore
@@ -0,0 +1,4 @@
+*.pyc
+*.pyo
+*.idb
+*.pdb \ No newline at end of file
diff --git a/src/libs/xpcom18a4/python/Makefile.kmk b/src/libs/xpcom18a4/python/Makefile.kmk
new file mode 100644
index 00000000..b8dcd44a
--- /dev/null
+++ b/src/libs/xpcom18a4/python/Makefile.kmk
@@ -0,0 +1,789 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-Makefile for Python bindings
+#
+
+#
+# Copyright (C) 2009-2022 Oracle and/or its affiliates.
+#
+# This file is part of VirtualBox base platform packages, as
+# available from https://www.virtualbox.org.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, in version 3 of the
+# License.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <https://www.gnu.org/licenses>.
+#
+# SPDX-License-Identifier: GPL-3.0-only
+#
+
+SUB_DEPTH = ../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+#
+# List of supported Python versions, defining a number of
+# VBOX_PYTHON[26|27|31|32|32M|33|33M|34|34M|35|35M|36|36M|37|37M|38|38M|39|39M|310|310M|DEF]_[INC|LIB] variables
+# which get picked up below.
+#
+ifeq ($(KBUILD_TARGET),darwin) # Relatively predictable, don't script.
+ ifn1of ($(VBOX_DEF_MACOSX_VERSION_MIN), 10.10 10.9 10.8 10.7 10.6 10.5 10.4) ## @todo @bugref{9790}: if $(VBOX_DEF_MACOSX_VERSION_MIN) vge 10.11
+ VBOX_PYTHON_SUFFTBD := .tbd
+ else
+ VBOX_PYTHON_SUFFTBD :=
+ endif
+ ifndef VBOX_WITHOUT_VBOXPYTHON_FOR_OSX_10_6
+ if1of ($(VBOX_DEF_MACOSX_VERSION_MIN), 10.5 10.4)
+ VBOX_PYTHON26_INC = $(VBOX_PATH_MACOSX_SDK_10_6)/usr/include/python2.6
+ VBOX_PYTHON26_LIB = $(VBOX_PATH_MACOSX_SDK_10_6)/usr/lib/libpython2.6.dylib
+ else if "$(VBOX_DEF_MACOSX_VERSION_MIN)" == "10.9" && "$(VBOX_XCODE_VERSION)" == "6.2" # 'effing 10.9 SDK in Xcode 6.2 is missing python. Stupid, stupid Apple!!
+ VBOX_PYTHON26_INC = $(VBOX_PATH_MACOSX_SDK)/../MacOSX10.10.sdk/System/Library/Frameworks/Python.framework/Versions/2.6/Headers
+ VBOX_PYTHON26_LIB = $(VBOX_PATH_MACOSX_SDK)/../MacOSX10.10.sdk/System/Library/Frameworks/Python.framework/Versions/2.6/Python
+ else if "$(VBOX_DEF_MACOSX_VERSION_MIN)" vlt "10.13"
+ VBOX_PYTHON26_INC = $(VBOX_PATH_MACOSX_SDK)/System/Library/Frameworks/Python.framework/Versions/2.6/Headers
+ VBOX_PYTHON26_LIB = $(VBOX_PATH_MACOSX_SDK)/System/Library/Frameworks/Python.framework/Versions/2.6/Python$(VBOX_PYTHON_SUFFTBD)
+ endif
+ if !defined(VBOX_OSE) || "$(wildcard $(VBOX_PYTHON26_LIB))" != ""
+ VBOX_PYTHON26_LIB_X86 = $(VBOX_PYTHON26_LIB)
+ else
+ VBOX_PYTHON26_INC =
+ VBOX_PYTHON26_LIB =
+ endif
+ endif
+ ifndef VBOX_WITHOUT_VBOXPYTHON_FOR_OSX_10_7
+ if1of ($(VBOX_DEF_MACOSX_VERSION_MIN), 10.6 10.5 10.4)
+ VBOX_PYTHON27_INC = $(VBOX_PATH_MACOSX_SDK_10_7)/usr/include/python2.7
+ VBOX_PYTHON27_LIB = $(VBOX_PATH_MACOSX_SDK_10_7)/usr/lib/libpython2.7.dylib
+ else if "$(VBOX_DEF_MACOSX_VERSION_MIN)" == "10.9" && "$(VBOX_XCODE_VERSION)" == "6.2" # 'effing 10.9 SDK in Xcode 6.2 is missing python. Stupid, stupid Apple!!
+ VBOX_PYTHON27_INC = $(VBOX_PATH_MACOSX_SDK)/../MacOSX10.10.sdk/System/Library/Frameworks/Python.framework/Versions/2.7/Headers
+ VBOX_PYTHON27_LIB = $(VBOX_PATH_MACOSX_SDK)/../MacOSX10.10.sdk/System/Library/Frameworks/Python.framework/Versions/2.7/Python
+ else
+ VBOX_PYTHON27_INC = $(VBOX_PATH_MACOSX_SDK)/System/Library/Frameworks/Python.framework/Versions/2.7/Headers
+ VBOX_PYTHON27_LIB = $(VBOX_PATH_MACOSX_SDK)/System/Library/Frameworks/Python.framework/Versions/2.7/Python$(VBOX_PYTHON_SUFFTBD)
+ endif
+ if !defined(VBOX_OSE) || "$(wildcard $(VBOX_PYTHON27_LIB))" != ""
+ VBOX_PYTHON27_LIB_X86 = $(VBOX_PYTHON27_LIB)
+ else
+ VBOX_PYTHON27_INC =
+ VBOX_PYTHON27_LIB =
+ endif
+ endif
+ # No Python 3.x yet as part of OSX versions including El Capitan, 10.11.
+
+else
+ # Use the script.
+ $(eval $(subst |,$(NL),$(shell $(VBOX_BLD_PYTHON) \
+ $(PATH_SUB_CURRENT)/gen_python_deps.py \
+ $(KBUILD_TARGET) \
+ $(KBUILD_TARGET_ARCH) \
+ $(if-expr defined(VBOX_WITH_MULTIVERSION_PYTHON),1,0))))
+endif
+
+ifndef VBOX_ONLY_SDK
+
+#
+# Base Python Client Module - the C++/XPCOM bits (not actually built).
+#
+VBoxPythonBase_TEMPLATE = XPCOM
+VBoxPythonBase_CXXFLAGS = -Wno-write-strings
+VBoxPythonBase_CXXFLAGS.solaris = $(VBOX_GCC_Wno-unknown-pragmas) # /usr/include/python[23].[75]*/ceval.h:67: warning: ignoring #pragma no_inline(PyEval_EvalFrameEx)
+VBoxPythonBase_DLLSUFF.darwin = .so
+VBoxPythonBase_DEFS = \
+ _IMPL_NS_COM \
+ _IMPL_NS_BASE \
+ EXPORT_XPTI_API \
+ EXPORT_XPT_API \
+ VBOX_PYXPCOM \
+ VBOX_WITH_XPCOM \
+ VBOX_PYXPCOM_VERSIONED
+#VBoxPythonBase_DEFS.debug = \
+# VBOX_DEBUG_LIFETIMES
+VBoxPythonBase_INCS = \
+ src
+VBoxPythonBase_SOURCES = \
+ src/module/_xpcom.cpp \
+ src/dllmain.cpp \
+ src/ErrorUtils.cpp \
+ src/PyGBase.cpp \
+ src/PyGInputStream.cpp \
+ src/PyGModule.cpp \
+ src/PyGStub.cpp \
+ src/PyGWeakReference.cpp \
+ src/PyIClassInfo.cpp \
+ src/PyIComponentManager.cpp \
+ src/PyIComponentManagerObsolete.cpp \
+ src/PyIEnumerator.cpp \
+ src/PyIID.cpp \
+ src/PyIInputStream.cpp \
+ src/PyIInterfaceInfo.cpp \
+ src/PyIInterfaceInfoManager.cpp \
+ src/PyISimpleEnumerator.cpp \
+ src/PyISupports.cpp \
+ src/PyIVariant.cpp \
+ src/Pyxpt_info.cpp \
+ src/TypeObject.cpp \
+ src/VariantUtils.cpp
+VBoxPythonBase_LIBS = \
+ $(PATH_STAGE_LIB)/VBoxCOM$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_BIN)/VBoxXPCOM$(VBOX_SUFF_DLL)
+
+# pymalloc abi variant.
+VBoxPythonBase_m_EXTENDS = VBoxPythonBase
+VBoxPythonBase_m_DEFS = MODULE_NAME_SUFFIX=m $(VBoxPythonBase_DEFS)
+
+# 32-bit base.
+VBoxPythonBase_x86_TEMPLATE = XPCOM-x86
+VBoxPythonBase_x86_EXTENDS = VBoxPythonBase
+VBoxPythonBase_x86_DEFS = MODULE_NAME_SUFFIX=_x86 $(VBoxPythonBase_DEFS)
+VBoxPythonBase_x86_LIBS = \
+ $(PATH_STAGE_LIB)/VBoxCOM-x86$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_BIN)/VBoxXPCOM-x86$(VBOX_SUFF_DLL)
+
+# 32-bit pymalloc abi variant.
+VBoxPythonBase_x86_m_EXTENDS = VBoxPythonBase_x86
+VBoxPythonBase_x86_m_DEFS = MODULE_NAME_SUFFIX=_x86m $(VBoxPythonBase_DEFS)
+
+
+ifdef VBOX_PYTHON26_INC
+#
+# Python 2.6 version
+#
+DLLS += VBoxPython2_6
+VBoxPython2_6_EXTENDS = VBoxPythonBase
+VBoxPython2_6_EXTENDS_BY = appending
+ ifdef KMK_WITH_VERSION_COMPARE
+VBoxPython2_6_TEMPLATE = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" vle "10.6",OSX106,)
+ else
+VBoxPython2_6_TEMPLATE = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" <= "10.6",OSX106,)
+ endif
+VBoxPython2_6_INCS = $(VBOX_PYTHON26_INC)
+VBoxPython2_6_LIBS = $(VBOX_PYTHON26_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON26_LIB_X86
+DLLS += VBoxPython2_6_x86
+VBoxPython2_6_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython2_6_x86_EXTENDS_BY = appending
+ ifdef KMK_WITH_VERSION_COMPARE
+VBoxPython2_6_x86_TEMPLATE = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" vle "10.6",OSX106,-x86)
+ else
+VBoxPython2_6_x86_TEMPLATE = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" <= "10.6",OSX106,-x86)
+ endif
+VBoxPython2_6_x86_INCS = $(VBOX_PYTHON26_INC)
+VBoxPython2_6_x86_LIBS = $(VBOX_PYTHON26_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON27_INC
+#
+# Python 2.7 version
+#
+DLLS += VBoxPython2_7
+VBoxPython2_7_EXTENDS = VBoxPythonBase
+VBoxPython2_7_EXTENDS_BY = appending
+ ifdef KMK_WITH_VERSION_COMPARE
+VBoxPython2_7_TEMPLATE = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" vle "10.7",OSX107,)
+ else
+VBoxPython2_7_TEMPLATE = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" <= "10.7" && "$(length-var VBOX_DEF_MACOSX_VERSION_MIN)" == "4",OSX107,)
+ endif
+VBoxPython2_7_INCS = $(VBOX_PYTHON27_INC)
+VBoxPython2_7_LIBS = $(VBOX_PYTHON27_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON27_LIB_X86
+DLLS += VBoxPython2_7_x86
+VBoxPython2_7_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython2_7_x86_EXTENDS_BY = appending
+ ifdef KMK_WITH_VERSION_COMPARE
+VBoxPython2_7_x86_TEMPLATE = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" vle "10.7",OSX107,-x86)
+ else
+VBoxPython2_7_x86_TEMPLATE = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" <= "10.7" && "$(length-var VBOX_DEF_MACOSX_VERSION_MIN)" == "4",OSX107,-x86)
+ endif
+VBoxPython2_7_x86_INCS = $(VBOX_PYTHON27_INC)
+VBoxPython2_7_x86_LIBS = $(VBOX_PYTHON27_LIB_X86)
+ endif
+ endif
+endif
+
+#
+# Unversioned Python 2.x.
+#
+ if defined(VBOX_PYTHON27_INC) || defined(VBOX_PYTHON26_INC)
+DLLS += VBoxPython2
+VBoxPython2_EXTENDS = VBoxPythonBase
+VBoxPython2_EXTENDS_BY = appending
+VBoxPython2_DEFS = VBOX_PYXPCOM_MAJOR_VERSIONED
+ ifdef KMK_WITH_VERSION_COMPARE
+VBoxPython2_TEMPLATE = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" vle "10.7",OSX107,)
+ else
+VBoxPython2_TEMPLATE = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" <= "10.7" && "$(length-var VBOX_DEF_MACOSX_VERSION_MIN)" == "4",OSX107,)
+ endif
+ if defined(VBOX_PYTHON26_INC)
+VBoxPython2_INCS = $(VBOX_PYTHON26_INC)
+ ifn1of ($(KBUILD_TARGET), linux)
+VBoxPython2_LIBS = $(VBOX_PYTHON26_LIB)
+ endif
+ else
+VBoxPython2_INCS = $(VBOX_PYTHON27_INC)
+ ifn1of ($(KBUILD_TARGET), linux)
+VBoxPython2_LIBS = $(VBOX_PYTHON27_LIB)
+ endif
+ endif
+ endif
+
+ if defined(VBOX_WITH_32_ON_64_MAIN_API) && (defined(VBOX_PYTHON27_LIB_X86) || defined(VBOX_PYTHON26_INC_X86))
+DLLS += VBoxPython2_x86
+VBoxPython2_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython2_x86_EXTENDS_BY = appending
+VBoxPython2_x86_DEFS = VBOX_PYXPCOM_MAJOR_VERSIONED $(VBoxPythonBase_x86_DEFS)
+ ifdef KMK_WITH_VERSION_COMPARE
+VBoxPython2_x86_TEMPLATE = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" vle "10.7",OSX107,-x86)
+ else
+VBoxPython2_x86_TEMPLATE = XPCOM$(if-expr "$(KBUILD_TARGET)" == "darwin" && "$(VBOX_DEF_MACOSX_VERSION_MIN)" <= "10.7" && "$(length-var VBOX_DEF_MACOSX_VERSION_MIN)" == "4",OSX107,-x86)
+ endif
+ if defined(VBOX_PYTHON26LIB_X86)
+VBoxPython2_x86_INCS = $(VBOX_PYTHON26_INC)
+ ifn1of ($(KBUILD_TARGET), linux)
+VBoxPython2_x86_LIBS = $(VBOX_PYTHON26_LIB_X86)
+ endif
+ else
+VBoxPython2_x86_INCS = $(VBOX_PYTHON27_INC)
+ ifn1of ($(KBUILD_TARGET), linux)
+VBoxPython2_x86_LIBS = $(VBOX_PYTHON27_LIB_X86)
+ endif
+ endif
+ endif
+
+
+ifdef VBOX_PYTHON31_INC
+#
+# Python 3.1 version
+#
+DLLS += VBoxPython3_1
+VBoxPython3_1_EXTENDS = VBoxPythonBase
+VBoxPython3_1_EXTENDS_BY = appending
+VBoxPython3_1_TEMPLATE = XPCOM
+VBoxPython3_1_INCS = $(VBOX_PYTHON31_INC)
+VBoxPython3_1_LIBS = $(VBOX_PYTHON31_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON31_LIB_X86
+DLLS += VBoxPython3_1_x86
+VBoxPython3_1_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython3_1_x86_EXTENDS_BY = appending
+VBoxPython3_1_x86_TEMPLATE = XPCOM
+VBoxPython3_1_x86_INCS = $(VBOX_PYTHON31_INC)
+VBoxPython3_1_x86_LIBS = $(VBOX_PYTHON31_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON32_INC
+#
+# Python 3.2 version
+#
+DLLS += VBoxPython3_2
+VBoxPython3_2_EXTENDS = VBoxPythonBase
+VBoxPython3_2_EXTENDS_BY = appending
+VBoxPython3_2_TEMPLATE = XPCOM
+VBoxPython3_2_INCS = $(VBOX_PYTHON32_INC)
+VBoxPython3_2_LIBS = $(VBOX_PYTHON32_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON32_LIB_X86
+DLLS += VBoxPython3_2_x86
+VBoxPython3_2_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython3_2_x86_EXTENDS_BY = appending
+VBoxPython3_2_x86_TEMPLATE = XPCOM
+VBoxPython3_2_x86_INCS = $(VBOX_PYTHON32_INC)
+VBoxPython3_2_x86_LIBS = $(VBOX_PYTHON32_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON32M_INC
+#
+# Python 3.2 version with pymalloc
+#
+DLLS += VBoxPython3_2m
+VBoxPython3_2m_EXTENDS = VBoxPythonBase_m
+VBoxPython3_2m_EXTENDS_BY = appending
+VBoxPython3_2m_TEMPLATE = XPCOM
+VBoxPython3_2m_INCS = $(VBOX_PYTHON32M_INC)
+VBoxPython3_2m_LIBS = $(VBOX_PYTHON32M_LIB)
+VBoxPython3_2m_DEFS = MODULE_NAME_SUFFIX
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON32M_LIB_X86
+DLLS += VBoxPython3_2m_x86
+VBoxPython3_2m_x86_EXTENDS = VBoxPythonBase_x86_m
+VBoxPython3_2m_x86_EXTENDS_BY = appending
+VBoxPython3_2m_x86_TEMPLATE = XPCOM
+VBoxPython3_2m_x86_INCS = $(VBOX_PYTHON32M_INC)
+VBoxPython3_2m_x86_LIBS = $(VBOX_PYTHON32M_LIB_X86)
+ endif
+ endif
+endif
+
+ ifndef VBOX_WITH_ONLY_PYTHON_LIMITED_API
+
+ifdef VBOX_PYTHON33_INC
+#
+# Python 3.3 version
+#
+DLLS += VBoxPython3_3
+VBoxPython3_3_EXTENDS = VBoxPythonBase
+VBoxPython3_3_EXTENDS_BY = appending
+VBoxPython3_3_TEMPLATE = XPCOM
+VBoxPython3_3_INCS = $(VBOX_PYTHON33_INC)
+VBoxPython3_3_LIBS = $(VBOX_PYTHON33_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON33_LIB_X86
+DLLS += VBoxPython3_3_x86
+VBoxPython3_3_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython3_3_x86_EXTENDS_BY = appending
+VBoxPython3_3_x86_TEMPLATE = XPCOM
+VBoxPython3_3_x86_INCS = $(VBOX_PYTHON33_INC)
+VBoxPython3_3_x86_LIBS = $(VBOX_PYTHON33_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON33M_INC
+#
+# Python 3.3 version with pymalloc
+#
+DLLS += VBoxPython3_3m
+VBoxPython3_3m_EXTENDS = VBoxPythonBase_m
+VBoxPython3_3m_EXTENDS_BY = appending
+VBoxPython3_3m_TEMPLATE = XPCOM
+VBoxPython3_3m_INCS = $(VBOX_PYTHON33M_INC)
+VBoxPython3_3m_LIBS = $(VBOX_PYTHON33M_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON33M_LIB_X86
+DLLS += VBoxPython3_3m_x86
+VBoxPython3_3m_x86_EXTENDS = VBoxPythonBase_x86_m
+VBoxPython3_3m_x86_EXTENDS_BY = appending
+VBoxPython3_3m_x86_TEMPLATE = XPCOM
+VBoxPython3_3m_x86_INCS = $(VBOX_PYTHON33M_INC)
+VBoxPython3_3m_x86_LIBS = $(VBOX_PYTHON33M_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON34_INC
+#
+# Python 3.4 version
+#
+DLLS += VBoxPython3_4
+VBoxPython3_4_EXTENDS = VBoxPythonBase
+VBoxPython3_4_EXTENDS_BY = appending
+VBoxPython3_4_TEMPLATE = XPCOM
+VBoxPython3_4_INCS = $(VBOX_PYTHON34_INC)
+VBoxPython3_4_LIBS = $(VBOX_PYTHON34_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON34_LIB_X86
+DLLS += VBoxPython3_4_x86
+VBoxPython3_4_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython3_4_x86_EXTENDS_BY = appending
+VBoxPython3_4_x86_TEMPLATE = XPCOM
+VBoxPython3_4_x86_INCS = $(VBOX_PYTHON34_INC)
+VBoxPython3_4_x86_LIBS = $(VBOX_PYTHON34_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON34M_INC
+#
+# Python 3.4 version with pymalloc
+#
+DLLS += VBoxPython3_4m
+VBoxPython3_4m_EXTENDS = VBoxPythonBase_m
+VBoxPython3_4m_EXTENDS_BY = appending
+VBoxPython3_4m_TEMPLATE = XPCOM
+VBoxPython3_4m_INCS = $(VBOX_PYTHON34M_INC)
+VBoxPython3_4m_LIBS = $(VBOX_PYTHON34M_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON34M_LIB_X86
+DLLS += VBoxPython3_4m_x86
+VBoxPython3_4m_x86_EXTENDS = VBoxPythonBase_x86_m
+VBoxPython3_4m_x86_EXTENDS_BY = appending
+VBoxPython3_4m_x86_TEMPLATE = XPCOM
+VBoxPython3_4m_x86_INCS = $(VBOX_PYTHON34M_INC)
+VBoxPython3_4m_x86_LIBS = $(VBOX_PYTHON34M_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON35_INC
+#
+# Python 3.5 version
+#
+DLLS += VBoxPython3_5
+VBoxPython3_5_EXTENDS = VBoxPythonBase
+VBoxPython3_5_EXTENDS_BY = appending
+VBoxPython3_5_TEMPLATE = XPCOM
+VBoxPython3_5_INCS = $(VBOX_PYTHON35_INC)
+VBoxPython3_5_LIBS = $(VBOX_PYTHON35_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON35_LIB_X86
+DLLS += VBoxPython3_5_x86
+VBoxPython3_5_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython3_5_x86_EXTENDS_BY = appending
+VBoxPython3_5_x86_TEMPLATE = XPCOM
+VBoxPython3_5_x86_INCS = $(VBOX_PYTHON35_INC)
+VBoxPython3_5_x86_LIBS = $(VBOX_PYTHON35_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON35M_INC
+#
+# Python 3.5 version with pymalloc
+#
+DLLS += VBoxPython3_5m
+VBoxPython3_5m_EXTENDS = VBoxPythonBase_m
+VBoxPython3_5m_EXTENDS_BY = appending
+VBoxPython3_5m_TEMPLATE = XPCOM
+VBoxPython3_5m_INCS = $(VBOX_PYTHON35M_INC)
+VBoxPython3_5m_LIBS = $(VBOX_PYTHON35M_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON35M_LIB_X86
+DLLS += VBoxPython3_5m_x86
+VBoxPython3_5m_x86_EXTENDS = VBoxPythonBase_x86_m
+VBoxPython3_5m_x86_EXTENDS_BY = appending
+VBoxPython3_5m_x86_TEMPLATE = XPCOM
+VBoxPython3_5m_x86_INCS = $(VBOX_PYTHON35M_INC)
+VBoxPython3_5m_x86_LIBS = $(VBOX_PYTHON35M_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON36_INC
+#
+# Python 3.6 version
+#
+DLLS += VBoxPython3_6
+VBoxPython3_6_EXTENDS = VBoxPythonBase
+VBoxPython3_6_EXTENDS_BY = appending
+VBoxPython3_6_TEMPLATE = XPCOM
+VBoxPython3_6_INCS = $(VBOX_PYTHON36_INC)
+VBoxPython3_6_LIBS = $(VBOX_PYTHON36_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON36_LIB_X86
+DLLS += VBoxPython3_6_x86
+VBoxPython3_6_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython3_6_x86_EXTENDS_BY = appending
+VBoxPython3_6_x86_TEMPLATE = XPCOM
+VBoxPython3_6_x86_INCS = $(VBOX_PYTHON36_INC)
+VBoxPython3_6_x86_LIBS = $(VBOX_PYTHON36_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON36M_INC
+#
+# Python 3.6 version with pymalloc
+#
+DLLS += VBoxPython3_6m
+VBoxPython3_6m_EXTENDS = VBoxPythonBase_m
+VBoxPython3_6m_EXTENDS_BY = appending
+VBoxPython3_6m_TEMPLATE = XPCOM
+VBoxPython3_6m_INCS = $(VBOX_PYTHON36M_INC)
+VBoxPython3_6m_LIBS = $(VBOX_PYTHON36M_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON36M_LIB_X86
+DLLS += VBoxPython3_6m_x86
+VBoxPython3_6m_x86_EXTENDS = VBoxPythonBase_x86_m
+VBoxPython3_6m_x86_EXTENDS_BY = appending
+VBoxPython3_6m_x86_TEMPLATE = XPCOM
+VBoxPython3_6m_x86_INCS = $(VBOX_PYTHON36M_INC)
+VBoxPython3_6m_x86_LIBS = $(VBOX_PYTHON36M_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON37_INC
+#
+# Python 3.7 version
+#
+DLLS += VBoxPython3_7
+VBoxPython3_7_EXTENDS = VBoxPythonBase
+VBoxPython3_7_EXTENDS_BY = appending
+VBoxPython3_7_TEMPLATE = XPCOM
+VBoxPython3_7_INCS = $(VBOX_PYTHON37_INC)
+VBoxPython3_7_LIBS = $(VBOX_PYTHON37_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON37_LIB_X86
+DLLS += VBoxPython3_7_x86
+VBoxPython3_7_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython3_7_x86_EXTENDS_BY = appending
+VBoxPython3_7_x86_TEMPLATE = XPCOM
+VBoxPython3_7_x86_INCS = $(VBOX_PYTHON37_INC)
+VBoxPython3_7_x86_LIBS = $(VBOX_PYTHON37_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON37M_INC
+#
+# Python 3.7 version with pymalloc
+#
+DLLS += VBoxPython3_7m
+VBoxPython3_7m_EXTENDS = VBoxPythonBase_m
+VBoxPython3_7m_EXTENDS_BY = appending
+VBoxPython3_7m_TEMPLATE = XPCOM
+VBoxPython3_7m_INCS = $(VBOX_PYTHON37M_INC)
+VBoxPython3_7m_LIBS = $(VBOX_PYTHON37M_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON37M_LIB_X86
+DLLS += VBoxPython3_7m_x86
+VBoxPython3_7m_x86_EXTENDS = VBoxPythonBase_x86_m
+VBoxPython3_7m_x86_EXTENDS_BY = appending
+VBoxPython3_7m_x86_TEMPLATE_ = XPCOM
+VBoxPython3_7m_x86_INCS = $(VBOX_PYTHON37M_INC)
+VBoxPython3_7m_x86_LIBS = $(VBOX_PYTHON37M_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON38_INC
+#
+# Python 3.8 version
+#
+DLLS += VBoxPython3_8
+VBoxPython3_8_EXTENDS = VBoxPythonBase
+VBoxPython3_8_EXTENDS_BY = appending
+VBoxPython3_8_TEMPLATE = XPCOM
+VBoxPython3_8_INCS = $(VBOX_PYTHON38_INC)
+VBoxPython3_8_LIBS = $(VBOX_PYTHON38_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON38_LIB_X86
+DLLS += VBoxPython3_8_x86
+VBoxPython3_8_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython3_8_x86_EXTENDS_BY = appending
+VBoxPython3_8_x86_TEMPLATE = XPCOM
+VBoxPython3_8_x86_INCS = $(VBOX_PYTHON38_INC)
+VBoxPython3_8_x86_LIBS = $(VBOX_PYTHON38_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON38M_INC
+#
+# Python 3.8 version with pymalloc
+#
+DLLS += VBoxPython3_8m
+VBoxPython3_8m_EXTENDS = VBoxPythonBase_m
+VBoxPython3_8m_EXTENDS_BY = appending
+VBoxPython3_8m_TEMPLATE = XPCOM
+VBoxPython3_8m_INCS = $(VBOX_PYTHON38M_INC)
+VBoxPython3_8m_LIBS = $(VBOX_PYTHON38M_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON38M_LIB_X86
+DLLS += VBoxPython3_8m_x86
+VBoxPython3_8m_x86_EXTENDS = VBoxPythonBase_x86_m
+VBoxPython3_8m_x86_EXTENDS_BY = appending
+VBoxPython3_8m_x86_TEMPLATE_ = XPCOM
+VBoxPython3_8m_x86_INCS = $(VBOX_PYTHON38M_INC)
+VBoxPython3_8m_x86_LIBS = $(VBOX_PYTHON38M_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON39_INC
+#
+# Python 3.9 version
+#
+DLLS += VBoxPython3_9
+VBoxPython3_9_EXTENDS = VBoxPythonBase
+VBoxPython3_9_EXTENDS_BY = appending
+VBoxPython3_9_TEMPLATE = XPCOM
+VBoxPython3_9_INCS = $(VBOX_PYTHON39_INC)
+VBoxPython3_9_LIBS = $(VBOX_PYTHON39_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON39_LIB_X86
+DLLS += VBoxPython3_9_x86
+VBoxPython3_9_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython3_9_x86_EXTENDS_BY = appending
+VBoxPython3_9_x86_TEMPLATE = XPCOM
+VBoxPython3_9_x86_INCS = $(VBOX_PYTHON39_INC)
+VBoxPython3_9_x86_LIBS = $(VBOX_PYTHON39_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON39M_INC
+#
+# Python 3.9 version with pymalloc
+#
+DLLS += VBoxPython3_9m
+VBoxPython3_9m_EXTENDS = VBoxPythonBase_m
+VBoxPython3_9m_EXTENDS_BY = appending
+VBoxPython3_9m_TEMPLATE = XPCOM
+VBoxPython3_9m_INCS = $(VBOX_PYTHON39M_INC)
+VBoxPython3_9m_LIBS = $(VBOX_PYTHON39M_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON39M_LIB_X86
+DLLS += VBoxPython3_9m_x86
+VBoxPython3_9m_x86_EXTENDS = VBoxPythonBase_x86_m
+VBoxPython3_9m_x86_EXTENDS_BY = appending
+VBoxPython3_9m_x86_TEMPLATE_ = XPCOM
+VBoxPython3_9m_x86_INCS = $(VBOX_PYTHON39M_INC)
+VBoxPython3_9m_x86_LIBS = $(VBOX_PYTHON39M_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON310_INC
+#
+# Python 3.10 version
+#
+DLLS += VBoxPython3_10
+VBoxPython3_10_EXTENDS = VBoxPythonBase
+VBoxPython3_10_EXTENDS_BY = appending
+VBoxPython3_10_TEMPLATE = XPCOM
+VBoxPython3_10_INCS = $(VBOX_PYTHON310_INC)
+VBoxPython3_10_LIBS = $(VBOX_PYTHON310_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON310_LIB_X86
+DLLS += VBoxPython3_10_x86
+VBoxPython3_10_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython3_10_x86_EXTENDS_BY = appending
+VBoxPython3_10_x86_TEMPLATE = XPCOM
+VBoxPython3_10_x86_INCS = $(VBOX_PYTHON310_INC)
+VBoxPython3_10_x86_LIBS = $(VBOX_PYTHON310_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHON310M_INC
+#
+# Python 3.10 version with pymalloc
+#
+DLLS += VBoxPython3_10m
+VBoxPython3_10m_EXTENDS = VBoxPythonBase_m
+VBoxPython3_10m_EXTENDS_BY = appending
+VBoxPython3_10m_TEMPLATE = XPCOM
+VBoxPython3_10m_INCS = $(VBOX_PYTHON310M_INC)
+VBoxPython3_10m_LIBS = $(VBOX_PYTHON310M_LIB)
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHON310M_LIB_X86
+DLLS += VBoxPython3_10m_x86
+VBoxPython3_10m_x86_EXTENDS = VBoxPythonBase_x86_m
+VBoxPython3_10m_x86_EXTENDS_BY = appending
+VBoxPython3_10m_x86_TEMPLATE_ = XPCOM
+VBoxPython3_10m_x86_INCS = $(VBOX_PYTHON310M_INC)
+VBoxPython3_10m_x86_LIBS = $(VBOX_PYTHON310M_LIB_X86)
+ endif
+ endif
+endif
+
+ifdef VBOX_PYTHONDEF_INC
+#
+# Python without versioning
+#
+DLLS += VBoxPython
+VBoxPython_EXTENDS = VBoxPythonBase
+VBoxPython_DEFS = $(filter-out VBOX_PYXPCOM_VERSIONED,$(VBoxPythonBase_DEFS))
+VBoxPython_INCS = $(VBoxPythonBase_INCS) $(VBOX_PYTHONDEF_INC)
+if "$(KBUILD_TARGET)" == "linux"
+ VBoxPython_LIBS = $(VBoxPythonBase_LIBS)
+else
+ VBoxPython_LIBS = $(VBoxPythonBase_LIBS) $(VBOX_PYTHONDEF_LIB)
+endif
+
+ ifdef VBOX_WITH_32_ON_64_MAIN_API
+ ifdef VBOX_PYTHONDEF_LIB_X86
+VBoxPython_x86_EXTENDS = VBoxPythonBase_x86
+VBoxPython_x86_DEFS = $(filter-out VBOX_PYXPCOM_VERSIONED,$(VBoxPythonBase_x86_DEFS))
+VBoxPython_x86_INCS = $(VBoxPythonBase_x86_INCS) $(VBOX_PYTHONDEF_INC)
+if "$(KBUILD_TARGET)" == "linux"
+ VBoxPython_x86_LIBS = $(VBoxPythonBase_x86_LIBS)
+else
+ VBoxPython_x86_LIBS = $(VBoxPythonBase_x86_LIBS) $(VBOX_PYTHONDEF_LIB_X86)
+endif
+ endif
+ endif
+endif
+
+ endif # !VBOX_WITH_ONLY_PYTHON_LIMITED_API
+
+ ifndef VBOX_WITHOUT_PYTHON_LIMITED_API
+#
+# If there is python 3.3 or later present, we can build a generic
+# 3.x extension. Since 3.3 and 3.4 are rather old, we will pick
+# those headers last.
+#
+# Note! No library dependencies are needed here (at least that's
+# how the xxlimited.so demo extension is done on linux and darwin).
+# Note! The 'm' ABI suffix was discontinued in 3.8.
+# TODO: ASSUMING that we don't need a different headers for pymalloc
+# ('m' builds < 3.8) and CRT malloc.
+#
+VBOX_PYTHON_LIMITED_API_VER := $(firstword $(foreach ver, 35 36 38 39 310 34 33 \
+,$(if-expr defined(VBOX_PYTHON$(ver)_INC),$(ver),)$(if-expr defined(VBOX_PYTHON$(ver)M_INC),$(ver)M,)))
+ ifneq ($(VBOX_PYTHON_LIMITED_API_VER),)
+DLLS += VBoxPython3
+VBoxPython3_EXTENDS = VBoxPythonBase
+VBoxPython3_DEFS = $(filter-out VBOX_PYXPCOM_VERSIONED,$(VBoxPythonBase_DEFS)) Py_LIMITED_API=0x03030000
+VBoxPython3_INCS = $(VBoxPythonBase_INCS) $(VBOX_PYTHON$(VBOX_PYTHON_LIMITED_API_VER)_INC)
+
+DLLS += VBoxPython3m
+VBoxPython3m_EXTENDS = VBoxPythonBase_m
+VBoxPython3m_DEFS = $(filter-out VBOX_PYXPCOM_VERSIONED,$(VBoxPythonBase_m_DEFS)) Py_LIMITED_API=0x03030000
+VBoxPython3m_INCS = $(VBoxPythonBase_m_INCS) $(VBOX_PYTHON$(VBOX_PYTHON_LIMITED_API_VER)_INC)
+ endif
+ endif # VBOX_WITH_PYTHON_LIMITED_API
+
+endif # VBOX_ONLY_SDK
+
+#
+# Install the python modules.
+#
+INSTALLS += VBoxPython-inst-py-xpcom
+VBoxPython-inst-py-xpcom_INST = $(INST_SDK)bindings/xpcom/python/xpcom/
+VBoxPython-inst-py-xpcom_MODE = a+r,u+w
+VBoxPython-inst-py-xpcom_SOURCES = \
+ vboxxpcom.py \
+ components.py \
+ file.py \
+ __init__.py \
+ nsError.py \
+ primitives.py \
+ xpcom_consts.py \
+ xpt.py \
+ client/__init__.py=>client/__init__.py \
+ server/__init__.py=>server/__init__.py \
+ server/enumerator.py=>server/enumerator.py \
+ server/factory.py=>server/factory.py \
+ server/loader.py=>server/loader.py \
+ server/module.py=>server/module.py \
+ server/policy.py=>server/policy.py
+
+
+include $(FILE_KBUILD_SUB_FOOTER)
diff --git a/src/libs/xpcom18a4/python/README.vbox b/src/libs/xpcom18a4/python/README.vbox
new file mode 100644
index 00000000..b85f854c
--- /dev/null
+++ b/src/libs/xpcom18a4/python/README.vbox
@@ -0,0 +1,5 @@
+ PyXPCOM sources (see http://developer.mozilla.org/en/docs/PyXPCOM)
+were taken from :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot,
+directory extensions/python/xpcom, branch DOM_AGNOSTIC2_BRANCH, Aug 14 2008.
+
+ Imported to VirtualBox codebase in revision 34814.
diff --git a/src/libs/xpcom18a4/python/__init__.py b/src/libs/xpcom18a4/python/__init__.py
new file mode 100755
index 00000000..3a5943b6
--- /dev/null
+++ b/src/libs/xpcom18a4/python/__init__.py
@@ -0,0 +1,173 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# Activestate Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@activestate.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 *****
+#
+
+# The XPCOM (Cross Platform COM) package.
+from __future__ import print_function
+import sys
+if sys.version_info[0] <= 2:
+ import exceptions
+ XPCOMBaseException = exceptions.Exception
+else:
+ XPCOMBaseException = Exception
+
+# A global "verbose" flag - currently used by the
+# server package to print trace messages
+verbose = 0
+# Map of nsresult -> constant_name.
+hr_map = {}
+
+# The standard XPCOM exception object.
+# Instances of this class are raised by the XPCOM extension module.
+class Exception(XPCOMBaseException):
+ def __init__(self, errno, message = None):
+ assert int(errno) == errno, "The errno param must be an integer"
+ self.errno = errno
+ self.msg = message
+ XPCOMBaseException.__init__(self, errno)
+ def __str__(self):
+ if not hr_map:
+ from . import nsError
+ for name, val in list(nsError.__dict__.items()):
+ if type(val)==type(0):
+ hr_map[val] = name
+ message = self.msg
+ if message is None:
+ message = hr_map.get(self.errno)
+ if message is None:
+ message = ""
+ return "0x%x (%s)" % (self.errno & 0xFFFFFFFF, message)
+
+# An alias for Exception - allows code to say "from xpcom import COMException"
+# rather than "Exception", preventing clashes with the builtin Exception
+COMException = Exception
+
+# Exceptions thrown by servers. It can be good for diagnostics to
+# differentiate between a ServerException (which was presumably explicitly thrown)
+# and a normal exception which may simply be propagating down.
+# (When ServerException objects are thrown across the XPConnect
+# gateway they will be converted back to normal client exceptions if
+# subsequently re-caught by Python)
+class ServerException(Exception):
+ def __init__(self, errno=None, *args, **kw):
+ if errno is None:
+ from . import nsError
+ errno = nsError.NS_ERROR_FAILURE
+ Exception.__init__(self, errno, *args, **kw)
+
+# Logging support - setup the 'xpcom' logger to write to the Mozilla
+# console service, and also to sys.stderr, or optionally a file.
+# Environment variables supports:
+# PYXPCOM_LOG_FILE=filename - if set, used instead of sys.stderr.
+# PYXPCOM_LOG_LEVEL=level - level may be a number or a logging level
+# constant (eg, 'debug', 'error')
+# Later it may make sense to allow a different log level to be set for
+# the file than for the console service.
+import logging
+class ConsoleServiceStream:
+ # enough of a stream to keep logging happy
+ def flush(self):
+ pass
+ def write(self, msg):
+ import xpcom._xpcom as _xpcom
+ _xpcom.LogConsoleMessage(msg)
+ def close(self):
+ pass
+
+def setupLogging():
+ import os
+ if sys.version_info[0] <= 2:
+ import threading, thread
+ hdlr = logging.StreamHandler(ConsoleServiceStream())
+ fmt = logging.Formatter(logging.BASIC_FORMAT)
+ hdlr.setFormatter(fmt)
+ # There is a bug in 2.3 and 2.4.x logging module in that it doesn't
+ # use an RLock, leading to deadlocks in some cases (specifically,
+ # logger.warning("ob is %r", ob), and where repr(ob) itself tries to log)
+ # Later versions of logging use an RLock, so we detect an "old" style
+ # handler and update its lock
+ if sys.version_info[0] <= 2:
+ if type(hdlr.lock) == thread.LockType:
+ hdlr.lock = threading.RLock()
+
+ logger.addHandler(hdlr)
+ # The console handler in mozilla does not go to the console!?
+ # Add a handler to print to stderr, or optionally a file
+ # PYXPCOM_LOG_FILE can specify a filename
+ filename = os.environ.get("PYXPCOM_LOG_FILE")
+ stream = sys.stderr # this is what logging uses as default
+ if filename:
+ try:
+ # open without buffering so never pending output
+ stream = open(filename, "wU", 0)
+ except IOError as why:
+ print("pyxpcom failed to open log file '%s': %s" % (filename, why), file=sys.stderr)
+ # stream remains default
+
+ hdlr = logging.StreamHandler(stream)
+ # see above - fix a deadlock problem on this handler too.
+ if sys.version_info[0] <= 2:
+ if type(hdlr.lock) == thread.LockType:
+ hdlr.lock = threading.RLock()
+
+ fmt = logging.Formatter(logging.BASIC_FORMAT)
+ hdlr.setFormatter(fmt)
+ logger.addHandler(hdlr)
+ # Allow PYXPCOM_LOG_LEVEL to set the level
+ level = os.environ.get("PYXPCOM_LOG_LEVEL")
+ if level:
+ try:
+ level = int(level)
+ except ValueError:
+ try:
+ # might be a symbolic name - all are upper-case
+ level = int(getattr(logging, level.upper()))
+ except (AttributeError, ValueError):
+ logger.warning("The PYXPCOM_LOG_LEVEL variable specifies an "
+ "invalid level")
+ level = None
+ if level:
+ logger.setLevel(level)
+
+logger = logging.getLogger('xpcom')
+# If someone else has already setup this logger, leave things alone.
+if len(logger.handlers) == 0:
+ setupLogging()
+
+# Cleanup namespace - but leave 'logger' there for people to use, so they
+# don't need to know the exact name of the logger.
+del ConsoleServiceStream, logging, setupLogging
diff --git a/src/libs/xpcom18a4/python/client/.cvsignore b/src/libs/xpcom18a4/python/client/.cvsignore
new file mode 100644
index 00000000..52e4e611
--- /dev/null
+++ b/src/libs/xpcom18a4/python/client/.cvsignore
@@ -0,0 +1,2 @@
+*.pyc
+*.pyo
diff --git a/src/libs/xpcom18a4/python/client/__init__.py b/src/libs/xpcom18a4/python/client/__init__.py
new file mode 100755
index 00000000..48adc7f5
--- /dev/null
+++ b/src/libs/xpcom18a4/python/client/__init__.py
@@ -0,0 +1,539 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.com> (original author)
+#
+# 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 *****
+
+import os
+from types import MethodType
+import logging
+from xpcom import xpt, COMException, nsError, logger
+
+# Suck in stuff from _xpcom we use regularly to prevent a module lookup
+from xpcom._xpcom import IID_nsISupports, IID_nsIClassInfo, \
+ IID_nsISupportsCString, IID_nsISupportsString, \
+ IID_nsISupportsWeakReference, IID_nsIWeakReference, \
+ XPTI_GetInterfaceInfoManager, GetComponentManager, XPTC_InvokeByIndex
+
+# Python 3 hacks:
+import sys
+if sys.version_info[0] >= 3:
+ long = int # pylint: disable=W0622,C0103
+
+# Attribute names we may be __getattr__'d for, but know we don't want to delegate
+# Could maybe just look for startswith("__") but this may screw things for some objects.
+_special_getattr_names = ["__del__", "__len__", "__nonzero__", "__eq__", "__neq__"]
+
+_just_int_interfaces = ["nsISupportsPRInt32", "nsISupportsPRInt16", "nsISupportsPRUint32", "nsISupportsPRUint16", "nsISupportsPRUint8", "nsISupportsPRBool"]
+_just_long_interfaces = ["nsISupportsPRInt64", "nsISupportsPRUint64"]
+_just_float_interfaces = ["nsISupportsDouble", "nsISupportsFloat"]
+# When doing a specific conversion, the order we try the interfaces in.
+_int_interfaces = _just_int_interfaces + _just_float_interfaces
+_long_interfaces = _just_long_interfaces + _just_int_interfaces + _just_float_interfaces
+_float_interfaces = _just_float_interfaces + _just_long_interfaces + _just_int_interfaces
+
+method_template = """
+def %s(self, %s):
+ return XPTC_InvokeByIndex(self._comobj_, %d, (%s, (%s)))
+"""
+def _MakeMethodCode(method):
+ # Build a declaration
+ param_no = 0
+ param_decls = []
+ param_flags = []
+ param_names = []
+ used_default = 0
+ for param in method.params:
+ param_no = param_no + 1
+ param_name = "Param%d" % (param_no,)
+ param_default = ""
+ if not param.hidden_indicator and param.IsIn() and not param.IsDipper():
+ if param.IsOut() or used_default: # If the param is "inout", provide a useful default for the "in" direction.
+ param_default = " = None"
+ used_default = 1 # Once we have used one once, we must for the rest!
+ param_decls.append(param_name + param_default)
+ param_names.append(param_name)
+
+ type_repr = xpt.MakeReprForInvoke(param)
+ param_flags.append( (param.param_flags,) + type_repr )
+ sep = ", "
+ param_decls = sep.join(param_decls)
+ if len(param_names)==1: # Damn tuple reprs.
+ param_names = param_names[0] + ","
+ else:
+ param_names = sep.join(param_names)
+ # A couple of extra newlines make them easier to read for debugging :-)
+ return method_template % (method.name, param_decls, method.method_index, tuple(param_flags), param_names)
+
+# Keyed by IID, each item is a tuple of (methods, getters, setters)
+interface_cache = {}
+# Keyed by [iid][name], each item is an unbound method.
+interface_method_cache = {}
+
+# Keyed by clsid from nsIClassInfo - everything ever queried for the CID.
+contractid_info_cache = {}
+have_shutdown = 0
+
+def _shutdown():
+ interface_cache.clear()
+ interface_method_cache.clear()
+ contractid_info_cache.clear()
+ global have_shutdown
+ have_shutdown = 1
+
+# Fully process the named method, generating method code etc.
+def BuildMethod(method_info, iid):
+ name = method_info.name
+ try:
+ return interface_method_cache[iid][name]
+ except KeyError:
+ pass
+ # Generate it.
+ assert not (method_info.IsSetter() or method_info.IsGetter()), "getters and setters should have been weeded out by now"
+ method_code = _MakeMethodCode(method_info)
+ # Build the method - We only build a function object here
+ # - they are bound to each instance as needed.
+
+## print "Method Code for %s (%s):" % (name, iid)
+## print method_code
+ codeObject = compile(method_code, "<XPCOMObject method '%s'>" % (name,), "exec")
+ # Exec the code object
+ tempNameSpace = {}
+ exec(codeObject, globals(), tempNameSpace)
+ ret = tempNameSpace[name]
+ if iid not in interface_method_cache:
+ interface_method_cache[iid] = {}
+ interface_method_cache[iid][name] = ret
+ return ret
+
+from xpcom.xpcom_consts import XPT_MD_GETTER, XPT_MD_SETTER, XPT_MD_NOTXPCOM, XPT_MD_CTOR, XPT_MD_HIDDEN
+FLAGS_TO_IGNORE = XPT_MD_NOTXPCOM | XPT_MD_CTOR | XPT_MD_HIDDEN
+
+# Pre-process the interface - generate a list of methods, constants etc,
+# but don't actually generate the method code.
+def BuildInterfaceInfo(iid):
+ assert not have_shutdown, "Can't build interface info after a shutdown"
+ ret = interface_cache.get(iid, None)
+ if ret is None:
+ # Build the data for the cache.
+ method_code_blocks = []
+ getters = {}
+ setters = {}
+ method_infos = {}
+
+ interface = xpt.Interface(iid)
+ for m in interface.methods:
+ flags = m.flags
+ if flags & FLAGS_TO_IGNORE == 0:
+ if flags & XPT_MD_SETTER:
+ param_flags = list([(x.param_flags,) + xpt.MakeReprForInvoke(x) for x in m.params])
+ setters[m.name] = m.method_index, param_flags
+ elif flags & XPT_MD_GETTER:
+ param_flags = list([(x.param_flags,) + xpt.MakeReprForInvoke(x) for x in m.params])
+ getters[m.name] = m.method_index, param_flags
+ else:
+ method_infos[m.name] = m
+
+ # Build the constants.
+ constants = {}
+ for c in interface.constants:
+ constants[c.name] = c.value
+ ret = method_infos, getters, setters, constants
+ interface_cache[iid] = ret
+ return ret
+
+class _XPCOMBase:
+ def __cmp__(self, other):
+ try:
+ other = other._comobj_
+ except AttributeError:
+ pass
+ return cmp(self._comobj_, other)
+
+ def __hash__(self):
+ return hash(self._comobj_)
+
+ # The basic rich compare ops for equality
+ def __eq__(self, other):
+ try:
+ other = other._comobj_
+ except AttributeError:
+ pass
+ return self._comobj_ == other
+
+ def __neq__(self, other):
+ try:
+ other = other._comobj_
+ except AttributeError:
+ pass
+ return self._comobj_ != other
+
+ # See if the object support strings.
+ def __str__(self):
+ try:
+ self._comobj_.QueryInterface(IID_nsISupportsCString, 0)
+ return str(self._comobj_)
+ except COMException:
+ return self.__repr__()
+
+ def __unicode__(self):
+ try:
+ prin = self._comobj_.QueryInterface(IID_nsISupportsString)
+ except COMException:
+ return unicode(str(self))
+ return prin.data
+
+ # Try the numeric support.
+ def _do_conversion(self, interface_names, cvt):
+ iim = XPTI_GetInterfaceInfoManager()
+ for interface_name in interface_names:
+ iid = iim.GetInfoForName(interface_name).GetIID()
+ try:
+ prim = self._comobj_.QueryInterface(iid)
+ return cvt(prim.data)
+ except COMException:
+ pass
+ raise ValueError("This object does not support automatic numeric conversion to this type")
+
+ def __int__(self):
+ if sys.version_info[0] >= 3:
+ return self._do_conversion(_int_interfaces + _long_interfaces, int)
+ return self._do_conversion(_int_interfaces, int)
+
+ def __long__(self):
+ return self._do_conversion(_long_interfaces, long)
+
+ def __float__(self):
+ return self._do_conversion(_float_interfaces, float)
+
+class Component(_XPCOMBase):
+ def __init__(self, ob, iid = IID_nsISupports):
+ assert not hasattr(ob, "_comobj_"), "Should be a raw nsIWhatever, not a wrapped one"
+ ob_name = None
+ if not hasattr(ob, "IID"):
+ ob_name = ob
+ cm = GetComponentManager()
+ ob = cm.createInstanceByContractID(ob)
+ assert not hasattr(ob, "_comobj_"), "The created object should be a raw nsIWhatever, not a wrapped one"
+ # Keep a reference to the object in the component too
+ self.__dict__['_comobj_'] = ob
+ # hit __dict__ directly to avoid __setattr__()
+ self.__dict__['_interfaces_'] = {} # keyed by IID
+ self.__dict__['_interface_names_'] = {} # keyed by IID name
+ self.__dict__['_interface_infos_'] = {} # keyed by IID
+ self.__dict__['_name_to_interface_iid_'] = {}
+ self.__dict__['_tried_classinfo_'] = 0
+
+ if ob_name is None:
+ ob_name = "<unknown>"
+ self.__dict__['_object_name_'] = ob_name
+ self.QueryInterface(iid)
+
+ def _build_all_supported_interfaces_(self):
+ # Use nsIClassInfo, but don't do it at object construction to keep perf up.
+ # Only pay the penalty when we really need it.
+ assert not self._tried_classinfo_, "already tried to get the class info."
+ self.__dict__['_tried_classinfo_'] = 1
+ # See if nsIClassInfo is supported.
+ try:
+ classinfo = self._comobj_.QueryInterface(IID_nsIClassInfo, 0)
+ except COMException:
+ classinfo = None
+ if classinfo is not None:
+ try:
+ real_cid = classinfo.contractID
+ except COMException:
+ real_cid = None
+ if real_cid:
+ self.__dict__['_object_name_'] = real_cid
+ contractid_info = contractid_info_cache.get(real_cid)
+ else:
+ contractid_info = None
+ if contractid_info is None:
+ try:
+ interface_infos = classinfo.getInterfaces()
+ except COMException:
+ interface_infos = []
+ for nominated_iid in interface_infos:
+ # Interface may appear twice in the class info list, so check this here.
+ if nominated_iid not in self.__dict__['_interface_infos_']:
+ # Just invoke our QI on the object
+ self.queryInterface(nominated_iid)
+ if real_cid is not None:
+ contractid_info = {}
+ contractid_info['_name_to_interface_iid_'] = self.__dict__['_name_to_interface_iid_']
+ contractid_info['_interface_infos_'] = self.__dict__['_interface_infos_']
+ contractid_info_cache[real_cid] = contractid_info
+ else:
+ for key, val in list(contractid_info.items()):
+ self.__dict__[key].update(val)
+
+ self.__dict__['_com_classinfo_'] = classinfo
+
+ def _remember_interface_info(self, iid):
+ # XXX - there is no good reason to cache this only in each instance
+ # It should be cached at the module level, so we don't need to
+ # rebuild the world for each new object.
+ iis = self.__dict__['_interface_infos_']
+ assert iid not in iis, "Already remembered this interface!"
+ try:
+ method_infos, getters, setters, constants = BuildInterfaceInfo(iid)
+ except COMException as why:
+ # Failing to build an interface info generally isn't a real
+ # problem - its probably just that the interface is non-scriptable.
+ logger.info("Failed to build interface info for %s: %s", iid, why)
+ # Remember the fact we failed.
+ iis[iid] = None
+ return
+
+ # Remember all the names so we can delegate
+ iis[iid] = method_infos, getters, setters, constants
+ names = self.__dict__['_name_to_interface_iid_']
+ for name in list(method_infos.keys()): names[name] = iid
+ for name in list(getters.keys()): names[name] = iid
+ for name in list(setters.keys()): names[name] = iid
+ for name in list(constants.keys()): names[name] = iid
+
+ def QueryInterface(self, iid):
+ if iid in self._interfaces_:
+ assert iid.name in self._interface_names_, "_interfaces_ has the key, but _interface_names_ does not!"
+ return self
+ # Haven't seen this before - do a real QI.
+ if iid not in self._interface_infos_:
+ self._remember_interface_info(iid)
+ iface_info = self._interface_infos_[iid]
+ if iface_info is None:
+ # We have tried, but failed, to get this interface info. Its
+ # unlikely to work later either - its probably non-scriptable.
+ # That means our component wrappers are useless - so just return a
+ # raw nsISupports object with no wrapper.
+ return self._comobj_.QueryInterface(iid, 0)
+
+ raw_iface = self._comobj_.QueryInterface(iid, 0)
+
+ method_infos, getters, setters, constants = iface_info
+ new_interface = _Interface(raw_iface, iid, method_infos,
+ getters, setters, constants)
+ self._interfaces_[iid] = new_interface
+ self._interface_names_[iid.name] = new_interface
+ # As we 'flatten' objects when possible, a QI on an object just
+ # returns ourself - all the methods etc on this interface are
+ # available.
+ return self
+
+ queryInterface = QueryInterface # Alternate name.
+
+ def __getattr__(self, attr):
+ if attr in _special_getattr_names:
+ raise AttributeError(attr)
+ # First allow the interface name to return the "raw" interface
+ interface = self.__dict__['_interface_names_'].get(attr, None)
+ if interface is not None:
+ return interface
+ # See if we know the IID of an interface providing this attribute
+ iid = self.__dict__['_name_to_interface_iid_'].get(attr, None)
+ # This may be first time trying this interface - get the nsIClassInfo
+ if iid is None and not self._tried_classinfo_:
+ self._build_all_supported_interfaces_()
+ iid = self.__dict__['_name_to_interface_iid_'].get(attr, None)
+ # If the request is for an interface name, it may now be
+ # available.
+ interface = self.__dict__['_interface_names_'].get(attr, None)
+ if interface is not None:
+ return interface
+
+ if iid is not None:
+ interface = self.__dict__['_interfaces_'].get(iid, None)
+ if interface is None:
+ self.QueryInterface(iid)
+ interface = self.__dict__['_interfaces_'][iid]
+ return getattr(interface, attr)
+ # Some interfaces may provide this name via "native" support.
+ # Loop over all interfaces, and if found, cache it for next time.
+ for interface in list(self.__dict__['_interfaces_'].values()):
+ try:
+ ret = getattr(interface, attr)
+ self.__dict__['_name_to_interface_iid_'][attr] = interface._iid_
+ return ret
+ except AttributeError:
+ pass
+ raise AttributeError("XPCOM component '%s' has no attribute '%s'" % (self._object_name_, attr))
+
+ def __setattr__(self, attr, val):
+ iid = self._name_to_interface_iid_.get(attr, None)
+ # This may be first time trying this interface - get the nsIClassInfo
+ if iid is None and not self._tried_classinfo_:
+ self._build_all_supported_interfaces_()
+ iid = self.__dict__['_name_to_interface_iid_'].get(attr, None)
+ if iid is not None:
+ interface = self._interfaces_.get(iid, None)
+ if interface is None:
+ self.QueryInterface(iid)
+ interface = self.__dict__['_interfaces_'][iid]
+ setattr(interface, attr, val)
+ return
+ raise AttributeError("XPCOM component '%s' has no attribute '%s'" % (self._object_name_, attr))
+
+ def _get_classinfo_repr_(self):
+ try:
+ if not self._tried_classinfo_:
+ self._build_all_supported_interfaces_()
+ assert self._tried_classinfo_, "Should have tried the class info by now!"
+ except COMException:
+ # Error building the info - ignore the error, but ensure that
+ # we are flagged as *not* having built, so the error is seen
+ # by the first caller who actually *needs* this to work.
+ self.__dict__['_tried_classinfo_'] = 0
+
+ iface_names = list(self.__dict__['_interface_names_'].keys())
+ try:
+ iface_names.remove("nsISupports")
+ except ValueError:
+ pass
+ iface_names.sort()
+
+ iface_desc = "implementing %s" % (",".join(iface_names),)
+ return iface_desc
+
+ def __repr__(self):
+ # We can advantage from nsIClassInfo - use it.
+ iface_desc = self._get_classinfo_repr_()
+ return "<XPCOM component '%s' (%s)>" % (self._object_name_,iface_desc)
+
+class _Interface(_XPCOMBase):
+ def __init__(self, comobj, iid, method_infos, getters, setters, constants):
+ self.__dict__['_comobj_'] = comobj
+ self.__dict__['_iid_'] = iid
+ self.__dict__['_property_getters_'] = getters
+ self.__dict__['_property_setters_'] = setters
+ self.__dict__['_method_infos_'] = method_infos # method infos waiting to be turned into real methods.
+ self.__dict__['_methods_'] = {} # unbound methods
+ self.__dict__['_object_name_'] = iid.name
+ self.__dict__.update(constants)
+ # We remember the constant names to prevent the user trying to assign to them!
+ self.__dict__['_constant_names_'] = list(constants.keys())
+
+ def __getattr__(self, attr):
+ # Allow the underlying interface to provide a better implementation if desired.
+ if attr in _special_getattr_names:
+ raise AttributeError(attr)
+
+ ret = getattr(self.__dict__['_comobj_'], attr, None)
+ if ret is not None:
+ return ret
+ # Do the function thing first.
+ unbound_method = self.__dict__['_methods_'].get(attr, None)
+ if unbound_method is not None:
+ return MethodType(unbound_method, self)
+
+ getters = self.__dict__['_property_getters_']
+ info = getters.get(attr)
+ if info is not None:
+ method_index, param_infos = info
+ if len(param_infos)!=1: # Only expecting a retval
+ raise RuntimeError("Can't get properties with this many args!")
+ args = ( param_infos, () )
+ return XPTC_InvokeByIndex(self._comobj_, method_index, args)
+
+ # See if we have a method info waiting to be turned into a method.
+ # Do this last as it is a one-off hit.
+ method_info = self.__dict__['_method_infos_'].get(attr, None)
+ if method_info is not None:
+ unbound_method = BuildMethod(method_info, self._iid_)
+ # Cache it locally
+ self.__dict__['_methods_'][attr] = unbound_method
+ return MethodType(unbound_method, self)
+
+ raise AttributeError("XPCOM component '%s' has no attribute '%s'" % (self._object_name_, attr))
+
+ def __setattr__(self, attr, val):
+ # If we already have a __dict__ item of that name, and its not one of
+ # our constants, we just directly set it, and leave.
+ if attr in self.__dict__ and attr not in self.__dict__['_constant_names_']:
+ self.__dict__[attr] = val
+ return
+ # Start sniffing for what sort of attribute this might be?
+ setters = self.__dict__['_property_setters_']
+ info = setters.get(attr)
+ if info is None:
+ raise AttributeError("XPCOM component '%s' can not set attribute '%s'" % (self._object_name_, attr))
+ method_index, param_infos = info
+ if len(param_infos)!=1: # Only expecting a single input val
+ raise RuntimeError("Can't set properties with this many args!")
+ real_param_infos = ( param_infos, (val,) )
+ return XPTC_InvokeByIndex(self._comobj_, method_index, real_param_infos)
+
+ def __repr__(self):
+ return "<XPCOM interface '%s'>" % (self._object_name_,)
+
+
+# Called by the _xpcom C++ framework to wrap interfaces up just
+# before they are returned.
+def MakeInterfaceResult(ob, iid):
+ return Component(ob, iid)
+
+class WeakReference:
+ """A weak-reference object. You construct a weak reference by passing
+ any COM object you like. If the object does not support weak
+ refs, you will get a standard NS_NOINTERFACE exception.
+
+ Once you have a weak-reference, you can "call" the object to get
+ back a strong reference. Eg:
+
+ >>> some_ob = components.classes['...']
+ >>> weak_ref = WeakReference(some_ob)
+ >>> new_ob = weak_ref() # new_ob is effectively "some_ob" at this point
+ >>> # EXCEPT: new_ob may be None if some_ob has already died - a
+ >>> # weak reference does not keep the object alive (that is the point)
+
+ You should never hold onto this resulting strong object for a long time,
+ or else you defeat the purpose of the weak-reference.
+ """
+ def __init__(self, ob, iid = None):
+ swr = Component(ob._comobj_, IID_nsISupportsWeakReference)
+ self._comobj_ = Component(swr.GetWeakReference()._comobj_, IID_nsIWeakReference)
+ if iid is None:
+ try:
+ iid = ob.IID
+ except AttributeError:
+ iid = IID_nsISupports
+ self._iid_ = iid
+ def __call__(self, iid = None):
+ if iid is None: iid = self._iid_
+ try:
+ return Component(self._comobj_.QueryReferent(iid)._comobj_, iid)
+ except COMException as details:
+ if details.errno != nsError.NS_ERROR_NULL_POINTER:
+ raise
+ return None
diff --git a/src/libs/xpcom18a4/python/components.py b/src/libs/xpcom18a4/python/components.py
new file mode 100755
index 00000000..b0910f87
--- /dev/null
+++ b/src/libs/xpcom18a4/python/components.py
@@ -0,0 +1,248 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.com> (original author)
+#
+# 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 *****
+
+# This module provides the JavaScript "components" interface
+from . import xpt
+import xpcom
+import xpcom._xpcom as _xpcom
+import xpcom.client
+import xpcom.server
+
+StringTypes = [bytes, str]
+
+def _get_good_iid(iid):
+ if iid is None:
+ iid = _xpcom.IID_nsISupports
+ elif type(iid) in StringTypes and len(iid)>0 and iid[0] != "{":
+ iid = getattr(interfaces, iid)
+ return iid
+
+# The "manager" object.
+manager = xpcom.client.Component(_xpcom.GetComponentManager(), _xpcom.IID_nsIComponentManager)
+
+# The component registrar
+registrar = xpcom.client.Component(_xpcom.GetComponentManager(), _xpcom.IID_nsIComponentRegistrar)
+
+# The "interfaceInfoManager" object - JS doesnt have this.
+interfaceInfoManager = _xpcom.XPTI_GetInterfaceInfoManager()
+
+# The serviceManager - JS doesnt have this either!
+serviceManager = _xpcom.GetServiceManager()
+
+# The "Exception" object
+Exception = xpcom.COMException
+
+# Base class for our collections.
+# It appears that all objects supports "." and "[]" notation.
+# eg, "interface.nsISupports" or interfaces["nsISupports"]
+class _ComponentCollection:
+ # Bases are to over-ride 2 methods.
+ # _get_one(self, name) - to return one object by name
+ # _build_dict - to return a dictionary which provide access into
+ def __init__(self):
+ self._dict_data = None
+ def keys(self):
+ if self._dict_data is None:
+ self._dict_data = self._build_dict()
+ return list(self._dict_data.keys())
+ def items(self):
+ if self._dict_data is None:
+ self._dict_data = self._build_dict()
+ return list(self._dict_data.items())
+ def values(self):
+ if self._dict_data is None:
+ self._dict_data = self._build_dict()
+ return list(self._dict_data.values())
+# def has_key(self, key):
+# if self._dict_data is None:
+# self._dict_data = self._build_dict()
+# return self._dict_data.has_key(key)
+
+ def __len__(self):
+ if self._dict_data is None:
+ self._dict_data = self._build_dict()
+ return len(self._dict_data)
+
+ def __getattr__(self, attr):
+ if self._dict_data is not None and attr in self._dict_data:
+ return self._dict_data[attr]
+ return self._get_one(attr)
+ def __getitem__(self, item):
+ if self._dict_data is not None and item in self._dict_data:
+ return self._dict_data[item]
+ return self._get_one(item)
+
+_constants_by_iid_map = {}
+
+class _Interface:
+ # An interface object.
+ def __init__(self, name, iid):
+ # Bypass self.__setattr__ when initializing attributes.
+ d = self.__dict__
+ d['_iidobj_'] = iid # Allows the C++ framework to treat this as a native IID.
+ d['name'] = name
+ def __cmp__(self, other):
+ this_iid = self._iidobj_
+ other_iid = getattr(other, "_iidobj_", other)
+ return cmp(this_iid, other_iid)
+ def __eq__(self, other):
+ this_iid = self._iidobj_
+ other_iid = getattr(other, "_iidobj_", other)
+ return this_iid == other_iid
+ def __hash__(self):
+ return hash(self._iidobj_)
+ def __str__(self):
+ return str(self._iidobj_)
+ def __getitem__(self, item):
+ raise TypeError("components.interface objects are not subscriptable")
+ def __setitem__(self, item, value):
+ raise TypeError("components.interface objects are not subscriptable")
+ def __setattr__(self, attr, value):
+ raise AttributeError("Can not set attributes on components.Interface objects")
+ def __getattr__(self, attr):
+ # Support constants as attributes.
+ c = _constants_by_iid_map.get(self._iidobj_)
+ if c is None:
+ c = {}
+ i = xpt.Interface(self._iidobj_)
+ for c_ob in i.constants:
+ c[c_ob.name] = c_ob.value
+ _constants_by_iid_map[self._iidobj_] = c
+ if attr in c:
+ return c[attr]
+ raise AttributeError("'%s' interfaces do not define a constant '%s'" % (self.name, attr))
+
+
+class _Interfaces(_ComponentCollection):
+ def _get_one(self, name):
+ try:
+ item = interfaceInfoManager.GetInfoForName(name)
+ except xpcom.COMException as why:
+ # Present a better exception message, and give a more useful error code.
+ from . import nsError
+ raise xpcom.COMException(nsError.NS_ERROR_NO_INTERFACE, "The interface '%s' does not exist" % (name,))
+ return _Interface(item.GetName(), item.GetIID())
+
+ def _build_dict(self):
+ ret = {}
+ enum = interfaceInfoManager.EnumerateInterfaces()
+ while not enum.IsDone():
+ # Call the Python-specific FetchBlock, to keep the loop in C.
+ items = enum.FetchBlock(500, _xpcom.IID_nsIInterfaceInfo)
+ # This shouldnt be necessary, but appears to be so!
+ for item in items:
+ ret[item.GetName()] = _Interface(item.GetName(), item.GetIID())
+ return ret
+
+# And the actual object people use.
+interfaces = _Interfaces()
+
+del _Interfaces # Keep our namespace clean.
+
+#################################################
+class _Class:
+ def __init__(self, contractid):
+ self.contractid = contractid
+ def __getattr__(self, attr):
+ if attr == "clsid":
+ rc = registrar.contractIDToCID(self.contractid)
+ # stash it away - it can never change!
+ self.clsid = rc
+ return rc
+ raise AttributeError("%s class has no attribute '%s'" % (self.contractid, attr))
+ def createInstance(self, iid = None):
+ import xpcom.client
+ try:
+ return xpcom.client.Component(self.contractid, _get_good_iid(iid))
+ except xpcom.COMException as details:
+ from . import nsError
+ # Handle "no such component" in a cleaner way for the user.
+ if details.errno == nsError.NS_ERROR_FACTORY_NOT_REGISTERED:
+ raise xpcom.COMException(details.errno, "No such component '%s'" % (self.contractid,))
+ raise # Any other exception reraise.
+ def getService(self, iid = None):
+ return serviceManager.getServiceByContractID(self.contractid, _get_good_iid(iid))
+
+class _Classes(_ComponentCollection):
+ def __init__(self):
+ _ComponentCollection.__init__(self)
+ def _get_one(self, name):
+ # XXX - Need to check the contractid is valid!
+ return _Class(name)
+
+ def _build_dict(self):
+ ret = {}
+ enum = registrar.enumerateContractIDs()
+ while enum.hasMoreElements():
+ # Call the Python-specific FetchBlock, to keep the loop in C.
+ items = enum.fetchBlock(2000, _xpcom.IID_nsISupportsCString)
+ for item in items:
+ name = str(item.data)
+ ret[name] = _Class(name)
+ return ret
+
+classes = _Classes()
+
+del _Classes
+
+del _ComponentCollection
+
+# The ID function
+ID = _xpcom.ID
+
+# A helper to cleanup our namespace as xpcom shuts down.
+class _ShutdownObserver:
+ _com_interfaces_ = interfaces.nsIObserver
+ def observe(self, service, topic, extra):
+ global manager, registrar, classes, interfaces, interfaceInfoManager, _shutdownObserver, serviceManager, _constants_by_iid_map
+ manager = registrar = classes = interfaces = interfaceInfoManager = _shutdownObserver = serviceManager = _constants_by_iid_map = None
+ xpcom.client._shutdown()
+ xpcom.server._shutdown()
+ def _query_interface_(self, iid): # VBox: Needed so that the interface check in the DefaultPolicy initialization will pass; @bugref{10079}.
+ if iid == interfaces.nsIObserver:
+ return 1
+ return None
+
+svc = _xpcom.GetServiceManager().getServiceByContractID("@mozilla.org/observer-service;1", interfaces.nsIObserverService)
+# Observers will be QI'd for a weak-reference, so we must keep the
+# observer alive ourself, and must keep the COM object alive,
+# _not_ just the Python instance!!!
+_shutdownObserver = xpcom.server.WrapObject(_ShutdownObserver(), interfaces.nsIObserver)
+# Say we want a weak ref due to an assertion failing. If this is fixed, we can pass 0,
+# and remove the lifetime hacks above! See http://bugzilla.mozilla.org/show_bug.cgi?id=99163
+svc.addObserver(_shutdownObserver, "xpcom-shutdown", 1)
+del svc, _ShutdownObserver
diff --git a/src/libs/xpcom18a4/python/doc/advanced.html b/src/libs/xpcom18a4/python/doc/advanced.html
new file mode 100644
index 00000000..ab6994fc
--- /dev/null
+++ b/src/libs/xpcom18a4/python/doc/advanced.html
@@ -0,0 +1,176 @@
+<html>
+<!-- ***** 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 PyXPCOM.
+ -
+ - The Initial Developer of the Original Code is
+ - ActiveState Tool Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2000-2001
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - 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 LGPL or the GPL. 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 ***** -->
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Python XPCOM Advanced Topics</title>
+</head>
+
+<body>
+
+<h1>Python XPCOM Advanced Topics</h1>
+
+<p>This document contains a series of tidbits that don't fit
+anywhere else. As the Python XPCOM Package documentation matures, most of
+these topics will have another home.</p>
+
+<h2>XPCOM Services</h2>
+<p>An XPCOM service is simply a singleton registered by name.&nbsp; Python has
+full support for both using and implementing XPCOM services.&nbsp; To use a
+service, use <i>xpcom.components.services</i> just like the JavaScript
+counterpart.&nbsp; There is nothing special about implementing a service in
+Python; see the standard XPCOM documentation on services for more information.</p>
+
+<h2>nsIVariant</h2>
+
+<p>There is (almost) full support for <i>nsIVariant</i>.&nbsp; Any <i>nsIVariant</i>
+parameters will automatically be translated to and from regular Python objects
+giving, in effect, a multi-type parameter.&nbsp; This should be automatic, so
+there is not much else to say!&nbsp; Note that if you really want, you can
+create and pass your own <i>nsIVariant</i> object instead of a regular Python
+object, thereby allowing explicit control over the type of variant created.</p>
+
+<h2>nsISupports Primitives.</h2>
+
+<p>There is a set of interfaces described in <i>nsISupportsPrimitives.idl</i>, which I
+term collectively the <i>nsISupports Primitives Interfaces</i>.&nbsp; These
+are a set of interfaces a component can support to allow automatic conversion to
+and from many basic types.&nbsp; For example, an interface can define that it
+supports the <i>nsISupportsCString</i> interface, and this could be used by any
+program that wishes to get a string representation of the object.&nbsp; If an
+interface wishes to expose itself as a &quot;boolean value&quot;, it may choose
+to support the <i>nsISupportsPRBool</i> interface.</p>
+<p>When you call an XPCOM object (i.e., you have an XPCOM interface you are
+calling), you can use
+the builtin functions <i>str()</i>, <i>int()</i>, <i>long()</i> etc., on the
+object<i>.</i>&nbsp; In the
+case of <i>str()</i>, if the object does not support the <i>nsISupportsCString</i>
+or <i>nsISupportsString</i> interfaces, the default string <i>str()</i> for the
+object will be returned (i.e., what is normally returned for most XPCOM objects -
+support for these interface is not very common!).&nbsp; In the case of the numeric functions, a <i>ValueError</i>
+exception will be raised if the objects do not support any interface that can be
+used for the conversion.&nbsp;<i>ValueError</i> is used instead of <i>TypeError</i>,
+as the type itself (i.e., an XPCOM object) can sometimes be used in this context -
+hence it is the specific <i>value</i> of the object that is the problem.</p>
+<p>The use of <i>repr()</i> on an XPCOM interface object prevents support
+attempts for these interfaces, and allows you to see the
+&quot;real&quot; object, rather than what the object wants you to see!</p>
+<p>When you implement an XPCOM object, you have two choices for implementation
+of these interfaces:</p>
+<ul>
+ <li>You can explicitly handle these interfaces like any other interface.&nbsp;
+ In this case, you have full control.&nbsp; However, if you
+ implement only one of these standard interfaces, then you are only
+ overriding the default behavior for that specific interface - all other
+ interfaces not explicitly listed in your class will still get the behavior
+ described below.<br>
+ </li>
+ <li>If your class does not define support for these interfaces, the framework
+ will use standard Python class semantics to implement them - i.e., if your
+ class provides a <i>__str__</i> method, it will be used to implement <i>nsISupportsCString</i>
+ and <i>nsISupportsString</i>, if you provide <i>__int__</i>, <i>__long__</i>,
+ <i>__float__</i> etc., methods, they will be used to implement the numeric
+ interfaces.&nbsp; If your class defines no such special methods, then the <i>
+ QueryInterface()</i> for those interfaces fails (rather than the QI succeeding
+ and the operation to fetch the data failing).</li>
+</ul>
+<blockquote>
+<p>This allows for an interesting feature that would not normally be
+possible.&nbsp; Consider Python code that does a <i>str()</i> on an&nbsp; XPCOM
+interface, and where the XPCOM interface itself is implemented in Python and
+provides a <i>__str__</i> method.&nbsp; The <i>str()</i> on the original
+interface queries for the <i>nsISupportsCString</i> interface.&nbsp; The
+Python implemented object responds to this interface and delegates to the <i>__str__</i>
+method. At the end of all this, <i>str()</i> returns the same result
+as if the objects were native Python objects with no XPCOM layer in between.</p>
+
+</blockquote>
+
+<h2>Enumerators</h2>
+
+<p>The primary enumerator used by XPCOM is <i>nsISimpleEnumerator</i>.
+Although the Python XPCOM package has full support for <i>nsIEnumerator</i>,
+since this interface is not &quot;scriptable&quot;, you should avoided using it in interfaces
+you design.</p>
+
+<p>When you use <i>nsISimpleEnumerator</i> from Python, the following enhancements
+are available:</p>
+<ul>
+ <li>The <i>GetNext()</i> method takes an optional IID as a parameter. If
+ this is specified, the returned object will be of this interface.&nbsp; This
+ prevents the manual <i>QueryInterface()</i> generally required from other
+ languages.</li>
+ <li>There is a <i>FetchBlock(num, [iid])</i> method, which fetches the
+ specified number of elements in one operation and returns a Python
+ list. This can be useful for large enumerator sets, so the loop
+ iterating the elements runs at full C++ speed.</li>
+</ul>
+<p><i>nsIEnumerator</i> has similar enhancements.</p>
+<p>When implementing a Python XPCOM object, the Python class <i>xpcom.server.enumerator.SimpleEnumerator()</i>
+can be used.&nbsp; You can pass a standard Python sequence (list, etc), and it
+will be correctly wrapped in an <i>nsISimpleEnumerator</i> interface.</p>
+<h2>Files</h2>
+<p>The Python XPCOM package provides an <i> xpcom.file</i> module.&nbsp; This implements
+a Python-like file object on top of the XPCOM/Mozilla stream interfaces.&nbsp;
+When run from within the Mozilla environment, this allows you to open almost any
+URL supported by Mozilla (including &quot;chrome://&quot; etc.,).</p>
+<p>See this module for more information, including test code.</p>
+<h2>XPCOM Object Identity</h2>
+<p>XPCOM has defined rules for object identity and for how objects must behave
+in their <i> QueryInterface()</i> implementations.&nbsp; The Python XPCOM framework
+manages this for you; your code can return new Python instances etc., when
+responding to new interfaces, and the framework itself will ensure the XPCOM
+semantics are followed.&nbsp; Critically, the framework provides no mechanism
+for breaking these rules.</p>
+<h2>Policies</h2>
+<p>The Python XPCOM framework has the concept of &quot;policies&quot; that
+define how XPCOM semantics are mapped to Python objects.&nbsp; It is the policy
+that implements delegation of <i> QueryInterface()</i>, translates property
+references into direct property references, and failing that, &quot;get_name&quot;
+and &quot;set_name&quot; calls, decides how to handle exceptions in the
+component, and so on.</p>
+<p>The default policy is very flexible and suitable for most purposes.
+Indeed, the Komodo project has never had to implement a custom policy.
+However, you should be aware the feature exists should you wish to do some
+bizarre things, such as using Python as a bridge between XPCOM and some other
+component technology.</p>
+
+</body>
+
+</html>
diff --git a/src/libs/xpcom18a4/python/doc/architecture.html b/src/libs/xpcom18a4/python/doc/architecture.html
new file mode 100644
index 00000000..d12a2a76
--- /dev/null
+++ b/src/libs/xpcom18a4/python/doc/architecture.html
@@ -0,0 +1,116 @@
+<html>
+<!-- ***** 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 PyXPCOM.
+ -
+ - The Initial Developer of the Original Code is
+ - ActiveState Tool Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2000-2001
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - 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 LGPL or the GPL. 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 ***** -->
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Architecture</title>
+</head>
+
+<body>
+
+<h1>Python XPCOM Package Architecture</h1>
+<h2><a name="Architecture">Architecture</a></h2>
+<p>Much of the design for the Python XPCOM Package has been borrowed from the Python MS-COM
+extensions in <i>win32com</i>. Most of the major limitations and drawbacks in the <i>win32com</i>
+design have been addressed, mainly &quot;auto-wrapping&quot; of
+interface objects, which is not supported by <i>win32com</i>.</p>
+<p>Like <i>win32com</i>, this architecture includes the concept of <i>client COM</i> and <i>server
+COM.</i> </p>
+<p>Client COM:</p>
+<ul>
+ <li>calls other interfaces</li>
+ <li>is supported by <i>PyInterfaces</i> implemented in C++, which assists
+in making the COM calls</li>
+ <li>is supported by <i>PyGateways</i>, which assists in receiving
+external COM calls and dispatching them to the correct Python object</li>
+ <li> is supported in the <i>xpcom/client</i> package</li>
+</ul>
+<p>Server COM:</p>
+<ul>
+ <li>implements interfaces for use by other XPCOM applications or components</li>
+ <li> is
+supported in the <i>xpcom/server</i> package</li>
+</ul>
+<p>The XPConnect framework is very powerful, and far exceeds what COM's <i>
+IDispatch</i> can offer.&nbsp; Thus, we are able to get by with far fewer interfaces
+supported in the C++ level, and defer most things to the Python code that uses
+XPConnect.&nbsp; As a result, the requirement for a huge number of interfaces to
+exist in the <i>.pyd</i> does not exist.&nbsp; There are, however, a number of
+interfaces that do require native C++ support: these are interfaces
+required to &quot;boot&quot; the XPConnect support (i.e., the interfaces that are
+used to get information about interfaces), and also two gateways that need to
+work without interface information available. This last requirement is
+due to the XPCOM shutdown-ordering - it may be a bug, but is not an unreasonable
+amount of code anyway.</p>
+<p><b>Auto-wrapping</b> of COM objects is supported by both client COM and
+server COM.&nbsp;For client COM, auto-wrapping means that the
+Python programmer always sees Python &quot;component&quot; objects, rather than
+raw C++ interface objects; to the user, it all appears to &quot;just
+work&quot;.&nbsp; This is a major source of frustration in the <i>win32com</i>
+framework.</p>
+<p>For server COM, auto-wrapping means that you can
+pass Python instances wherever a COM object is expected. If the Python
+instance supports COM interfaces, by virtue of having a <i>_com_interfaces_</i>
+attribute that lists the interface requested, it will be automatically wrapped
+in the correct COM object.&nbsp;</p>
+<p><b>Error Handling:</b> The C++ framework has good error handling support,
+and uses the XPCOM console service to log debug messages, Python exceptions and
+tracebacks.&nbsp; <i>win32com</i> does not have good exception/traceback support
+at the C++ level, mainly because COM does not define a service like
+the console where debug messages can go.&nbsp; This does mean that in Mozilla
+release builds, these debug messages are likely to be lost, but the <i>--console</i>
+command line option to a release Mozilla will get them back.&nbsp; Therefore,
+the other error-support utilities, such as the error callbacks made on the
+policy object, may be used.</p>
+<p><b>Component Loader, Modules and Factories:</b>&nbsp; XPCOM has the concept
+of a component loader - a module used to load all components of a
+particular type.&nbsp; For example, the <i>moz.jsloader.1</i> component loads all
+the JavaScript components.&nbsp;Similarly, the <i>moz.pyloader.1</i>
+component loads all Python components.&nbsp; However, unlike
+JavaScript, the Python component loader is actually implemented in Python
+itself!&nbsp;Since the Python component loader can not be used to load
+itself, this component has some special code, <i>pyloader.dll,</i> to boot-strap itself.</p>
+<p>This means is that all XPCOM components, including the Python loader itself and all
+XPCOM module and factory interfaces, are implemented in
+Python.&nbsp;<b>There are no components or interfaces implemented purely in C++
+in this entire package!</b></p>
+
+</body>
+
+</html>
diff --git a/src/libs/xpcom18a4/python/doc/configure.html b/src/libs/xpcom18a4/python/doc/configure.html
new file mode 100644
index 00000000..e2b5d416
--- /dev/null
+++ b/src/libs/xpcom18a4/python/doc/configure.html
@@ -0,0 +1,196 @@
+<html>
+<!-- ***** 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 PyXPCOM.
+ -
+ - The Initial Developer of the Original Code is
+ - ActiveState Tool Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2000-2001
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - 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 LGPL or the GPL. 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 ***** -->
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Configuring your Environment</title>
+</head>
+
+<body>
+
+<h1>Building, Configuring and Testing Python XPCOM Package</h1>
+<p>This document attempts to explain how to build, configure and test the
+Python XPCOM Package. This document assumes you have already successfully
+built
+Mozilla from source and your environment is currently set up for such a build -
+see the <a href="http://www.mozilla.org/build/">Mozilla build documentation</a>
+for more information.</p>
+<p>PyXPCOM can be built on Windows using either the <i>nmake makefile.win</i>
+process, or the <i>configure; gmake</i> process used by Linux.</p>
+<h2>configure; gmake Instructions</h2>
+<h3>Preparing for the build</h3>
+<ul>
+ <li>Apply the patch in <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=129216">bugzilla
+ bug 129216</a>. (If this bug is marked as &quot;FIXED&quot;, it probably
+ means there is no need to apply the patch and that these docs are out of
+ date)</li>
+ <li>On Linux, you must have Python built for dynamic linking.&nbsp; <a href="http://aspn.activestate.com/ASPN/Python">ActivePython</a>
+ 2.1 is one such build.</li>
+ <li>On Windows, you must have a Python source tree installed and built.&nbsp;
+ Patches gratefully accepted that allow an installed Python to be used (it
+ should not be hard!)</li>
+ <li>Ensure the Python interpreter you wish to use is on your path, such that
+ &quot;python&quot; will execute it correctly.&nbsp; The configure process
+ uses this to locate the Python support files.</li>
+</ul>
+<h3>Building</h3>
+<ul>
+ <li>From the top-level Mozilla directory, execute <i>./configure
+ --enable-extensions=python/xpcom</i>. As per the Mozilla build
+ instructions, you may add this option to your <i>.mozconfig</i> file.&nbsp;
+ If you wish to enable debugging, just enable it as you would normally for
+ Mozilla; PyXPCOM will pick up the same settings.<br>
+ (On Windows you will need to execute <i>sh ./configure ...</i> if running
+ from a Command Prompt.&nbsp; See the <a href="http://www.mozilla.org/build/win32.html#ss2.2b">Mozilla
+ win32 specific gmake build instructions</a> for more details.</li>
+ <li>Build the Mozilla tree as normal; PyXPCOM will automatically be
+ built.&nbsp; Alternatively, change to the top-level PyXPCOM directory and
+ execute <i>gmake</i> in that directory.</li>
+</ul>
+<h2>PyXPCOM outside Mozilla</h2>
+<p>When you are using PyXPCOM from inside mozilla, no additional configuration
+options should be necessary.&nbsp; However, if you wish to use PyXPCOM from
+stand-alone Python (ie, so you can write simple Python scripts that can be
+executed normally and use XPCOM), then additional environment variables must be
+setup.</p>
+<ul>
+ <li><a name="PYTHONPATH"><b>PYTHONPATH</b></a> - <tt>PYTHONPATH</tt> needs to
+ be set appropriately.&nbsp;You must manually ensure that the <i>mozilla/dist/bin/python</i>
+ directory (which is where PyXPCOM was installed during the build process) is
+ listed.&nbsp; Note that when PyXPCOM is used from within Mozilla (or any
+ other xpcom process), this path will automatically be added to sys.path.&nbsp;
+ It is only when Python directly uses xpcom that this step is necessary.<br>
+ If anything is wrong here you should get a normal <tt>ImportError</tt>.</li>
+</ul>
+<blockquote>
+ <p>Note that on Windows, the PYTHONPATH is generally maintained in the
+ Registry; however, you can set this variable at a DOS prompt, and it will still be
+added to the core PYTHONPATH.
+</blockquote>
+<ul>
+ <li><b><a name="PATH">PATH</a>, LD_LIBRARY_PATH, etc</b> - On Windows, you
+ must ensure that the Mozilla bin directory is listed on your PATH, or that
+ you execute your scripts with the Mozilla bin directory as the current
+ directory.<br>
+ On Linux, you must set your PATH and LD_LIBRARY_PATH variables
+ appropriately.&nbsp; However, you may find it simpler and easier to use the <i>run-mozilla.sh</i>
+ script in the Mozilla bin directory.&nbsp; For example, changing to the
+ Mozilla bin directory and executing:<br>
+ <i>./run-mozilla.sh python ~/src/mozilla/extensions/python/xpcom/test/regrtest.py</i><br>
+ should setup a correct environment and execute the PyXPCOM test suite.</li>
+</ul>
+<h2><a name="RunningTheTests">Testing your Setup</a></h2>
+<p>The Python XPCOM Package has a complete test suite.</p>
+<p>In the rest of this section, we walk through some simpler tests a step at a time,
+to help diagnose any problems.</p>
+<p><b>Note:</b> We recommend you do all your testing outside of <i> mozilla.exe</i>; it is far simpler to test all of
+this using the PyXPCOM package stand-alone.</p>
+<p><b>Note:</b> On Windows, if you use a debug build of Mozilla (i.e., in <i>dist\WIN32_D.OBJ\bin)</i>,
+ you <b>must</b> use <i>python_d.exe</i>; if you use a release build (i.e., in
+ a <i>dist\WIN32_O.OBJ\bin</i> directory), you must use <i>python.exe</i>.&nbsp;
+<i>makefile.stupid.win</i> handles this automatically.</p>
+<p>To test your setup:</p>
+<ol>
+ <li>Start Python, and check<br>
+ &gt;&gt;&gt; <i>import xpcom</i><br>
+ works. If not, <a href="#PYTHONPATH">check your PYTHONPATH</a> - the
+ main PyXPCOM package can not be located.&nbsp; Also check your <a href="#PATH">PATH</a>,
+ and if you are on Linux, remember that executing ./run-mozilla.sh python is
+ the easiest way.</li>
+ <li>Check<i><br>
+ &gt;&gt;&gt; import xpcom._xpcom</i><br>
+
+works. If not, then most likely your <a href="#PATH">Mozilla
+ directory is not on your path</a>, or something is wrong with <i>_xpcom(_d).pyd/_xpcommodule.so</i>.</li>
+
+ <li>Next run a simple test: <i>test/test_misc.py</i>.&nbsp;With a Windows debug build, the command may look like:<br>
+ <i>C:\Anywhere&gt; python_d \src\python\xpcom\test\test_misc.py<br>
+ </i>or on Linux<br>
+ <i>/home/user/src/mozilla/dist/bin$ python /home/user/src/python/xpcom/test/test_misc.py</i></li>
+</ol>
+<p>If you can't get this going, you won't get much further! (You may see a few
+errors - that is OK, as long as it appears something worked!).&nbsp; If
+everything looks OK, the
+next step is to register our test component and run our full test suite.</p>
+<h2><a name="Registration">Registering the Loader and Test Component</a></h2>
+<p>First register the generic Python loader. For instructions, see the <a href="file:///F:/src/as/Komodo/src/pyxpcom/xpcom/doc/architecture.html">architecture
+document</a>.&nbsp;Do this only once, regardless of how many
+Python components you have.&nbsp; Then install the test component itself, and
+finally you can test it!</p>
+<h3>Registering the Python Loader and Component</h3>
+<p>To register the Python Loader and Component:</p>
+<ol>
+ <li>Ensure the build process has put <i>pyloader.dll </i>(or <i>modpyloader.so</i>
+ for Unix), and the files <i> py_test_component.py </i> and <i> py_test_component.idl</i> into
+ the Mozilla <i>bin/components</i> directory.&nbsp; If not, copy the files
+ there manually.</li>
+ <li>Run <i>regxpcom </i>(or .<i>/run-mozilla.sh ./regxpcom</i> if appropriate).&nbsp;<i>regxpcom</i> is a standard Mozilla
+ executable, found in the <i>bin</i> directory, that detects the new DLL and
+ .py
+ files and registers them accordingly.&nbsp; You should
+ see a few messages that include the following:</li>
+</ol>
+<blockquote>
+ <pre>Registering: PythonComponentLoader
+Registered 1 Python components in pyloader.dll
+nsNativeComponentLoader: autoregistering succeeded
+Auto-registering all Python components in F:\src\mozilla\dist\WIN32_D.OBJ\bin\components
+Registering: PythonTestComponent
+Registered 1 Python components in py_test_component.py</pre>
+</blockquote>
+<p>If so (or you see no message at all), you are ready to run the test suite.</p>
+<p><b>Note</b>: If you execute this same step a second time, you will not
+see any of the above mentioned messages.&nbsp;XPCOM knows that nothing has
+changed since you last ran <i>regxpcom</i>, so nothing is registered.&nbsp; If
+you do not see these messages the first time you run it, there is the
+possibility that some other process, possibly the build process, has already
+executed this step.</p>
+<h2><b>Running the Test Suite</b></h2>
+<p>Before running the test suite, you should change to the <i>mozilla/xpcom/sample</i>
+directory and build it.&nbsp; This will build and install a sample component
+which is used by the test suite.&nbsp; If you do not have this component
+available, some of the Python tests will fail.</p>
+
+<p>To run the test suite, run <i>xpcom/test/regrtest.py.</i>&nbsp; This runs the
+tests and ensures that the test output is as expected.&nbsp; If all tests
+pass, you have a fully functioning Python XPCOM package.&nbsp; Enjoy!</p>
+
+</body>
+
+</html>
diff --git a/src/libs/xpcom18a4/python/doc/credits.html b/src/libs/xpcom18a4/python/doc/credits.html
new file mode 100644
index 00000000..2be7809f
--- /dev/null
+++ b/src/libs/xpcom18a4/python/doc/credits.html
@@ -0,0 +1,86 @@
+<html>
+<!-- ***** 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 PyXPCOM.
+ -
+ - The Initial Developer of the Original Code is
+ - ActiveState Tool Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2000-2001
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - 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 LGPL or the GPL. 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 ***** -->
+
+<head>
+<meta http-equiv="Content-Language" content="en-au">
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Credits and Acknowledgements</title>
+</head>
+
+<body>
+
+<h1>Credits and Acknowledgements</h1>
+<h2>ActiveState Tool Corporation</h2>
+<p>The Python XPCOM Package was developed primarily by <a href="mailto:markh@activestate.com">Mark
+Hammond</a> of <a href="http://www.ActiveState.com">ActiveState Tool Corporation</a>.</p>
+<p>The developers on the <a href="http://www.ActiveState.com/Products/Komodo">Komodo
+project</a> deserve high praise for putting up with early versions when almost
+nothing worked, and for believing in Python as a viable XPCOM language.&nbsp;
+Their feedback and patience has allowed the first public release to be amazingly
+functional and bug-free.</p>
+<h3>Komodo Development Team (at December 2000)</h3>
+<p><a href="mailto:davida@activestate.com">David Ascher</a>, <a href="mailto:aaronb@ActiveState.com">Aaron Bingham</a>,
+<a href="mailto:bindu@activestate.com">Bin Du</a>, <a href="mailto:markh@activestate.com">Mark
+Hammond</a>, <a href="mailto:trentm@activestate.com">Trent Mick (build god)</a>,&nbsp;
+<a href="mailto:paulp@activestate.com">Paul Prescod</a>,&nbsp; <a href="mailto:ericp@ActiveState.com">Eric Promislow</a>,
+<a href="mailto:kens@ActiveState.com">Ken Simpson</a>, <a href="mailto:neilw@ActiveState.com">Neil Watkiss</a>,
+<a href="mailto:AudreyS@ActiveState.com">Audrey Schumacher</a>.</p>
+<h2>Mozilla/Netscape</h2>
+<p>The following people at <a href="http://www.netscape.com">Netscape</a> and <a href="http://www.mozilla.org">Mozilla</a>
+(or not there but still heavily involved in the project) have provided enormous
+help in getting things integrated with their build system, answering us on the
+newsgroup, teaching us the finer points of XPCOM, gently slapping us for accidentally
+referring to <i>jscript</i>, etc., and otherwise lending us a clue in the
+Mozilla/Netscape/XPCOM world.</p>
+<p><a href="mailto:jband@netscape.com">John Bandhauer</a>, <a href="mailto:brendan@meer.net">Brendan
+Eich</a>, <a href="mailto:shaver@zeroknowledge.com">Mike Shaver</a>, <a href="mailto:evaughan@netscape.com">Eric Vaughan</a>,
+<a href="mailto:hyatt@netscape.com">David Hyatt</a></p>
+<h2>External Contributors</h2>
+<p>The following people have made contributions to the project, simply because
+they find it useful and enjoy supporting Open Source projects.</p>
+<p><a href="mailto:cmeerw@web.de">Christof Meerwald</a></p>
+<h2>Documentation Credits</h2>
+<p>The following people have contributed to the Python XPCOM Package
+documentation&nbsp;</p>
+<p><a href="mailto:markh@activestate.com">Mark
+Hammond</a>, <a href="mailto:AudreyS@ActiveState.com">Audrey Schumacher</a></p>
+
+</body>
+
+</html>
diff --git a/src/libs/xpcom18a4/python/doc/tutorial.html b/src/libs/xpcom18a4/python/doc/tutorial.html
new file mode 100644
index 00000000..808d4c06
--- /dev/null
+++ b/src/libs/xpcom18a4/python/doc/tutorial.html
@@ -0,0 +1,286 @@
+<html>
+<!-- ***** 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 PyXPCOM.
+ -
+ - The Initial Developer of the Original Code is
+ - ActiveState Tool Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2000-2001
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - 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 LGPL or the GPL. 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 ***** -->
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Python XPCOM Package Tutorial</title>
+</head>
+
+<body>
+
+<h1>Python XPCOM Package Tutorial</h1>
+<p>This is a quick introduction to the Python XPCOM Package. We assume that you have a good understanding of Python and <a href="http://www.mozilla.org/projects/xpcom/">XPCOM</a>,
+and have experience both using and implementing XPCOM objects in some other
+language (e.g., C++ or JavaScript). We <b><i>do not</i></b> attempt to
+provide a tutorial to XPCOM or Python itself, only to using Python <i>and</i>
+ XPCOM.</p>
+<p>This tutorial contains the following sections:</p>
+<ul>
+ <li><a href="#Using">Using XPCOM Objects and Interfaces</a> - when you wish to
+ <i>use</i> a component written by anyone else in any XPCOM supported
+ language.</li>
+ <li><a href="#Implementing">Implementing XPCOM Objects and Interfaces</a> -
+ when you wish to implement a component for use by anyone else in any xpcom
+ supported language.</li>
+ <li><a href="#Parameters">Parameters and Types</a> - useful information
+ regarding how Python translates XPCOM types, and handles byref parameters.</li>
+</ul>
+<p>For anything not covered here, try the <a href="advanced.html">advanced
+documentation</a>, and if that fails, use the source, Luke!</p>
+<h2><a name="Using">Using XPCOM object and interfaces.</a></h2>
+<p>The techniques for using XPCOM in Python have been borrowed from JavaScript -
+thus, the model described here should be quite familiar to existing JavaScript
+XPCOM programmers.</p>
+<h3>xpcom.components module</h3>
+<p>When using an XPCOM object, the primary module used is the <u><i>xpcom.components</i></u>
+ module.&nbsp; Using this module, you can get a Python object that supports any
+scriptable XPCOM interface. Once you have this Python object, you can
+simply call XPCOM methods on the object, as normal.</p>
+<p>The <u><i>xpcom.components</i></u> module defines the following public
+members:</p>
+<table border="1" width="100%">
+ <tr>
+ <td width="16%"><b>Name</b></td>
+ <td width="84%"><b>Description</b></td>
+ </tr>
+ <tr>
+ <td width="16%">classes</td>
+ <td width="84%">A mapping (dictionary-like object) used to get XPCOM
+ &quot;classes&quot;.&nbsp; These are indexed by XPCOM contract ID, just
+ like the JavaScript object of the same name.&nbsp;&nbsp;
+ <p>Example:</p>
+ <pre>cls = components.classes[&quot;@mozilla.org/sample;1&quot;]
+ob = cls.createInstance() # Now have an nsISupports</pre>
+ </td>
+ </tr>
+ <tr>
+ <td width="16%">interfaces</td>
+ <td width="84%">An object that exposes all XPCOM interface IDs (IIDs).&nbsp;
+ Like the JavaScript object of the same name, this object uses
+ &quot;dot&quot; notation, as demonstrated below.
+ <p>Example:</p>
+ <pre>ob = cls.createInstance(components.interfaces.nsISample)
+# Now have an nsISample</pre>
+ </td>
+ </tr>
+</table>
+<p>For many people, this is all you need to know. Consider the Mozilla Sample Component.&nbsp; The Mozilla Sample
+Component has a contract ID of <i>@mozilla.org/sample;1</i>,
+and implements the <i>nsISample</i> interface.</p>
+<p>Thus, a complete Python program that uses this component is shown below.</p>
+<pre>from xpcom import components
+cls = components.classes[&quot;@mozilla.org/sample;1&quot;]
+ob = cls.createInstance() # no need to specify an IID for most components
+# nsISample defines a &quot;value&quot; property - let's use it!
+ob.value = &quot;new value&quot;
+if ob.value != &quot;new value&quot;:
+ print &quot;Eeek - what happened?&quot;</pre>
+<p>And that is it - a complete Python program that uses XPCOM.</p>
+<h2><a name="Implementing">Implementing XPCOM Objects and Interfaces.</a></h2>
+<p>Implementing XPCOM objects is almost as simple as using them. The
+basic strategy is this:</p>
+<ol>
+ <li>Create a standard Python source file, with a standard Python class.</li>
+ <li>Add some special <a href="#Attributes"> attributes</a> to your class for use by the Python XPCOM
+ framework. This controls the XPCOM behavior of your object.</li>
+ <li>Implement the XPCOM <a href="#Properties"> properties</a> and methods of your classes as normal.</li>
+ <li>Put the Python source file in the Mozilla <i> components</i> directory.</li>
+ <li>Run <i> regxpcom.</i></li>
+</ol>
+<p>Your component is now ready to be used.</p>
+<h3><a name="Attributes">Attributes</a></h3>
+<p>There are two classes of attributes: those used at runtime to define the object
+behavior and those used at registration time to control object
+registration.&nbsp; Not all objects require registration, thus not all
+Python XPCOM objects will have registration-related attributes.</p>
+<table border="1" width="100%">
+ <tr>
+ <td width="17%"><b>Attribute</b></td>
+ <td width="83%"><b>Description</b></td>
+ </tr>
+ <tr>
+ <td width="17%">_com_interfaces_</td>
+ <td width="83%">The interface IDs (IIDs) supported by the component.&nbsp;
+ For simplicity, this may be either a single IID, or a list of IIDs.&nbsp;
+ There is no need to specify base interfaces, as all parent interfaces are
+ automatically supported. Thus, it is never necessary to nominate <i>
+ nsISupports</i> in the list of interfaces.
+ <p>This attribute is required. Objects without such an attribute are
+ deemed unsuitable for use as a XPCOM object.</td>
+ </tr>
+ <tr>
+ <td width="17%">_reg_contractid_</td>
+ <td width="83%">The contract ID of the component.&nbsp; Required if the
+ component requires registration (i.e., exists in the components directory).</td>
+ </tr>
+ <tr>
+ <td width="17%">_reg_clsid_</td>
+ <td width="83%">The Class ID (CLSID) of the component, as a string in the
+ standard &quot;{XXX-XXX-XXX-XXX}&quot; format. Required if the
+ component requires registration (i.e., exists in the components directory).</td>
+ </tr>
+ <tr>
+ <td width="17%">_reg_registrar_</td>
+ <td width="83%">Nominates a function that is called at registration
+ time. The default is for no extra function to be called. This can
+ be useful if a component has special registration requirements and needs
+ to hook into the registration process.</td>
+ </tr>
+ <tr>
+ <td width="17%">_reg_desc_</td>
+ <td width="83%">The description of the XPCOM object. This may be used by
+ browsers or other such objects.&nbsp; If not specified, the contract ID
+ is used.</td>
+ </tr>
+</table>
+<h3><a name="Properties">Properties</a></h3>
+<p>A Python class can support XPCOM properties in one of two ways.&nbsp; Either
+a standard Python property of the same name can exist - our sample
+component demonstrates this with the <i>boolean_value</i> property.&nbsp;
+Alternatively, the class can provide the <i>get_propertyName(self)</i> and <i>set_propertyName(self,
+value)</i> functions (with <i>propertyName</i> changed to the appropriate value for the
+property), and these functions will be called instead.</p>
+<h4>Example:&nbsp; The Python XPCOM Test Component</h4>
+<p>As an example, examine the Python XPCOM Test Component.&nbsp; This
+code can be found in <i>py_test_component.py</i>.</p>
+<pre>from xpcom import components
+
+class PythonTestComponent:
+ _com_interfaces_ = components.interfaces.nsIPythonTestInterface
+ _reg_clsid_ = &quot;{7EE4BDC6-CB53-42c1-A9E4-616B8E012ABA}&quot;
+ _reg_contractid_ = &quot;Python.TestComponent&quot;
+ def __init__(self):
+ self.boolean_value = 1
+ ...
+ def do_boolean(self, p1, p2):
+ ret = p1 ^ p2
+ return ret, not ret, ret
+...</pre>
+<p><b>Note:</b> This component only specifies the mandatory attributes - <i>_com_interfaces</i>,
+<i>_reg_clsid_</i> and <i>_reg_contractid_</i>.</p>
+<p>This sample code demonstrates supporting the <i>boolean_value</i> attribute,
+supported implicitly, as it is defined in the IDL and exists as a real Python
+attribute of that name, and a method called <i>do_boolean</i>.</p>
+<h4>Tip: The xpcom/xpt.py Script</h4>
+<p> The xpcom/xpt.py script is a useful script that can generate the skeleton of a class for
+any XPCOM interface.&nbsp; Just specify the interface name on the command-line,
+and paste the output into your source file.</p>
+<p>This is the output of running this program over the <i>nsISample</i>
+interface (i.e., assuming we wanted to implement a component that supported this
+interface):</p>
+<pre>class nsISample:
+ _com_interfaces_ = xpcom.components.interfaces.nsISample
+ # If this object needs to be registered, the following 2 are also needed.
+ # _reg_clsid_ = {a new clsid generated for this object}
+ # _reg_contractid_ = &quot;The.Object.Name&quot;
+
+ def get_value( self ):
+ # Result: string
+ pass
+ def set_value( self, param0 ):
+ # Result: void - None
+ # In: param0: string
+ pass
+ def writeValue( self, param0 ):
+ # Result: void - None
+ # In: param0: string
+ pass
+ def poke( self, param0 ):
+ # Result: void - None
+ # In: param0: string
+ pass</pre>
+<p><b>Note:</b> The types of the parameters and the function itself are included in
+the comments.&nbsp;You need to implement the functions
+themselves.&nbsp; Another advantage of this script is that the <a href="#HiddenParams">hidden
+parameters</a> are handled for you; the comments indicate when parameters
+have been hidden.</p>
+<h2><a name="Parameters">Parameters and Types</a></h2>
+<p>This section briefly describes the XPCOM type support in
+Python.</p>
+<p>All XPCOM interfaces define parameters of a specific type.&nbsp; There is
+currently no concept of a variant, or union of all types. Thus, the
+conversion rules are very straightforward, and generally surprise free: for
+any given XPCOM method, there is only one possible type for a given parameter.</p>
+<h3>Type Conversion Rules:</h3>
+<ul>
+ <li>All numeric types will attempt to be coerced to the correct type.&nbsp;
+ Thus, you can pass a Python float to an XPCOM method expecting an integer,
+ or vice-versa. Specifically, when an integer is required, you can pass
+ any Python object for which <i>int()</i> would succeed; for a Python float,
+ any object for which <i>float()</i> would succeed is acceptable.&nbsp; This
+ means that you can pass a Python string object as an integer, as long as the
+ string was holding a valid integer.</li>
+ <li>Strings and Unicode objects are interchangeable, but no other automatic
+ string conversions are performed.&nbsp; Thus, you can not pass an integer
+ where a string is expected, even though the reverse is true.</li>
+ <li>Any sequence object can be passed as an array.&nbsp; List objects are
+ always returned for arrays.</li>
+ <li>Any Python instance suitable for use as a XPCOM object (i.e., with the
+ <a href="#Implementing">necessary annotations</a>) can be
+ passed as a XPCOM object. No special wrapping step is needed to turn a
+ Python instance into a XPCOM object.&nbsp; Note you must pass a class <i>instance</i>,
+ not the class itself.</li>
+ <li><a name="HiddenParams">Many XPCOM <b> method signatures</b> specify
+ &quot;count&quot; or &quot;size&quot; parameters.&nbsp; For example, every
+ time an array is passed via XPCOM, the method signature will always specify
+ an integer that holds the count of the array.&nbsp; These parameters are
+ always hidden in Python.&nbsp; As the size param can be implied from the
+ length of the Python sequence passed, the Python programmer need never pass
+ these parameters;&nbsp;in contrast, JavaScript requires these redundant parameters.</a></li>
+</ul>
+
+<h2>Interface Flattening</h2>
+<p>Most people can ignore this information - Python XPCOM objects just
+work.&nbsp; However, if you are familiar with xpcom from C++ and the concept of <i>QueryInterface</i>,
+you may like to read this.</p>
+<p>Most components support the concept of &quot;interface
+flattening&quot;.&nbsp; Such objects can report the interfaces they support,
+allowing languages such as Python and Javascript avoid using <i>QueryInterface</i>.&nbsp;
+When you are using an XPCOM object from Python, you can just call methods and
+reference properties without regard for the interface that implements it.</p>
+<p>When multiple interfaces share the same method or property name, you can use
+the name of the interface as a differentiator.&nbsp; Thus, <i>ob.nsIFoo.close()</i>
+will call close on <i>ob</i>'s <i>nsIFoo</i> interface, while <i>ob.nsIBar.close()</i>
+will use the <i>nsIBar</i> interface.&nbsp; <i>ob.close()</i> is not defined.</p>
+
+</body>
+
+</html>
+
+
diff --git a/src/libs/xpcom18a4/python/file.py b/src/libs/xpcom18a4/python/file.py
new file mode 100755
index 00000000..59b0da58
--- /dev/null
+++ b/src/libs/xpcom18a4/python/file.py
@@ -0,0 +1,318 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.com> (original author)
+#
+# 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 *****
+
+"""Implementation of Python file objects for Mozilla/xpcom.
+
+Introduction:
+ This module defines various class that are implemented using
+ Mozilla streams. This allows you to open Mozilla URI's, and
+ treat them as Python file object.
+
+Example:
+>>> file = URIFile("chrome://whatever")
+>>> data = file.read(5) # Pass no arg to read everything.
+
+Known Limitations:
+ * Not all URL schemes will work from "python.exe" - most notably
+ "chrome://" and "http://" URLs - this is because a simple initialization of
+ xpcom by Python does not load up the full set of Mozilla URL handlers.
+ If you can work out how to correctly initialize the chrome registry and
+ setup a message queue.
+
+Known Bugs:
+ * Only read ("r") mode is supported. Although write ("w") mode doesnt make
+ sense for HTTP type URLs, it potentially does for file:// etc type ones.
+ * No concept of text mode vs binary mode. It appears Mozilla takes care of
+ this internally (ie, all "text/???" mime types are text, rest are binary)
+
+"""
+
+from xpcom import components, Exception, _xpcom
+import os
+import threading # for locks.
+
+NS_RDONLY = 0x01
+NS_WRONLY = 0x02
+NS_RDWR = 0x04
+NS_CREATE_FILE = 0x08
+NS_APPEND = 0x10
+NS_TRUNCATE = 0x20
+NS_SYNC = 0x40
+NS_EXCL = 0x80
+
+# A helper function that may come in useful
+def LocalFileToURL(localFileName):
+ "Convert a filename to an XPCOM nsIFileURL object."
+ # Create an nsILocalFile
+ localFile = components.classes["@mozilla.org/file/local;1"] \
+ .createInstance(components.interfaces.nsILocalFile)
+ localFile.initWithPath(localFileName)
+
+ # Use the IO Service to create the interface, then QI for a FileURL
+ io_service = components.classes["@mozilla.org/network/io-service;1"] \
+ .getService(components.interfaces.nsIIOService)
+ url = io_service.newFileURI(localFile).queryInterface(components.interfaces.nsIFileURL)
+ # Setting the "file" attribute causes initialization...
+ url.file = localFile
+ return url
+
+# A base class for file objects.
+class _File:
+ def __init__(self, name_thingy = None, mode="r"):
+ self.lockob = threading.Lock()
+ self.inputStream = self.outputStream = None
+ if name_thingy is not None:
+ self.init(name_thingy, mode)
+
+ def __del__(self):
+ self.close()
+
+ # The Moz file streams are not thread safe.
+ def _lock(self):
+ self.lockob.acquire()
+ def _release(self):
+ self.lockob.release()
+ def read(self, n = -1):
+ assert self.inputStream is not None, "Not setup for read!"
+ self._lock()
+ try:
+ return str(self.inputStream.read(n))
+ finally:
+ self._release()
+
+ def readlines(self):
+ # Not part of the xpcom interface, but handy for direct Python users.
+ # Not 100% faithful, but near enough for now!
+ lines = self.read().split("\n")
+ if len(lines) and len(lines[-1]) == 0:
+ lines = lines[:-1]
+ return [s+"\n" for s in lines ]
+
+ def write(self, data):
+ assert self.outputStream is not None, "Not setup for write!"
+ self._lock()
+ try:
+ self.outputStream.write(data, len(data))
+ finally:
+ self._release()
+
+ def close(self):
+ self._lock()
+ try:
+ if self.inputStream is not None:
+ self.inputStream.close()
+ self.inputStream = None
+ if self.outputStream is not None:
+ self.outputStream.close()
+ self.outputStream = None
+ self.channel = None
+ finally:
+ self._release()
+
+ def flush(self):
+ self._lock()
+ try:
+ if self.outputStream is not None: self.outputStream.flush()
+ finally:
+ self._release()
+
+# A synchronous "file object" used to open a URI.
+class URIFile(_File):
+ def init(self, url, mode="r"):
+ self.close()
+ if mode != "r":
+ raise ValueError("only 'r' mode supported")
+ io_service = components.classes["@mozilla.org/network/io-service;1"] \
+ .getService(components.interfaces.nsIIOService)
+ if hasattr(url, "queryInterface"):
+ url_ob = url
+ else:
+ url_ob = io_service.newURI(url, None, None)
+ # Mozilla asserts and starts saying "NULL POINTER" if this is wrong!
+ if not url_ob.scheme:
+ raise ValueError("The URI '%s' is invalid (no scheme)"
+ % (url_ob.spec,))
+ self.channel = io_service.newChannelFromURI(url_ob)
+ self.inputStream = self.channel.open()
+
+# A "file object" implemented using Netscape's native file support.
+# Based on io.js - http://lxr.mozilla.org/seamonkey/source/xpcom/tests/utils/io.js
+# You open this file using a local file name (as a string) so it really is pointless -
+# you may as well be using a standard Python file object!
+class LocalFile(_File):
+ def __init__(self, *args):
+ self.fileIO = None
+ _File.__init__(self, *args)
+
+ def init(self, name, mode = "r"):
+ name = os.path.abspath(name) # Moz libraries under Linux fail with relative paths.
+ self.close()
+ file = components.classes['@mozilla.org/file/local;1'].createInstance("nsILocalFile")
+ file.initWithPath(name)
+ if mode in ["w","a"]:
+ self.fileIO = components.classes["@mozilla.org/network/file-output-stream;1"].createInstance("nsIFileOutputStream")
+ if mode== "w":
+ if file.exists():
+ file.remove(0)
+ moz_mode = NS_CREATE_FILE | NS_WRONLY
+ elif mode=="a":
+ moz_mode = NS_APPEND
+ else:
+ assert 0, "Can't happen!"
+ self.fileIO.init(file, moz_mode, -1,0)
+ self.outputStream = self.fileIO
+ elif mode == "r":
+ self.fileIO = components.classes["@mozilla.org/network/file-input-stream;1"].createInstance("nsIFileInputStream")
+ self.fileIO.init(file, NS_RDONLY, -1,0)
+ self.inputStream = components.classes["@mozilla.org/scriptableinputstream;1"].createInstance("nsIScriptableInputStream")
+ self.inputStream.init(self.fileIO)
+ else:
+ raise ValueError("Unknown mode")
+
+ def close(self):
+ if self.fileIO is not None:
+ self.fileIO.close()
+ self.fileIO = None
+ _File.close(self)
+
+ def read(self, n = -1):
+ return _File.read(self, n)
+
+
+##########################################################
+##
+## Test Code
+##
+##########################################################
+def _DoTestRead(file, expected):
+ # read in a couple of chunks, just to test that our various arg combinations work.
+ got = file.read(3)
+ got = got + file.read(300)
+ got = got + file.read(0)
+ got = got + file.read()
+ if got != expected:
+ raise RuntimeError("Reading '%s' failed - got %d bytes, but expected %d bytes" % (file, len(got), len(expected)))
+
+def _DoTestBufferRead(file, expected):
+ # read in a couple of chunks, just to test that our various arg combinations work.
+ buffer = _xpcom.AllocateBuffer(50)
+ got = ''
+ while 1:
+ # Note - we need to reach into the file object so we
+ # can get at the native buffer supported function.
+ num = file.inputStream.read(buffer)
+ if num == 0:
+ break
+ got = got + str(buffer[:num])
+ if got != expected:
+ raise RuntimeError("Reading '%s' failed - got %d bytes, but expected %d bytes" % (file, len(got), len(expected)))
+
+def _TestLocalFile():
+ import tempfile, os
+ fname = tempfile.mktemp()
+ data = "Hello from Python"
+ test_file = LocalFile(fname, "w")
+ try:
+ test_file.write(data)
+ test_file.close()
+ # Make sure Python can read it OK.
+ f = open(fname, "r")
+ assert f.read() == data, "Eeek - Python could not read the data back correctly!"
+ f.close()
+ # For the sake of the test, try a re-init.
+ test_file.init(fname, "r")
+ got = str(test_file.read())
+ assert got == data, got
+ test_file.close()
+ # Try reading in chunks.
+ test_file = LocalFile(fname, "r")
+ got = test_file.read(10) + test_file.read()
+ assert got == data, got
+ test_file.close()
+ # Open the same file again for writing - this should delete the old one.
+ if not os.path.isfile(fname):
+ raise RuntimeError("The file '%s' does not exist, but we are explicitly testing create semantics when it does" % (fname,))
+ test_file = LocalFile(fname, "w")
+ test_file.write(data)
+ test_file.close()
+ # Make sure Python can read it OK.
+ f = open(fname, "r")
+ assert f.read() == data, "Eeek - Python could not read the data back correctly after recreating an existing file!"
+ f.close()
+
+ # XXX - todo - test "a" mode!
+ finally:
+ os.unlink(fname)
+
+def _TestAll():
+ # A mini test suite.
+ # Get a test file, and convert it to a file:// URI.
+ # check what we read is the same as when
+ # we read this file "normally"
+ fname = components.__file__
+ if fname[-1] in "cCoO": # fix .pyc/.pyo
+ fname = fname[:-1]
+ expected = open(fname, "rb").read()
+ # convert the fname to a URI.
+ url = LocalFileToURL(fname)
+ # First try passing a URL as a string.
+ _DoTestRead( URIFile( url.spec), expected)
+ # Now with a URL object.
+ _DoTestRead( URIFile( url ), expected)
+
+ _DoTestBufferRead( URIFile( url ), expected)
+
+ # For the sake of testing, do our pointless, demo object!
+ _DoTestRead( LocalFile(fname), expected )
+
+ # Now do the full test of our pointless, demo object!
+ _TestLocalFile()
+
+def _TestURI(url):
+ test_file = URIFile(url)
+ print("Opened file is", test_file)
+ got = test_file.read()
+ print("Read %d bytes of data from %r" % (len(got), url))
+ test_file.close()
+
+if __name__=='__main__':
+ import sys
+ if len(sys.argv) < 2:
+ print("No URL specified on command line - performing self-test")
+ _TestAll()
+ else:
+ _TestURI(sys.argv[1])
diff --git a/src/libs/xpcom18a4/python/gen_python_deps.py b/src/libs/xpcom18a4/python/gen_python_deps.py
new file mode 100755
index 00000000..12fbb7ac
--- /dev/null
+++ b/src/libs/xpcom18a4/python/gen_python_deps.py
@@ -0,0 +1,147 @@
+#!/usr/bin/python
+
+"""
+Copyright (C) 2009-2022 Oracle and/or its affiliates.
+
+This file is part of VirtualBox base platform packages, as
+available from https://www.virtualbox.org.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation, in version 3 of the
+License.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, see <https://www.gnu.org/licenses>.
+
+SPDX-License-Identifier: GPL-3.0-only
+"""
+
+from __future__ import print_function
+import os,sys
+from distutils.version import StrictVersion
+
+versions = ["2.6", "2.7", "3.1", "3.2", "3.2m", "3.3", "3.3m", "3.4", "3.4m", "3.5", "3.5m", "3.6", "3.6m", "3.7", "3.7m", "3.8", "3.8m", "3.9", "3.9m", "3.10", "3.10m", "3.11", "3.11m" ]
+prefixes = ["/usr", "/usr/local", "/opt", "/opt/local"]
+known = {}
+
+def checkPair(p, v, dllpre, dllsuff, bitness_magic):
+ incdir = os.path.join(p, "include", "python"+v)
+ incfile = os.path.join(incdir, "Python.h")
+ if not os.path.isfile(incfile):
+ return None
+
+ lib = os.path.join(p, "lib/i386-linux-gnu", dllpre+"python"+v+dllsuff)
+ if not os.path.isfile(lib):
+ lib = os.path.join(p, "lib", dllpre+"python"+v+dllsuff)
+ if not os.path.isfile(lib):
+ lib = None
+
+ if bitness_magic == 1:
+ lib64 = os.path.join(p, "lib", "64", dllpre+"python"+v+dllsuff)
+ if not os.path.isfile(lib64):
+ lib64 = None
+ elif bitness_magic == 2:
+ lib64 = os.path.join(p, "lib/x86_64-linux-gnu", dllpre+"python"+v+dllsuff)
+ if not os.path.isfile(lib64):
+ lib64 = os.path.join(p, "lib64", dllpre+"python"+v+dllsuff)
+ if not os.path.isfile(lib64):
+ lib64 = os.path.join(p, "lib", dllpre+"python"+v+dllsuff)
+ if not os.path.isfile(lib64):
+ lib64 = None
+ else:
+ lib64 = None
+
+ if lib is None and lib64 is None:
+ return None
+ else:
+ return [incdir, lib, lib64]
+
+def print_vars(vers, known, sep, bitness_magic):
+ print("VBOX_PYTHON%s_INC=%s%s" %(vers, known[0], sep))
+ if bitness_magic > 0:
+ if known[2]:
+ print("VBOX_PYTHON%s_LIB=%s%s" %(vers, known[2], sep))
+ if known[1]:
+ print("VBOX_PYTHON%s_LIB_X86=%s%s" %(vers, known[1], sep))
+ else:
+ print("VBOX_PYTHON%s_LIB=%s%s" %(vers, known[1], sep))
+
+
+def main(argv):
+ global prefixes
+ global versions
+
+ dllpre = "lib"
+ dllsuff = ".so"
+ bitness_magic = 0
+
+ if len(argv) > 1:
+ target = argv[1]
+ else:
+ target = sys.platform
+
+ if len(argv) > 2:
+ arch = argv[2]
+ else:
+ arch = "unknown"
+
+ if len(argv) > 3:
+ multi = int(argv[3])
+ else:
+ multi = 1
+
+ if multi == 0:
+ prefixes = ["/usr"]
+ versions = [str(sys.version_info[0])+'.'+str(sys.version_info[1]),
+ str(sys.version_info[0])+'.'+str(sys.version_info[1])+'m']
+
+ if target == 'darwin':
+ ## @todo Pick up the locations from VBOX_PATH_MACOSX_SDK_10_*.
+ prefixes = ['/Developer/SDKs/MacOSX10.4u.sdk/usr',
+ '/Developer/SDKs/MacOSX10.5.sdk/usr',
+ '/Developer/SDKs/MacOSX10.6.sdk/usr',
+ '/Developer/SDKs/MacOSX10.7.sdk/usr']
+ dllsuff = '.dylib'
+
+ if target == 'solaris' and arch == 'amd64':
+ bitness_magic = 1
+
+ if target == 'linux' and arch == 'amd64':
+ bitness_magic = 2
+
+ for v in versions:
+ if v.endswith("m"):
+ realversion = v[:-1]
+ else:
+ realversion = v
+ if StrictVersion(realversion) < StrictVersion('2.6'):
+ continue
+ for p in prefixes:
+ c = checkPair(p, v, dllpre, dllsuff, bitness_magic)
+ if c is not None:
+ known[v] = c
+ break
+ keys = list(known.keys())
+ # we want default to be the lowest versioned Python
+ keys.sort()
+ d = None
+ # We need separator other than newline, to sneak through $(shell)
+ sep = "|"
+ for k in keys:
+ if d is None:
+ d = k
+ vers = k.replace('.', '').upper()
+ print_vars(vers, known[k], sep, bitness_magic)
+ if d is not None:
+ print_vars("DEF", known[d], sep, bitness_magic)
+ else:
+ print(argv[0] + ": No Python development package found!", file=sys.stderr)
+
+if __name__ == '__main__':
+ main(sys.argv)
diff --git a/src/libs/xpcom18a4/python/nsError.py b/src/libs/xpcom18a4/python/nsError.py
new file mode 100755
index 00000000..af9cdbfd
--- /dev/null
+++ b/src/libs/xpcom18a4/python/nsError.py
@@ -0,0 +1,166 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is ActiveState Tool Corp.
+# Portions created by ActiveState Tool Corp. are Copyright (C) 2000, 2001
+# ActiveState Tool Corp. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.com> (original author)
+#
+# 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 *****
+
+# Generated by h2py from nsError.h
+# CMD line: h2py.py -i (nsresult) nsError.h
+
+# XXX - NOTE - some manual code at the end, and all literals moved back to ints
+NS_ERROR_MODULE_XPCOM = 1
+NS_ERROR_MODULE_BASE = 2
+NS_ERROR_MODULE_GFX = 3
+NS_ERROR_MODULE_WIDGET = 4
+NS_ERROR_MODULE_CALENDAR = 5
+NS_ERROR_MODULE_NETWORK = 6
+NS_ERROR_MODULE_PLUGINS = 7
+NS_ERROR_MODULE_LAYOUT = 8
+NS_ERROR_MODULE_HTMLPARSER = 9
+NS_ERROR_MODULE_RDF = 10
+NS_ERROR_MODULE_UCONV = 11
+NS_ERROR_MODULE_REG = 12
+NS_ERROR_MODULE_FILES = 13
+NS_ERROR_MODULE_DOM = 14
+NS_ERROR_MODULE_IMGLIB = 15
+NS_ERROR_MODULE_MAILNEWS = 16
+NS_ERROR_MODULE_EDITOR = 17
+NS_ERROR_MODULE_XPCONNECT = 18
+NS_ERROR_MODULE_PROFILE = 19
+NS_ERROR_MODULE_LDAP = 20
+NS_ERROR_MODULE_SECURITY = 21
+NS_ERROR_MODULE_DOM_XPATH = 22
+NS_ERROR_MODULE_DOM_RANGE = 23
+NS_ERROR_MODULE_URILOADER = 24
+NS_ERROR_MODULE_CONTENT = 25
+NS_ERROR_MODULE_PYXPCOM = 26
+NS_ERROR_MODULE_XSLT = 27
+NS_ERROR_MODULE_IPC = 28
+NS_ERROR_MODULE_SVG = 29
+NS_ERROR_MODULE_GENERAL = 51
+
+def NS_FAILED(_nsresult): return ((_nsresult) & -2147483648)
+
+NS_ERROR_SEVERITY_SUCCESS = 0
+NS_ERROR_SEVERITY_ERROR = 1
+NS_ERROR_MODULE_BASE_OFFSET = 69
+def NS_ERROR_GET_CODE(err): return ((err) & 65535)
+
+def NS_ERROR_GET_MODULE(err): return (((((err) >> 16) - NS_ERROR_MODULE_BASE_OFFSET) & 8191))
+
+def NS_ERROR_GET_SEVERITY(err): return (((err) >> 31) & 1)
+
+NS_OK = 0
+NS_COMFALSE = 1
+NS_ERROR_BASE = ( -1041039360)
+NS_ERROR_NOT_INITIALIZED = (NS_ERROR_BASE + 1)
+NS_ERROR_ALREADY_INITIALIZED = (NS_ERROR_BASE + 2)
+NS_ERROR_NOT_IMPLEMENTED = ( -2147467263)
+NS_NOINTERFACE = ( -2147467262)
+NS_ERROR_NO_INTERFACE = NS_NOINTERFACE
+NS_ERROR_INVALID_POINTER = ( -2147467261)
+NS_ERROR_NULL_POINTER = NS_ERROR_INVALID_POINTER
+NS_ERROR_ABORT = ( -2147467260)
+NS_ERROR_FAILURE = ( -2147467259)
+NS_ERROR_UNEXPECTED = ( -2147418113)
+NS_ERROR_OUT_OF_MEMORY = ( -2147024882)
+NS_ERROR_ILLEGAL_VALUE = ( -2147024809)
+NS_ERROR_INVALID_ARG = NS_ERROR_ILLEGAL_VALUE
+NS_ERROR_NO_AGGREGATION = ( -2147221232)
+NS_ERROR_NOT_AVAILABLE = ( -2147221231)
+NS_ERROR_FACTORY_NOT_REGISTERED = ( -2147221164)
+NS_ERROR_FACTORY_REGISTER_AGAIN = ( -2147221163)
+NS_ERROR_FACTORY_NOT_LOADED = ( -2147221000)
+NS_ERROR_FACTORY_NO_SIGNATURE_SUPPORT = \
+ (NS_ERROR_BASE + 257)
+NS_ERROR_FACTORY_EXISTS = (NS_ERROR_BASE + 256)
+NS_ERROR_PROXY_INVALID_IN_PARAMETER = ( -2147418096)
+NS_ERROR_PROXY_INVALID_OUT_PARAMETER = ( -2147418095)
+
+##### END OF GENERATED CODE
+#####
+def NS_ERROR_GENERATE_FAILURE(module,code):
+ # slightly optimized, and avoids 2.3->2.4 long/int changes
+ # return (NS_ERROR_SEVERITY_ERROR<<31) | ((module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | (code)
+ return -2147483648 | ((module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | (code)
+
+def NS_ERROR_GENERATE_SUCCESS(module,code):
+ #return (NS_ERROR_SEVERITY_SUCCESS<<31) | ((module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | (code)
+ return ((module+NS_ERROR_MODULE_BASE_OFFSET)<<16) | (code)
+
+NS_BASE_STREAM_CLOSED = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_BASE, 2)
+NS_BASE_STREAM_OSERROR = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_BASE, 3)
+NS_BASE_STREAM_ILLEGAL_ARGS = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_BASE, 4)
+NS_BASE_STREAM_NO_CONVERTER = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_BASE, 5)
+NS_BASE_STREAM_BAD_CONVERSION = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_BASE, 6)
+NS_BASE_STREAM_WOULD_BLOCK = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_BASE, 7)
+NS_ERROR_FILE_UNRECOGNIZED_PATH = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 1)
+NS_ERROR_FILE_UNRESOLVABLE_SYMLINK = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 2)
+NS_ERROR_FILE_EXECUTION_FAILED = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 3)
+NS_ERROR_FILE_UNKNOWN_TYPE = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 4)
+NS_ERROR_FILE_DESTINATION_NOT_DIR = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 5)
+NS_ERROR_FILE_TARGET_DOES_NOT_EXIST = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 6)
+NS_ERROR_FILE_COPY_OR_MOVE_FAILED = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 7)
+NS_ERROR_FILE_ALREADY_EXISTS = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 8)
+NS_ERROR_FILE_INVALID_PATH = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 9)
+NS_ERROR_FILE_DISK_FULL = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 10)
+NS_ERROR_FILE_CORRUPTED = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 11)
+NS_ERROR_FILE_NOT_DIRECTORY = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 12)
+NS_ERROR_FILE_IS_DIRECTORY = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 13)
+NS_ERROR_FILE_IS_LOCKED = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 14)
+NS_ERROR_FILE_TOO_BIG = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 15)
+NS_ERROR_FILE_NO_DEVICE_SPACE = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 16)
+NS_ERROR_FILE_NAME_TOO_LONG = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 17)
+NS_ERROR_FILE_NOT_FOUND = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 18)
+NS_ERROR_FILE_READ_ONLY = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 19)
+NS_ERROR_FILE_DIR_NOT_EMPTY = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 20)
+NS_ERROR_FILE_ACCESS_DENIED = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES, 21)
+
+## from netCore.h
+NS_ERROR_ALREADY_CONNECTED = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 11)
+
+NS_ERROR_NOT_CONNECTED = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 12)
+NS_ERROR_IN_PROGRESS = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 15)
+NS_ERROR_OFFLINE = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 16)
+
+## from nsISocketTransportService.idl
+NS_ERROR_CONNECTION_REFUSED = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 13)
+
+NS_ERROR_NET_TIMEOUT = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 14)
+
+# Status nsresult codes: used with nsIProgressEventSink::OnStatus
+NS_NET_STATUS_RESOLVING_HOST = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 3)
+NS_NET_STATUS_CONNECTED_TO = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 4)
+NS_NET_STATUS_SENDING_TO = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 5)
+NS_NET_STATUS_RECEIVING_FROM = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 6)
+NS_NET_STATUS_CONNECTING_TO = NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 7)
diff --git a/src/libs/xpcom18a4/python/primitives.py b/src/libs/xpcom18a4/python/primitives.py
new file mode 100755
index 00000000..464f12e4
--- /dev/null
+++ b/src/libs/xpcom18a4/python/primitives.py
@@ -0,0 +1,39 @@
+# Various utilities for working with nsISupportsPrimitive
+from xpcom import components
+
+_primitives_map = {}
+
+def _build_map():
+ ifaces = components.interfaces
+ iface = ifaces.nsISupportsPrimitive
+ m = _primitives_map
+
+ m[iface.TYPE_ID] = ifaces.nsISupportsID
+ m[iface.TYPE_CSTRING] = ifaces.nsISupportsCString
+ m[iface.TYPE_STRING] = ifaces.nsISupportsString
+ m[iface.TYPE_PRBOOL] = ifaces.nsISupportsPRBool
+ m[iface.TYPE_PRUINT8] = ifaces.nsISupportsPRUint8
+ m[iface.TYPE_PRUINT16] = ifaces.nsISupportsPRUint16
+ m[iface.TYPE_PRUINT32] = ifaces.nsISupportsPRUint32
+ m[iface.TYPE_PRUINT64] = ifaces.nsISupportsPRUint64
+ m[iface.TYPE_PRINT16] = ifaces.nsISupportsPRInt16
+ m[iface.TYPE_PRINT32] = ifaces.nsISupportsPRInt32
+ m[iface.TYPE_PRINT64] = ifaces.nsISupportsPRInt64
+ m[iface.TYPE_PRTIME] = ifaces.nsISupportsPRTime
+ m[iface.TYPE_CHAR] = ifaces.nsISupportsChar
+ m[iface.TYPE_FLOAT] = ifaces.nsISupportsFloat
+ m[iface.TYPE_DOUBLE] = ifaces.nsISupportsDouble
+ # Do interface pointer specially - it provides the IID.
+ #m[iface.TYPE_INTERFACE_POINTER] = ifaces.nsISupportsDouble
+
+def GetPrimitive(ob):
+ if len(_primitives_map)==0:
+ _build_map()
+
+ prin = ob.QueryInterface(components.interfaces.nsISupportsPrimitive)
+ try:
+ better = _primitives_map[prin.type]
+ except KeyError:
+ raise ValueError("This primitive type (%d) is not supported" % (prin.type,))
+ prin = prin.QueryInterface(better)
+ return prin.data
diff --git a/src/libs/xpcom18a4/python/readme.html b/src/libs/xpcom18a4/python/readme.html
new file mode 100644
index 00000000..112f43e0
--- /dev/null
+++ b/src/libs/xpcom18a4/python/readme.html
@@ -0,0 +1,121 @@
+<html>
+<!-- ***** 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 PyXPCOM.
+ -
+ - The Initial Developer of the Original Code is
+ - ActiveState Tool Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2000-2001
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - 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 LGPL or the GPL. 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 ***** -->
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Python XPCOM module</title>
+</head>
+
+<body>
+
+<h1>Python XPCOM Package</h1>
+
+<p>Mozilla CVS Version - Last updated May 2002</p>
+<p>This is the readme for the Python interface to <b>XPCOM</b>.</p>
+<p><b>XPCOM </b>is an acronym for &quot;Cross Platform COM&quot;.&nbsp; It has
+come out of the <a href="http://www.mozilla.org">Mozilla</a> project, which
+maintains the <a href="http://www.mozilla.org/projects/xpcom/">main XPCOM
+project pages.</a>&nbsp; The Python XPCOM package is a set of Python bindings to
+XPCOM, allowing a Python programmer to both use and implement XPCOM
+interfaces.&nbsp; If you don't know what <a href="http://www.python.org">Python</a>
+is, then none of this probably interests you at all!</p>
+<p>This readme has links to the following information:</p>
+<ul>
+ <li><a href="doc/configure.html">Building, Configuring and
+ Testing the Python
+ XPCOM Package</a></li>
+ <li><a href="doc/tutorial.html">A tutorial for the Python XPCOM package</a></li>
+ <li>Some <a href="doc/advanced.html">advanced
+ topics and other miscellaneous information</a></li>
+ <li><a href="doc/architecture.html">Information on the architecture</a></li>
+ <li>A list of the <a href="#KnownBugs">known issues and bugs</a>, the <a href="#ReleaseHistory">release
+ history</a> and the <a href="doc/credits.html">PyXPCOM acknowledgements</a></li>
+</ul>
+<p>Note: <b>This package requires Python 1.6 or later</b>; we recommend using
+the latest
+official Python version.&nbsp; This package works
+very well with the latest <a href="http://www.ActiveState.com/Products/ActivePython">ActivePython</a>,
+and does not require any external modules or packages beyond what is provided in
+the core Python release for each platform.</p>
+<h2>About the Python XPCOM Package</h2>
+<p>The Python XPCOM Package was developed by <a href="http://www.ActiveState.com">ActiveState
+Tool Corporation</a>, and came out of their <a href="http://www.ActiveState.com/Products/Komodo">Komodo
+project</a>.&nbsp; The Python XPCOM package is released under the <a href="http://www.mozilla.org/MPL/">Mozilla
+Public License (MPL)</a></p>
+<p>Please see the <a href="doc/credits.html">credits file</a> for a list of
+contributors. </p>
+<h2><a name="KnownBugs">Known Bugs</a>/Issues</h2>
+<ul>
+ <li>No attempt is made to recurse sub-directories of the main
+&quot;components&quot; directory.&nbsp; This is because we may decide on some
+smart scheme for recursion (similar to Python packages), and don't want people
+to rely on simple recursive searches.</li>
+ <li>No unregistration support at all.&nbsp;The main Python Component Loader supports
+ unregistration, but the actual Python objects themselves do not support unregistration.&nbsp;It is unclear if the Component Loader
+ unregistration process needs to manually remove each component it is responsible
+for.</li>
+ <li>All Python-implemented components unconditionally support
+weak-references.&nbsp; There is no way to disable this feature for any or all
+components.&nbsp; It is unclear if there is a need to prevent this, but it is
+documented here just in case!</li>
+</ul>
+<h2><a name="ReleaseHistory">Release History</a></h2>
+<h3>Version 0.90 - January 2001</h3>
+<ul>
+ <li>First public release.</li>
+</ul>
+<h3>Version 0.91 - January 2001</h3>
+<ul>
+ <li>Fix a seg fault on Linux when PYTHONPATH is not set.</li>
+ <li>Changes to allow building with stand-alone XPCOM.</li>
+</ul>
+
+<h3>Version 0.92 - May 2001</h3>
+<p>Implement interface flattening.&nbsp; You should (almost) never need to use <i>QueryInterface()</i>!&nbsp;
+We are still 100% backwards compatible, so usage of QI still works - just is
+generally not necessary.</p>
+
+<h3>Version 0.93 - May 2002</h3>
+
+<p>Implement <i>nsIVariant</i> and all new string types.&nbsp; Complete move to
+autoconf build system.</p>
+
+</body>
+
+</html>
diff --git a/src/libs/xpcom18a4/python/server/.cvsignore b/src/libs/xpcom18a4/python/server/.cvsignore
new file mode 100644
index 00000000..52e4e611
--- /dev/null
+++ b/src/libs/xpcom18a4/python/server/.cvsignore
@@ -0,0 +1,2 @@
+*.pyc
+*.pyo
diff --git a/src/libs/xpcom18a4/python/server/__init__.py b/src/libs/xpcom18a4/python/server/__init__.py
new file mode 100755
index 00000000..48b15106
--- /dev/null
+++ b/src/libs/xpcom18a4/python/server/__init__.py
@@ -0,0 +1,88 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# Activestate Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.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 *****
+
+# The xpcom.server package.
+
+from xpcom.server.policy import DefaultPolicy
+from xpcom import _xpcom
+
+# We define the concept of a single "tracer" object - similar to the single
+# Python "trace hook" for debugging. Someone can set
+# xpcom.server.tracer to some class/function, and it will be used in place
+# of the real xpcom object. Presumably this "trace" object will delegate
+# to the real object, but presumably also taking some other action, such
+# as calling a profiler or debugger.
+# tracer_unwrap is a function used to "unwrap" the tracer object.
+# If is expected that tracer_unwrap will be called with an object
+# previously returned by "tracer()".
+tracer = tracer_unwrap = None
+
+# Wrap an instance in an interface (via a policy)
+def WrapObject(ob, iid, policy = None, bWrapClient = 1):
+ """Called by the framework to attempt to wrap
+ an object in a policy.
+ If iid is None, it will use the first interface the object indicates it supports.
+ """
+ if policy is None:
+ policy = DefaultPolicy
+ if tracer is not None:
+ ob = tracer(ob)
+ return _xpcom.WrapObject(policy( ob, iid ), iid, bWrapClient)
+
+# Unwrap a Python object back into the Python object
+def UnwrapObject(ob):
+ if ob is None:
+ return None
+ ret = _xpcom.UnwrapObject(ob)._obj_
+ if tracer_unwrap is not None:
+ ret = tracer_unwrap(ret)
+ return ret
+
+# Create the main module for the Python loader.
+# This is a once only init process, and the returned object
+# if used to load all other Python components.
+
+# This means that we keep all factories, modules etc implemented in
+# Python!
+def NS_GetModule( serviceManager, nsIFile ):
+ from . import loader
+ iid = _xpcom.IID_nsIModule
+ return WrapObject(loader.MakePythonComponentLoaderModule(serviceManager, nsIFile), iid, bWrapClient = 0)
+
+def _shutdown():
+ from xpcom.server.policy import _shutdown
+ _shutdown()
diff --git a/src/libs/xpcom18a4/python/server/enumerator.py b/src/libs/xpcom18a4/python/server/enumerator.py
new file mode 100755
index 00000000..d3fb89a9
--- /dev/null
+++ b/src/libs/xpcom18a4/python/server/enumerator.py
@@ -0,0 +1,58 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.com> (original author)
+#
+# 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 *****
+
+from xpcom import components
+
+# This class is created by Python components when it
+# needs to return an enumerator.
+# For example, a component may implement a function:
+# nsISimpleEnumerator enumSomething();
+# This could could simply say:
+# return SimpleEnumerator([something1, something2, something3])
+class SimpleEnumerator:
+ _com_interfaces_ = [components.interfaces.nsISimpleEnumerator]
+
+ def __init__(self, data):
+ self._data = data
+ self._index = 0
+
+ def hasMoreElements(self):
+ return self._index < len(self._data)
+
+ def getNext(self):
+ self._index = self._index + 1
+ return self._data[self._index-1]
diff --git a/src/libs/xpcom18a4/python/server/factory.py b/src/libs/xpcom18a4/python/server/factory.py
new file mode 100755
index 00000000..b65483dd
--- /dev/null
+++ b/src/libs/xpcom18a4/python/server/factory.py
@@ -0,0 +1,68 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.com> (original author)
+#
+# 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 *****
+
+# Class factory
+#
+# Hardly worth its own source file!
+import xpcom
+from xpcom import components, nsError, _xpcom, logger
+
+class Factory:
+ _com_interfaces_ = components.interfaces.nsIFactory
+ # This will only ever be constructed via other Python code,
+ # so we can have ctor args.
+ def __init__(self, klass):
+ self.klass = klass
+
+ def createInstance(self, outer, iid):
+ if outer is not None:
+ raise xpcom.ServerException(nsError.NS_ERROR_NO_AGGREGATION)
+
+ logger.debug("Python Factory creating %s", self.klass.__name__)
+ try:
+ return self.klass()
+ except:
+ # An exception here may not be obvious to the user - none
+ # of their code has been called yet. It can be handy on
+ # failure to tell the user what class failed!
+ logger.error("Creation of class '%r' failed!\nException details follow\n",
+ self.klass)
+ # The framework itself will also report the error.
+ raise
+
+ def lockServer(self, lock):
+ logger.debug("Python Factory LockServer called '%s'", lock)
diff --git a/src/libs/xpcom18a4/python/server/loader.py b/src/libs/xpcom18a4/python/server/loader.py
new file mode 100755
index 00000000..ebd42b61
--- /dev/null
+++ b/src/libs/xpcom18a4/python/server/loader.py
@@ -0,0 +1,227 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# Activestate Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.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 *****
+
+import xpcom
+from xpcom import components, logger
+from . import module
+import glob
+import os
+from xpcom.client import Component
+
+# Until we get interface constants.
+When_Startup = 0
+When_Component = 1
+When_Timer = 2
+
+def _has_good_attr(object, attr):
+ # Actually allows "None" to be specified to disable inherited attributes.
+ return getattr(object, attr, None) is not None
+
+def FindCOMComponents(py_module):
+ # For now, just run over all classes looking for likely candidates.
+ comps = []
+ for name, object in list(py_module.__dict__.items()):
+ try:
+ if (type(object) == type or issubclass(object, object)) and \
+ _has_good_attr(object, "_com_interfaces_") and \
+ _has_good_attr(object, "_reg_clsid_") and \
+ _has_good_attr(object, "_reg_contractid_"):
+ comps.append(object)
+ except TypeError:
+ # The issubclass call raises TypeError when the obj is not a class.
+ pass;
+ return comps
+
+def register_self(klass, compMgr, location, registryLocation, componentType):
+ pcl = PythonComponentLoader
+ from xpcom import _xpcom
+ svc = _xpcom.GetServiceManager().getServiceByContractID("@mozilla.org/categorymanager;1", components.interfaces.nsICategoryManager)
+ svc.addCategoryEntry("component-loader", pcl._reg_component_type_, pcl._reg_contractid_, 1, 1)
+
+class PythonComponentLoader:
+ _com_interfaces_ = components.interfaces.nsIComponentLoader
+ _reg_clsid_ = "{63B68B1E-3E62-45f0-98E3-5E0B5797970C}" # Never copy these!
+ _reg_contractid_ = "moz.pyloader.1"
+ _reg_desc_ = "Python component loader"
+ # Optional function which performs additional special registration
+ # Appears that no special unregistration is needed for ComponentLoaders, hence no unregister function.
+ _reg_registrar_ = (register_self,None)
+ # Custom attributes for ComponentLoader registration.
+ _reg_component_type_ = "script/python"
+
+ def __init__(self):
+ self.com_modules = {} # Keyed by module's FQN as obtained from nsIFile.path
+ self.moduleFactory = module.Module
+ self.num_modules_this_register = 0
+
+ def _getCOMModuleForLocation(self, componentFile):
+ fqn = componentFile.path
+ mod = self.com_modules.get(fqn)
+ if mod is not None:
+ return mod
+ import ihooks, sys
+ base_name = os.path.splitext(os.path.basename(fqn))[0]
+ loader = ihooks.ModuleLoader()
+
+ module_name_in_sys = "component:%s" % (base_name,)
+ stuff = loader.find_module(base_name, [componentFile.parent.path])
+ assert stuff is not None, "Couldnt find the module '%s'" % (base_name,)
+ py_mod = loader.load_module( module_name_in_sys, stuff )
+
+ # Make and remember the COM module.
+ comps = FindCOMComponents(py_mod)
+ mod = self.moduleFactory(comps)
+
+ self.com_modules[fqn] = mod
+ return mod
+
+ def getFactory(self, clsid, location, type):
+ # return the factory
+ assert type == self._reg_component_type_, "Being asked to create an object not of my type:%s" % (type,)
+ # FIXME: how to do this without obsolete component manager?
+ cmo = components.manager.queryInterface(components.interfaces.nsIComponentManagerObsolete)
+ file_interface = cmo.specForRegistryLocation(location)
+ # delegate to the module.
+ m = self._getCOMModuleForLocation(file_interface)
+ return m.getClassObject(components.manager, clsid, components.interfaces.nsIFactory)
+
+ def init(self, comp_mgr, registry):
+ # void
+ self.comp_mgr = comp_mgr
+ logger.debug("Python component loader init() called")
+
+ # Called when a component of the appropriate type is registered,
+ # to give the component loader an opportunity to do things like
+ # annotate the registry and such.
+ def onRegister (self, clsid, type, className, proId, location, replace, persist):
+ logger.debug("Python component loader - onRegister() called")
+
+ def autoRegisterComponents (self, when, directory):
+ directory_path = directory.path
+ self.num_modules_this_register = 0
+ logger.debug("Auto-registering all Python components in '%s'", directory_path)
+
+ # ToDo - work out the right thing here
+ # eg - do we recurse?
+ # - do we support packages?
+ entries = directory.directoryEntries
+ while entries.HasMoreElements():
+ entry = entries.GetNext(components.interfaces.nsIFile)
+ if os.path.splitext(entry.path)[1]==".py":
+ try:
+ self.autoRegisterComponent(when, entry)
+ # Handle some common user errors
+ except xpcom.COMException as details:
+ from xpcom import nsError
+ # If the interface name does not exist, suppress the traceback
+ if details.errno==nsError.NS_ERROR_NO_INTERFACE:
+ logger.error("Registration of '%s' failed\n %s",
+ entry.leafName, details.message)
+ else:
+ logger.exception("Registration of '%s' failed!", entry.leafName)
+ except SyntaxError as details:
+ # Syntax error in source file - no useful traceback here either.
+ logger.error("Registration of '%s' failed\n %s",
+ entry.leafName, details)
+ except:
+ # All other exceptions get the full traceback.
+ logger.exception("Registration of '%s' failed.", entry.leafName)
+
+ def autoRegisterComponent (self, when, componentFile):
+ # bool return
+
+ # Check if we actually need to do anything
+ modtime = componentFile.lastModifiedTime
+ loader_mgr = components.manager.queryInterface(components.interfaces.nsIComponentLoaderManager)
+ if not loader_mgr.hasFileChanged(componentFile, None, modtime):
+ return 1
+
+ if self.num_modules_this_register == 0:
+ # New components may have just installed new Python
+ # modules into the main python directory (including new .pth files)
+ # So we ask Python to re-process our site directory.
+ # Note that the pyloader does the equivalent when loading.
+ try:
+ from xpcom import _xpcom
+ import site
+ NS_XPCOM_CURRENT_PROCESS_DIR="XCurProcD"
+ dirname = _xpcom.GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR)
+ dirname.append("python")
+ site.addsitedir(dirname.path)
+ except:
+ logger.exception("PyXPCOM loader failed to process site directory before component registration")
+
+ self.num_modules_this_register += 1
+
+ # auto-register via the module.
+ m = self._getCOMModuleForLocation(componentFile)
+ m.registerSelf(components.manager, componentFile, None, self._reg_component_type_)
+ loader_mgr = components.manager.queryInterface(components.interfaces.nsIComponentLoaderManager)
+ loader_mgr.saveFileInfo(componentFile, None, modtime)
+ return 1
+
+ def autoUnregisterComponent (self, when, componentFile):
+ # bool return
+ # auto-unregister via the module.
+ m = self._getCOMModuleForLocation(componentFile)
+ loader_mgr = components.manager.queryInterface(components.interfaces.nsIComponentLoaderManager)
+ try:
+ m.unregisterSelf(components.manager, componentFile)
+ finally:
+ loader_mgr.removeFileInfo(componentFile, None)
+ return 1
+
+ def registerDeferredComponents (self, when):
+ # bool return
+ logger.debug("Python component loader - registerDeferred() called")
+ return 0 # no more to register
+
+ def unloadAll (self, when):
+ # This is called at shutdown time - don't get too upset if an error
+ # results from logging due to the logfile being closed
+ try:
+ logger.debug("Python component loader being asked to unload all components!")
+ except:
+ # Evil blank except, but restricting to just catching IOError
+ # failure means custom logs could still screw us
+ pass
+ self.comp_mgr = None
+ self.com_modules = {}
+
+def MakePythonComponentLoaderModule(serviceManager, nsIFile):
+ from . import module
+ return module.Module( [PythonComponentLoader] )
diff --git a/src/libs/xpcom18a4/python/server/module.py b/src/libs/xpcom18a4/python/server/module.py
new file mode 100755
index 00000000..73024e95
--- /dev/null
+++ b/src/libs/xpcom18a4/python/server/module.py
@@ -0,0 +1,108 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is ActiveState Tool Corp.
+# Portions created by ActiveState Tool Corp. are Copyright (C) 2000, 2001
+# ActiveState Tool Corp. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.com> (original author)
+#
+# 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 *****
+
+from xpcom import components
+from xpcom import ServerException, Exception
+from xpcom import nsError
+
+from . import factory
+
+import types
+import os
+
+class Module:
+ _com_interfaces_ = components.interfaces.nsIModule
+ def __init__(self, comps):
+ # Build a map of classes we can provide factories for.
+ c = self.components = {}
+ for klass in comps:
+ c[components.ID(klass._reg_clsid_)] = klass
+ self.klassFactory = factory.Factory
+
+ def getClassObject(self, compMgr, clsid, iid):
+ # Single retval result.
+ try:
+ klass = self.components[clsid]
+ except KeyError:
+ raise ServerException(nsError.NS_ERROR_FACTORY_NOT_REGISTERED)
+
+ # We can ignore the IID - the auto-wrap process will automatically QI us.
+ return self.klassFactory(klass)
+
+ def registerSelf(self, compMgr, location, loaderStr, componentType):
+ # void function.
+ fname = os.path.basename(location.path)
+ for klass in list(self.components.values()):
+ reg_contractid = klass._reg_contractid_
+ print("Registering '%s' (%s)" % (reg_contractid, fname))
+ reg_desc = getattr(klass, "_reg_desc_", reg_contractid)
+ compMgr = compMgr.queryInterface(components.interfaces.nsIComponentRegistrar)
+ compMgr.registerFactoryLocation(klass._reg_clsid_,
+ reg_desc,
+ reg_contractid,
+ location,
+ loaderStr,
+ componentType)
+
+ # See if this class nominates custom register_self
+ extra_func = getattr(klass, "_reg_registrar_", (None,None))[0]
+ if extra_func is not None:
+ extra_func(klass, compMgr, location, loaderStr, componentType)
+
+ def unregisterSelf(self, compMgr, location, loaderStr):
+ # void function.
+ for klass in list(self.components.values()):
+ ok = 1
+ try:
+ compMgr.unregisterComponentSpec(klass._reg_clsid_, location)
+ except Exception:
+ ok = 0
+ # Give the class a bash even if we failed!
+ extra_func = getattr(klass, "_reg_registrar_", (None,None))[1]
+ if extra_func is not None:
+ try:
+ extra_func(klass, compMgr, location, loaderStr)
+ except Exception:
+ ok = 0
+ if ok:
+ print("Successfully unregistered", klass.__name__)
+ else:
+ print("Unregistration of", klass.__name__, "failed. (probably just not already registered)")
+
+ def canUnload(self, compMgr):
+ # single bool result
+ return 0 # we can never unload!
+
diff --git a/src/libs/xpcom18a4/python/server/policy.py b/src/libs/xpcom18a4/python/server/policy.py
new file mode 100755
index 00000000..7f84167c
--- /dev/null
+++ b/src/libs/xpcom18a4/python/server/policy.py
@@ -0,0 +1,398 @@
+# ***** 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 Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <mhammond@skippinet.com.au> (original author)
+#
+# 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 *****
+
+from xpcom import xpcom_consts, _xpcom, client, nsError, logger
+from xpcom import ServerException, COMException
+import xpcom
+import xpcom.server
+import operator
+import types
+import logging
+import sys
+
+# Python 3 hacks:
+if sys.version_info[0] >= 3:
+ long = int # pylint: disable=W0622,C0103
+
+
+IID_nsISupports = _xpcom.IID_nsISupports
+IID_nsIVariant = _xpcom.IID_nsIVariant
+XPT_MD_IS_GETTER = xpcom_consts.XPT_MD_IS_GETTER
+XPT_MD_IS_SETTER = xpcom_consts.XPT_MD_IS_SETTER
+
+VARIANT_INT_TYPES = xpcom_consts.VTYPE_INT8, xpcom_consts.VTYPE_INT16, xpcom_consts.VTYPE_INT32, \
+ xpcom_consts.VTYPE_UINT8, xpcom_consts.VTYPE_UINT16, xpcom_consts.VTYPE_INT32
+VARIANT_LONG_TYPES = xpcom_consts.VTYPE_INT64, xpcom_consts.VTYPE_UINT64
+VARIANT_FLOAT_TYPES = xpcom_consts.VTYPE_FLOAT, xpcom_consts.VTYPE_DOUBLE
+VARIANT_STRING_TYPES = xpcom_consts.VTYPE_CHAR, xpcom_consts.VTYPE_CHAR_STR, xpcom_consts.VTYPE_STRING_SIZE_IS, \
+ xpcom_consts.VTYPE_CSTRING
+VARIANT_UNICODE_TYPES = xpcom_consts.VTYPE_WCHAR, xpcom_consts.VTYPE_DOMSTRING, xpcom_consts.VTYPE_WSTRING_SIZE_IS, \
+ xpcom_consts.VTYPE_ASTRING
+
+_supports_primitives_map_ = {} # Filled on first use.
+
+_interface_sequence_types_ = tuple, list
+if sys.version_info[0] <= 2:
+ _string_types_ = str, unicode
+else:
+ _string_types_ = bytes, str
+XPTI_GetInterfaceInfoManager = _xpcom.XPTI_GetInterfaceInfoManager
+
+def _GetNominatedInterfaces(obj):
+ ret = getattr(obj, "_com_interfaces_", None)
+ if ret is None: return None
+ # See if the user only gave one.
+ if type(ret) not in _interface_sequence_types_:
+ ret = [ret]
+ real_ret = []
+ # For each interface, walk to the root of the interface tree.
+ iim = XPTI_GetInterfaceInfoManager()
+ for interface in ret:
+ # Allow interface name or IID.
+ interface_info = None
+ if type(interface) in _string_types_:
+ try:
+ interface_info = iim.GetInfoForName(interface)
+ except COMException:
+ pass
+ if interface_info is None:
+ # Allow a real IID
+ interface_info = iim.GetInfoForIID(interface)
+ real_ret.append(interface_info.GetIID())
+ parent = interface_info.GetParent()
+ while parent is not None:
+ parent_iid = parent.GetIID()
+ if parent_iid == IID_nsISupports:
+ break
+ real_ret.append(parent_iid)
+ parent = parent.GetParent()
+ return real_ret
+
+##
+## ClassInfo support
+##
+## We cache class infos by class
+class_info_cache = {}
+
+def GetClassInfoForObject(ob):
+ if xpcom.server.tracer_unwrap is not None:
+ ob = xpcom.server.tracer_unwrap(ob)
+ klass = ob.__class__
+ ci = class_info_cache.get(klass)
+ if ci is None:
+ ci = DefaultClassInfo(klass)
+ ci = xpcom.server.WrapObject(ci, _xpcom.IID_nsIClassInfo, bWrapClient = 0)
+ class_info_cache[klass] = ci
+ return ci
+
+class DefaultClassInfo:
+ _com_interfaces_ = _xpcom.IID_nsIClassInfo
+ def __init__(self, klass):
+ self.klass = klass
+ self.contractID = getattr(klass, "_reg_contractid_", None)
+ self.classDescription = getattr(klass, "_reg_desc_", None)
+ self.classID = getattr(klass, "_reg_clsid_", None)
+ self.implementationLanguage = 3 # Python - avoid lookups just for this
+ self.flags = 0 # what to do here??
+ self.interfaces = None
+
+ def get_classID(self):
+ if self.classID is None:
+ raise ServerException(nsError.NS_ERROR_NOT_IMPLEMENTED, "Class '%r' has no class ID" % (self.klass,))
+ return self.classID
+
+ def getInterfaces(self):
+ if self.interfaces is None:
+ self.interfaces = _GetNominatedInterfaces(self.klass)
+ return self.interfaces
+
+ def getHelperForLanguage(self, language):
+ return None # Not sure what to do here.
+
+class DefaultPolicy:
+ def __init__(self, instance, iid):
+ self._obj_ = instance
+ self._nominated_interfaces_ = ni = _GetNominatedInterfaces(instance)
+ self._iid_ = iid
+ if ni is None:
+ raise ValueError("The object '%r' can not be used as a COM object" % (instance,))
+ # This is really only a check for the user
+ if __debug__:
+ if iid != IID_nsISupports and iid not in ni:
+ # The object may delegate QI.
+ delegate_qi = getattr(instance, "_query_interface_", None)
+ # Perform the actual QI and throw away the result - the _real_
+ # QI performed by the framework will set things right!
+ if delegate_qi is None or not delegate_qi(iid):
+ raise ServerException(nsError.NS_ERROR_NO_INTERFACE)
+ # Stuff for the magic interface conversion.
+ self._interface_info_ = None
+ self._interface_iid_map_ = {} # Cache - Indexed by (method_index, param_index)
+
+ def _QueryInterface_(self, com_object, iid):
+ # Framework allows us to return a single boolean integer,
+ # or a COM object.
+ if iid in self._nominated_interfaces_:
+ # We return the underlying object re-wrapped
+ # in a new gateway - which is desirable, as one gateway should only support
+ # one interface (this wont affect the users of this policy - we can have as many
+ # gateways as we like pointing to the same Python objects - the users never
+ # see what object the call came in from.
+ # NOTE: We could have simply returned the instance and let the framework
+ # do the auto-wrap for us - but this way we prevent a round-trip back into Python
+ # code just for the autowrap.
+ return xpcom.server.WrapObject(self._obj_, iid, bWrapClient = 0)
+
+ # Always support nsIClassInfo
+ if iid == _xpcom.IID_nsIClassInfo:
+ return GetClassInfoForObject(self._obj_)
+
+ # See if the instance has a QI
+ # use lower-case "_query_interface_" as win32com does, and it doesnt really matter.
+ delegate = getattr(self._obj_, "_query_interface_", None)
+ if delegate is not None:
+ # The COM object itself doesnt get passed to the child
+ # (again, as win32com doesnt). It is rarely needed
+ # (in win32com, we dont even pass it to the policy, although we have identified
+ # one place where we should - for marshalling - so I figured I may as well pass it
+ # to the policy layer here, but no all the way down to the object.
+ return delegate(iid)
+ # Finally see if we are being queried for one of the "nsISupports primitives"
+ if not _supports_primitives_map_:
+ iim = _xpcom.XPTI_GetInterfaceInfoManager()
+ for (iid_name, attr, cvt) in _supports_primitives_data_:
+ special_iid = iim.GetInfoForName(iid_name).GetIID()
+ _supports_primitives_map_[special_iid] = (attr, cvt)
+ attr, cvt = _supports_primitives_map_.get(iid, (None,None))
+ if attr is not None and hasattr(self._obj_, attr):
+ return xpcom.server.WrapObject(SupportsPrimitive(iid, self._obj_, attr, cvt), iid, bWrapClient = 0)
+ # Out of clever things to try!
+ return None # We dont support this IID.
+
+ def _MakeInterfaceParam_(self, interface, iid, method_index, mi, param_index):
+ # Wrap a "raw" interface object in a nice object. The result of this
+ # function will be passed to one of the gateway methods.
+ if iid is None:
+ # look up the interface info - this will be true for all xpcom called interfaces.
+ if self._interface_info_ is None:
+ import xpcom.xpt
+ self._interface_info_ = xpcom.xpt.Interface( self._iid_ )
+ iid = self._interface_iid_map_.get( (method_index, param_index))
+ if iid is None:
+ iid = self._interface_info_.GetIIDForParam(method_index, param_index)
+ self._interface_iid_map_[(method_index, param_index)] = iid
+ # handle nsIVariant
+ if iid == IID_nsIVariant:
+ interface = interface.QueryInterface(iid)
+ dt = interface.dataType
+ if dt in VARIANT_INT_TYPES:
+ return interface.getAsInt32()
+ if dt in VARIANT_LONG_TYPES:
+ return interface.getAsInt64()
+ if dt in VARIANT_FLOAT_TYPES:
+ return interface.getAsFloat()
+ if dt in VARIANT_STRING_TYPES:
+ return interface.getAsStringWithSize()
+ if dt in VARIANT_UNICODE_TYPES:
+ return interface.getAsWStringWithSize()
+ if dt == xpcom_consts.VTYPE_BOOL:
+ return interface.getAsBool()
+ if dt == xpcom_consts.VTYPE_INTERFACE:
+ return interface.getAsISupports()
+ if dt == xpcom_consts.VTYPE_INTERFACE_IS:
+ return interface.getAsInterface()
+ if dt == xpcom_consts.VTYPE_EMPTY or dt == xpcom_consts.VTYPE_VOID:
+ return None
+ if dt == xpcom_consts.VTYPE_ARRAY:
+ return interface.getAsArray()
+ if dt == xpcom_consts.VTYPE_EMPTY_ARRAY:
+ return []
+ if dt == xpcom_consts.VTYPE_ID:
+ return interface.getAsID()
+ # all else fails...
+ logger.warning("Warning: nsIVariant type %d not supported - returning a string", dt)
+ try:
+ return interface.getAsString()
+ except COMException:
+ logger.exception("Error: failed to get Variant as a string - returning variant object")
+ return interface
+
+ return client.Component(interface, iid)
+
+ def _CallMethod_(self, com_object, index, info, params):
+ #print "_CallMethod_", index, info, params
+ flags, name, param_descs, ret = info
+ assert ret[1][0] == xpcom_consts.TD_UINT32, "Expected an nsresult (%s)" % (ret,)
+ if XPT_MD_IS_GETTER(flags):
+ # Look for a function of that name
+ func = getattr(self._obj_, "get_" + name, None)
+ if func is None:
+ assert len(param_descs)==1 and len(params)==0, "Can only handle a single [out] arg for a default getter"
+ ret = getattr(self._obj_, name) # Let attribute error go here!
+ else:
+ ret = func(*params)
+ return 0, ret
+ elif XPT_MD_IS_SETTER(flags):
+ # Look for a function of that name
+ func = getattr(self._obj_, "set_" + name, None)
+ if func is None:
+ assert len(param_descs)==1 and len(params)==1, "Can only handle a single [in] arg for a default setter"
+ setattr(self._obj_, name, params[0]) # Let attribute error go here!
+ else:
+ func(*params)
+ return 0
+ else:
+ # A regular method.
+ func = getattr(self._obj_, name)
+ return 0, func(*params)
+
+ def _doHandleException(self, func_name, exc_info):
+ exc_val = exc_info[1]
+ is_server_exception = isinstance(exc_val, ServerException)
+ if is_server_exception:
+ # When a component raised an explicit COM exception, it is
+ # considered 'normal' - however, we still write a debug log
+ # record to help track these otherwise silent exceptions.
+
+ # Note that Python 2.3 does not allow an explicit exc_info tuple
+ # and passing 'True' will not work as there is no exception pending.
+ # Trick things!
+ if logger.isEnabledFor(logging.DEBUG):
+ try:
+ if sys.version_info[0] <= 2:
+ exec('raise exc_info[0], exc_info[1], exc_info[2]')
+ else:
+ raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
+ except:
+ logger.debug("'%s' raised COM Exception %s",
+ func_name, exc_val, exc_info = 1)
+ return exc_val.errno
+ # Unhandled exception - always print a warning and the traceback.
+ # As above, trick the logging module to handle Python 2.3
+ try:
+ if sys.version_info[0] <= 2:
+ exec('raise exc_info[0], exc_info[1], exc_info[2]')
+ else:
+ raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
+ except:
+ logger.exception("Unhandled exception calling '%s'", func_name)
+ return nsError.NS_ERROR_FAILURE
+
+ # Called whenever an unhandled Python exception is detected as a result
+ # of _CallMethod_ - this exception may have been raised during the _CallMethod_
+ # invocation, or after its return, but when unpacking the results
+ # eg, type errors, such as a Python integer being used as a string "out" param.
+ def _CallMethodException_(self, com_object, index, info, params, exc_info):
+ # Later we may want to have some smart "am I debugging" flags?
+ # Or maybe just delegate to the actual object - it's probably got the best
+ # idea what to do with them!
+ flags, name, param_descs, ret = info
+ exc_typ, exc_val, exc_tb = exc_info
+ # use the xpt module to get a better repr for the method.
+ # But if we fail, ignore it!
+ try:
+ import xpcom.xpt
+ m = xpcom.xpt.Method(info, index, None)
+ func_repr = m.Describe().lstrip()
+ except COMException:
+ func_repr = "%s(%r)" % (name, param_descs)
+ except:
+ # any other errors are evil!? Log it
+ self._doHandleException("<building method repr>", sys.exc_info())
+ # And fall through to logging the original error.
+ return self._doHandleException(func_repr, exc_info)
+
+ # Called whenever a gateway fails due to anything other than _CallMethod_.
+ # Really only used for the component loader etc objects, so most
+ # users should never see exceptions triggered here.
+ def _GatewayException_(self, name, exc_info):
+ return self._doHandleException(name, exc_info)
+
+if sys.version_info[0] <= 2:
+ _supports_primitives_data_ = [
+ ("nsISupportsCString", "__str__", str),
+ ("nsISupportsString", "__unicode__", unicode),
+ ("nsISupportsPRUint64", "__long__", long),
+ ("nsISupportsPRInt64", "__long__", long),
+ ("nsISupportsPRUint32", "__int__", int),
+ ("nsISupportsPRInt32", "__int__", int),
+ ("nsISupportsPRUint16", "__int__", int),
+ ("nsISupportsPRInt16", "__int__", int),
+ ("nsISupportsPRUint8", "__int__", int),
+ ("nsISupportsPRBool", "__nonzero__", operator.truth),
+ ("nsISupportsDouble", "__float__", float),
+ ("nsISupportsFloat", "__float__", float),
+ ]
+else:
+ _supports_primitives_data_ = [
+ ("nsISupportsCString", "__str__", str),
+ ("nsISupportsString", "__unicode__", str),
+ ("nsISupportsPRUint64", "__long__", int),
+ ("nsISupportsPRInt64", "__long__", int),
+ ("nsISupportsPRUint32", "__int__", int),
+ ("nsISupportsPRInt32", "__int__", int),
+ ("nsISupportsPRUint16", "__int__", int),
+ ("nsISupportsPRInt16", "__int__", int),
+ ("nsISupportsPRUint8", "__int__", int),
+ ("nsISupportsPRBool", "__nonzero__", operator.truth),
+ ("nsISupportsDouble", "__float__", float),
+ ("nsISupportsFloat", "__float__", float),
+ ]
+
+# Support for the nsISupports primitives:
+class SupportsPrimitive:
+ _com_interfaces_ = ["nsISupports"]
+ def __init__(self, iid, base_ob, attr_name, converter):
+ self.iid = iid
+ self.base_ob = base_ob
+ self.attr_name = attr_name
+ self.converter = converter
+ def _query_interface_(self, iid):
+ if iid == self.iid:
+ return 1
+ return None
+ def get_data(self):
+ method = getattr(self.base_ob, self.attr_name)
+ val = method()
+ return self.converter(val)
+ def set_data(self, val):
+ raise ServerException(nsError.NS_ERROR_NOT_IMPLEMENTED)
+ def toString(self):
+ return str(self.get_data())
+
+def _shutdown():
+ class_info_cache.clear()
diff --git a/src/libs/xpcom18a4/python/src/ErrorUtils.cpp b/src/libs/xpcom18a4/python/src/ErrorUtils.cpp
new file mode 100644
index 00000000..9400799b
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/ErrorUtils.cpp
@@ -0,0 +1,483 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <MarkH@ActiveState.com> (original author)
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+#include "nsReadableUtils.h"
+#include <nsIConsoleService.h>
+#ifdef VBOX
+# include <nsIExceptionService.h>
+# include <iprt/err.h>
+# include <iprt/string.h>
+#endif
+#include "nspr.h" // PR_fprintf
+
+static char *PyTraceback_AsString(PyObject *exc_tb);
+
+// The internal helper that actually moves the
+// formatted string to the target!
+
+// Only used in really bad situations!
+static void _PanicErrorWrite(const char *msg)
+{
+ nsCOMPtr<nsIConsoleService> consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+ if (consoleService)
+ consoleService->LogStringMessage(NS_ConvertASCIItoUCS2(msg).get());
+ PR_fprintf(PR_STDERR,"%s\n", msg);
+}
+
+// Called when our "normal" error logger fails.
+static void HandleLogError(const char *pszMessageText)
+{
+ nsCAutoString streamout;
+
+ _PanicErrorWrite("Failed to log an error record");
+ if (PyXPCOM_FormatCurrentException(streamout))
+ _PanicErrorWrite(streamout.get());
+ _PanicErrorWrite("Original error follows:");
+ _PanicErrorWrite(pszMessageText);
+}
+
+static const char *LOGGER_WARNING = "warning";
+static const char *LOGGER_ERROR = "error";
+static const char *LOGGER_DEBUG = "debug";
+
+// Our "normal" error logger - calls back to the logging module.
+void DoLogMessage(const char *methodName, const char *pszMessageText)
+{
+ // We use the logging module now. Originally this code called
+ // the logging module directly by way of the C API's
+ // PyImport_ImportModule/PyObject_CallMethod etc. However, this
+ // causes problems when there is no Python caller on the stack -
+ // the logging module's findCaller method fails with a None frame.
+ // We now work around this by calling PyRun_SimpleString - this
+ // causes a new frame to be created for executing the compiled
+ // string, and the logging module no longer fails.
+ // XXX - this implementation is less than ideal - findCaller now
+ // returns ("<string>", 2). Ideally we would compile with a
+ // filename something similar to "<pydom error reporter>".
+
+ // But this also means we need a clear error state...
+ PyObject *exc_typ = NULL, *exc_val = NULL, *exc_tb = NULL;
+ PyErr_Fetch(&exc_typ, &exc_val, &exc_tb);
+// We will execute:
+// import logging
+// logging.getLogger('xpcom').{warning/error/etc}("%s", {msg_text})
+ nsCAutoString c("import logging\nlogging.getLogger('xpcom').");
+ c += methodName;
+ c += "('%s', ";
+ // Pull a trick to ensure a valid string - use Python repr!
+#if PY_MAJOR_VERSION <= 2
+ PyObject *obMessage = PyString_FromString(pszMessageText);
+#else
+ PyObject *obMessage = PyUnicode_FromString(pszMessageText);
+#endif
+ if (obMessage) {
+ PyObject *repr = PyObject_Repr(obMessage);
+ if (repr) {
+#if PY_MAJOR_VERSION <= 2
+ c += PyString_AsString(repr);
+#else
+ c += PyUnicode_AsUTF8(repr);
+#endif
+ Py_DECREF(repr);
+ }
+ Py_DECREF(obMessage);
+ }
+ c += ")\n";
+ if (PyRun_SimpleString(c.get()) != 0) {
+ HandleLogError(pszMessageText);
+ }
+ PyErr_Restore(exc_typ, exc_val, exc_tb);
+}
+
+void LogMessage(const char *methodName, const char *pszMessageText)
+{
+ // Be careful to save and restore the Python exception state
+ // before calling back to Python, or we lose the original error.
+ PyObject *exc_typ = NULL, *exc_val = NULL, *exc_tb = NULL;
+ PyErr_Fetch( &exc_typ, &exc_val, &exc_tb);
+ DoLogMessage(methodName, pszMessageText);
+ PyErr_Restore(exc_typ, exc_val, exc_tb);
+}
+
+
+void LogMessage(const char *methodName, nsACString &text)
+{
+ char *c = ToNewCString(text);
+ LogMessage(methodName, c);
+ nsCRT::free(c);
+}
+
+// A helper for the various logging routines.
+static void VLogF(const char *methodName, const char *fmt, va_list argptr)
+{
+ char buff[512];
+#ifdef VBOX /* Enable the use of VBox formatting types. */
+ RTStrPrintfV(buff, sizeof(buff), fmt, argptr);
+#else
+ // Use safer NS_ functions.
+ PR_vsnprintf(buff, sizeof(buff), fmt, argptr);
+#endif
+
+ LogMessage(methodName, buff);
+}
+
+PRBool PyXPCOM_FormatCurrentException(nsCString &streamout)
+{
+ PRBool ok = PR_FALSE;
+ PyObject *exc_typ = NULL, *exc_val = NULL, *exc_tb = NULL;
+ PyErr_Fetch( &exc_typ, &exc_val, &exc_tb);
+ PyErr_NormalizeException( &exc_typ, &exc_val, &exc_tb);
+ if (exc_typ) {
+ ok = PyXPCOM_FormatGivenException(streamout, exc_typ, exc_val,
+ exc_tb);
+ }
+ PyErr_Restore(exc_typ, exc_val, exc_tb);
+ return ok;
+}
+
+PRBool PyXPCOM_FormatGivenException(nsCString &streamout,
+ PyObject *exc_typ, PyObject *exc_val,
+ PyObject *exc_tb)
+{
+ if (!exc_typ)
+ return PR_FALSE;
+ streamout += "\n";
+
+ if (exc_tb) {
+ const char *szTraceback = PyTraceback_AsString(exc_tb);
+ if (szTraceback == NULL)
+ streamout += "Can't get the traceback info!";
+ else {
+ streamout += "Traceback (most recent call last):\n";
+ streamout += szTraceback;
+ PyMem_Free((void *)szTraceback);
+ }
+ }
+ PyObject *temp = PyObject_Str(exc_typ);
+ if (temp) {
+#if PY_MAJOR_VERSION <= 2
+ streamout += PyString_AsString(temp);
+#else
+ streamout += PyUnicode_AsUTF8(temp);
+#endif
+ Py_DECREF(temp);
+ } else
+ streamout += "Can't convert exception to a string!";
+ streamout += ": ";
+ if (exc_val != NULL) {
+ temp = PyObject_Str(exc_val);
+ if (temp) {
+#if PY_MAJOR_VERSION <= 2
+ streamout += PyString_AsString(temp);
+#else
+ streamout += PyUnicode_AsUTF8(temp);
+#endif
+ Py_DECREF(temp);
+ } else
+ streamout += "Can't convert exception value to a string!";
+ }
+ return PR_TRUE;
+}
+
+void PyXPCOM_LogError(const char *fmt, ...)
+{
+ va_list marker;
+ va_start(marker, fmt);
+ // NOTE: It is tricky to use logger.exception here - the exception
+ // state when called back from the C code is clear. Only Python 2.4
+ // and later allows an explicit exc_info tuple().
+
+ // Don't use VLogF here, instead arrange for exception info and
+ // traceback to be in the same buffer.
+ char buff[512];
+ PR_vsnprintf(buff, sizeof(buff), fmt, marker);
+ // If we have a Python exception, also log that:
+ nsCAutoString streamout(buff);
+ if (PyXPCOM_FormatCurrentException(streamout)) {
+ LogMessage(LOGGER_ERROR, streamout);
+ }
+ va_end(marker);
+}
+
+void PyXPCOM_LogWarning(const char *fmt, ...)
+{
+ va_list marker;
+ va_start(marker, fmt);
+ VLogF(LOGGER_WARNING, fmt, marker);
+ va_end(marker);
+}
+
+void PyXPCOM_Log(const char *level, const nsCString &msg)
+{
+ DoLogMessage(level, msg.get());
+}
+
+#ifdef DEBUG
+void PyXPCOM_LogDebug(const char *fmt, ...)
+{
+ va_list marker;
+ va_start(marker, fmt);
+ VLogF(LOGGER_DEBUG, fmt, marker);
+ va_end(marker);
+}
+#endif
+
+#ifdef VBOX
+PyObject *PyXPCOM_BuildErrorMessage(nsresult r)
+{
+ char msg[512];
+ bool gotMsg = false;
+
+ if (!gotMsg)
+ {
+ nsresult rc;
+ nsCOMPtr <nsIExceptionService> es;
+ es = do_GetService (NS_EXCEPTIONSERVICE_CONTRACTID, &rc);
+ if (NS_SUCCEEDED (rc))
+ {
+ nsCOMPtr <nsIExceptionManager> em;
+ rc = es->GetCurrentExceptionManager (getter_AddRefs (em));
+ if (NS_SUCCEEDED (rc))
+ {
+ nsCOMPtr <nsIException> ex;
+ rc = em->GetExceptionFromProvider(r, NULL, getter_AddRefs (ex));
+ if (NS_SUCCEEDED (rc) && ex)
+ {
+ nsXPIDLCString emsg;
+ ex->GetMessage(getter_Copies(emsg));
+ PR_snprintf(msg, sizeof(msg), "%s",
+ emsg.get());
+ gotMsg = true;
+ }
+ }
+ }
+ }
+
+ if (!gotMsg)
+ {
+ const RTCOMERRMSG* pMsg = RTErrCOMGet(r);
+ if (strncmp(pMsg->pszMsgFull, "Unknown", 7) != 0)
+ {
+ PR_snprintf(msg, sizeof(msg), "%s (%s)",
+ pMsg->pszMsgFull, pMsg->pszDefine);
+ gotMsg = true;
+ }
+ }
+
+ if (!gotMsg)
+ {
+ PR_snprintf(msg, sizeof(msg), "Error 0x%x in module 0x%x",
+ NS_ERROR_GET_CODE(r), NS_ERROR_GET_MODULE(r));
+ }
+ PyObject *evalue = Py_BuildValue("is", r, msg);
+ return evalue;
+}
+#endif
+
+PyObject *PyXPCOM_BuildPyException(nsresult r)
+{
+#ifndef VBOX
+ // Need the message etc.
+ PyObject *evalue = Py_BuildValue("i", r);
+#else
+ PyObject *evalue = PyXPCOM_BuildErrorMessage(r);
+#endif
+ PyErr_SetObject(PyXPCOM_Error, evalue);
+ Py_XDECREF(evalue);
+ return NULL;
+}
+
+nsresult PyXPCOM_SetCOMErrorFromPyException()
+{
+ if (!PyErr_Occurred())
+ // No error occurred
+ return NS_OK;
+ nsresult rv = NS_ERROR_FAILURE;
+ if (PyErr_ExceptionMatches(PyExc_MemoryError))
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ // todo:
+ // * Set an exception using the exception service.
+
+ // Once we have returned to the xpcom caller, we don't want to leave a
+ // Python exception pending - it may get noticed when the next call
+ // is made on the same thread.
+ PyErr_Clear();
+ return rv;
+}
+
+/* Obtains a string from a Python traceback.
+ This is the exact same string as "traceback.print_exc" would return.
+
+ Pass in a Python traceback object (probably obtained from PyErr_Fetch())
+ Result is a string which must be free'd using PyMem_Free()
+*/
+#define TRACEBACK_FETCH_ERROR(what) {errMsg = what; goto done;}
+
+char *PyTraceback_AsString(PyObject *exc_tb)
+{
+ const char *errMsg = NULL; /* holds a local error message */
+ char *result = NULL; /* a valid, allocated result. */
+ PyObject *modStringIO = NULL;
+ PyObject *modTB = NULL;
+ PyObject *obFuncStringIO = NULL;
+ PyObject *obStringIO = NULL;
+ PyObject *obFuncTB = NULL;
+ PyObject *argsTB = NULL;
+ PyObject *obResult = NULL;
+
+#if PY_MAJOR_VERSION <= 2
+ /* Import the modules we need - cStringIO and traceback */
+ modStringIO = PyImport_ImportModule("cStringIO");
+ if (modStringIO==NULL)
+ TRACEBACK_FETCH_ERROR("cant import cStringIO\n");
+
+ modTB = PyImport_ImportModule("traceback");
+ if (modTB==NULL)
+ TRACEBACK_FETCH_ERROR("cant import traceback\n");
+ /* Construct a cStringIO object */
+ obFuncStringIO = PyObject_GetAttrString(modStringIO, "StringIO");
+ if (obFuncStringIO==NULL)
+ TRACEBACK_FETCH_ERROR("cant find cStringIO.StringIO\n");
+ obStringIO = PyObject_CallObject(obFuncStringIO, NULL);
+ if (obStringIO==NULL)
+ TRACEBACK_FETCH_ERROR("cStringIO.StringIO() failed\n");
+#else
+ /* Import the modules we need - io and traceback */
+ modStringIO = PyImport_ImportModule("io");
+ if (modStringIO==NULL)
+ TRACEBACK_FETCH_ERROR("cant import io\n");
+
+ modTB = PyImport_ImportModule("traceback");
+ if (modTB==NULL)
+ TRACEBACK_FETCH_ERROR("cant import traceback\n");
+ /* Construct a StringIO object */
+ obFuncStringIO = PyObject_GetAttrString(modStringIO, "StringIO");
+ if (obFuncStringIO==NULL)
+ TRACEBACK_FETCH_ERROR("cant find io.StringIO\n");
+ obStringIO = PyObject_CallObject(obFuncStringIO, NULL);
+ if (obStringIO==NULL)
+ TRACEBACK_FETCH_ERROR("io.StringIO() failed\n");
+#endif
+ /* Get the traceback.print_exception function, and call it. */
+ obFuncTB = PyObject_GetAttrString(modTB, "print_tb");
+ if (obFuncTB==NULL)
+ TRACEBACK_FETCH_ERROR("cant find traceback.print_tb\n");
+
+ argsTB = Py_BuildValue("OOO",
+ exc_tb ? exc_tb : Py_None,
+ Py_None,
+ obStringIO);
+ if (argsTB==NULL)
+ TRACEBACK_FETCH_ERROR("cant make print_tb arguments\n");
+
+ obResult = PyObject_CallObject(obFuncTB, argsTB);
+ if (obResult==NULL)
+ TRACEBACK_FETCH_ERROR("traceback.print_tb() failed\n");
+ /* Now call the getvalue() method in the StringIO instance */
+ Py_DECREF(obFuncStringIO);
+ obFuncStringIO = PyObject_GetAttrString(obStringIO, "getvalue");
+ if (obFuncStringIO==NULL)
+ TRACEBACK_FETCH_ERROR("cant find getvalue function\n");
+ Py_DECREF(obResult);
+ obResult = PyObject_CallObject(obFuncStringIO, NULL);
+ if (obResult==NULL)
+ TRACEBACK_FETCH_ERROR("getvalue() failed.\n");
+
+ /* And it should be a string all ready to go - duplicate it. */
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(obResult))
+#else
+ if (!PyUnicode_Check(obResult))
+#endif
+ TRACEBACK_FETCH_ERROR("getvalue() did not return a string\n");
+
+ { // a temp scope so I can use temp locals.
+#if PY_MAJOR_VERSION <= 2
+ char *tempResult = PyString_AsString(obResult);
+#else
+ /* PyUnicode_AsUTF8() is const char * as of Python 3.7, char * earlier. */
+ const char *tempResult = (const char *)PyUnicode_AsUTF8(obResult);
+#endif
+ result = (char *)PyMem_Malloc(strlen(tempResult)+1);
+ if (result==NULL)
+ TRACEBACK_FETCH_ERROR("memory error duplicating the traceback string\n");
+
+ strcpy(result, tempResult);
+ } // end of temp scope.
+done:
+ /* All finished - first see if we encountered an error */
+ if (result==NULL && errMsg != NULL) {
+ result = (char *)PyMem_Malloc(strlen(errMsg)+1);
+ if (result != NULL)
+ /* if it does, not much we can do! */
+ strcpy(result, errMsg);
+ }
+ Py_XDECREF(modStringIO);
+ Py_XDECREF(modTB);
+ Py_XDECREF(obFuncStringIO);
+ Py_XDECREF(obStringIO);
+ Py_XDECREF(obFuncTB);
+ Py_XDECREF(argsTB);
+ Py_XDECREF(obResult);
+ return result;
+}
+
+// See comments in PyXPCOM.h for why we need this!
+void PyXPCOM_MakePendingCalls()
+{
+ while (1) {
+ int rc = Py_MakePendingCalls();
+ if (rc == 0)
+ break;
+ // An exception - just report it as normal.
+ // Note that a traceback is very unlikely!
+ PyXPCOM_LogError("Unhandled exception detected before entering Python.\n");
+ PyErr_Clear();
+ // And loop around again until we are told everything is done!
+ }
+}
diff --git a/src/libs/xpcom18a4/python/src/PyGBase.cpp b/src/libs/xpcom18a4/python/src/PyGBase.cpp
new file mode 100644
index 00000000..e73b2a6d
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyGBase.cpp
@@ -0,0 +1,852 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+// PyGBase.cpp - implementation of the PyG_Base class
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+#include <nsIModule.h>
+#include <nsIComponentLoader.h>
+#include <nsIInputStream.h>
+
+static PRInt32 cGateways = 0;
+PRInt32 _PyXPCOM_GetGatewayCount(void)
+{
+ return cGateways;
+}
+
+extern PyG_Base *MakePyG_nsIModule(PyObject *);
+extern PyG_Base *MakePyG_nsIComponentLoader(PyObject *instance);
+extern PyG_Base *MakePyG_nsIInputStream(PyObject *instance);
+
+static char *PyXPCOM_szDefaultGatewayAttributeName = (char*)"_com_instance_default_gateway_";
+PyG_Base *GetDefaultGateway(PyObject *instance);
+void AddDefaultGateway(PyObject *instance, nsISupports *gateway);
+PRBool CheckDefaultGateway(PyObject *real_inst, REFNSIID iid, nsISupports **ret_gateway);
+
+/*static*/ nsresult
+PyG_Base::CreateNew(PyObject *pPyInstance, const nsIID &iid, void **ppResult)
+{
+ NS_PRECONDITION(ppResult && *ppResult==NULL, "NULL or uninitialized pointer");
+ if (ppResult==nsnull)
+ return NS_ERROR_NULL_POINTER;
+
+ PyG_Base *ret;
+ // Hack for few extra gateways we support.
+ if (iid.Equals(NS_GET_IID(nsIModule)))
+ ret = MakePyG_nsIModule(pPyInstance);
+ else if (iid.Equals(NS_GET_IID(nsIComponentLoader)))
+ ret = MakePyG_nsIComponentLoader(pPyInstance);
+ else if (iid.Equals(NS_GET_IID(nsIInputStream)))
+ ret = MakePyG_nsIInputStream(pPyInstance);
+ else
+ ret = new PyXPCOM_XPTStub(pPyInstance, iid);
+ if (ret==nsnull)
+ return NS_ERROR_OUT_OF_MEMORY;
+ ret->AddRef(); // The first reference for the caller.
+ *ppResult = ret->ThisAsIID(iid);
+ NS_ABORT_IF_FALSE(*ppResult != NULL, "ThisAsIID() gave NULL, but we know it supports it!");
+ return *ppResult ? NS_OK : NS_ERROR_FAILURE;
+}
+
+PyG_Base::PyG_Base(PyObject *instance, const nsIID &iid)
+{
+ // Note that "instance" is the _policy_ instance!!
+ PR_AtomicIncrement(&cGateways);
+ m_pBaseObject = GetDefaultGateway(instance);
+ // m_pWeakRef is an nsCOMPtr and needs no init.
+
+ NS_ABORT_IF_FALSE(!(iid.Equals(NS_GET_IID(nsISupportsWeakReference)) || iid.Equals(NS_GET_IID(nsIWeakReference))),"Should not be creating gateways with weak-ref interfaces");
+ m_iid = iid;
+ m_pPyObject = instance;
+ NS_PRECONDITION(instance, "NULL PyObject for PyXPCOM_XPTStub!");
+
+#ifdef NS_BUILD_REFCNT_LOGGING
+ // If XPCOM reference count logging is enabled, then allow us to give the Python class.
+ PyObject *realInstance = PyObject_GetAttrString(instance, "_obj_");
+ PyObject *r = PyObject_Repr(realInstance);
+ const char *szRepr;
+ if (r==NULL) {
+ PyXPCOM_LogError("Getting the __repr__ of the object failed");
+ PyErr_Clear();
+ szRepr = "(repr failed!)";
+ }
+ else
+#if PY_MAJOR_VERSION <= 2
+ szRepr = PyString_AsString(r);
+#else
+ szRepr = PyUnicode_AsUTF8(r);
+#endif
+ if (szRepr==NULL) szRepr = "";
+ int reprOffset = *szRepr=='<' ? 1 : 0;
+ static const char *reprPrefix = "component:";
+ if (strncmp(reprPrefix, szRepr+reprOffset, strlen(reprPrefix)) == 0)
+ reprOffset += strlen(reprPrefix);
+ strncpy(refcntLogRepr, szRepr + reprOffset, sizeof(refcntLogRepr)-1);
+ refcntLogRepr[sizeof(refcntLogRepr)-1] = '\0';
+ // See if we should get rid of the " at 0x12345" portion.
+ char *lastPos = strstr(refcntLogRepr, " at ");
+ if (lastPos) *lastPos = '\0';
+ Py_XDECREF(realInstance);
+ Py_XDECREF(r);
+#endif // NS_BUILD_REFCNT_LOGGING
+
+#ifdef DEBUG_LIFETIMES
+ {
+ char *iid_repr;
+ nsCOMPtr<nsIInterfaceInfoManager> iim = XPTI_GetInterfaceInfoManager();
+ if (iim!=nsnull)
+ iim->GetNameForIID(&iid, &iid_repr);
+ PyObject *real_instance = PyObject_GetAttrString(instance, "_obj_");
+ PyObject *real_repr = PyObject_Repr(real_instance);
+
+ PYXPCOM_LOG_DEBUG("PyG_Base created at %p\n instance_repr=%s\n IID=%s\n", this, PyString_AsString(real_repr), iid_repr);
+ nsMemory::Free(iid_repr);
+ Py_XDECREF(real_instance);
+ Py_XDECREF(real_repr);
+ }
+#endif // DEBUG_LIFETIMES
+ Py_XINCREF(instance); // instance should never be NULL - but whats an X between friends!
+
+ PyXPCOM_DLLAddRef();
+
+#ifdef DEBUG_FULL
+ LogF("PyGatewayBase: created %s", m_pPyObject ? PyXPCOM_ObTypeName(m_pPyObject) : "<NULL>");
+#endif
+}
+
+PyG_Base::~PyG_Base()
+{
+ PR_AtomicDecrement(&cGateways);
+#ifdef DEBUG_LIFETIMES
+ PYXPCOM_LOG_DEBUG("PyG_Base: deleted %p", this);
+#endif
+ if ( m_pPyObject ) {
+ CEnterLeavePython celp;
+ Py_DECREF(m_pPyObject);
+ }
+ if (m_pBaseObject)
+ m_pBaseObject->Release();
+ if (m_pWeakRef) {
+ // Need to ensure some other thread isnt doing a QueryReferent on
+ // our weak reference at the same time
+ CEnterLeaveXPCOMFramework _celf;
+ PyXPCOM_GatewayWeakReference *p = (PyXPCOM_GatewayWeakReference *)(nsISupports *)m_pWeakRef;
+ p->m_pBase = nsnull;
+ m_pWeakRef = nsnull;
+ }
+ PyXPCOM_DLLRelease();
+}
+
+// Get the correct interface pointer for this object given the IID.
+void *PyG_Base::ThisAsIID( const nsIID &iid )
+{
+ if (this==NULL) return NULL;
+ if (iid.Equals(NS_GET_IID(nsISupports)))
+ return (nsISupports *)(nsIInternalPython *)this;
+ if (iid.Equals(NS_GET_IID(nsISupportsWeakReference)))
+ return (nsISupportsWeakReference *)this;
+ if (iid.Equals(NS_GET_IID(nsIInternalPython)))
+ return (nsISupports *)(nsIInternalPython *)this;
+ return NULL;
+}
+
+// Call back into Python, passing a Python instance, and get back
+// an interface object that wraps the instance.
+/*static*/ PRBool
+PyG_Base::AutoWrapPythonInstance(PyObject *ob, const nsIID &iid, nsISupports **ppret)
+{
+ NS_PRECONDITION(ppret!=NULL, "null pointer when wrapping a Python instance!");
+ NS_PRECONDITION(ob && PyObject_HasAttrString(ob, "__class__"),
+ "AutoWrapPythonInstance is expecting an non-NULL instance!");
+ PRBool ok = PR_FALSE;
+ // XXX - todo - this static object leaks! (but Python on Windows leaks 2000+ objects as it is ;-)
+ static PyObject *func = NULL; // fetch this once and remember!
+ PyObject *obIID = NULL;
+ PyObject *wrap_ret = NULL;
+ PyObject *args = NULL;
+ if (func==NULL) { // not thread-safe, but nothing bad can happen, except an extra reference leak
+ PyObject *mod = PyImport_ImportModule("xpcom.server");
+ if (mod)
+ func = PyObject_GetAttrString(mod, "WrapObject");
+ Py_XDECREF(mod);
+ if (func==NULL) goto done;
+ }
+ // See if the instance has previously been wrapped.
+ if (CheckDefaultGateway(ob, iid, ppret)) {
+ ok = PR_TRUE; // life is good!
+ } else {
+ PyErr_Clear();
+
+ obIID = Py_nsIID::PyObjectFromIID(iid);
+ if (obIID==NULL) goto done;
+ args = Py_BuildValue("OOzi", ob, obIID, NULL, 0);
+ if (args==NULL) goto done;
+ wrap_ret = PyEval_CallObject(func, args);
+ if (wrap_ret==NULL) goto done;
+ ok = Py_nsISupports::InterfaceFromPyObject(wrap_ret, iid, ppret, PR_FALSE, PR_FALSE);
+#ifdef DEBUG
+ if (ok)
+ // Check we _now_ have a default gateway
+ {
+ nsISupports *temp = NULL;
+ NS_ABORT_IF_FALSE(CheckDefaultGateway(ob, iid, &temp), "Auto-wrapped object didnt get a default gateway!");
+ if (temp) temp->Release();
+ }
+#endif
+ }
+done:
+// Py_XDECREF(func); -- func is static for performance reasons.
+ Py_XDECREF(obIID);
+ Py_XDECREF(wrap_ret);
+ Py_XDECREF(args);
+ return ok;
+}
+
+// Call back into Python, passing a raw nsIInterface object, getting back
+// the object to actually use as the gateway parameter for this interface.
+// For example, it is expected that the policy will wrap the interface
+// object in one of the xpcom.client.Interface objects, allowing
+// natural usage of the interface from Python clients.
+// Note that piid will usually be NULL - this is because the runtime
+// reflection interfaces dont provide this information to me.
+// In this case, the Python code may choose to lookup the complete
+// interface info to obtain the IID.
+// It is expected (but should not be assumed) that the method info
+// or the IID will be NULL.
+// Worst case, the code should provide a wrapper for the nsiSupports interface,
+// so at least the user can simply QI the object.
+PyObject *
+PyG_Base::MakeInterfaceParam(nsISupports *pis,
+ const nsIID *piid,
+ int methodIndex /* = -1 */,
+ const XPTParamDescriptor *d /* = NULL */,
+ int paramIndex /* = -1 */)
+{
+ if (pis==NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ // This condition is true today, but not necessarily so.
+ // But if it ever triggers, the poor Python code has no real hope
+ // of returning something useful, so we should at least do our
+ // best to provide the useful data.
+ NS_WARN_IF_FALSE( ((piid != NULL) ^ (d != NULL)) == 1, "No information on the interface available - Python's gunna have a hard time doing much with it!");
+ PyObject *obIID = NULL;
+ PyObject *obISupports = NULL;
+ PyObject *obParamDesc = NULL;
+ PyObject *result = NULL;
+
+ // get the basic interface first, as if we fail, we can try and use this.
+ // If we don't know the IID, we must explicitly query for nsISupports.
+ nsCOMPtr<nsISupports> piswrap;
+ nsIID iid_check;
+ if (piid) {
+ iid_check = *piid;
+ piswrap = pis;
+ } else {
+ /* HACK ALERT! Dropping the python interpreter lock here while
+ doing QueryInterface because it may involve IPC to a python
+ object in the same interpreter and deadlock. Not at all
+ sure if this is a good idea or not for the internal PyXPCOM
+ state, but it might fix the deadloock... Hoping for the best. */
+ Py_BEGIN_ALLOW_THREADS;
+ iid_check = NS_GET_IID(nsISupports);
+ pis->QueryInterface(iid_check, getter_AddRefs(piswrap));
+ Py_END_ALLOW_THREADS;
+ }
+
+ obISupports = Py_nsISupports::PyObjectFromInterface(piswrap, iid_check, PR_FALSE);
+ if (!obISupports)
+ goto done;
+ if (piid==NULL) {
+ obIID = Py_None;
+ Py_INCREF(Py_None);
+ } else
+ obIID = Py_nsIID::PyObjectFromIID(*piid);
+ if (obIID==NULL)
+ goto done;
+ obParamDesc = PyObject_FromXPTParamDescriptor(d);
+ if (obParamDesc==NULL)
+ goto done;
+
+ result = PyObject_CallMethod(m_pPyObject,
+ (char*)"_MakeInterfaceParam_",
+ (char*)"OOiOi",
+ obISupports,
+ obIID,
+ methodIndex,
+ obParamDesc,
+ paramIndex);
+done:
+ if (PyErr_Occurred()) {
+ NS_WARN_IF_FALSE(result==NULL, "Have an error, but also a result!");
+ PyXPCOM_LogError("Wrapping an interface object for the gateway failed\n");
+ }
+ Py_XDECREF(obIID);
+ Py_XDECREF(obParamDesc);
+ if (result==NULL) { // we had an error.
+ PyErr_Clear(); // but are not reporting it back to Python itself!
+ // return our obISupports. If NULL, we are really hosed and nothing we can do.
+ return obISupports;
+ }
+ // Dont need to return this - we have a better result.
+ Py_XDECREF(obISupports);
+ return result;
+}
+
+NS_IMETHODIMP
+PyG_Base::QueryInterface(REFNSIID iid, void** ppv)
+{
+#ifdef PYXPCOM_DEBUG_FULL
+ {
+ char *sziid = iid.ToString();
+ LogF("PyGatewayBase::QueryInterface: %s", sziid);
+ Allocator::Free(sziid);
+ }
+#endif
+ NS_PRECONDITION(ppv, "NULL pointer");
+ if (ppv==nsnull)
+ return NS_ERROR_NULL_POINTER;
+ *ppv = nsnull;
+ // If one of our native interfaces (but NOT nsISupports if we have a base)
+ // return this.
+ // It is important is that nsISupports come from the base object
+ // to ensure that we live by XPCOM identity rules (other interfaces need
+ // not abide by this rule - only nsISupports.)
+ if ( (m_pBaseObject==NULL || !iid.Equals(NS_GET_IID(nsISupports)))
+ && (*ppv=ThisAsIID(iid)) != NULL ) {
+ AddRef();
+ return NS_OK;
+ }
+ // If we have a "base object", then we need to delegate _every_ remaining
+ // QI to it.
+ if (m_pBaseObject != NULL)
+ return m_pBaseObject->QueryInterface(iid, ppv);
+
+ // Call the Python policy to see if it (says it) supports the interface
+ PRBool supports = PR_FALSE;
+ { // temp scope for Python lock
+ CEnterLeavePython celp;
+
+ PyObject * ob = Py_nsIID::PyObjectFromIID(iid);
+ // must say this is an 'internal' call, else we recurse QI into
+ // oblivion.
+ PyObject * this_interface_ob = Py_nsISupports::PyObjectFromInterface(
+ (nsXPTCStubBase *)this,
+ iid, PR_FALSE, PR_TRUE);
+ if ( !ob || !this_interface_ob) {
+ Py_XDECREF(ob);
+ Py_XDECREF(this_interface_ob);
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ PyObject *result = PyObject_CallMethod(m_pPyObject, (char*)"_QueryInterface_",
+ (char*)"OO",
+ this_interface_ob, ob);
+ Py_DECREF(ob);
+ Py_DECREF(this_interface_ob);
+
+ if ( result ) {
+ if (Py_nsISupports::InterfaceFromPyObject(result, iid, (nsISupports **)ppv, PR_TRUE)) {
+ // If OK, but NULL, _QI_ returned None, which simply means
+ // "no such interface"
+ supports = (*ppv!=NULL);
+ // result has been QI'd and AddRef'd all ready for return.
+ } else {
+ // Dump this message and any Python exception before
+ // reporting the fact that QI failed - this error
+ // may provide clues!
+ PyXPCOM_LogError("The _QueryInterface_ method returned an object of type '%s', but an interface was expected\n", PyXPCOM_ObTypeName(result));
+ // supports remains false
+ }
+ Py_DECREF(result);
+ } else {
+ NS_ABORT_IF_FALSE(PyErr_Occurred(), "Got NULL result, but no Python error flagged!");
+ NS_WARN_IF_FALSE(!supports, "Have failure with success flag set!");
+ PyXPCOM_LogError("The _QueryInterface_ processing failed.\n");
+ // supports remains false.
+ // We have reported the error, and are returning to COM,
+ // so we should clear it.
+ PyErr_Clear();
+ }
+ } // end of temp scope for Python lock - lock released here!
+ if ( !supports )
+ return NS_ERROR_NO_INTERFACE;
+ return NS_OK;
+}
+
+nsrefcnt
+PyG_Base::AddRef(void)
+{
+ nsrefcnt cnt = (nsrefcnt) PR_AtomicIncrement((PRInt32*)&mRefCnt);
+#ifdef NS_BUILD_REFCNT_LOGGING
+ // If we have no pBaseObject, then we need to ignore them
+ if (m_pBaseObject == NULL)
+ NS_LOG_ADDREF(this, cnt, refcntLogRepr, sizeof(*this));
+#endif
+ return cnt;
+}
+
+nsrefcnt
+PyG_Base::Release(void)
+{
+ nsrefcnt cnt = (nsrefcnt) PR_AtomicDecrement((PRInt32*)&mRefCnt);
+#ifdef NS_BUILD_REFCNT_LOGGING
+ if (m_pBaseObject == NULL)
+ NS_LOG_RELEASE(this, cnt, refcntLogRepr);
+#endif
+ if ( cnt == 0 )
+ delete this;
+ return cnt;
+}
+
+NS_IMETHODIMP
+PyG_Base::GetWeakReference(nsIWeakReference **ret)
+{
+ // always delegate back to the "base" gateway for the object, as this tear-off
+ // interface may not live as long as the base. So we recurse back to the base.
+ if (m_pBaseObject) {
+ NS_PRECONDITION(m_pWeakRef == nsnull, "Not a base object, but do have a weak-ref!");
+ return m_pBaseObject->GetWeakReference(ret);
+ }
+ NS_PRECONDITION(ret, "null pointer");
+ if (ret==nsnull) return NS_ERROR_INVALID_POINTER;
+ if (!m_pWeakRef) {
+ // First query for a weak reference - create it.
+ // XXX - this looks like it needs thread safety!?
+ m_pWeakRef = new PyXPCOM_GatewayWeakReference(this);
+ NS_ABORT_IF_FALSE(m_pWeakRef, "Shouldn't be able to fail creating a weak reference!");
+ if (!m_pWeakRef)
+ return NS_ERROR_UNEXPECTED;
+ }
+ *ret = m_pWeakRef;
+ (*ret)->AddRef();
+ return NS_OK;
+}
+
+nsresult PyG_Base::HandleNativeGatewayError(const char *szMethodName)
+{
+ nsresult rc = NS_OK;
+ if (PyErr_Occurred()) {
+ // The error handling - fairly involved, but worth it as
+ // good error reporting is critical for users to know WTF
+ // is going on - especially with TypeErrors etc in their
+ // return values (ie, after the Python code has successfully
+ // exited, but we encountered errors unpacking their
+ // result values for the COM caller - there is literally no
+ // way to catch these exceptions from Python code, as their
+ // is no Python function directly on the call-stack)
+
+ // First line of attack in an error is to call-back on the policy.
+ // If the callback of the error handler succeeds and returns an
+ // integer (for the nsresult), we take no further action.
+
+ // If this callback fails, we log _2_ exceptions - the error
+ // handler error, and the original error.
+
+ PRBool bProcessMainError = PR_TRUE; // set to false if our exception handler does its thing!
+ PyObject *exc_typ, *exc_val, *exc_tb;
+ PyErr_Fetch(&exc_typ, &exc_val, &exc_tb);
+
+ PyObject *err_result = PyObject_CallMethod(m_pPyObject,
+ (char*)"_GatewayException_",
+ (char*)"z(OOO)",
+ szMethodName,
+ exc_typ ? exc_typ : Py_None, // should never be NULL, but defensive programming...
+ exc_val ? exc_val : Py_None, // may well be NULL.
+ exc_tb ? exc_tb : Py_None); // may well be NULL.
+ if (err_result == NULL) {
+ PyXPCOM_LogError("The exception handler _CallMethodException_ failed!\n");
+ } else if (err_result == Py_None) {
+ // The exception handler has chosen not to do anything with
+ // this error, so we still need to print it!
+ ;
+ } else if (PyInt_Check(err_result)) {
+ // The exception handler has given us the nresult.
+ rc = PyInt_AsLong(err_result);
+ bProcessMainError = PR_FALSE;
+ } else {
+ // The exception handler succeeded, but returned other than
+ // int or None.
+ PyXPCOM_LogError("The _CallMethodException_ handler returned object of type '%s' - None or an integer expected\n", PyXPCOM_ObTypeName(err_result));
+ }
+ Py_XDECREF(err_result);
+ PyErr_Restore(exc_typ, exc_val, exc_tb);
+ if (bProcessMainError) {
+ PyXPCOM_LogError("The function '%s' failed\n", szMethodName);
+ rc = PyXPCOM_SetCOMErrorFromPyException();
+ }
+ PyErr_Clear();
+ }
+ return rc;
+}
+
+static nsresult do_dispatch(
+ PyObject *pPyObject,
+ PyObject **ppResult,
+ const char *szMethodName,
+ const char *szFormat,
+ va_list va
+ )
+{
+ NS_PRECONDITION(ppResult, "Must provide a result buffer");
+ *ppResult = nsnull;
+ // Build the Invoke arguments...
+ PyObject *args = NULL;
+ PyObject *method = NULL;
+ PyObject *real_ob = NULL;
+ nsresult ret = NS_ERROR_FAILURE;
+ if ( szFormat )
+ args = Py_VaBuildValue((char *)szFormat, va);
+ else
+ args = PyTuple_New(0);
+ if ( !args )
+ goto done;
+
+ // make sure a tuple.
+ if ( !PyTuple_Check(args) ) {
+ PyObject *a = PyTuple_New(1);
+ if ( a == NULL )
+ {
+ Py_DECREF(args);
+ goto done;
+ }
+ PyTuple_SET_ITEM(a, 0, args);
+ args = a;
+ }
+ // Bit to a hack here to maintain the use of a policy.
+ // We actually get the policies underlying object
+ // to make the call on.
+ real_ob = PyObject_GetAttrString(pPyObject, "_obj_");
+ if (real_ob == NULL) {
+ PyErr_Format(PyExc_AttributeError, "The policy object does not have an '_obj_' attribute.");
+ goto done;
+ }
+ method = PyObject_GetAttrString(real_ob, (char *)szMethodName);
+ if ( !method ) {
+ PyErr_Clear();
+ ret = NS_PYXPCOM_NO_SUCH_METHOD;
+ goto done;
+ }
+ // Make the call
+ *ppResult = PyEval_CallObject(method, args);
+ ret = *ppResult ? NS_OK : NS_ERROR_FAILURE;
+done:
+ Py_XDECREF(method);
+ Py_XDECREF(real_ob);
+ Py_XDECREF(args);
+ return ret;
+}
+
+
+nsresult PyG_Base::InvokeNativeViaPolicyInternal(
+ const char *szMethodName,
+ PyObject **ppResult,
+ const char *szFormat,
+ va_list va
+ )
+{
+ if ( m_pPyObject == NULL || szMethodName == NULL )
+ return NS_ERROR_NULL_POINTER;
+
+ PyObject *temp = nsnull;
+ if (ppResult == nsnull)
+ ppResult = &temp;
+ nsresult nr = do_dispatch(m_pPyObject, ppResult, szMethodName, szFormat, va);
+
+ // If temp is NULL, they provided a buffer, and we dont touch it.
+ // If not NULL, *ppResult = temp, and _we_ do own it.
+ Py_XDECREF(temp);
+ return nr;
+}
+
+nsresult PyG_Base::InvokeNativeViaPolicy(
+ const char *szMethodName,
+ PyObject **ppResult /* = NULL */,
+ const char *szFormat /* = NULL */,
+ ...
+ )
+{
+ va_list va;
+ va_start(va, szFormat);
+ nsresult nr = InvokeNativeViaPolicyInternal(szMethodName, ppResult, szFormat, va);
+ va_end(va);
+
+ if (nr == NS_PYXPCOM_NO_SUCH_METHOD) {
+ // Only problem was missing method.
+ PyErr_Format(PyExc_AttributeError, "The object does not have a '%s' function.", szMethodName);
+ }
+ return nr == NS_OK ? NS_OK : HandleNativeGatewayError(szMethodName);
+}
+
+nsresult PyG_Base::InvokeNativeGetViaPolicy(
+ const char *szPropertyName,
+ PyObject **ppResult /* = NULL */
+ )
+{
+ PyObject *ob_ret = NULL;
+ nsresult ret = NS_OK;
+ PyObject *real_ob = NULL;
+ if ( m_pPyObject == NULL || szPropertyName == NULL )
+ return NS_ERROR_NULL_POINTER;
+ // First see if we have a method of that name.
+ char buf[256];
+ strcpy(buf, "get_");
+ strncat(buf, szPropertyName, sizeof(buf)*sizeof(buf[0])-strlen(buf)-1);
+ buf[sizeof(buf)/sizeof(buf[0])-1] = '\0';
+ ret = InvokeNativeViaPolicyInternal(buf, ppResult, nsnull, nsnull);
+ if (ret == NS_PYXPCOM_NO_SUCH_METHOD) {
+ // No method of that name - just try a property.
+ // Bit to a hack here to maintain the use of a policy.
+ // We actually get the policies underlying object
+ // to make the call on.
+ real_ob = PyObject_GetAttrString(m_pPyObject, "_obj_");
+ if (real_ob == NULL) {
+ PyErr_Format(PyExc_AttributeError, "The policy object does not have an '_obj_' attribute.");
+ ret = HandleNativeGatewayError(szPropertyName);
+ goto done;
+ }
+ ob_ret = PyObject_GetAttrString(real_ob, (char *)szPropertyName);
+ if (ob_ret==NULL) {
+ PyErr_Format(PyExc_AttributeError,
+ "The object does not have a 'get_%s' function, or a '%s attribute.",
+ szPropertyName, szPropertyName);
+ } else {
+ ret = NS_OK;
+ if (ppResult)
+ *ppResult = ob_ret;
+ else
+ Py_XDECREF(ob_ret);
+ }
+ }
+ if (ret != NS_OK)
+ ret = HandleNativeGatewayError(szPropertyName);
+
+done:
+ Py_XDECREF(real_ob);
+ return ret;
+}
+
+nsresult PyG_Base::InvokeNativeSetViaPolicy(
+ const char *szPropertyName,
+ ...
+ )
+{
+ if ( m_pPyObject == NULL || szPropertyName == NULL )
+ return NS_ERROR_NULL_POINTER;
+ nsresult ret = NS_OK;
+ PyObject *real_ob = NULL;
+ char buf[256];
+ strcpy(buf, "set_");
+ strncat(buf, szPropertyName, sizeof(buf)*sizeof(buf[0])-strlen(buf)-1);
+ buf[sizeof(buf)/sizeof(buf[0])-1] = '\0';
+ va_list va;
+ va_start(va, szPropertyName);
+ ret = InvokeNativeViaPolicyInternal(buf, NULL, "O", va);
+ va_end(va);
+ if (ret == NS_PYXPCOM_NO_SUCH_METHOD) {
+ // No method of that name - just try a property.
+ // Bit to a hack here to maintain the use of a policy.
+ // We actually get the policies underlying object
+ // to make the call on.
+ real_ob = PyObject_GetAttrString(m_pPyObject, "_obj_");
+ if (real_ob == NULL) {
+ PyErr_Format(PyExc_AttributeError, "The policy object does not have an '_obj_' attribute.");
+ ret = HandleNativeGatewayError(szPropertyName);
+ goto done;
+ }
+ va_list va2;
+ va_start(va2, szPropertyName);
+ PyObject *arg = va_arg( va2, PyObject *);
+ va_end(va2);
+ if (PyObject_SetAttrString(real_ob, (char *)szPropertyName, arg) == 0)
+ ret = NS_OK;
+ else {
+ PyErr_Format(PyExc_AttributeError,
+ "The object does not have a 'set_%s' function, or a '%s attribute.",
+ szPropertyName, szPropertyName);
+ }
+ }
+ if (ret != NS_OK)
+ ret = HandleNativeGatewayError(szPropertyName);
+done:
+ Py_XDECREF(real_ob);
+ return ret;
+}
+
+// Get at the underlying Python object.
+PyObject *PyG_Base::UnwrapPythonObject(void)
+{
+ Py_INCREF(m_pPyObject);
+ return m_pPyObject;
+}
+/******************************************************
+
+ Some special support to help with object identity.
+
+ In the simplest case, assume a Python XPCOM object is
+ supporting a function "nsIWhatever GetWhatever()",
+ so implements it as:
+ return self
+ it is almost certain they intend returning
+ the same COM OBJECT to the caller! Thus, if a user of this COM
+ object does:
+
+ p1 = foo.GetWhatever();
+ p2 = foo.GetWhatever();
+
+ We almost certainly expect p1==p2==foo.
+
+ We previously _did_ have special support for the "self"
+ example above, but this implements a generic scheme that
+ works for _all_ objects.
+
+ Whenever we are asked to "AutoWrap" a Python object, the
+ first thing we do is see if it has been auto-wrapped before.
+
+ If not, we create a new wrapper, then make a COM weak reference
+ to that wrapper, and store it directly back into the instance
+ we are auto-wrapping! The use of a weak-reference prevents
+ cycles.
+
+ The existance of this attribute in an instance indicates if it
+ has been previously auto-wrapped.
+
+ If it _has_ previously been auto-wrapped, we de-reference the
+ weak reference, and use that gateway.
+
+*********************************************************************/
+
+PyG_Base *GetDefaultGateway(PyObject *policy)
+{
+ // NOTE: Instance is the policy, not the real instance
+ PyObject *instance = PyObject_GetAttrString(policy, "_obj_");
+ if (instance == nsnull)
+ return nsnull;
+ PyObject *ob_existing_weak = PyObject_GetAttrString(instance, PyXPCOM_szDefaultGatewayAttributeName);
+ Py_DECREF(instance);
+ if (ob_existing_weak != NULL) {
+ PRBool ok = PR_TRUE;
+ nsCOMPtr<nsIWeakReference> pWeakRef;
+ ok = NS_SUCCEEDED(Py_nsISupports::InterfaceFromPyObject(ob_existing_weak,
+ NS_GET_IID(nsIWeakReference),
+ getter_AddRefs(pWeakRef),
+ PR_FALSE));
+ Py_DECREF(ob_existing_weak);
+ nsISupports *pip;
+ if (ok) {
+ nsresult nr = pWeakRef->QueryReferent( NS_GET_IID(nsIInternalPython), (void **)&pip);
+ if (NS_FAILED(nr))
+ return nsnull;
+ return (PyG_Base *)(nsIInternalPython *)pip;
+ }
+ } else
+ PyErr_Clear();
+ return nsnull;
+}
+
+PRBool CheckDefaultGateway(PyObject *real_inst, REFNSIID iid, nsISupports **ret_gateway)
+{
+ NS_ABORT_IF_FALSE(real_inst, "Did not have an _obj_ attribute");
+ if (real_inst==NULL) {
+ PyErr_Clear();
+ return PR_FALSE;
+ }
+ PyObject *ob_existing_weak = PyObject_GetAttrString(real_inst, PyXPCOM_szDefaultGatewayAttributeName);
+ if (ob_existing_weak != NULL) {
+ // We have an existing default, but as it is a weak reference, it
+ // may no longer be valid. Check it.
+ PRBool ok = PR_TRUE;
+ nsCOMPtr<nsIWeakReference> pWeakRef;
+ ok = NS_SUCCEEDED(Py_nsISupports::InterfaceFromPyObject(ob_existing_weak,
+ NS_GET_IID(nsIWeakReference),
+ getter_AddRefs(pWeakRef),
+ PR_FALSE));
+ Py_DECREF(ob_existing_weak);
+ if (ok) {
+ Py_BEGIN_ALLOW_THREADS;
+ ok = NS_SUCCEEDED(pWeakRef->QueryReferent( iid, (void **)(ret_gateway)));
+ Py_END_ALLOW_THREADS;
+ }
+ if (!ok) {
+ // We have the attribute, but not valid - wipe it
+ // before restoring it.
+ if (0 != PyObject_DelAttrString(real_inst, PyXPCOM_szDefaultGatewayAttributeName))
+ PyErr_Clear();
+ }
+ return ok;
+ }
+ PyErr_Clear();
+ return PR_FALSE;
+}
+
+void AddDefaultGateway(PyObject *instance, nsISupports *gateway)
+{
+ // NOTE: Instance is the _policy_!
+ PyObject *real_inst = PyObject_GetAttrString(instance, "_obj_");
+ NS_ABORT_IF_FALSE(real_inst, "Could not get the '_obj_' element");
+ if (!real_inst) return;
+ if (!PyObject_HasAttrString(real_inst, PyXPCOM_szDefaultGatewayAttributeName)) {
+ nsCOMPtr<nsISupportsWeakReference> swr( do_QueryInterface((nsISupportsWeakReference *)(gateway)) );
+ NS_ABORT_IF_FALSE(swr, "Our gateway failed with a weak reference query");
+ // Create the new default gateway - get a weak reference for our gateway.
+ if (swr) {
+ nsCOMPtr<nsIWeakReference> pWeakReference;
+ swr->GetWeakReference( getter_AddRefs(pWeakReference) );
+ if (pWeakReference) {
+ PyObject *ob_new_weak = Py_nsISupports::PyObjectFromInterface(pWeakReference,
+ NS_GET_IID(nsIWeakReference),
+ PR_FALSE ); /* bMakeNicePyObject */
+ // pWeakReference reference consumed.
+ if (ob_new_weak) {
+ PyObject_SetAttrString(real_inst, PyXPCOM_szDefaultGatewayAttributeName, ob_new_weak);
+ Py_DECREF(ob_new_weak);
+ }
+ }
+ }
+ }
+ Py_DECREF(real_inst);
+}
diff --git a/src/libs/xpcom18a4/python/src/PyGInputStream.cpp b/src/libs/xpcom18a4/python/src/PyGInputStream.cpp
new file mode 100644
index 00000000..d7c27043
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyGInputStream.cpp
@@ -0,0 +1,173 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <MarkH@ActiveState.com> (original author)
+ *
+ * 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 ***** */
+
+// PyGInputStream.cpp
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written October 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+#include <nsIInputStream.h>
+
+class PyG_nsIInputStream : public PyG_Base, public nsIInputStream
+{
+public:
+ PyG_nsIInputStream(PyObject *instance) : PyG_Base(instance, NS_GET_IID(nsIInputStream)) {;}
+ PYGATEWAY_BASE_SUPPORT(nsIInputStream, PyG_Base);
+
+ NS_IMETHOD Close(void);
+ NS_IMETHOD Available(PRUint32 *_retval);
+ NS_IMETHOD Read(char * buf, PRUint32 count, PRUint32 *_retval);
+ NS_IMETHOD ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval);
+ NS_IMETHOD IsNonBlocking(PRBool *aNonBlocking);
+};
+
+
+PyG_Base *MakePyG_nsIInputStream(PyObject *instance)
+{
+ return new PyG_nsIInputStream(instance);
+}
+
+NS_IMETHODIMP
+PyG_nsIInputStream::Close()
+{
+ CEnterLeavePython _celp;
+ const char *methodName = "close";
+ return InvokeNativeViaPolicy(methodName, NULL);
+}
+
+NS_IMETHODIMP
+PyG_nsIInputStream::Available(PRUint32 *_retval)
+{
+ NS_PRECONDITION(_retval, "null pointer");
+ CEnterLeavePython _celp;
+ PyObject *ret;
+ const char *methodName = "available";
+ nsresult nr = InvokeNativeViaPolicy(methodName, &ret);
+ if (NS_SUCCEEDED(nr)) {
+ *_retval = PyInt_AsLong(ret);
+ if (PyErr_Occurred())
+ nr = HandleNativeGatewayError(methodName);
+ Py_XDECREF(ret);
+ }
+ return nr;
+}
+
+NS_IMETHODIMP
+PyG_nsIInputStream::Read(char * buf, PRUint32 count, PRUint32 *_retval)
+{
+ NS_PRECONDITION(_retval, "null pointer");
+ NS_PRECONDITION(buf, "null pointer");
+ CEnterLeavePython _celp;
+ PyObject *ret;
+ const char *methodName = "read";
+ nsresult nr = InvokeNativeViaPolicy(methodName, &ret, "i", count);
+ if (NS_SUCCEEDED(nr)) {
+#if 0 /* VBox: new buffer protocol (though I could use it for Py_LIMITED_API and ditch the warning, but cpython specific) */
+ Py_buffer py_view;
+ if (PyObject_GetBuffer(ret, &py_view, PyBUF_SIMPLE) == 0) {
+ if (py_view.len <= count) {
+ count = py_view.len;
+ } else {
+ PyXPCOM_LogWarning("nsIInputStream::read() was asked for %d bytes, but the string returned is %d bytes - truncating!\n", count, py_size);
+ }
+ memcpy(buf, py_view.py_buf, count);
+ PyBuffer_Release(&py_view);
+ *_retval = count;
+ } else {
+ PyErr_Format(PyExc_TypeError, "nsIInputStream::read() method must return a buffer object - not a '%s' object", PyXPCOM_ObTypeName(ret));
+ nr = HandleNativeGatewayError(methodName);
+ }
+#else /* Old protocol: */
+# ifndef VBOX /* unsafe cast on 64-bit hosts. */
+ PRUint32 py_size;
+ const void *py_buf;
+ if (PyObject_AsReadBuffer(ret, &py_buf, (Py_ssize_t*)&py_size)!=0) {
+# else /* VBOX */
+ const void *py_buf;
+# if PY_VERSION_HEX >= 0x02050000 || defined(PY_SSIZE_T_MIN)
+ Py_ssize_t py_size;
+# else
+ int py_size;
+# endif
+ if (PyObject_AsReadBuffer(ret, &py_buf, &py_size)!=0) {
+# endif /* VBOX */
+ PyErr_Format(PyExc_TypeError, "nsIInputStream::read() method must return a buffer object - not a '%s' object", PyXPCOM_ObTypeName(ret));
+ nr = HandleNativeGatewayError(methodName);
+ } else {
+ if (py_size > count) {
+ PyXPCOM_LogWarning("nsIInputStream::read() was asked for %d bytes, but the string returned is %d bytes - truncating!\n", count, py_size);
+ py_size = count;
+ }
+ memcpy(buf, py_buf, py_size);
+ *_retval = py_size;
+ }
+#endif
+ }
+ return nr;
+}
+
+
+NS_IMETHODIMP
+PyG_nsIInputStream::ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval)
+{
+ NS_WARNING("ReadSegments() not implemented!!!");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+PyG_nsIInputStream::IsNonBlocking(PRBool *aNonBlocking)
+{
+ NS_PRECONDITION(aNonBlocking, "null pointer");
+ CEnterLeavePython _celp;
+ PyObject *ret;
+ const char *methodName = "isNonBlocking";
+ nsresult nr = InvokeNativeViaPolicy(methodName, &ret);
+ if (NS_SUCCEEDED(nr)) {
+ *aNonBlocking = PyInt_AsLong(ret);
+ if (PyErr_Occurred())
+ nr = HandleNativeGatewayError(methodName);
+ Py_XDECREF(ret);
+ }
+ return nr;
+}
diff --git a/src/libs/xpcom18a4/python/src/PyGModule.cpp b/src/libs/xpcom18a4/python/src/PyGModule.cpp
new file mode 100644
index 00000000..599e0f87
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyGModule.cpp
@@ -0,0 +1,297 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+// Unfortunately, we can not use an XPConnect object for
+// the nsiModule and nsiComponentLoader interfaces.
+// As XPCOM shuts down, it shuts down the interface manager before
+// it releases all the modules. This is a bit of a problem for
+// us, as it means we can't get runtime info on the interface at shutdown time.
+
+#include "PyXPCOM_std.h"
+#include <nsIModule.h>
+#include <nsIComponentLoader.h>
+
+class PyG_nsIModule : public PyG_Base, public nsIModule
+{
+public:
+ PyG_nsIModule(PyObject *instance) : PyG_Base(instance, NS_GET_IID(nsIModule)) {;}
+ PYGATEWAY_BASE_SUPPORT(nsIModule, PyG_Base);
+
+ NS_DECL_NSIMODULE
+};
+
+PyG_Base *MakePyG_nsIModule(PyObject *instance)
+{
+ return new PyG_nsIModule(instance);
+}
+
+
+// Create a factory object for creating instances of aClass.
+NS_IMETHODIMP
+PyG_nsIModule::GetClassObject(nsIComponentManager *aCompMgr,
+ const nsCID& aClass,
+ const nsIID& aIID,
+ void** r_classObj)
+{
+ NS_PRECONDITION(r_classObj, "null pointer");
+ *r_classObj = nsnull;
+ CEnterLeavePython _celp;
+ PyObject *cm = PyObject_FromNSInterface(aCompMgr, NS_GET_IID(nsIComponentManager));
+ PyObject *iid = Py_nsIID::PyObjectFromIID(aIID);
+ PyObject *clsid = Py_nsIID::PyObjectFromIID(aClass);
+ const char *methodName = "getClassObject";
+ PyObject *ret = NULL;
+ nsresult nr = InvokeNativeViaPolicy(methodName, &ret, "OOO", cm, clsid, iid);
+ Py_XDECREF(cm);
+ Py_XDECREF(iid);
+ Py_XDECREF(clsid);
+ if (NS_SUCCEEDED(nr)) {
+ nr = Py_nsISupports::InterfaceFromPyObject(ret, aIID, (nsISupports **)r_classObj, PR_FALSE);
+ if (PyErr_Occurred())
+ nr = HandleNativeGatewayError(methodName);
+ }
+ if (NS_FAILED(nr)) {
+ NS_ABORT_IF_FALSE(*r_classObj==NULL, "returning error result with an interface - probable leak!");
+ }
+ Py_XDECREF(ret);
+ return nr;
+}
+
+NS_IMETHODIMP
+PyG_nsIModule::RegisterSelf(nsIComponentManager *aCompMgr,
+ nsIFile* aPath,
+ const char* registryLocation,
+ const char* componentType)
+{
+ NS_PRECONDITION(aCompMgr, "null pointer");
+ NS_PRECONDITION(aPath, "null pointer");
+ CEnterLeavePython _celp;
+ PyObject *cm = PyObject_FromNSInterface(aCompMgr, NS_GET_IID(nsIComponentManager));
+ PyObject *path = PyObject_FromNSInterface(aPath, NS_GET_IID(nsIFile));
+ const char *methodName = "registerSelf";
+ nsresult nr = InvokeNativeViaPolicy(methodName, NULL, "OOzz", cm, path, registryLocation, componentType);
+ Py_XDECREF(cm);
+ Py_XDECREF(path);
+ return nr;
+}
+
+NS_IMETHODIMP
+PyG_nsIModule::UnregisterSelf(nsIComponentManager* aCompMgr,
+ nsIFile* aPath,
+ const char* registryLocation)
+{
+ NS_PRECONDITION(aCompMgr, "null pointer");
+ NS_PRECONDITION(aPath, "null pointer");
+ CEnterLeavePython _celp;
+ PyObject *cm = PyObject_FromNSInterface(aCompMgr, NS_GET_IID(nsIComponentManager));
+ PyObject *path = PyObject_FromNSInterface(aPath, NS_GET_IID(nsIFile));
+ const char *methodName = "unregisterSelf";
+ nsresult nr = InvokeNativeViaPolicy(methodName, NULL, "OOz", cm, path, registryLocation);
+ Py_XDECREF(cm);
+ Py_XDECREF(path);
+ return nr;
+}
+
+NS_IMETHODIMP
+PyG_nsIModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload)
+{
+ NS_PRECONDITION(aCompMgr, "null pointer");
+ NS_PRECONDITION(okToUnload, "null pointer");
+ CEnterLeavePython _celp;
+ // we are shutting down - don't ask for a nice wrapped object.
+ PyObject *cm = PyObject_FromNSInterface(aCompMgr, NS_GET_IID(nsIComponentManager), PR_FALSE);
+ const char *methodName = "canUnload";
+ PyObject *ret = NULL;
+ nsresult nr = InvokeNativeViaPolicy(methodName, &ret, "O", cm);
+ Py_XDECREF(cm);
+ if (NS_SUCCEEDED(nr)) {
+ *okToUnload = PyInt_AsLong(ret);
+ if (PyErr_Occurred())
+ nr = HandleNativeGatewayError(methodName);
+ }
+ Py_XDECREF(ret);
+ return nr;
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+
+class PyG_nsIComponentLoader : public PyG_Base, public nsIComponentLoader
+{
+public:
+ PyG_nsIComponentLoader(PyObject *instance) : PyG_Base(instance, NS_GET_IID(nsIComponentLoader)) {;}
+ PYGATEWAY_BASE_SUPPORT(nsIComponentLoader, PyG_Base);
+
+ NS_DECL_NSICOMPONENTLOADER
+};
+
+PyG_Base *MakePyG_nsIComponentLoader(PyObject *instance)
+{
+ return new PyG_nsIComponentLoader(instance);
+}
+
+/* nsIFactory getFactory (in nsIIDRef aCID, in string aLocation, in string aType); */
+NS_IMETHODIMP PyG_nsIComponentLoader::GetFactory(const nsIID & aCID, const char *aLocation, const char *aType, nsIFactory **_retval)
+{
+ CEnterLeavePython _celp;
+ const char *methodName = "getFactory";
+ PyObject *iid = Py_nsIID::PyObjectFromIID(aCID);
+ PyObject *ret = NULL;
+ nsresult nr = InvokeNativeViaPolicy(methodName, &ret, "Ozz",
+ iid,
+ aLocation,
+ aType);
+ Py_XDECREF(iid);
+ if (NS_SUCCEEDED(nr)) {
+ Py_nsISupports::InterfaceFromPyObject(ret, NS_GET_IID(nsIFactory), (nsISupports **)_retval, PR_FALSE);
+ if (PyErr_Occurred())
+ nr = HandleNativeGatewayError(methodName);
+ }
+ Py_XDECREF(ret);
+ return nr;
+}
+
+/* void init (in nsIComponentManager aCompMgr, in nsISupports aRegistry); */
+NS_IMETHODIMP PyG_nsIComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aRegistry)
+{
+ CEnterLeavePython _celp;
+ const char *methodName = "init";
+ PyObject *c = PyObject_FromNSInterface(aCompMgr, NS_GET_IID(nsIComponentManager));
+ PyObject *r = PyObject_FromNSInterface(aRegistry, NS_GET_IID(nsISupports));
+ nsresult nr = InvokeNativeViaPolicy(methodName, NULL, "OO", c, r);
+ Py_XDECREF(c);
+ Py_XDECREF(r);
+ return nr;
+}
+
+/* void onRegister (in nsIIDRef aCID, in string aType, in string aClassName, in string aContractID, in string aLocation, in boolean aReplace, in boolean aPersist); */
+NS_IMETHODIMP PyG_nsIComponentLoader::OnRegister(const nsIID & aCID, const char *aType, const char *aClassName, const char *aContractID, const char *aLocation, PRBool aReplace, PRBool aPersist)
+{
+ CEnterLeavePython _celp;
+ const char *methodName = "onRegister";
+ PyObject *iid = Py_nsIID::PyObjectFromIID(aCID);
+ nsresult nr = InvokeNativeViaPolicy(methodName, NULL, "Ossssii",
+ iid,
+ aType,
+ aClassName,
+ aContractID,
+ aLocation,
+ aReplace,
+ aPersist);
+ Py_XDECREF(iid);
+ return nr;
+}
+
+/* void autoRegisterComponents (in long aWhen, in nsIFile aDirectory); */
+NS_IMETHODIMP PyG_nsIComponentLoader::AutoRegisterComponents(PRInt32 aWhen, nsIFile *aDirectory)
+{
+ CEnterLeavePython _celp;
+ const char *methodName = "autoRegisterComponents";
+ PyObject *c = PyObject_FromNSInterface(aDirectory, NS_GET_IID(nsIFile));
+ nsresult nr = InvokeNativeViaPolicy(methodName, NULL, "iO", aWhen, c);
+ Py_XDECREF(c);
+ return nr;
+}
+
+/* boolean autoRegisterComponent (in long aWhen, in nsIFile aComponent); */
+NS_IMETHODIMP PyG_nsIComponentLoader::AutoRegisterComponent(PRInt32 aWhen, nsIFile *aComponent, PRBool *_retval)
+{
+ CEnterLeavePython _celp;
+ const char *methodName = "autoRegisterComponent";
+ PyObject *ret = NULL;
+ PyObject *c = PyObject_FromNSInterface(aComponent, NS_GET_IID(nsIFile));
+ nsresult nr = InvokeNativeViaPolicy(methodName, &ret, "iO", aWhen, c);
+ Py_XDECREF(c);
+ if (NS_SUCCEEDED(nr)) {
+ *_retval = PyInt_AsLong(ret);
+ if (PyErr_Occurred())
+ nr = HandleNativeGatewayError(methodName);
+ }
+ Py_XDECREF(ret);
+ return nr;
+}
+
+/* boolean autoUnregisterComponent (in long aWhen, in nsIFile aComponent); */
+NS_IMETHODIMP PyG_nsIComponentLoader::AutoUnregisterComponent(PRInt32 aWhen, nsIFile *aComponent, PRBool *_retval)
+{
+ CEnterLeavePython _celp;
+ const char *methodName = "autoUnregisterComponent";
+ PyObject *ret = NULL;
+ PyObject *c = PyObject_FromNSInterface(aComponent, NS_GET_IID(nsIFile));
+ nsresult nr = InvokeNativeViaPolicy(methodName, &ret, "iO", aWhen, c);
+ Py_XDECREF(c);
+ if (NS_SUCCEEDED(nr)) {
+ *_retval = PyInt_AsLong(ret);
+ if (PyErr_Occurred())
+ nr = HandleNativeGatewayError(methodName);
+ }
+ Py_XDECREF(ret);
+ return nr;
+}
+
+/* boolean registerDeferredComponents (in long aWhen); */
+NS_IMETHODIMP PyG_nsIComponentLoader::RegisterDeferredComponents(PRInt32 aWhen, PRBool *_retval)
+{
+ CEnterLeavePython _celp;
+ const char *methodName = "registerDeferredComponents";
+ PyObject *ret = NULL;
+ nsresult nr = InvokeNativeViaPolicy(methodName, &ret, "i", aWhen);
+ if (NS_SUCCEEDED(nr)) {
+ *_retval = PyInt_AsLong(ret);
+ if (PyErr_Occurred())
+ nr = HandleNativeGatewayError(methodName);
+ }
+ Py_XDECREF(ret);
+ return nr;
+}
+
+/* void unloadAll (in long aWhen); */
+NS_IMETHODIMP PyG_nsIComponentLoader::UnloadAll(PRInt32 aWhen)
+{
+ CEnterLeavePython _celp;
+ const char *methodName = "unloadAll";
+ return InvokeNativeViaPolicy(methodName, NULL, "i", aWhen);
+}
diff --git a/src/libs/xpcom18a4/python/src/PyGStub.cpp b/src/libs/xpcom18a4/python/src/PyGStub.cpp
new file mode 100644
index 00000000..6f219333
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyGStub.cpp
@@ -0,0 +1,180 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+// PyXPTStub - the stub for implementing interfaces.
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+#include <nsIInterfaceInfoManager.h>
+
+void *PyXPCOM_XPTStub::ThisAsIID(const nsIID &iid)
+{
+ if (iid.Equals(NS_GET_IID(nsISupports)))
+ return (nsISupports *)(nsXPTCStubBase *)this;
+ else if (iid.Equals(m_iid))
+ return (nsISupports *)(nsXPTCStubBase *)this;
+ else
+ return PyG_Base::ThisAsIID(iid);
+}
+
+
+NS_IMETHODIMP
+PyXPCOM_XPTStub::GetInterfaceInfo(nsIInterfaceInfo** info)
+{
+ NS_PRECONDITION(info, "NULL pointer");
+ if (info==nsnull)
+ return NS_ERROR_NULL_POINTER;
+ // Simply get the XPCOM runtime to provide this
+ // (but there must be some reason why they dont get it themselves!?
+ // Maybe because they dont know the IID?
+ nsCOMPtr<nsIInterfaceInfoManager> iim(do_GetService(
+ NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
+ NS_ABORT_IF_FALSE(iim != nsnull, "Cant get interface from IIM!");
+ if (iim==nsnull)
+ return NS_ERROR_FAILURE;
+
+ return iim->GetInfoForIID( &m_iid, info);
+}
+
+// call this method and return result
+NS_IMETHODIMP
+PyXPCOM_XPTStub::CallMethod(PRUint16 methodIndex,
+ const nsXPTMethodInfo* info,
+ nsXPTCMiniVariant* params)
+{
+ nsresult rc = NS_ERROR_FAILURE;
+ NS_PRECONDITION(info, "NULL methodinfo pointer");
+ NS_PRECONDITION(params, "NULL variant pointer");
+ CEnterLeavePython _celp;
+ PyObject *obParams = NULL;
+ PyObject *result = NULL;
+ PyObject *obThisObject = NULL;
+ PyObject *obMI = PyObject_FromXPTMethodDescriptor(info);
+ PyXPCOM_GatewayVariantHelper arg_helper(this, methodIndex, info, params);
+ if (obMI==NULL)
+ goto done;
+ // base object is passed raw.
+ obThisObject = PyObject_FromNSInterface((nsXPTCStubBase *)this,
+ m_iid, PR_FALSE);
+ obParams = arg_helper.MakePyArgs();
+ if (obParams==NULL)
+ goto done;
+ result = PyObject_CallMethod(m_pPyObject,
+ (char*)"_CallMethod_",
+ (char*)"OiOO",
+ obThisObject,
+ (int)methodIndex,
+ obMI,
+ obParams);
+ if (result!=NULL) {
+ rc = arg_helper.ProcessPythonResult(result);
+ // Use an xor to check failure && pyerr, or !failure && !pyerr.
+ NS_ABORT_IF_FALSE( ((NS_FAILED(rc)!=0)^(PyErr_Occurred()!=0)) == 0, "We must have failure with a Python error, or success without a Python error.");
+ }
+done:
+ if (PyErr_Occurred()) {
+ // The error handling - fairly involved, but worth it as
+ // good error reporting is critical for users to know WTF
+ // is going on - especially with TypeErrors etc in their
+ // return values (ie, after the Python code has successfully
+ // exited, but we encountered errors unpacking the
+ // result values for the COM caller - there is literally no
+ // way to catch these exceptions from Python code, as their
+ // is no Python function on the call-stack)
+
+ // First line of attack in an error is to call-back on the policy.
+ // If the callback of the error handler succeeds and returns an
+ // integer (for the nsresult), we take no further action.
+
+ // If this callback fails, we log _2_ exceptions - the error handler
+ // error, and the original error.
+
+ PRBool bProcessMainError = PR_TRUE; // set to false if our exception handler does its thing!
+ PyObject *exc_typ, *exc_val, *exc_tb;
+ PyErr_Fetch(&exc_typ, &exc_val, &exc_tb);
+ PyErr_NormalizeException( &exc_typ, &exc_val, &exc_tb);
+
+ PyObject *err_result = PyObject_CallMethod(m_pPyObject,
+ (char*)"_CallMethodException_",
+ (char*)"OiOO(OOO)",
+ obThisObject,
+ (int)methodIndex,
+ obMI,
+ obParams,
+ exc_typ ? exc_typ : Py_None, // should never be NULL, but defensive programming...
+ exc_val ? exc_val : Py_None, // may well be NULL.
+ exc_tb ? exc_tb : Py_None); // may well be NULL.
+ if (err_result == NULL) {
+ PyXPCOM_LogError("The exception handler _CallMethodException_ failed!\n");
+ } else if (err_result == Py_None) {
+ // The exception handler has chosen not to do anything with
+ // this error, so we still need to print it!
+ ;
+ } else if (PyInt_Check(err_result)) {
+ // The exception handler has given us the nresult.
+ rc = PyInt_AsLong(err_result);
+ bProcessMainError = PR_FALSE;
+ } else {
+ // The exception handler succeeded, but returned other than
+ // int or None.
+ PyXPCOM_LogError("The _CallMethodException_ handler returned object of type '%s' - None or an integer expected\n", PyXPCOM_ObTypeName(err_result));
+ }
+ Py_XDECREF(err_result);
+ PyErr_Restore(exc_typ, exc_val, exc_tb);
+ if (bProcessMainError) {
+ PyXPCOM_LogError("The function '%s' failed\n", info->GetName());
+ rc = PyXPCOM_SetCOMErrorFromPyException();
+ }
+ // else everything is already setup,
+ // just clear the Python error state.
+ PyErr_Clear();
+ }
+
+ Py_XDECREF(obMI);
+ Py_XDECREF(obParams);
+ Py_XDECREF(obThisObject);
+ Py_XDECREF(result);
+ return rc;
+}
diff --git a/src/libs/xpcom18a4/python/src/PyGWeakReference.cpp b/src/libs/xpcom18a4/python/src/PyGWeakReference.cpp
new file mode 100644
index 00000000..e5254acc
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyGWeakReference.cpp
@@ -0,0 +1,112 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <MarkH@ActiveState.com> (original author)
+ *
+ * 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 ***** */
+
+// PyGWeakReference - implements weak references for gateways.
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written November 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+
+PyXPCOM_GatewayWeakReference::PyXPCOM_GatewayWeakReference( PyG_Base *base )
+{
+ m_pBase = base;
+
+#ifdef NS_BUILD_REFCNT_LOGGING
+ // bloat view uses 40 chars - stick "(WR)" at the end of this position.
+ strncpy(refcntLogRepr, m_pBase->refcntLogRepr, sizeof(refcntLogRepr));
+ refcntLogRepr[sizeof(refcntLogRepr)-1] = '\0';
+ char *dest = refcntLogRepr + ((strlen(refcntLogRepr) > 36) ? 36 : strlen(refcntLogRepr));
+ strcpy(dest, "(WR)");
+#endif // NS_BUILD_REFCNT_LOGGING
+}
+
+PyXPCOM_GatewayWeakReference::~PyXPCOM_GatewayWeakReference()
+{
+ // Simply zap my reference to the gateway!
+ // No need to zap my gateway's reference to me, as
+ // it already holds a reference, so if we are destructing,
+ // then it can't possibly hold one.
+ m_pBase = NULL;
+}
+
+nsrefcnt
+PyXPCOM_GatewayWeakReference::AddRef(void)
+{
+ nsrefcnt cnt = (nsrefcnt) PR_AtomicIncrement((PRInt32*)&mRefCnt);
+#ifdef NS_BUILD_REFCNT_LOGGING
+ NS_LOG_ADDREF(this, cnt, refcntLogRepr, sizeof(*this));
+#endif
+ return cnt;
+}
+
+nsrefcnt
+PyXPCOM_GatewayWeakReference::Release(void)
+{
+ nsrefcnt cnt = (nsrefcnt) PR_AtomicDecrement((PRInt32*)&mRefCnt);
+#ifdef NS_BUILD_REFCNT_LOGGING
+ NS_LOG_RELEASE(this, cnt, refcntLogRepr);
+#endif
+ if ( cnt == 0 )
+ delete this;
+ return cnt;
+}
+
+NS_IMPL_THREADSAFE_QUERY_INTERFACE1(PyXPCOM_GatewayWeakReference, nsIWeakReference)
+
+NS_IMETHODIMP
+PyXPCOM_GatewayWeakReference::QueryReferent(REFNSIID iid, void * *ret)
+{
+ {
+ // Temp scope for lock. We can't hold the lock during
+ // a QI, as this may itself need the lock.
+ // Make sure our object isn't dieing right now on another thread.
+ CEnterLeaveXPCOMFramework _celf;
+ if (m_pBase == NULL)
+ return NS_ERROR_NULL_POINTER;
+ m_pBase->AddRef(); // Can't die while we have a ref.
+ } // end of lock scope - lock unlocked.
+ nsresult nr = m_pBase->QueryInterface(iid, ret);
+ m_pBase->Release();
+ return nr;
+}
diff --git a/src/libs/xpcom18a4/python/src/PyIClassInfo.cpp b/src/libs/xpcom18a4/python/src/PyIClassInfo.cpp
new file mode 100644
index 00000000..6d0f499d
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyIClassInfo.cpp
@@ -0,0 +1,181 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp. Portions created by ActiveState Tool Corp. are Copyright (C) 2001 ActiveState Tool Corp. All Rights Reserved.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2001 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2001, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+#include "nsIClassInfo.h"
+
+static nsIClassInfo *_GetI(PyObject *self) {
+ nsIID iid = NS_GET_IID(nsIClassInfo);
+
+ if (!Py_nsISupports::Check(self, iid)) {
+ PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
+ return NULL;
+ }
+ return (nsIClassInfo *)Py_nsISupports::GetI(self);
+}
+
+static PyObject *PyGetInterfaces(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ nsIClassInfo *pI = _GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsIID** iidArray = nsnull;
+ PRUint32 iidCount = 0;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetInterfaces(&iidCount, &iidArray);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ PyObject *ret = PyTuple_New(iidCount);
+ if (ret==NULL)
+ return NULL;
+ for (PRUint32 i=0;i<iidCount;i++)
+ PyTuple_SET_ITEM( ret, i, Py_nsIID::PyObjectFromIID(*(iidArray[i])) );
+ return ret;
+}
+
+static PyObject *PyGetHelperForLanguage(PyObject *self, PyObject *args)
+{
+ PRUint32 language = nsIProgrammingLanguage::PYTHON;
+ if (!PyArg_ParseTuple(args, "|i", &language))
+ return NULL;
+ nsIClassInfo *pI = _GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsresult r;
+ nsCOMPtr<nsISupports> pi;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetHelperForLanguage(language, getter_AddRefs(pi));
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ return Py_nsISupports::PyObjectFromInterface(pi, NS_GET_IID(nsISupports));
+}
+
+static PyObject *MakeStringOrNone(char *v)
+{
+ if (v)
+#if PY_MAJOR_VERSION <= 2
+ return PyString_FromString(v);
+#else
+ return PyUnicode_FromString(v);
+#endif
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#define GETATTR_CHECK_RESULT(nr) if (NS_FAILED(nr)) return PyXPCOM_BuildPyException(nr)
+
+PyObject *
+Py_nsIClassInfo::getattr(const char *name)
+{
+ nsIClassInfo *pI = _GetI(this);
+ if (pI==NULL)
+ return NULL;
+
+ nsresult nr;
+ PyObject *ret = NULL;
+ if (strcmp(name, "contractID")==0) {
+ char *str_ret = NULL;
+ Py_BEGIN_ALLOW_THREADS;
+ nr = pI->GetContractID(&str_ret);
+ Py_END_ALLOW_THREADS;
+ GETATTR_CHECK_RESULT(nr);
+ ret = MakeStringOrNone(str_ret);
+ nsMemory::Free(str_ret);
+ } else if (strcmp(name, "classDescription")==0) {
+ char *str_ret = NULL;
+ Py_BEGIN_ALLOW_THREADS;
+ nr = pI->GetClassDescription(&str_ret);
+ Py_END_ALLOW_THREADS;
+ GETATTR_CHECK_RESULT(nr);
+ ret = MakeStringOrNone(str_ret);
+ nsMemory::Free(str_ret);
+ } else if (strcmp(name, "classID")==0) {
+ nsIID *iid = NULL;
+ Py_BEGIN_ALLOW_THREADS;
+ nr = pI->GetClassID(&iid);
+ Py_END_ALLOW_THREADS;
+ GETATTR_CHECK_RESULT(nr);
+ ret = Py_nsIID::PyObjectFromIID(*iid);
+ nsMemory::Free(iid);
+ } else if (strcmp(name, "implementationLanguage")==0) {
+ PRUint32 i;
+ Py_BEGIN_ALLOW_THREADS;
+ nr = pI->GetImplementationLanguage(&i);
+ Py_END_ALLOW_THREADS;
+ GETATTR_CHECK_RESULT(nr);
+ ret = PyInt_FromLong(i);
+ } else {
+ ret = Py_nsISupports::getattr(name);
+ }
+ return ret;
+}
+
+int
+Py_nsIClassInfo::setattr(const char *name, PyObject *v)
+{
+ return Py_nsISupports::setattr(name, v);
+
+}
+
+struct PyMethodDef
+PyMethods_IClassInfo[] =
+{
+ { "getInterfaces", PyGetInterfaces, 1},
+ { "GetInterfaces", PyGetInterfaces, 1},
+ { "getHelperForLanguage", PyGetHelperForLanguage, 1},
+ { "GetHelperForLanguage", PyGetHelperForLanguage, 1},
+ {NULL}
+};
diff --git a/src/libs/xpcom18a4/python/src/PyIComponentManager.cpp b/src/libs/xpcom18a4/python/src/PyIComponentManager.cpp
new file mode 100644
index 00000000..c3b89112
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyIComponentManager.cpp
@@ -0,0 +1,138 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+
+static nsIComponentManager *GetI(PyObject *self) {
+ static const nsIID iid = NS_GET_IID(nsIComponentManager);
+
+ if (!Py_nsISupports::Check(self, iid)) {
+ PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
+ return NULL;
+ }
+ return NS_STATIC_CAST(nsIComponentManager*, Py_nsISupports::GetI(self));
+}
+
+static PyObject *PyCreateInstanceByContractID(PyObject *self, PyObject *args)
+{
+ // second arg to CreateInstanceByContractID is a "delegate" - we
+ // aren't sure of the semantics of this yet and it seems rarely used,
+ // so we just punt for now.
+ char *pid, *notyet = NULL;
+ PyObject *obIID = NULL;
+ if (!PyArg_ParseTuple(args, "s|zO", &pid, &notyet, &obIID))
+ return NULL;
+ if (notyet != NULL) {
+ PyErr_SetString(PyExc_ValueError, "2nd arg must be none");
+ return NULL;
+ }
+ nsIComponentManager *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsIID iid;
+ if (obIID==NULL)
+ iid = NS_GET_IID(nsISupports);
+ else
+ if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
+ return NULL;
+
+ nsCOMPtr<nsISupports> pis;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->CreateInstanceByContractID(pid, NULL, iid, getter_AddRefs(pis));
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ /* Return a type based on the IID (with no extra ref) */
+ return Py_nsISupports::PyObjectFromInterface(pis, iid, PR_FALSE);
+}
+
+static PyObject *PyCreateInstance(PyObject *self, PyObject *args)
+{
+ char *notyet = NULL;
+ PyObject *obClassID = NULL, *obIID = NULL;
+ if (!PyArg_ParseTuple(args, "O|zO", &obClassID, &notyet, &obIID))
+ return NULL;
+ if (notyet != NULL) {
+ PyErr_SetString(PyExc_ValueError, "2nd arg must be none");
+ return NULL;
+ }
+ nsIComponentManager *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsIID classID;
+ if (!Py_nsIID::IIDFromPyObject(obClassID, &classID))
+ return NULL;
+ nsIID iid;
+ if (obIID==NULL)
+ iid = NS_GET_IID(nsISupports);
+ else
+ if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
+ return NULL;
+
+ nsCOMPtr<nsISupports> pis;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->CreateInstance(classID, NULL, iid, getter_AddRefs(pis));
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ /* Return a type based on the IID (with no extra ref) */
+ return Py_nsISupports::PyObjectFromInterface(pis, iid, PR_FALSE);
+}
+
+struct PyMethodDef
+PyMethods_IComponentManager[] =
+{
+ { "createInstanceByContractID", PyCreateInstanceByContractID, 1},
+ { "createInstance", PyCreateInstance, 1},
+ {NULL}
+};
diff --git a/src/libs/xpcom18a4/python/src/PyIComponentManagerObsolete.cpp b/src/libs/xpcom18a4/python/src/PyIComponentManagerObsolete.cpp
new file mode 100644
index 00000000..7d07d421
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyIComponentManagerObsolete.cpp
@@ -0,0 +1,203 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+
+static nsIComponentManagerObsolete *GetI(PyObject *self) {
+ static const nsIID iid = NS_GET_IID(nsIComponentManagerObsolete);
+
+ if (!Py_nsISupports::Check(self, iid)) {
+ PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
+ return NULL;
+ }
+ return (nsIComponentManagerObsolete *)Py_nsISupports::GetI(self);
+}
+
+static PyObject *PyCreateInstanceByContractID(PyObject *self, PyObject *args)
+{
+ char *pid, *notyet = NULL;
+ PyObject *obIID = NULL;
+ if (!PyArg_ParseTuple(args, "s|zO", &pid, &notyet, &obIID))
+ return NULL;
+ if (notyet != NULL) {
+ PyErr_SetString(PyExc_ValueError, "2nd arg must be none");
+ return NULL;
+ }
+ nsIComponentManagerObsolete *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsIID iid;
+ if (obIID==NULL)
+ iid = NS_GET_IID(nsISupports);
+ else
+ if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
+ return NULL;
+
+ nsISupports *pis;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->CreateInstanceByContractID(pid, NULL, iid, (void **)&pis);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ /* Return a type based on the IID (with no extra ref) */
+ return Py_nsISupports::PyObjectFromInterface(pis, iid, PR_FALSE, PR_FALSE);
+}
+
+static PyObject *PyContractIDToClassID(PyObject *self, PyObject *args)
+{
+ char *pid;
+ if (!PyArg_ParseTuple(args, "s", &pid))
+ return NULL;
+ nsIComponentManagerObsolete *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsIID iid;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->ContractIDToClassID(pid, &iid);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ return Py_nsIID::PyObjectFromIID(iid);
+}
+
+static PyObject *PyCLSIDToContractID(PyObject *self, PyObject *args)
+{
+ PyObject *obIID;
+ if (!PyArg_ParseTuple(args, "O", &obIID))
+ return NULL;
+
+ nsIID iid;
+ if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
+ return NULL;
+ char *ret_pid = nsnull;
+ char *ret_class = nsnull;
+ nsIComponentManagerObsolete *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->CLSIDToContractID(iid, &ret_class, &ret_pid);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+#if PY_MAJOR_VERSION <= 2
+ PyObject *ob_pid = PyString_FromString(ret_pid);
+ PyObject *ob_class = PyString_FromString(ret_class);
+#else
+ PyObject *ob_pid = PyUnicode_FromString(ret_pid);
+ PyObject *ob_class = PyUnicode_FromString(ret_class);
+#endif
+ PyObject *ret = Py_BuildValue("OO", ob_pid, ob_class);
+ nsMemory::Free(ret_pid);
+ nsMemory::Free(ret_class);
+ Py_XDECREF(ob_pid);
+ Py_XDECREF(ob_class);
+ return ret;
+}
+
+static PyObject *PyEnumerateCLSIDs(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+
+ nsIComponentManagerObsolete *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsIEnumerator *pRet;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->EnumerateCLSIDs(&pRet);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ return Py_nsISupports::PyObjectFromInterface(pRet, NS_GET_IID(nsIEnumerator), PR_FALSE);
+}
+
+static PyObject *PyEnumerateContractIDs(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+
+ nsIComponentManagerObsolete *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsIEnumerator *pRet;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->EnumerateContractIDs(&pRet);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ return Py_nsISupports::PyObjectFromInterface(pRet, NS_GET_IID(nsIEnumerator), PR_FALSE);
+}
+
+struct PyMethodDef
+PyMethods_IComponentManagerObsolete[] =
+{
+ { "CreateInstanceByContractID", PyCreateInstanceByContractID, 1},
+ { "createInstanceByContractID", PyCreateInstanceByContractID, 1},
+ { "EnumerateCLSIDs", PyEnumerateCLSIDs, 1},
+ { "enumerateCLSIDs", PyEnumerateCLSIDs, 1},
+ { "EnumerateContractIDs", PyEnumerateContractIDs, 1},
+ { "enumerateContractIDs", PyEnumerateContractIDs, 1},
+ { "ContractIDToClassID", PyContractIDToClassID, 1},
+ { "contractIDToClassID", PyContractIDToClassID, 1},
+ { "CLSIDToContractID", PyCLSIDToContractID, 1},
+ {NULL}
+};
diff --git a/src/libs/xpcom18a4/python/src/PyIEnumerator.cpp b/src/libs/xpcom18a4/python/src/PyIEnumerator.cpp
new file mode 100644
index 00000000..b196d956
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyIEnumerator.cpp
@@ -0,0 +1,235 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <MarkH@ActiveState.com> (original author)
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+#include <nsIEnumerator.h>
+
+static nsIEnumerator *GetI(PyObject *self) {
+ nsIID iid = NS_GET_IID(nsIEnumerator);
+
+ if (!Py_nsISupports::Check(self, iid)) {
+ PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
+ return NULL;
+ }
+ return (nsIEnumerator *)Py_nsISupports::GetI(self);
+}
+
+static PyObject *PyFirst(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":First"))
+ return NULL;
+
+ nsIEnumerator *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->First();
+ Py_END_ALLOW_THREADS;
+ return PyInt_FromLong(r);
+}
+
+static PyObject *PyNext(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":Next"))
+ return NULL;
+
+ nsIEnumerator *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->Next();
+ Py_END_ALLOW_THREADS;
+ return PyInt_FromLong(r);
+}
+
+static PyObject *PyCurrentItem(PyObject *self, PyObject *args)
+{
+ PyObject *obIID = NULL;
+ if (!PyArg_ParseTuple(args, "|O:CurrentItem", &obIID))
+ return NULL;
+
+ nsIID iid(NS_GET_IID(nsISupports));
+ if (obIID != NULL && !Py_nsIID::IIDFromPyObject(obIID, &iid))
+ return NULL;
+ nsIEnumerator *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsISupports *pRet = nsnull;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->CurrentItem(&pRet);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+ if (obIID) {
+ nsISupports *temp;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pRet->QueryInterface(iid, (void **)&temp);
+ pRet->Release();
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) ) {
+ return PyXPCOM_BuildPyException(r);
+ }
+ pRet = temp;
+ }
+ PyObject *ret = Py_nsISupports::PyObjectFromInterface(pRet, iid);
+ NS_IF_RELEASE(pRet);
+ return ret;
+}
+
+// A method added for Python performance if you really need
+// it. Allows you to fetch a block of objects in one
+// hit, allowing the loop to remain implemented in C.
+static PyObject *PyFetchBlock(PyObject *self, PyObject *args)
+{
+ PyObject *obIID = NULL;
+ int n_wanted;
+ int n_fetched = 0;
+ if (!PyArg_ParseTuple(args, "i|O:FetchBlock", &n_wanted, &obIID))
+ return NULL;
+
+ nsIID iid(NS_GET_IID(nsISupports));
+ if (obIID != NULL && !Py_nsIID::IIDFromPyObject(obIID, &iid))
+ return NULL;
+ nsIEnumerator *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ // We want to fetch with the thread-lock released,
+ // but this means we can not append to the PyList
+ nsISupports **fetched = new nsISupports*[n_wanted];
+ if (fetched==nsnull) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ memset(fetched, 0, sizeof(nsISupports *) * n_wanted);
+ nsresult r = NS_OK;
+ Py_BEGIN_ALLOW_THREADS;
+ for (;n_fetched<n_wanted;) {
+ nsISupports *pNew;
+ r = pI->CurrentItem(&pNew);
+ if (NS_FAILED(r)) {
+ r = 0; // Normal enum end
+ break;
+ }
+ if (obIID) {
+ nsISupports *temp;
+ r = pNew->QueryInterface(iid, (void **)&temp);
+ pNew->Release();
+ if ( NS_FAILED(r) ) {
+ break;
+ }
+ pNew = temp;
+ }
+ fetched[n_fetched] = pNew;
+ n_fetched++; // must increment before breaking out.
+ if (NS_FAILED(pI->Next()))
+ break; // not an error condition.
+ }
+ Py_END_ALLOW_THREADS;
+ PyObject *ret;
+ if (NS_SUCCEEDED(r)) {
+ ret = PyList_New(n_fetched);
+ if (ret)
+ for (int i=0;i<n_fetched;i++) {
+ PyObject *new_ob = Py_nsISupports::PyObjectFromInterface(fetched[i], iid);
+ NS_IF_RELEASE(fetched[i]);
+ PyList_SET_ITEM(ret, i, new_ob);
+ }
+ } else
+ ret = PyXPCOM_BuildPyException(r);
+
+ if ( ret == NULL ) {
+ // Free the objects we consumed.
+ for (int i=0;i<n_fetched;i++)
+ fetched[i]->Release();
+
+ }
+ delete [] fetched;
+ return ret;
+}
+
+static PyObject *PyIsDone(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":IsDone"))
+ return NULL;
+
+ nsIEnumerator *pI = GetI(self);
+ nsresult r;
+ if (pI==NULL)
+ return NULL;
+
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->IsDone();
+ Py_END_ALLOW_THREADS;
+ if (NS_FAILED(r))
+ return PyXPCOM_BuildPyException(r);
+ PyObject *ret = r==NS_OK ? Py_True : Py_False;
+ Py_INCREF(ret);
+ return ret;
+}
+
+struct PyMethodDef
+PyMethods_IEnumerator[] =
+{
+ { "First", PyFirst, 1},
+ { "first", PyFirst, 1},
+ { "Next", PyNext, 1},
+ { "next", PyNext, 1},
+ { "CurrentItem", PyCurrentItem, 1},
+ { "currentItem", PyCurrentItem, 1},
+ { "IsDone", PyIsDone, 1},
+ { "isDone", PyIsDone, 1},
+ { "FetchBlock", PyFetchBlock, 1},
+ { "fetchBlock", PyFetchBlock, 1},
+ {NULL}
+};
diff --git a/src/libs/xpcom18a4/python/src/PyIID.cpp b/src/libs/xpcom18a4/python/src/PyIID.cpp
new file mode 100644
index 00000000..f24ae20e
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyIID.cpp
@@ -0,0 +1,410 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+// Py_nsIID.cpp -- IID type for Python/XPCOM
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+//
+// @doc
+
+#include "PyXPCOM_std.h"
+#include <nsIInterfaceInfoManager.h>
+
+nsIID Py_nsIID_NULL = {0,0,0,{0,0,0,0,0,0,0,0}};
+
+// @pymethod <o Py_nsIID>|xpcom|IID|Creates a new IID object
+PYXPCOM_EXPORT PyObject *PyXPCOMMethod_IID(PyObject *self, PyObject *args)
+{
+ PyObject *obIID;
+ PyObject *obBuf;
+ if ( PyArg_ParseTuple(args, "O", &obBuf)) {
+#if PY_MAJOR_VERSION <= 2
+ if (PyBuffer_Check(obBuf)) {
+ PyBufferProcs *pb = NULL;
+ pb = obBuf->ob_type->tp_as_buffer;
+ void *buf = NULL;
+ int size = (*pb->bf_getreadbuffer)(obBuf, 0, &buf);
+#else
+ if (PyObject_CheckBuffer(obBuf)) {
+# ifndef Py_LIMITED_API
+ Py_buffer view;
+ if (PyObject_GetBuffer(obBuf, &view, PyBUF_CONTIG_RO) != 0) {
+ PyErr_Format(PyExc_ValueError, "Could not get contiguous buffer from object");
+ return NULL;
+ }
+ Py_ssize_t size = view.len;
+ const void *buf = view.buf;
+# else /* Py_LIMITED_API - the buffer API is non-existant, from what I can tell */
+ const void *buf = NULL;
+ Py_ssize_t size = 0;
+ if (PyObject_AsReadBuffer(obBuf, &buf, &size) != 0) {
+ PyErr_Format(PyExc_ValueError, "Could not get read-only buffer from object");
+ return NULL;
+ }
+# endif /* Py_LIMITED_API */
+#endif
+ if (size != sizeof(nsIID) || buf==NULL) {
+#if PY_MAJOR_VERSION >= 3 && !defined(Py_LIMITED_API)
+ PyBuffer_Release(&view);
+#endif
+#ifdef VBOX
+ PyErr_Format(PyExc_ValueError, "A buffer object to be converted to an IID must be exactly %d bytes long", (int)sizeof(nsIID));
+#else
+ PyErr_Format(PyExc_ValueError, "A buffer object to be converted to an IID must be exactly %d bytes long", sizeof(nsIID));
+#endif
+ return NULL;
+ }
+ nsIID iid;
+ unsigned char const *ptr = (unsigned char const *)buf;
+ iid.m0 = XPT_SWAB32(*((PRUint32 *)ptr));
+ ptr = ((unsigned char const *)buf) + offsetof(nsIID, m1);
+ iid.m1 = XPT_SWAB16(*((PRUint16 *)ptr));
+ ptr = ((unsigned char const *)buf) + offsetof(nsIID, m2);
+ iid.m2 = XPT_SWAB16(*((PRUint16 *)ptr));
+ ptr = ((unsigned char const *)buf) + offsetof(nsIID, m3);
+ for (int i=0;i<8;i++) {
+ iid.m3[i] = *((PRUint8 const *)ptr);
+ ptr += sizeof(PRUint8);
+ }
+#if PY_MAJOR_VERSION >= 3 && !defined(Py_LIMITED_API)
+ PyBuffer_Release(&view);
+#endif
+ return new Py_nsIID(iid);
+ }
+ }
+ PyErr_Clear();
+ // @pyparm string/Unicode|iidString||A string representation of an IID, or a ContractID.
+ if ( !PyArg_ParseTuple(args, "O", &obIID) )
+ return NULL;
+
+ nsIID iid;
+ if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
+ return NULL;
+ return new Py_nsIID(iid);
+}
+
+/*static*/ PRBool
+Py_nsIID::IIDFromPyObject(PyObject *ob, nsIID *pRet) {
+ PRBool ok = PR_TRUE;
+ nsIID iid;
+ if (ob==NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "The IID object is invalid!");
+ return PR_FALSE;
+ }
+#if PY_MAJOR_VERSION <= 2
+ if (PyString_Check(ob)) {
+ ok = iid.Parse(PyString_AsString(ob));
+#else
+ if (PyUnicode_Check(ob)) {
+ ok = iid.Parse(PyUnicode_AsUTF8(ob));
+#endif
+ if (!ok) {
+ PyXPCOM_BuildPyException(NS_ERROR_ILLEGAL_VALUE);
+ return PR_FALSE;
+ }
+#ifndef Py_LIMITED_API
+ } else if (ob->ob_type == &type) {
+#else
+ } else if (ob->ob_type == Py_nsIID::GetTypeObject()) {
+#endif
+ iid = ((Py_nsIID *)ob)->m_iid;
+ } else if (PyObject_HasAttrString(ob, "__class__")) {
+ // Get the _iidobj_ attribute
+ PyObject *use_ob = PyObject_GetAttrString(ob, "_iidobj_");
+ if (use_ob==NULL) {
+ PyErr_SetString(PyExc_TypeError, "Only instances with _iidobj_ attributes can be used as IID objects");
+ return PR_FALSE;
+ }
+#ifndef Py_LIMITED_API
+ if (use_ob->ob_type != &type) {
+#else
+ if (use_ob->ob_type != Py_nsIID::GetTypeObject()) {
+#endif
+ Py_DECREF(use_ob);
+ PyErr_SetString(PyExc_TypeError, "instance _iidobj_ attributes must be raw IID object");
+ return PR_FALSE;
+ }
+ iid = ((Py_nsIID *)use_ob)->m_iid;
+ Py_DECREF(use_ob);
+ } else {
+ PyErr_Format(PyExc_TypeError, "Objects of type '%s' can not be converted to an IID", PyXPCOM_ObTypeName(ob));
+ ok = PR_FALSE;
+ }
+ if (ok) *pRet = iid;
+ return ok;
+}
+
+
+// @object Py_nsIID|A Python object, representing an IID/CLSID.
+// <nl>All pythoncom functions that return a CLSID/IID will return one of these
+// objects. However, in almost all cases, functions that expect a CLSID/IID
+// as a param will accept either a string object, or a native Py_nsIID object.
+#ifndef Py_LIMITED_API
+PyTypeObject Py_nsIID::type =
+{
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "IID",
+ sizeof(Py_nsIID),
+ 0,
+ PyTypeMethod_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ PyTypeMethod_getattr, /* tp_getattr */
+ 0, /* tp_setattr */
+#if PY_MAJOR_VERSION <= 2
+ PyTypeMethod_compare, /* tp_compare */
+#else
+ 0, /* reserved */
+#endif
+ PyTypeMethod_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ PyTypeMethod_hash, /* tp_hash */
+ 0, /* tp_call */
+ PyTypeMethod_str, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ 0, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ PyTypeMethod_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+};
+#else /* Py_LIMITED_API */
+NS_EXPORT_STATIC_MEMBER_(PyTypeObject *) Py_nsIID::s_pType = NULL;
+
+PyTypeObject *Py_nsIID::GetTypeObject(void)
+{
+ PyTypeObject *pTypeObj = Py_nsIID::s_pType;
+ if (pTypeObj)
+ return pTypeObj;
+
+ PyType_Slot aTypeSlots[] = {
+ { Py_tp_base, &PyType_Type },
+ { Py_tp_dealloc, (void *)(uintptr_t)&Py_nsIID::PyTypeMethod_dealloc },
+ { Py_tp_getattr, (void *)(uintptr_t)&Py_nsIID::PyTypeMethod_getattr },
+ { Py_tp_repr, (void *)(uintptr_t)&Py_nsIID::PyTypeMethod_repr },
+ { Py_tp_hash, (void *)(uintptr_t)&Py_nsIID::PyTypeMethod_hash },
+ { Py_tp_str, (void *)(uintptr_t)&Py_nsIID::PyTypeMethod_str },
+ { Py_tp_richcompare, (void *)(uintptr_t)&Py_nsIID::PyTypeMethod_richcompare },
+ { 0, NULL } /* terminator */
+ };
+ PyType_Spec TypeSpec = {
+ /* .name: */ "IID",
+ /* .basicsize: */ sizeof(Py_nsIID),
+ /* .itemsize: */ 0,
+ /* .flags: */ 0,
+ /* .slots: */ aTypeSlots,
+ };
+
+ PyObject *exc_typ = NULL, *exc_val = NULL, *exc_tb = NULL;
+ PyErr_Fetch(&exc_typ, &exc_val, &exc_tb); /* goes south in PyType_Ready if we don't clear exceptions first. */
+
+ pTypeObj = (PyTypeObject *)PyType_FromSpec(&TypeSpec);
+ assert(pTypeObj);
+
+ PyErr_Restore(exc_typ, exc_val, exc_tb);
+ Py_nsIID::s_pType = pTypeObj;
+ return pTypeObj;
+}
+#endif /* Py_LIMITED_API */
+
+Py_nsIID::Py_nsIID(const nsIID &riid)
+{
+#ifndef Py_LIMITED_API
+ ob_type = &type;
+#else
+ ob_type = GetTypeObject();
+#endif
+#if 1 /* VBox: Must use for 3.9+, includes _Py_NewReferences. Works for all older versions too. @bugref{10079} */
+ PyObject_Init(this, ob_type);
+#else
+ _Py_NewReference(this);
+#endif
+
+ m_iid = riid;
+}
+
+/*static*/PyObject *
+Py_nsIID::PyTypeMethod_getattr(PyObject *self, char *name)
+{
+ Py_nsIID *me = (Py_nsIID *)self;
+ if (strcmp(name, "name")==0) {
+ char *iid_repr = nsnull;
+ nsCOMPtr<nsIInterfaceInfoManager> iim(do_GetService(
+ NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
+ if (iim!=nsnull)
+ iim->GetNameForIID(&me->m_iid, &iid_repr);
+ if (iid_repr==nsnull)
+ iid_repr = me->m_iid.ToString();
+ PyObject *ret;
+ if (iid_repr != nsnull) {
+#if PY_MAJOR_VERSION <= 2
+ ret = PyString_FromString(iid_repr);
+#else
+ ret = PyUnicode_FromString(iid_repr);
+#endif
+ nsMemory::Free(iid_repr);
+ } else
+#if PY_MAJOR_VERSION <= 2
+ ret = PyString_FromString("<cant get IID info!>");
+#else
+ ret = PyUnicode_FromString("<cant get IID info!>");
+#endif
+ return ret;
+ }
+ return PyErr_Format(PyExc_AttributeError, "IID objects have no attribute '%s'", name);
+}
+
+#if PY_MAJOR_VERSION <= 2
+/* static */ int
+Py_nsIID::PyTypeMethod_compare(PyObject *self, PyObject *other)
+{
+ Py_nsIID *s_iid = (Py_nsIID *)self;
+ Py_nsIID *o_iid = (Py_nsIID *)other;
+ int rc = memcmp(&s_iid->m_iid, &o_iid->m_iid, sizeof(s_iid->m_iid));
+ return rc == 0 ? 0 : (rc < 0 ? -1 : 1);
+}
+#endif
+
+/* static */ PyObject *
+Py_nsIID::PyTypeMethod_richcompare(PyObject *self, PyObject *other, int op)
+{
+ PyObject *result = NULL;
+ Py_nsIID *s_iid = (Py_nsIID *)self;
+ Py_nsIID *o_iid = (Py_nsIID *)other;
+ int rc = memcmp(&s_iid->m_iid, &o_iid->m_iid, sizeof(s_iid->m_iid));
+ switch (op)
+ {
+ case Py_LT:
+ result = rc < 0 ? Py_True : Py_False;
+ break;
+ case Py_LE:
+ result = rc <= 0 ? Py_True : Py_False;
+ break;
+ case Py_EQ:
+ result = rc == 0 ? Py_True : Py_False;
+ break;
+ case Py_NE:
+ result = rc != 0 ? Py_True : Py_False;
+ break;
+ case Py_GT:
+ result = rc > 0 ? Py_True : Py_False;
+ break;
+ case Py_GE:
+ result = rc >= 0 ? Py_True : Py_False;
+ break;
+ }
+ Py_XINCREF(result);
+ return result;
+}
+
+/* static */ PyObject *
+Py_nsIID::PyTypeMethod_repr(PyObject *self)
+{
+ Py_nsIID *s_iid = (Py_nsIID *)self;
+ char buf[256];
+ char *sziid = s_iid->m_iid.ToString();
+#ifdef VBOX
+ snprintf(buf, sizeof(buf), "_xpcom.ID('%s')", sziid);
+#else
+ sprintf(buf, "_xpcom.IID('%s')", sziid);
+#endif
+ nsMemory::Free(sziid);
+#if PY_MAJOR_VERSION <= 2
+ return PyString_FromString(buf);
+#else
+ return PyUnicode_FromString(buf);
+#endif
+}
+
+/* static */ PyObject *
+Py_nsIID::PyTypeMethod_str(PyObject *self)
+{
+ Py_nsIID *s_iid = (Py_nsIID *)self;
+ char *sziid = s_iid->m_iid.ToString();
+#if PY_MAJOR_VERSION <= 2
+ PyObject *ret = PyString_FromString(sziid);
+#else
+ PyObject *ret = PyUnicode_FromString(sziid);
+#endif
+ nsMemory::Free(sziid);
+ return ret;
+}
+
+#if PY_VERSION_HEX >= 0x03020000
+/* static */Py_hash_t
+Py_nsIID::PyTypeMethod_hash(PyObject *self)
+#else
+/* static */long
+Py_nsIID::PyTypeMethod_hash(PyObject *self)
+#endif
+{
+ const nsIID &iid = ((Py_nsIID *)self)->m_iid;
+
+#if PY_VERSION_HEX >= 0x03020000
+ Py_hash_t ret = iid.m0 + iid.m1 + iid.m2;
+#else
+ long ret = iid.m0 + iid.m1 + iid.m2;
+#endif
+ for (int i=0;i<7;i++)
+ ret += iid.m3[i];
+ if ( ret == -1 )
+ return -2;
+ return ret;
+}
+
+/*static*/ void
+Py_nsIID::PyTypeMethod_dealloc(PyObject *ob)
+{
+ delete (Py_nsIID *)ob;
+}
diff --git a/src/libs/xpcom18a4/python/src/PyIInputStream.cpp b/src/libs/xpcom18a4/python/src/PyIInputStream.cpp
new file mode 100644
index 00000000..b290a3e4
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyIInputStream.cpp
@@ -0,0 +1,190 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written September 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+#include "nsIInputStream.h"
+
+// Prevents us needing to use an nsIScriptableInputStream
+// (and even that can't read binary data!!!)
+
+static nsIInputStream *GetI(PyObject *self) {
+ nsIID iid = NS_GET_IID(nsIInputStream);
+
+ if (!Py_nsISupports::Check(self, iid)) {
+ PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
+ return NULL;
+ }
+ return (nsIInputStream *)Py_nsISupports::GetI(self);
+}
+
+static PyObject *DoPyRead_Buffer(nsIInputStream *pI, PyObject *obBuffer, PRUint32 n)
+{
+ PRUint32 nread;
+ void *buf;
+#ifndef VBOX /* unsafe cast on 64-bit hosts. */
+ PRUint32 buf_len;
+ if (PyObject_AsWriteBuffer(obBuffer, &buf, (Py_ssize_t *)&buf_len) != 0) {
+#else /* VBOX */
+# if PY_VERSION_HEX >= 0x02050000 || defined(PY_SSIZE_T_MIN)
+ Py_ssize_t buf_len;
+# else
+ int buf_len;
+# endif /* VBOX */
+ if (PyObject_AsWriteBuffer(obBuffer, &buf, &buf_len) != 0) {
+#endif
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError, "The buffer object does not have a write buffer!");
+ return NULL;
+ }
+ if (n==(PRUint32)-1) {
+ n = buf_len;
+ } else {
+ if (n > buf_len) {
+ NS_WARNING("Warning: PyIInputStream::read() was passed an integer size greater than the size of the passed buffer! Buffer size used.\n");
+ n = buf_len;
+ }
+ }
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->Read((char *)buf, n, &nread);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+ return PyInt_FromLong(nread);
+}
+
+static PyObject *DoPyRead_Size(nsIInputStream *pI, PRUint32 n)
+{
+ if (n==(PRUint32)-1) {
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->Available(&n);
+ Py_END_ALLOW_THREADS;
+ if (NS_FAILED(r))
+ return PyXPCOM_BuildPyException(r);
+ }
+ if (n==0) { // mozilla will assert if we alloc zero bytes.
+#if PY_MAJOR_VERSION <= 2
+ return PyBuffer_New(0);
+#else
+ return PyBytes_FromString("");
+#endif
+ }
+ char *buf = (char *)nsMemory::Alloc(n);
+ if (buf==NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ nsresult r;
+ PRUint32 nread;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->Read(buf, n, &nread);
+ Py_END_ALLOW_THREADS;
+ PyObject *rc = NULL;
+ if ( NS_SUCCEEDED(r) ) {
+#if PY_MAJOR_VERSION <= 2
+ rc = PyBuffer_New(nread);
+ if (rc != NULL) {
+ void *ob_buf;
+#ifndef VBOX /* unsafe cast on 64-bit hosts. */
+ PRUint32 buf_len;
+ if (PyObject_AsWriteBuffer(rc, &ob_buf, (Py_ssize_t *)&buf_len) != 0) {
+#else /* VBOX */
+# if PY_VERSION_HEX >= 0x02050000 || defined(PY_SSIZE_T_MIN)
+ Py_ssize_t buf_len;
+# else
+ int buf_len;
+# endif /* VBOX */
+ if (PyObject_AsWriteBuffer(rc, &ob_buf, &buf_len) != 0) {
+#endif
+ // should never fail - we just created it!
+ return NULL;
+ }
+ if (buf_len != nread) {
+ PyErr_SetString(PyExc_RuntimeError, "New buffer isnt the size we create it!");
+ return NULL;
+ }
+ memcpy(ob_buf, buf, nread);
+ }
+#else
+ rc = PyBytes_FromStringAndSize(buf, nread);
+#endif
+ } else
+ PyXPCOM_BuildPyException(r);
+ nsMemory::Free(buf);
+ return rc;
+}
+
+static PyObject *PyRead(PyObject *self, PyObject *args)
+{
+ PyObject *obBuffer = NULL;
+ PRUint32 n = (PRUint32)-1;
+
+ nsIInputStream *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+ if (PyArg_ParseTuple(args, "|i", (int *)&n))
+ // This worked - no args, or just an int.
+ return DoPyRead_Size(pI, n);
+ // try our other supported arg format.
+ PyErr_Clear();
+ if (!PyArg_ParseTuple(args, "O|i", &obBuffer, (int *)&n)) {
+ PyErr_Clear();
+ PyErr_SetString(PyExc_TypeError, "'read()' must be called as (buffer_ob, int_size=-1) or (int_size=-1)");
+ return NULL;
+ }
+ return DoPyRead_Buffer(pI, obBuffer, n);
+}
+
+
+struct PyMethodDef
+PyMethods_IInputStream[] =
+{
+ { "read", PyRead, 1},
+ // The rest are handled as normal
+ {NULL}
+};
diff --git a/src/libs/xpcom18a4/python/src/PyIInterfaceInfo.cpp b/src/libs/xpcom18a4/python/src/PyIInterfaceInfo.cpp
new file mode 100644
index 00000000..7e1a9466
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyIInterfaceInfo.cpp
@@ -0,0 +1,431 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+
+
+static nsIInterfaceInfo *GetI(PyObject *self) {
+ nsIID iid = NS_GET_IID(nsIInterfaceInfo);
+
+ if (!Py_nsISupports::Check(self, iid)) {
+ PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
+ return NULL;
+ }
+ return (nsIInterfaceInfo *)Py_nsISupports::GetI(self);
+}
+
+static PyObject *PyGetName(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":GetName"))
+ return NULL;
+
+ nsIInterfaceInfo *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ char *name;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetName(&name);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+#if PY_MAJOR_VERSION <= 2
+ PyObject *ret = PyString_FromString(name);
+#else
+ PyObject *ret = PyUnicode_FromString(name);
+#endif
+ nsMemory::Free(name);
+ return ret;
+}
+
+static PyObject *PyGetIID(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":GetIID"))
+ return NULL;
+
+ nsIInterfaceInfo *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsIID *iid_ret;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetInterfaceIID(&iid_ret);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+ PyObject *ret = Py_nsIID::PyObjectFromIID(*iid_ret);
+ nsMemory::Free(iid_ret);
+ return ret;
+}
+
+static PyObject *PyIsScriptable(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":IsScriptable"))
+ return NULL;
+
+ nsIInterfaceInfo *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ PRBool b_ret;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->IsScriptable(&b_ret);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+ return PyInt_FromLong(b_ret);
+}
+
+static PyObject *PyGetParent(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":GetParent"))
+ return NULL;
+
+ nsIInterfaceInfo *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsCOMPtr<nsIInterfaceInfo> pRet;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetParent(getter_AddRefs(pRet));
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+ return Py_nsISupports::PyObjectFromInterface(pRet, NS_GET_IID(nsIInterfaceInfo), PR_FALSE);
+}
+
+static PyObject *PyGetMethodCount(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":GetMethodCount"))
+ return NULL;
+
+ nsIInterfaceInfo *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ PRUint16 ret;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetMethodCount(&ret);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+ return PyInt_FromLong(ret);
+}
+
+
+static PyObject *PyGetConstantCount(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":GetConstantCount"))
+ return NULL;
+
+ nsIInterfaceInfo *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ PRUint16 ret;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetConstantCount(&ret);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+ return PyInt_FromLong(ret);
+}
+
+static PyObject *PyGetMethodInfo(PyObject *self, PyObject *args)
+{
+ PRUint16 index;
+ if (!PyArg_ParseTuple(args, "h:GetMethodInfo", &index))
+ return NULL;
+
+ nsIInterfaceInfo *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ PRUint16 nmethods;
+ pI->GetMethodCount(&nmethods);
+ if (index>=nmethods) {
+ PyErr_SetString(PyExc_ValueError, "The method index is out of range");
+ return NULL;
+ }
+
+ const nsXPTMethodInfo *pRet;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetMethodInfo(index, &pRet);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+ return PyObject_FromXPTMethodDescriptor(pRet);
+}
+
+static PyObject *PyGetMethodInfoForName(PyObject *self, PyObject *args)
+{
+ char *name;
+ if (!PyArg_ParseTuple(args, "s:GetMethodInfoForName", &name))
+ return NULL;
+
+ nsIInterfaceInfo *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ const nsXPTMethodInfo *pRet;
+ PRUint16 index;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetMethodInfoForName(name, &index, &pRet);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+ PyObject *ret_i = PyObject_FromXPTMethodDescriptor(pRet);
+ if (ret_i==NULL)
+ return NULL;
+ PyObject *real_ret = Py_BuildValue("iO", (int)index, ret_i);
+ Py_DECREF(ret_i);
+ return real_ret;
+}
+
+
+static PyObject *PyGetConstant(PyObject *self, PyObject *args)
+{
+ PRUint16 index;
+ if (!PyArg_ParseTuple(args, "h:GetConstant", &index))
+ return NULL;
+
+ nsIInterfaceInfo *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ const nsXPTConstant *pRet;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetConstant(index, &pRet);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+ return PyObject_FromXPTConstant(pRet);
+}
+
+static PRBool __GetMethodInfoHelper(nsIInterfaceInfo *pii, int mi, int pi, const nsXPTMethodInfo **ppmi)
+{
+ PRUint16 nmethods=0;
+ pii->GetMethodCount(&nmethods);
+ if (mi<0 || mi>=nmethods) {
+ PyErr_SetString(PyExc_ValueError, "The method index is out of range");
+ return PR_FALSE;
+ }
+ const nsXPTMethodInfo *pmi;
+ nsresult r = pii->GetMethodInfo(mi, &pmi);
+ if ( NS_FAILED(r) ) {
+ PyXPCOM_BuildPyException(r);
+ return PR_FALSE;
+ }
+
+ int nparams=0;
+ nparams = pmi->GetParamCount();
+ if (pi<0 || pi>=nparams) {
+ PyErr_SetString(PyExc_ValueError, "The param index is out of range");
+ return PR_FALSE;
+ }
+ *ppmi = pmi;
+ return PR_TRUE;
+}
+
+static PyObject *PyGetInfoForParam(PyObject *self, PyObject *args)
+{
+ nsIInterfaceInfo *pii = GetI(self);
+ if (pii==NULL)
+ return NULL;
+ PRUint16 mi, pi;
+ if (!PyArg_ParseTuple(args, "hh:GetInfoForParam", &mi, &pi))
+ return NULL;
+ const nsXPTMethodInfo *pmi;
+ if (!__GetMethodInfoHelper(pii, mi, pi, &pmi))
+ return NULL;
+ const nsXPTParamInfo& param_info = pmi->GetParam((PRUint8)pi);
+ nsCOMPtr<nsIInterfaceInfo> pnewii;
+ nsresult n = pii->GetInfoForParam(mi, &param_info, getter_AddRefs(pnewii));
+ if (NS_FAILED(n))
+ return PyXPCOM_BuildPyException(n);
+ return Py_nsISupports::PyObjectFromInterface(pnewii, NS_GET_IID(nsIInterfaceInfo));
+}
+
+static PyObject *PyGetIIDForParam(PyObject *self, PyObject *args)
+{
+ nsIInterfaceInfo *pii = GetI(self);
+ if (pii==NULL)
+ return NULL;
+ PRUint16 mi, pi;
+ if (!PyArg_ParseTuple(args, "hh:GetIIDForParam", &mi, &pi))
+ return NULL;
+ const nsXPTMethodInfo *pmi;
+ if (!__GetMethodInfoHelper(pii, mi, pi, &pmi))
+ return NULL;
+ const nsXPTParamInfo& param_info = pmi->GetParam((PRUint8)pi);
+ nsIID *piid;
+ nsresult n = pii->GetIIDForParam(mi, &param_info, &piid);
+ if (NS_FAILED(n) || piid==nsnull)
+ return PyXPCOM_BuildPyException(n);
+ PyObject *rc = Py_nsIID::PyObjectFromIID(*piid);
+ nsMemory::Free((void*)piid);
+ return rc;
+}
+
+static PyObject *PyGetTypeForParam(PyObject *self, PyObject *args)
+{
+ nsIInterfaceInfo *pii = GetI(self);
+ if (pii==NULL)
+ return NULL;
+ PRUint16 mi, pi, dim;
+ if (!PyArg_ParseTuple(args, "hhh:GetTypeForParam", &mi, &pi, &dim))
+ return NULL;
+ const nsXPTMethodInfo *pmi;
+ if (!__GetMethodInfoHelper(pii, mi, pi, &pmi))
+ return NULL;
+ nsXPTType datumType;
+ const nsXPTParamInfo& param_info = pmi->GetParam((PRUint8)pi);
+ nsresult n = pii->GetTypeForParam(mi, &param_info, dim, &datumType);
+ if (NS_FAILED(n))
+ return PyXPCOM_BuildPyException(n);
+ return PyObject_FromXPTType(&datumType);
+}
+
+static PyObject *PyGetSizeIsArgNumberForParam(PyObject *self, PyObject *args)
+{
+ nsIInterfaceInfo *pii = GetI(self);
+ if (pii==NULL)
+ return NULL;
+ PRUint16 mi, pi, dim;
+ if (!PyArg_ParseTuple(args, "hhh:GetSizeIsArgNumberForParam", &mi, &pi, &dim))
+ return NULL;
+ const nsXPTMethodInfo *pmi;
+ if (!__GetMethodInfoHelper(pii, mi, pi, &pmi))
+ return NULL;
+ PRUint8 ret;
+ const nsXPTParamInfo& param_info = pmi->GetParam((PRUint8)pi);
+ nsresult n = pii->GetSizeIsArgNumberForParam(mi, &param_info, dim, &ret);
+ if (NS_FAILED(n))
+ return PyXPCOM_BuildPyException(n);
+ return PyInt_FromLong(ret);
+}
+
+static PyObject *PyGetLengthIsArgNumberForParam(PyObject *self, PyObject *args)
+{
+ nsIInterfaceInfo *pii = GetI(self);
+ if (pii==NULL)
+ return NULL;
+ PRUint16 mi, pi, dim;
+ if (!PyArg_ParseTuple(args, "hhh:GetLengthIsArgNumberForParam", &mi, &pi, &dim))
+ return NULL;
+ const nsXPTMethodInfo *pmi;
+ if (!__GetMethodInfoHelper(pii, mi, pi, &pmi))
+ return NULL;
+ PRUint8 ret;
+ const nsXPTParamInfo& param_info = pmi->GetParam((PRUint8)pi);
+ nsresult n = pii->GetLengthIsArgNumberForParam(mi, &param_info, dim, &ret);
+ if (NS_FAILED(n))
+ return PyXPCOM_BuildPyException(n);
+ return PyInt_FromLong(ret);
+}
+
+static PyObject *PyGetInterfaceIsArgNumberForParam(PyObject *self, PyObject *args)
+{
+ nsIInterfaceInfo *pii = GetI(self);
+ if (pii==NULL)
+ return NULL;
+ PRUint16 mi, pi;
+ if (!PyArg_ParseTuple(args, "hhh:GetInterfaceIsArgNumberForParam", &mi, &pi))
+ return NULL;
+ const nsXPTMethodInfo *pmi;
+ if (!__GetMethodInfoHelper(pii, mi, pi, &pmi))
+ return NULL;
+ PRUint8 ret;
+ const nsXPTParamInfo& param_info = pmi->GetParam((PRUint8)pi);
+ nsresult n = pii->GetInterfaceIsArgNumberForParam(mi, &param_info, &ret);
+ if (NS_FAILED(n))
+ return PyXPCOM_BuildPyException(n);
+ return PyInt_FromLong(ret);
+}
+
+struct PyMethodDef
+PyMethods_IInterfaceInfo[] =
+{
+ { "GetName", PyGetName, 1},
+ { "GetIID", PyGetIID, 1},
+ { "IsScriptable", PyIsScriptable, 1},
+ { "GetParent", PyGetParent, 1},
+ { "GetMethodCount", PyGetMethodCount, 1},
+ { "GetConstantCount", PyGetConstantCount, 1},
+ { "GetMethodInfo", PyGetMethodInfo, 1},
+ { "GetMethodInfoForName", PyGetMethodInfoForName, 1},
+ { "GetConstant", PyGetConstant, 1},
+ { "GetInfoForParam", PyGetInfoForParam, 1},
+ { "GetIIDForParam", PyGetIIDForParam, 1},
+ { "GetTypeForParam", PyGetTypeForParam, 1},
+ { "GetSizeIsArgNumberForParam", PyGetSizeIsArgNumberForParam, 1},
+ { "GetLengthIsArgNumberForParam", PyGetLengthIsArgNumberForParam, 1},
+ { "GetInterfaceIsArgNumberForParam", PyGetInterfaceIsArgNumberForParam, 1},
+ {NULL}
+};
+
+/*
+ NS_IMETHOD GetMethodInfo(PRUint16 index, const nsXPTMethodInfo * *info) = 0;
+ NS_IMETHOD GetMethodInfoForName(const char *methodName, PRUint16 *index, const nsXPTMethodInfo * *info) = 0;
+ NS_IMETHOD GetConstant(PRUint16 index, const nsXPTConstant * *constant) = 0;
+ NS_IMETHOD GetInfoForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIInterfaceInfo **_retval) = 0;
+ NS_IMETHOD GetIIDForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, nsIID * *_retval) = 0;
+ NS_IMETHOD GetTypeForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, nsXPTType *_retval) = 0;
+ NS_IMETHOD GetSizeIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval) = 0;
+ NS_IMETHOD GetLengthIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint16 dimension, PRUint8 *_retval) = 0;
+ NS_IMETHOD GetInterfaceIsArgNumberForParam(PRUint16 methodIndex, const nsXPTParamInfo * param, PRUint8 *_retval) = 0;
+
+*/
diff --git a/src/libs/xpcom18a4/python/src/PyIInterfaceInfoManager.cpp b/src/libs/xpcom18a4/python/src/PyIInterfaceInfoManager.cpp
new file mode 100644
index 00000000..7c629413
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyIInterfaceInfoManager.cpp
@@ -0,0 +1,206 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+#include <nsIInterfaceInfoManager.h>
+
+static nsIInterfaceInfoManager *GetI(PyObject *self) {
+ nsIID iid = NS_GET_IID(nsIInterfaceInfoManager);
+
+ if (!Py_nsISupports::Check(self, iid)) {
+ PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
+ return NULL;
+ }
+ return (nsIInterfaceInfoManager *)Py_nsISupports::GetI(self);
+}
+
+static PyObject *PyGetInfoForIID(PyObject *self, PyObject *args)
+{
+ PyObject *obIID = NULL;
+ if (!PyArg_ParseTuple(args, "O", &obIID))
+ return NULL;
+
+ nsIInterfaceInfoManager *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsIID iid;
+ if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
+ return NULL;
+
+ nsCOMPtr<nsIInterfaceInfo> pi;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetInfoForIID(&iid, getter_AddRefs(pi));
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ /* Return a type based on the IID (with no extra ref) */
+ nsIID new_iid = NS_GET_IID(nsIInterfaceInfo);
+ // Can not auto-wrap the interface info manager as it is critical to
+ // building the support we need for autowrap.
+ return Py_nsISupports::PyObjectFromInterface(pi, new_iid, PR_FALSE);
+}
+
+static PyObject *PyGetInfoForName(PyObject *self, PyObject *args)
+{
+ char *name;
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ nsIInterfaceInfoManager *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsCOMPtr<nsIInterfaceInfo> pi;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetInfoForName(name, getter_AddRefs(pi));
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ /* Return a type based on the IID (with no extra ref) */
+ // Can not auto-wrap the interface info manager as it is critical to
+ // building the support we need for autowrap.
+ return Py_nsISupports::PyObjectFromInterface(pi, NS_GET_IID(nsIInterfaceInfo), PR_FALSE);
+}
+
+static PyObject *PyGetNameForIID(PyObject *self, PyObject *args)
+{
+ PyObject *obIID = NULL;
+ if (!PyArg_ParseTuple(args, "O", &obIID))
+ return NULL;
+
+ nsIInterfaceInfoManager *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsIID iid;
+ if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
+ return NULL;
+
+ char *ret_name = NULL;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetNameForIID(&iid, &ret_name);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+#if PY_MAJOR_VERSION <= 2
+ PyObject *ret = PyString_FromString(ret_name);
+#else
+ PyObject *ret = PyUnicode_FromString(ret_name);
+#endif
+ nsMemory::Free(ret_name);
+ return ret;
+}
+
+static PyObject *PyGetIIDForName(PyObject *self, PyObject *args)
+{
+ char *name;
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ nsIInterfaceInfoManager *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsIID *iid_ret;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetIIDForName(name, &iid_ret);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ PyObject *ret = Py_nsIID::PyObjectFromIID(*iid_ret);
+ nsMemory::Free(iid_ret);
+ return ret;
+}
+
+static PyObject *PyEnumerateInterfaces(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+
+ nsIInterfaceInfoManager *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsCOMPtr<nsIEnumerator> pRet;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->EnumerateInterfaces(getter_AddRefs(pRet));
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ return Py_nsISupports::PyObjectFromInterface(pRet, NS_GET_IID(nsIEnumerator));
+}
+
+// TODO:
+// void autoRegisterInterfaces();
+
+PyMethodDef
+PyMethods_IInterfaceInfoManager[] =
+{
+ { "GetInfoForIID", PyGetInfoForIID, 1},
+ { "getInfoForIID", PyGetInfoForIID, 1},
+ { "GetInfoForName", PyGetInfoForName, 1},
+ { "getInfoForName", PyGetInfoForName, 1},
+ { "GetIIDForName", PyGetIIDForName, 1},
+ { "getIIDForName", PyGetIIDForName, 1},
+ { "GetNameForIID", PyGetNameForIID, 1},
+ { "getNameForIID", PyGetNameForIID, 1},
+ { "EnumerateInterfaces", PyEnumerateInterfaces, 1},
+ { "enumerateInterfaces", PyEnumerateInterfaces, 1},
+ {NULL}
+};
diff --git a/src/libs/xpcom18a4/python/src/PyISimpleEnumerator.cpp b/src/libs/xpcom18a4/python/src/PyISimpleEnumerator.cpp
new file mode 100644
index 00000000..b94d8eb2
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyISimpleEnumerator.cpp
@@ -0,0 +1,202 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <MarkH@ActiveState.com> (original author)
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+#include <nsISimpleEnumerator.h>
+
+static nsISimpleEnumerator *GetI(PyObject *self) {
+ nsIID iid = NS_GET_IID(nsISimpleEnumerator);
+
+ if (!Py_nsISupports::Check(self, iid)) {
+ PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
+ return NULL;
+ }
+ return (nsISimpleEnumerator *)Py_nsISupports::GetI(self);
+}
+
+
+static PyObject *PyHasMoreElements(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":HasMoreElements"))
+ return NULL;
+
+ nsISimpleEnumerator *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsresult r;
+ PRBool more;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->HasMoreElements(&more);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+ return PyInt_FromLong(more);
+}
+
+static PyObject *PyGetNext(PyObject *self, PyObject *args)
+{
+ PyObject *obIID = NULL;
+ if (!PyArg_ParseTuple(args, "|O:GetNext", &obIID))
+ return NULL;
+
+ nsIID iid(NS_GET_IID(nsISupports));
+ if (obIID != NULL && !Py_nsIID::IIDFromPyObject(obIID, &iid))
+ return NULL;
+ nsISimpleEnumerator *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ nsISupports *pRet = nsnull;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pI->GetNext(&pRet);
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+ if (obIID) {
+ nsISupports *temp;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pRet->QueryInterface(iid, (void **)&temp);
+ pRet->Release();
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) ) {
+ return PyXPCOM_BuildPyException(r);
+ }
+ pRet = temp;
+ }
+ PyObject *ret = Py_nsISupports::PyObjectFromInterface(pRet, iid);
+ NS_IF_RELEASE(pRet);
+ return ret;
+}
+
+// A method added for Python performance if you really need
+// it. Allows you to fetch a block of objects in one
+// hit, allowing the loop to remain implemented in C.
+static PyObject *PyFetchBlock(PyObject *self, PyObject *args)
+{
+ PyObject *obIID = NULL;
+ int n_wanted;
+ int n_fetched = 0;
+ if (!PyArg_ParseTuple(args, "i|O:FetchBlock", &n_wanted, &obIID))
+ return NULL;
+
+ nsIID iid(NS_GET_IID(nsISupports));
+ if (obIID != NULL && !Py_nsIID::IIDFromPyObject(obIID, &iid))
+ return NULL;
+ nsISimpleEnumerator *pI = GetI(self);
+ if (pI==NULL)
+ return NULL;
+
+ // We want to fetch with the thread-lock released,
+ // but this means we can not append to the PyList
+ nsISupports **fetched = new nsISupports*[n_wanted];
+ if (fetched==nsnull) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ memset(fetched, 0, sizeof(nsISupports *) * n_wanted);
+ nsresult r = NS_OK;
+ PRBool more;
+ Py_BEGIN_ALLOW_THREADS;
+ for (;n_fetched<n_wanted;) {
+ r = pI->HasMoreElements(&more);
+ if (NS_FAILED(r))
+ break; // this _is_ an error!
+ if (!more)
+ break; // Normal enum end.
+ nsISupports *pNew;
+ r = pI->GetNext(&pNew);
+ if (NS_FAILED(r)) // IS an error
+ break;
+ if (obIID) {
+ nsISupports *temp;
+ r = pNew->QueryInterface(iid, (void **)&temp);
+ pNew->Release();
+ if ( NS_FAILED(r) ) {
+ break;
+ }
+ pNew = temp;
+ }
+ fetched[n_fetched] = pNew;
+ n_fetched++;
+ }
+ Py_END_ALLOW_THREADS;
+ PyObject *ret;
+ if (NS_SUCCEEDED(r)) {
+ ret = PyList_New(n_fetched);
+ if (ret)
+ for (int i=0;i<n_fetched;i++) {
+ PyObject *new_ob = Py_nsISupports::PyObjectFromInterface(fetched[i], iid);
+ NS_IF_RELEASE(fetched[i]);
+ PyList_SET_ITEM(ret, i, new_ob);
+ }
+ } else
+ ret = PyXPCOM_BuildPyException(r);
+
+ if ( ret == NULL ) {
+ // Free the objects we consumed.
+ for (int i=0;i<n_fetched;i++)
+ fetched[i]->Release();
+
+ }
+ delete [] fetched;
+ return ret;
+}
+
+
+struct PyMethodDef
+PyMethods_ISimpleEnumerator[] =
+{
+ { "HasMoreElements", PyHasMoreElements, 1},
+ { "hasMoreElements", PyHasMoreElements, 1},
+ { "GetNext", PyGetNext, 1},
+ { "getNext", PyGetNext, 1},
+ { "FetchBlock", PyFetchBlock, 1},
+ { "fetchBlock", PyFetchBlock, 1},
+ {NULL}
+};
diff --git a/src/libs/xpcom18a4/python/src/PyISupports.cpp b/src/libs/xpcom18a4/python/src/PyISupports.cpp
new file mode 100644
index 00000000..84504038
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyISupports.cpp
@@ -0,0 +1,621 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+#include "nsISupportsPrimitives.h"
+
+static PRInt32 cInterfaces=0;
+static PyObject *g_obFuncMakeInterfaceCount = NULL; // XXX - never released!!!
+
+#ifdef VBOX_DEBUG_LIFETIMES
+# include <iprt/log.h>
+# include <iprt/stream.h>
+
+/*static*/ RTLISTNODE Py_nsISupports::g_List;
+/*static*/ RTONCE Py_nsISupports::g_Once = RTONCE_INITIALIZER;
+/*static*/ RTCRITSECT Py_nsISupports::g_CritSect;
+
+/*static*/ DECLCALLBACK(int32_t)
+Py_nsISupports::initOnceCallback(void *pvUser1)
+{
+ NOREF(pvUser1);
+ RTListInit(&g_List);
+ return RTCritSectInit(&g_CritSect);
+}
+
+/*static*/ void
+Py_nsISupports::dumpList(void)
+{
+ RTOnce(&g_Once, initOnceCallback, NULL);
+ RTCritSectEnter(&g_CritSect);
+
+ uint32_t i = 0;
+ Py_nsISupports *pCur;
+ RTListForEach(&g_List, pCur, Py_nsISupports, m_ListEntry)
+ {
+ nsISupports *pISup = pCur->m_obj;
+ PyXPCOM_LogWarning("#%u: %p iid=%RTuuid obj=%p", i, pCur, &pCur->m_iid, pISup);
+ i++;
+ }
+
+ RTCritSectLeave(&g_CritSect);
+}
+
+/*static*/ void
+Py_nsISupports::dumpListToStdOut()
+{
+ RTOnce(&g_Once, initOnceCallback, NULL);
+ RTCritSectEnter(&g_CritSect);
+
+ uint32_t i = 0;
+ Py_nsISupports *pCur;
+ RTListForEach(&g_List, pCur, Py_nsISupports, m_ListEntry)
+ {
+ nsISupports *pISup = pCur->m_obj;
+ RTPrintf("#%u: %p iid=%RTuuid obj=%p\n", i, pCur, &pCur->m_iid, pISup);
+ i++;
+ }
+
+ RTCritSectLeave(&g_CritSect);
+}
+
+PRInt32
+_PyXPCOM_DumpInterfaces(void)
+{
+ Py_nsISupports::dumpListToStdOut();
+ return NS_OK;
+}
+
+#endif /* _DEBUG_LIFETIMES */
+
+
+
+PyObject *PyObject_FromNSInterface( nsISupports *aInterface,
+ const nsIID &iid,
+ PRBool bMakeNicePyObject /*= PR_TRUE */)
+{
+ return Py_nsISupports::PyObjectFromInterface(aInterface, iid,
+ bMakeNicePyObject);
+}
+
+PRInt32
+_PyXPCOM_GetInterfaceCount(void)
+{
+ return cInterfaces;
+}
+
+#ifndef Py_LIMITED_API
+Py_nsISupports::Py_nsISupports(nsISupports *punk, const nsIID &iid, PyTypeObject *this_type)
+#else
+Py_nsISupports::Py_nsISupports(nsISupports *punk, const nsIID &iid, PyXPCOM_TypeObject *this_type)
+#endif
+{
+#ifndef Py_LIMITED_API
+ ob_type = this_type;
+#else
+ ob_type = this_type->m_pTypeObj;
+ m_pMyTypeObj = this_type;
+#endif
+ m_obj = punk;
+ m_iid = iid;
+ // refcnt of object managed by caller.
+ PR_AtomicIncrement(&cInterfaces);
+ PyXPCOM_DLLAddRef();
+#if 1 /* VBox: Must use for 3.9+, includes _Py_NewReferences. Works for all older versions too. @bugref{10079} */
+ PyObject_Init(this, ob_type);
+#else
+ _Py_NewReference(this);
+#endif
+
+#ifdef VBOX_DEBUG_LIFETIMES
+ RTOnce(&g_Once, initOnceCallback, NULL);
+ RTCritSectEnter(&g_CritSect);
+ RTListAppend(&g_List, &m_ListEntry);
+ RTCritSectLeave(&g_CritSect);
+ PyXPCOM_LogWarning("Creating %p: iid=%RTuuid obj=%p", this, &m_iid, punk);
+#endif
+}
+
+Py_nsISupports::~Py_nsISupports()
+{
+#ifdef VBOX_DEBUG_LIFETIMES
+ RTCritSectEnter(&g_CritSect);
+ nsISupports *punk = m_obj;
+ RTListNodeRemove(&m_ListEntry);
+ RTCritSectLeave(&g_CritSect);
+ PyXPCOM_LogWarning("Destroying %p: iid=%RTuuid obj=%p", this, &m_iid, punk);
+#endif
+
+ SafeRelease(this);
+ PR_AtomicDecrement(&cInterfaces);
+ PyXPCOM_DLLRelease();
+}
+
+/*static*/ nsISupports *
+Py_nsISupports::GetI(PyObject *self, nsIID *ret_iid)
+{
+ if (self==NULL) {
+ PyErr_SetString(PyExc_ValueError, "The Python object is invalid");
+ return NULL;
+ }
+ Py_nsISupports *pis = (Py_nsISupports *)self;
+ if (pis->m_obj==NULL) {
+ // This should never be able to happen.
+ PyErr_SetString(PyExc_ValueError, "Internal Error - The XPCOM object has been released.");
+ return NULL;
+ }
+ if (ret_iid)
+ *ret_iid = pis->m_iid;
+ return pis->m_obj;
+}
+
+/*static*/ void
+Py_nsISupports::SafeRelease(Py_nsISupports *ob)
+{
+ if (!ob)
+ return;
+ if (ob->m_obj)
+ {
+ Py_BEGIN_ALLOW_THREADS;
+ ob->m_obj = nsnull;
+ Py_END_ALLOW_THREADS;
+ }
+}
+
+/* virtual */ PyObject *
+Py_nsISupports::getattr(const char *name)
+{
+ if (strcmp(name, "IID")==0)
+ return Py_nsIID::PyObjectFromIID( m_iid );
+
+ // Support for __unicode__ until we get a tp_unicode slot.
+ if (strcmp(name, "__unicode__")==0) {
+ nsresult rv;
+ PRUnichar *val = NULL;
+ Py_BEGIN_ALLOW_THREADS;
+ { // scope to kill pointer while thread-lock released.
+ nsCOMPtr<nsISupportsString> ss( do_QueryInterface(m_obj, &rv ));
+ if (NS_SUCCEEDED(rv))
+ rv = ss->ToString(&val);
+ } // end-scope
+ Py_END_ALLOW_THREADS;
+ PyObject *ret = NS_FAILED(rv) ?
+ PyXPCOM_BuildPyException(rv) :
+ PyObject_FromNSString(val);
+ if (val) nsMemory::Free(val);
+ return ret;
+ }
+#ifndef Py_LIMITED_API
+ PyXPCOM_TypeObject *this_type = (PyXPCOM_TypeObject *)ob_type;
+#else
+ PyXPCOM_TypeObject *this_type = m_pMyTypeObj;
+#endif
+#if PY_MAJOR_VERSION <= 2
+ return Py_FindMethodInChain(&this_type->chain, this, (char *)name);
+#else
+ PyMethodChain *chain = &this_type->chain;
+ if (name[0] == '_' && name[1] == '_') {
+# ifndef Py_LIMITED_API /** @todo ? */
+ if (!strcmp(name, "__doc__")) {
+ const char *doc = ob_type->tp_doc;
+ if (doc)
+ return PyUnicode_FromString(doc);
+ }
+# endif
+ }
+ while (chain) {
+ PyMethodDef *ml = chain->methods;
+ for (; ml->ml_name; ml++) {
+ if (!strcmp(name, ml->ml_name))
+ return PyCFunction_New(ml, this);
+ }
+ chain = chain->link;
+ }
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+#endif
+}
+
+/* virtual */ int
+Py_nsISupports::setattr(const char *name, PyObject *v)
+{
+ char buf[128];
+#ifdef VBOX
+ snprintf(buf, sizeof(buf), "%s has read-only attributes", PyXPCOM_ObTypeName(this) );
+#else
+ sprintf(buf, "%s has read-only attributes", PyXPCOM_ObTypeName(this) );
+#endif
+ PyErr_SetString(PyExc_TypeError, buf);
+ return -1;
+}
+
+/*static*/ Py_nsISupports *
+Py_nsISupports::Constructor(nsISupports *pInitObj, const nsIID &iid)
+{
+ return new Py_nsISupports(pInitObj,
+ iid,
+ type);
+}
+
+PRBool
+Py_nsISupports::InterfaceFromPyISupports(PyObject *ob,
+ const nsIID &iid,
+ nsISupports **ppv)
+{
+ nsISupports *pis;
+ PRBool rc = PR_FALSE;
+ if ( !Check(ob) )
+ {
+ PyErr_Format(PyExc_TypeError, "Objects of type '%s' can not be used as COM objects", PyXPCOM_ObTypeName(ob));
+ goto done;
+ }
+ nsIID already_iid;
+ pis = GetI(ob, &already_iid);
+ if ( !pis )
+ goto done; /* exception was set by GetI() */
+ /* note: we don't (yet) explicitly hold a reference to pis */
+ if (iid.Equals(Py_nsIID_NULL)) {
+ // a bit of a hack - we are asking for the arbitary interface
+ // wrapped by this object, not some other specific interface -
+ // so no QI, just an AddRef();
+ Py_BEGIN_ALLOW_THREADS
+ pis->AddRef();
+ Py_END_ALLOW_THREADS
+ *ppv = pis;
+ } else {
+ // specific interface requested - if it is not already the
+ // specific interface, QI for it and discard pis.
+ if (iid.Equals(already_iid)) {
+ *ppv = pis;
+ pis->AddRef();
+ } else {
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS
+ r = pis->QueryInterface(iid, (void **)ppv);
+ Py_END_ALLOW_THREADS
+ if ( NS_FAILED(r) )
+ {
+ PyXPCOM_BuildPyException(r);
+ goto done;
+ }
+ /* note: the QI added a ref for the return value */
+ }
+ }
+ rc = PR_TRUE;
+done:
+ return rc;
+}
+
+PRBool
+Py_nsISupports::InterfaceFromPyObject(PyObject *ob,
+ const nsIID &iid,
+ nsISupports **ppv,
+ PRBool bNoneOK,
+ PRBool bTryAutoWrap /* = PR_TRUE */)
+{
+ if ( ob == NULL )
+ {
+ // don't overwrite an error message
+ if ( !PyErr_Occurred() )
+ PyErr_SetString(PyExc_TypeError, "The Python object is invalid");
+ return PR_FALSE;
+ }
+ if ( ob == Py_None )
+ {
+ if ( bNoneOK )
+ {
+ *ppv = NULL;
+ return PR_TRUE;
+ }
+ else
+ {
+ PyErr_SetString(PyExc_TypeError, "None is not a invalid interface object in this context");
+ return PR_FALSE;
+ }
+ }
+
+ // support nsIVariant
+ if (iid.Equals(NS_GET_IID(nsIVariant)) || iid.Equals(NS_GET_IID(nsIWritableVariant))) {
+ // Check it is not already nsIVariant
+ if (PyObject_HasAttrString(ob, "__class__")) {
+ PyObject *sub_ob = PyObject_GetAttrString(ob, "_comobj_");
+ if (sub_ob==NULL) {
+ PyErr_Clear();
+ } else {
+ if (InterfaceFromPyISupports(sub_ob, iid, ppv)) {
+ Py_DECREF(sub_ob);
+ return PR_TRUE;
+ }
+ PyErr_Clear();
+ Py_DECREF(sub_ob);
+ }
+ }
+ nsresult nr = PyObject_AsVariant(ob, (nsIVariant **)ppv);
+ if (NS_FAILED(nr)) {
+ PyXPCOM_BuildPyException(nr);
+ return PR_FALSE;
+ }
+ NS_ASSERTION(ppv != nsnull, "PyObject_AsVariant worked but gave null!");
+ return PR_TRUE;
+ }
+ // end of variant support.
+
+ if (PyObject_HasAttrString(ob, "__class__")) {
+ // Get the _comobj_ attribute
+ PyObject *use_ob = PyObject_GetAttrString(ob, "_comobj_");
+ if (use_ob==NULL) {
+ PyErr_Clear();
+ if (bTryAutoWrap)
+ // Try and auto-wrap it - errors will leave Py exception set,
+ return PyXPCOM_XPTStub::AutoWrapPythonInstance(ob, iid, ppv);
+ PyErr_SetString(PyExc_TypeError, "The Python instance can not be converted to an XPCOM object");
+ return PR_FALSE;
+ } else
+ ob = use_ob;
+
+ } else {
+ Py_INCREF(ob);
+ }
+ PRBool rc = InterfaceFromPyISupports(ob, iid, ppv);
+ Py_DECREF(ob);
+ return rc;
+}
+
+
+// Interface conversions
+/*static*/void
+#ifndef Py_LIMITED_API
+Py_nsISupports::RegisterInterface( const nsIID &iid, PyTypeObject *t)
+#else
+Py_nsISupports::RegisterInterface( const nsIID &iid, PyXPCOM_TypeObject *t)
+#endif
+{
+ if (mapIIDToType==NULL)
+ mapIIDToType = PyDict_New();
+
+ if (mapIIDToType) {
+ PyObject *key = Py_nsIID::PyObjectFromIID(iid);
+ if (key)
+ PyDict_SetItem(mapIIDToType, key, (PyObject *)t);
+ Py_XDECREF(key);
+ }
+}
+
+/*static */PyObject *
+Py_nsISupports::PyObjectFromInterface(nsISupports *pis,
+ const nsIID &riid,
+ PRBool bMakeNicePyObject, /* = PR_TRUE */
+ PRBool bIsInternalCall /* = PR_FALSE */)
+{
+ // Quick exit.
+ if (pis==NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ if (!bIsInternalCall) {
+#ifdef NS_DEBUG
+ nsISupports *queryResult = nsnull;
+ Py_BEGIN_ALLOW_THREADS;
+ pis->QueryInterface(riid, (void **)&queryResult);
+ Py_END_ALLOW_THREADS;
+ NS_ASSERTION(queryResult == pis, "QueryInterface needed");
+ NS_IF_RELEASE(queryResult);
+#endif
+ }
+
+#ifndef Py_LIMITED_API
+ PyTypeObject *createType = NULL;
+#else
+ PyXPCOM_TypeObject *createType = NULL;
+#endif
+ // If the IID is for nsISupports, dont bother with
+ // a map lookup as we know the type!
+ if (!riid.Equals(NS_GET_IID(nsISupports))) {
+ // Look up the map
+ PyObject *obiid = Py_nsIID::PyObjectFromIID(riid);
+ if (!obiid) return NULL;
+
+ if (mapIIDToType != NULL)
+#ifndef Py_LIMITED_API
+ createType = (PyTypeObject *)PyDict_GetItem(mapIIDToType, obiid);
+#else
+ createType = (PyXPCOM_TypeObject *)PyDict_GetItem(mapIIDToType, obiid);
+#endif
+ Py_DECREF(obiid);
+ }
+ if (createType==NULL)
+ createType = Py_nsISupports::type;
+#ifndef Py_LIMITED_API
+ // Check it is indeed one of our types.
+ if (!PyXPCOM_TypeObject::IsType(createType)) {
+ PyErr_SetString(PyExc_RuntimeError, "The type map is invalid");
+ return NULL;
+ }
+ // we can now safely cast the thing to a PyComTypeObject and use it
+ PyXPCOM_TypeObject *myCreateType = (PyXPCOM_TypeObject *)createType;
+#else /* Since the mapIIDToType is only updated by us, there should be no need for the above. */
+ PyXPCOM_TypeObject * const myCreateType = createType;
+#endif
+ if (myCreateType->ctor==NULL) {
+ PyErr_SetString(PyExc_TypeError, "The type does not declare a PyCom constructor");
+ return NULL;
+ }
+
+ Py_nsISupports *ret = (*myCreateType->ctor)(pis, riid);
+#ifdef _DEBUG_LIFETIMES
+ PyXPCOM_LogF("XPCOM Object created at 0x%0xld, nsISupports at 0x%0xld",
+ ret, ret->m_obj);
+#endif
+ if (ret && bMakeNicePyObject)
+ return MakeDefaultWrapper(ret, riid);
+ return ret;
+}
+
+// Call back into Python, passing a raw nsIInterface object, getting back
+// the object to actually pass to Python.
+PyObject *
+Py_nsISupports::MakeDefaultWrapper(PyObject *pyis,
+ const nsIID &iid)
+{
+ NS_PRECONDITION(pyis, "NULL pyobject!");
+ PyObject *obIID = NULL;
+ PyObject *args = NULL;
+ PyObject *mod = NULL;
+ PyObject *ret = NULL;
+
+ obIID = Py_nsIID::PyObjectFromIID(iid);
+ if (obIID==NULL)
+ goto done;
+
+ if (g_obFuncMakeInterfaceCount==NULL) {
+ PyObject *mod = PyImport_ImportModule("xpcom.client");
+ if (mod)
+ g_obFuncMakeInterfaceCount = PyObject_GetAttrString(mod, "MakeInterfaceResult");
+ Py_XDECREF(mod);
+ }
+ if (g_obFuncMakeInterfaceCount==NULL) goto done;
+
+ args = Py_BuildValue("OO", pyis, obIID);
+ if (args==NULL) goto done;
+ ret = PyEval_CallObject(g_obFuncMakeInterfaceCount, args);
+done:
+ if (PyErr_Occurred()) {
+ NS_ABORT_IF_FALSE(ret==NULL, "Have an error, but also a return val!");
+ PyXPCOM_LogError("Creating an interface object to be used as a result failed\n");
+ PyErr_Clear();
+ }
+ Py_XDECREF(mod);
+ Py_XDECREF(args);
+ Py_XDECREF(obIID);
+ if (ret==NULL) // eek - error - return the original with no refcount mod.
+ ret = pyis;
+ else
+ // no error - decref the old object
+ Py_DECREF(pyis);
+ // return our obISupports. If NULL, we are really hosed and nothing we can do.
+ return ret;
+}
+
+// @pymethod <o Py_nsISupports>|Py_nsISupports|QueryInterface|Queries an object for a specific interface.
+PyObject *
+Py_nsISupports::QueryInterface(PyObject *self, PyObject *args)
+{
+ PyObject *obiid;
+ int bWrap = 1;
+ // @pyparm IID|iid||The IID requested.
+ // @rdesc The result is always a <o Py_nsISupports> object.
+ // Any error (including E_NOINTERFACE) will generate a <o com_error> exception.
+ if (!PyArg_ParseTuple(args, "O|i:QueryInterface", &obiid, &bWrap))
+ return NULL;
+
+ nsIID iid;
+ if (!Py_nsIID::IIDFromPyObject(obiid, &iid))
+ return NULL;
+
+ nsISupports *pMyIS = GetI(self);
+ if (pMyIS==NULL) return NULL;
+
+ // Optimization, If we already wrap the IID, just return
+ // ourself.
+ if (!bWrap && iid.Equals(((Py_nsISupports *)self)->m_iid)) {
+ Py_INCREF(self);
+ return self;
+ }
+
+ nsCOMPtr<nsISupports> pis;
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = pMyIS->QueryInterface(iid, getter_AddRefs(pis));
+ Py_END_ALLOW_THREADS;
+
+ /* Note that this failure may include E_NOINTERFACE */
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ /* Return a type based on the IID (with no extra ref) */
+ return ((Py_nsISupports *)self)->MakeInterfaceResult(pis, iid, (PRBool)bWrap);
+}
+
+
+#ifdef VBOX
+static PyObject *
+QueryErrorObject(PyObject *self, PyObject *args)
+{
+ nsresult rc = 0;
+
+ if (!PyArg_ParseTuple(args, "i", &rc))
+ return NULL;
+
+ return PyXPCOM_BuildErrorMessage(rc);
+}
+#endif
+
+// @object Py_nsISupports|The base object for all PythonCOM objects. Wraps a COM nsISupports interface.
+/*static*/ struct PyMethodDef
+Py_nsISupports::methods[] =
+{
+ { "queryInterface", Py_nsISupports::QueryInterface, 1, "Queries the object for an interface."},
+ { "QueryInterface", Py_nsISupports::QueryInterface, 1, "An alias for queryInterface."},
+#ifdef VBOX
+ { "QueryErrorObject", QueryErrorObject, 1, "Query an error object for given status code."},
+#endif
+ {NULL}
+};
+
+/*static*/void Py_nsISupports::InitType(void)
+{
+ type = new PyXPCOM_TypeObject(
+ "nsISupports",
+ NULL,
+ sizeof(Py_nsISupports),
+ methods,
+ Constructor);
+}
+
+PyXPCOM_TypeObject *Py_nsISupports::type = NULL;
+PyObject *Py_nsISupports::mapIIDToType = NULL;
diff --git a/src/libs/xpcom18a4/python/src/PyIVariant.cpp b/src/libs/xpcom18a4/python/src/PyIVariant.cpp
new file mode 100644
index 00000000..cd9f79c4
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyIVariant.cpp
@@ -0,0 +1,231 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * Mark Hammond.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+// This code is part of the XPCOM extensions for Python.
+//
+// Written April 2002
+
+#include "PyXPCOM_std.h"
+#include "nsIVariant.h"
+
+// Prevents us needing to use an nsIScriptableInputStream
+// (and even that can't read binary data!!!)
+
+static nsIVariant *GetI(PyObject *self) {
+ nsIID iid = NS_GET_IID(nsIVariant);
+
+ if (!Py_nsISupports::Check(self, iid)) {
+ PyErr_SetString(PyExc_TypeError, "This object is not the correct interface");
+ return NULL;
+ }
+ return (nsIVariant *)Py_nsISupports::GetI(self);
+}
+
+static PyObject *MyBool( PRBool v) {
+ PyObject *ret = v ? Py_True : Py_False;
+ Py_INCREF(ret);
+ return ret;
+}
+static PyObject *MyChar( char c) {
+#if PY_MAJOR_VERSION <= 2
+ return PyString_FromStringAndSize(&c, 1);
+#else
+ return PyUnicode_FromStringAndSize(&c, 1);
+#endif
+}
+static PyObject *MyUChar( PRUnichar c) {
+ return PyObject_FromNSString( &c, 1);
+}
+static PyObject *MyUnicode( PRUnichar *p) {
+ return PyObject_FromNSString(p);
+}
+
+#define GET_SIMPLE(Type, FuncGet, FuncConvert) \
+static PyObject *FuncGet(PyObject *self, PyObject *args) { \
+ nsIVariant *pI = GetI(self); \
+ if (pI==NULL) return NULL; \
+ if (!PyArg_ParseTuple(args, ":" #FuncGet)) return NULL; \
+ Type t; \
+ nsresult nr = pI->FuncGet(&t); \
+ if (NS_FAILED(nr)) return PyXPCOM_BuildPyException(nr); \
+ return FuncConvert(t); \
+}
+
+#define GET_ALLOCATED(Type, FuncGet, FuncConvert, FuncFree) \
+static PyObject *FuncGet(PyObject *self, PyObject *args) { \
+ nsIVariant *pI = GetI(self); \
+ if (pI==NULL) return NULL; \
+ if (!PyArg_ParseTuple(args, ":" #FuncGet)) return NULL; \
+ Type t; \
+ nsresult nr = pI->FuncGet(&t); \
+ if (NS_FAILED(nr)) return PyXPCOM_BuildPyException(nr); \
+ PyObject *ret = FuncConvert(t); \
+ FuncFree(t); \
+ return ret; \
+}
+
+#define GET_ALLOCATED_SIZE(Type, FuncGet, FuncConvert, FuncFree) \
+static PyObject *FuncGet(PyObject *self, PyObject *args) { \
+ nsIVariant *pI = GetI(self); \
+ if (pI==NULL) return NULL; \
+ if (!PyArg_ParseTuple(args, ":" #FuncGet)) return NULL; \
+ Type t; PRUint32 size; \
+ nsresult nr = pI->FuncGet(&size, &t); \
+ if (NS_FAILED(nr)) return PyXPCOM_BuildPyException(nr); \
+ PyObject *ret = FuncConvert(t, size); \
+ FuncFree(t); \
+ return ret; \
+}
+
+GET_SIMPLE(PRUint8, GetAsInt8, PyInt_FromLong)
+GET_SIMPLE(PRUint8, GetAsUint8, PyInt_FromLong)
+GET_SIMPLE(PRInt16, GetAsInt16, PyInt_FromLong)
+GET_SIMPLE(PRUint16, GetAsUint16, PyInt_FromLong)
+GET_SIMPLE(PRInt32, GetAsInt32, PyInt_FromLong)
+GET_SIMPLE(PRUint32, GetAsUint32, PyInt_FromLong)
+GET_SIMPLE(PRInt64, GetAsInt64, PyLong_FromLongLong)
+GET_SIMPLE(PRUint64, GetAsUint64, PyLong_FromUnsignedLongLong)
+GET_SIMPLE(float, GetAsFloat, PyFloat_FromDouble)
+GET_SIMPLE(double, GetAsDouble, PyFloat_FromDouble)
+GET_SIMPLE(PRBool, GetAsBool, MyBool)
+GET_SIMPLE(char, GetAsChar, MyChar)
+GET_SIMPLE(PRUnichar, GetAsWChar, MyUChar)
+GET_SIMPLE(nsIID, GetAsID, Py_nsIID::PyObjectFromIID)
+
+#if PY_MAJOR_VERSION <= 2
+GET_ALLOCATED(char *, GetAsString, PyString_FromString, nsMemory::Free)
+#else
+GET_ALLOCATED(char *, GetAsString, PyUnicode_FromString, nsMemory::Free)
+#endif
+GET_ALLOCATED(PRUnichar *, GetAsWString, MyUnicode, nsMemory::Free)
+#if PY_MAJOR_VERSION <= 2
+GET_ALLOCATED_SIZE(char *, GetAsStringWithSize, PyString_FromStringAndSize, nsMemory::Free)
+#else
+GET_ALLOCATED_SIZE(char *, GetAsStringWithSize, PyUnicode_FromStringAndSize, nsMemory::Free)
+#endif
+GET_ALLOCATED_SIZE(PRUnichar *, GetAsWStringWithSize, PyObject_FromNSString, nsMemory::Free)
+
+static PyObject *GetAsInterface(PyObject *self, PyObject *args) {
+ nsIVariant *pI = GetI(self);
+ if (pI==NULL) return NULL;
+ if (!PyArg_ParseTuple(args, ":GetAsInterface")) return NULL;
+ nsCOMPtr<nsISupports> p;
+ nsIID *iid;
+ nsresult nr = pI->GetAsInterface(&iid, getter_AddRefs(p));
+ if (NS_FAILED(nr)) return PyXPCOM_BuildPyException(nr);
+ return Py_nsISupports::PyObjectFromInterface(p, *iid);
+}
+
+static PyObject *GetAsISupports(PyObject *self, PyObject *args) {
+ nsIVariant *pI = GetI(self);
+ if (pI==NULL) return NULL;
+ if (!PyArg_ParseTuple(args, ":GetAsInterface")) return NULL;
+ nsCOMPtr<nsISupports> p;
+ nsIID *iid;
+ nsresult nr = pI->GetAsInterface(&iid, getter_AddRefs(p));
+ if (NS_FAILED(nr)) return PyXPCOM_BuildPyException(nr);
+ return Py_nsISupports::PyObjectFromInterface(p, *iid);
+}
+
+extern PyObject *PyObject_FromVariantArray( Py_nsISupports*, nsIVariant *v);
+
+static PyObject *GetAsArray(PyObject *self, PyObject *args) {
+ nsIVariant *pI = GetI(self);
+ if (pI==NULL) return NULL;
+ if (!PyArg_ParseTuple(args, ":GetAsArray")) return NULL;
+ return PyObject_FromVariantArray((Py_nsISupports *)self, pI);
+}
+
+static PyObject *Get(PyObject *self, PyObject *args) {
+ nsIVariant *pI = GetI(self);
+ if (pI==NULL) return NULL;
+ if (!PyArg_ParseTuple(args, ":Get")) return NULL;
+ return PyObject_FromVariant((Py_nsISupports *)self, pI);
+}
+
+struct PyMethodDef
+PyMethods_IVariant[] =
+{
+ { "getAsInt8", GetAsInt8, 1},
+ { "getAsUint8", GetAsUint8, 1},
+ { "getAsInt16", GetAsInt16, 1},
+ { "getAsUint16", GetAsUint16, 1},
+ { "getAsInt32", GetAsInt32, 1},
+ { "getAsUint32", GetAsUint32, 1},
+ { "getAsInt64", GetAsInt64, 1},
+ { "getAsUint64", GetAsUint64, 1},
+ { "getAsFloat", GetAsFloat, 1},
+ { "getAsDouble", GetAsDouble, 1},
+ { "getAsBool", GetAsBool, 1},
+ { "getAsChar", GetAsChar, 1},
+ { "getAsWChar", GetAsWChar, 1},
+ { "getAsString", GetAsString, 1},
+ { "getAsWString", GetAsWString, 1},
+ { "getAsStringWithSize", GetAsStringWithSize, 1},
+ { "getAsWStringWithSize", GetAsWStringWithSize, 1},
+ { "getAsISupports", GetAsISupports, 1},
+ { "getAsInterface", GetAsInterface, 1},
+ { "getAsArray", GetAsArray, 1},
+ { "getAsID", GetAsID, 1},
+ { "get", Get, 1},
+ {NULL}
+};
+
+PyObject *
+Py_nsIVariant::getattr(const char *name)
+{
+
+ PyObject *ret = NULL;
+ if (strcmp(name, "dataType")==0) {
+ nsIVariant *pI = ::GetI(this);
+ if (pI) {
+ PRUint16 dt;
+ nsresult nr = pI->GetDataType(&dt);
+ if (NS_FAILED(nr)) return PyXPCOM_BuildPyException(nr);
+ ret = PyInt_FromLong(dt);
+ }
+ } else {
+ ret = Py_nsISupports::getattr(name);
+ }
+ return ret;
+}
+
+int
+Py_nsIVariant::setattr(const char *name, PyObject *v)
+{
+ return Py_nsISupports::setattr(name, v);
+}
diff --git a/src/libs/xpcom18a4/python/src/PyXPCOM.h b/src/libs/xpcom18a4/python/src/PyXPCOM.h
new file mode 100644
index 00000000..91bc8d12
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyXPCOM.h
@@ -0,0 +1,1036 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+// PyXPCOM.h - the main header file for the Python XPCOM support.
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#ifndef __PYXPCOM_H__
+#define __PYXPCOM_H__
+
+#include "nsIAllocator.h"
+#include "nsIWeakReference.h"
+#include "nsIInterfaceInfoManager.h"
+#include "nsIClassInfo.h"
+#include "nsIComponentManager.h"
+#include "nsIComponentManagerObsolete.h"
+#include "nsIServiceManager.h"
+#include "nsIInputStream.h"
+#include "nsIVariant.h"
+#include "nsIModule.h"
+
+#include "nsXPIDLString.h"
+#include "nsCRT.h"
+#include "xptcall.h"
+#include "xpt_xdr.h"
+
+#ifdef VBOX_DEBUG_LIFETIMES
+# include <iprt/critsect.h>
+# include <iprt/list.h>
+# include <iprt/once.h>
+#endif
+
+#ifdef HAVE_LONG_LONG
+ // Mozilla also defines this - we undefine it to
+ // prevent a compiler warning.
+# undef HAVE_LONG_LONG
+#endif // HAVE_LONG_LONG
+
+#ifdef _POSIX_C_SOURCE // Ditto here
+# undef _POSIX_C_SOURCE
+#endif // _POSIX_C_SOURCE
+
+#ifdef VBOX_PYXPCOM
+// unfortunatelly, if SOLARIS is defined Python porting layer
+// defines gethostname() in invalid fashion what kills compilation
+# ifdef SOLARIS
+# undef SOLARIS
+# define SOLARIS_WAS_DEFINED
+# endif
+
+// Python.h/pyconfig.h redefines _XOPEN_SOURCE on some hosts
+# ifdef _XOPEN_SOURCE
+# define VBOX_XOPEN_SOURCE_DEFINED _XOPEN_SOURCE
+# undef _XOPEN_SOURCE
+# endif
+
+#endif /* VBOX_PYXPCOM */
+
+#include <Python.h>
+
+#ifdef VBOX_PYXPCOM
+
+# ifdef SOLARIS_WAS_DEFINED
+# define SOLARIS
+# undef SOLARIS_WAS_DEFINED
+# endif
+
+// restore the old value of _XOPEN_SOURCE if not defined by Python.h/pyconfig.h
+# if !defined(_XOPEN_SOURCE) && defined(VBOX_XOPEN_SOURCE_DEFINED)
+# define _XOPEN_SOURCE VBOX_XOPEN_SOURCE_DEFINED
+# endif
+# undef VBOX_XOPEN_SOURCE_DEFINED
+
+# if (PY_VERSION_HEX <= 0x02040000)
+// although in more recent versions of Python this type is ssize_t, earlier
+// it was used as int
+typedef int Py_ssize_t;
+# endif
+
+# if (PY_VERSION_HEX <= 0x02030000)
+// this one not defined before
+inline PyObject *PyBool_FromLong(long ok)
+{
+ PyObject *result;
+ if (ok)
+ result = Py_True;
+ else
+ result = Py_False;
+ Py_INCREF(result);
+ return result;
+}
+# endif
+
+# if PY_MAJOR_VERSION >= 3
+# define PyInt_FromLong(l) PyLong_FromLong(l)
+# define PyInt_Check(o) PyLong_Check(o)
+# define PyInt_AsLong(o) PyLong_AsLong(o)
+# define PyNumber_Int(o) PyNumber_Long(o)
+# if !defined(Py_LIMITED_API) && PY_VERSION_HEX <= 0x03030000 /* 3.3 added PyUnicode_AsUTF8AndSize */
+# ifndef PyUnicode_AsUTF8
+# define PyUnicode_AsUTF8(o) _PyUnicode_AsString(o)
+# endif
+# ifndef PyUnicode_AsUTF8AndSize
+# define PyUnicode_AsUTF8AndSize(o,s) _PyUnicode_AsStringAndSize(o,s)
+# endif
+# endif
+typedef struct PyMethodChain
+{
+ PyMethodDef *methods;
+ struct PyMethodChain *link;
+} PyMethodChain;
+# endif
+
+#endif /* VBOX_PYXPCOM */
+
+#ifdef BUILD_PYXPCOM
+ /* We are building the main dll */
+# define PYXPCOM_EXPORT NS_EXPORT
+#else
+ /* This module uses the dll */
+# define PYXPCOM_EXPORT NS_IMPORT
+#endif // BUILD_PYXPCOM
+
+// An IID we treat as NULL when passing as a reference.
+extern PYXPCOM_EXPORT nsIID Py_nsIID_NULL;
+
+class Py_nsISupports;
+
+
+/** @name VBox limited API hacks:
+ * @{ */
+#ifndef Py_LIMITED_API
+
+# define PyXPCOM_ObTypeName(obj) (Py_TYPE(obj)->tp_name)
+
+#else /* Py_LIMITED_API */
+
+# if PY_VERSION_HEX <= 0x03030000
+# error "Py_LIMITED_API mode only works for Python 3.3 and higher."
+# endif
+
+const char *PyXPCOMGetObTypeName(PyTypeObject *pTypeObj);
+# define PyXPCOM_ObTypeName(obj) PyXPCOMGetObTypeName(Py_TYPE(obj))
+
+# if Py_LIMITED_API < 0x030A0000
+/* Note! While we should not technically be using PyUnicode_AsUTF8AndSize, it was
+ made part of the limited API in 3.10 (see https://bugs.python.org/issue41784 and
+ https://github.com/python/cpython/commit/a05195ac61f1908ac5990cccb5aa82442bdaf15d). */
+extern "C" PyAPI_FUNC(const char *) PyUnicode_AsUTF8AndSize(PyObject *, Py_ssize_t *);
+# endif
+
+/* PyUnicode_AsUTF8 is just PyUnicode_AsUTF8AndSize without returning a size. */
+# define PyUnicode_AsUTF8(o) PyUnicode_AsUTF8AndSize(o, NULL)
+
+DECLINLINE(int) PyRun_SimpleString(const char *pszCode)
+{
+ /* Get the main mode dictionary: */
+ PyObject *pMainMod = PyImport_AddModule("__main__");
+ if (pMainMod) {
+ PyObject *pMainModDict = PyModule_GetDict(pMainMod);
+
+ /* Compile and run the code. */
+ PyObject *pCodeObject = Py_CompileString(pszCode, "PyXPCOM", Py_file_input);
+ if (pCodeObject) {
+ PyObject *pResult = PyEval_EvalCode(pCodeObject, pMainModDict, pMainModDict);
+ Py_DECREF(pCodeObject);
+ if (pResult) {
+ Py_DECREF(pResult);
+ return 0;
+ }
+ PyErr_Print();
+ }
+ }
+ return -1;
+}
+
+DECLINLINE(PyObject *) PyTuple_GET_ITEM(PyObject *pTuple, Py_ssize_t idx)
+{
+ return PyTuple_GetItem(pTuple, idx);
+}
+
+DECLINLINE(int) PyTuple_SET_ITEM(PyObject *pTuple, Py_ssize_t idx, PyObject *pItem)
+{
+ int rc = PyTuple_SetItem(pTuple, idx, pItem); /* Steals pItem ref, just like PyTuple_SET_ITEM. */
+ Assert(rc == 0);
+ return rc;
+}
+
+DECLINLINE(int) PyList_SET_ITEM(PyObject *pList, Py_ssize_t idx, PyObject *pItem)
+{
+ int rc = PyList_SetItem(pList, idx, pItem); /* Steals pItem ref, just like PyList_SET_ITEM. */
+ Assert(rc == 0);
+ return rc;
+}
+
+DECLINLINE(Py_ssize_t) PyBytes_GET_SIZE(PyObject *pBytes)
+{
+ return PyBytes_Size(pBytes);
+}
+
+DECLINLINE(const char *) PyBytes_AS_STRING(PyObject *pBytes)
+{
+ return PyBytes_AsString(pBytes);
+}
+
+DECLINLINE(Py_ssize_t) PyUnicode_GET_SIZE(PyObject *pUnicode)
+{
+ /* Note! Currently only used for testing for zero or 1 codepoints, so we don't
+ really need to deal with the different way these two treats surrogate pairs. */
+# if Py_LIMITED_API >= 0x03030000
+ return PyUnicode_GetLength(pUnicode);
+# else
+ return PyUnicode_GetSize(pUnicode);
+# endif
+}
+
+# define PyObject_CheckBuffer(pAllegedBuffer) PyObject_CheckReadBuffer(pAllegedBuffer)
+
+# include <iprt/asm.h>
+DECLINLINE(Py_hash_t) _Py_HashPointer(void *p)
+{
+ Py_hash_t uHash = (Py_hash_t)RT_CONCAT(ASMRotateRightU,ARCH_BITS)((uintptr_t)p, 4);
+ return uHash != -1 ? uHash : -2;
+}
+
+#endif /* Py_LIMITED_API */
+/** @} */
+
+
+/*************************************************************************
+**************************************************************************
+
+ Error and exception related function.
+
+**************************************************************************
+*************************************************************************/
+
+#define NS_PYXPCOM_NO_SUCH_METHOD \
+ NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_PYXPCOM, 0)
+
+// The exception object (loaded from the xpcom .py code)
+extern PYXPCOM_EXPORT PyObject *PyXPCOM_Error;
+
+// Client related functions - generally called by interfaces before
+// they return NULL back to Python to indicate the error.
+// All these functions return NULL so interfaces can generally
+// just "return PyXPCOM_BuildPyException(hr, punk, IID_IWhatever)"
+PYXPCOM_EXPORT PyObject *PyXPCOM_BuildPyException(nsresult res);
+
+#ifdef VBOX
+// Build human readable error message out of XPCOM error
+PYXPCOM_EXPORT PyObject *PyXPCOM_BuildErrorMessage(nsresult r);
+#endif
+
+// Used in gateways to handle the current Python exception
+// NOTE: this function assumes it is operating within the Python context
+PYXPCOM_EXPORT nsresult PyXPCOM_SetCOMErrorFromPyException();
+
+// Write current exception and traceback to a string.
+PYXPCOM_EXPORT PRBool PyXPCOM_FormatCurrentException(nsCString &streamout);
+// Write specified exception and traceback to a string.
+PYXPCOM_EXPORT PRBool PyXPCOM_FormatGivenException(nsCString &streamout,
+ PyObject *exc_typ, PyObject *exc_val,
+ PyObject *exc_tb);
+
+// A couple of logging/error functions. These probably end up
+// being written to the console service.
+
+// Log a warning for the user - something at runtime
+// they may care about, but nothing that prevents us actually
+// working.
+// As it's designed for user error/warning, it exists in non-debug builds.
+PYXPCOM_EXPORT void PyXPCOM_LogWarning(const char *fmt, ...);
+
+// Log an error for the user - something that _has_ prevented
+// us working. This is probably accompanied by a traceback.
+// As it's designed for user error/warning, it exists in non-debug builds.
+PYXPCOM_EXPORT void PyXPCOM_LogError(const char *fmt, ...);
+
+// The raw one
+PYXPCOM_EXPORT void PyXPCOM_Log(const char *level, const nsCString &msg);
+
+#ifdef DEBUG
+// Mainly designed for developers of the XPCOM package.
+// Only enabled in debug builds.
+PYXPCOM_EXPORT void PyXPCOM_LogDebug(const char *fmt, ...);
+#define PYXPCOM_LOG_DEBUG PyXPCOM_LogDebug
+#else
+#define PYXPCOM_LOG_DEBUG()
+#endif // DEBUG
+
+// Some utility converters
+// moz strings to PyObject.
+PYXPCOM_EXPORT PyObject *PyObject_FromNSString( const nsACString &s,
+ PRBool bAssumeUTF8 = PR_FALSE );
+PYXPCOM_EXPORT PyObject *PyObject_FromNSString( const nsAString &s );
+PYXPCOM_EXPORT PyObject *PyObject_FromNSString( const PRUnichar *s,
+ PRUint32 len = (PRUint32)-1);
+
+// PyObjects to moz strings. As per the moz string guide, we pass a reference
+// to an abstract string
+PYXPCOM_EXPORT PRBool PyObject_AsNSString( PyObject *ob, nsAString &aStr);
+
+// Variants.
+PYXPCOM_EXPORT nsresult PyObject_AsVariant( PyObject *ob, nsIVariant **aRet);
+PYXPCOM_EXPORT PyObject *PyObject_FromVariant( Py_nsISupports *parent,
+ nsIVariant *v);
+
+// Interfaces - these are the "official" functions
+PYXPCOM_EXPORT PyObject *PyObject_FromNSInterface( nsISupports *aInterface,
+ const nsIID &iid,
+ PRBool bMakeNicePyObject = PR_TRUE);
+
+/*************************************************************************
+**************************************************************************
+
+ Support for CALLING (ie, using) interfaces.
+
+**************************************************************************
+*************************************************************************/
+
+typedef Py_nsISupports* (* PyXPCOM_I_CTOR)(nsISupports *, const nsIID &);
+
+//////////////////////////////////////////////////////////////////////////
+// class PyXPCOM_TypeObject
+// Base class for (most of) the type objects.
+
+#ifndef Py_LIMITED_API
+class PYXPCOM_EXPORT PyXPCOM_TypeObject : public PyTypeObject {
+#else
+class PYXPCOM_EXPORT PyXPCOM_TypeObject : public PyObject {
+#endif
+public:
+ PyXPCOM_TypeObject(
+ const char *name,
+ PyXPCOM_TypeObject *pBaseType,
+ int typeSize,
+ struct PyMethodDef* methodList,
+ PyXPCOM_I_CTOR ctor);
+ ~PyXPCOM_TypeObject();
+
+ PyMethodChain chain;
+ PyXPCOM_TypeObject *baseType;
+ PyXPCOM_I_CTOR ctor;
+
+ static PRBool IsType(PyTypeObject *t);
+ // Static methods for the Python type.
+ static void Py_dealloc(PyObject *ob);
+ static PyObject *Py_repr(PyObject *ob);
+ static PyObject *Py_str(PyObject *ob);
+ static PyObject *Py_getattr(PyObject *self, char *name);
+ static int Py_setattr(PyObject *op, char *name, PyObject *v);
+ static int Py_cmp(PyObject *ob1, PyObject *ob2);
+ static PyObject *Py_richcmp(PyObject *ob1, PyObject *ob2, int op);
+#if PY_VERSION_HEX >= 0x03020000
+ static Py_hash_t Py_hash(PyObject *self);
+#else
+ static long Py_hash(PyObject *self);
+#endif
+#ifdef Py_LIMITED_API
+ PyTypeObject *m_pTypeObj; /**< The python type object we wrap. */
+#endif
+};
+
+//////////////////////////////////////////////////////////////////////////
+// class Py_nsISupports
+// This class serves 2 purposes:
+// * It is a base class for other interfaces we support "natively"
+// * It is instantiated for _all_ other interfaces.
+//
+// This is different than win32com, where a PyIUnknown only
+// ever holds an IUnknown - but here, we could be holding
+// _any_ interface.
+class PYXPCOM_EXPORT Py_nsISupports : public PyObject
+{
+public:
+ // Check if a Python object can safely be cast to an Py_nsISupports,
+ // and optionally check that the object is wrapping the specified
+ // interface.
+ static PRBool Check( PyObject *ob, const nsIID &checkIID = Py_nsIID_NULL) {
+ Py_nsISupports *self = static_cast<Py_nsISupports *>(ob);
+ if (ob==NULL || !PyXPCOM_TypeObject::IsType(ob->ob_type ))
+ return PR_FALSE;
+ if (!checkIID.Equals(Py_nsIID_NULL))
+ return self->m_iid.Equals(checkIID) != 0;
+ return PR_TRUE;
+ }
+ // Get the nsISupports interface from the PyObject WITH NO REF COUNT ADDED
+ static nsISupports *GetI(PyObject *self, nsIID *ret_iid = NULL);
+ nsCOMPtr<nsISupports> m_obj;
+ nsIID m_iid;
+#ifdef Py_LIMITED_API
+ /** Because PyXPCOM_TypeObject cannot inherit from PyTypeObject in
+ * Py_LIMITED_API mode, we cannot use ob_type to get to the method list.
+ * Instead of we store it here. */
+ PyXPCOM_TypeObject *m_pMyTypeObj;
+#endif
+
+ // Given an nsISupports and an Interface ID, create and return an object
+ // Does not QI the object - the caller must ensure the nsISupports object
+ // is really a pointer to an object identified by the IID (although
+ // debug builds should check this)
+ // PRBool bMakeNicePyObject indicates if we should call back into
+ // Python to wrap the object. This allows Python code to
+ // see the correct xpcom.client.Interface object even when calling
+ // xpcom functions directly from C++.
+ // NOTE: There used to be a bAddRef param to this as an internal
+ // optimization, but since removed. This function *always* takes a
+ // reference to the nsISupports.
+ static PyObject *PyObjectFromInterface(nsISupports *ps,
+ const nsIID &iid,
+ PRBool bMakeNicePyObject = PR_TRUE,
+ PRBool bIsInternalCall = PR_FALSE);
+
+ // Given a Python object that is a registered COM type, return a given
+ // interface pointer on its underlying object, with a NEW REFERENCE ADDED.
+ // bTryAutoWrap indicates if a Python instance object should attempt to
+ // be automatically wrapped in an XPCOM object. This is really only
+ // provided to stop accidental recursion should the object returned by
+ // the wrap process itself be in instance (where it should already be
+ // a COM object.
+ // If |iid|==nsIVariant, then arbitary Python objects will be wrapped
+ // in an nsIVariant.
+ static PRBool InterfaceFromPyObject(
+ PyObject *ob,
+ const nsIID &iid,
+ nsISupports **ppret,
+ PRBool bNoneOK,
+ PRBool bTryAutoWrap = PR_TRUE);
+
+ // Given a Py_nsISupports, return an interface.
+ // Object *must* be Py_nsISupports - there is no
+ // "autowrap", no "None" support, etc
+ static PRBool InterfaceFromPyISupports(PyObject *ob,
+ const nsIID &iid,
+ nsISupports **ppv);
+
+ static Py_nsISupports *Constructor(nsISupports *pInitObj, const nsIID &iid);
+ // The Python methods
+ static PyObject *QueryInterface(PyObject *self, PyObject *args);
+
+ // Internal (sort-of) objects.
+ static NS_EXPORT_STATIC_MEMBER_(PyXPCOM_TypeObject) *type;
+ static NS_EXPORT_STATIC_MEMBER_(PyMethodDef) methods[];
+ static PyObject *mapIIDToType;
+ static void SafeRelease(Py_nsISupports *ob);
+#ifndef Py_LIMITED_API
+ static void RegisterInterface( const nsIID &iid, PyTypeObject *t);
+#else
+ static void RegisterInterface( const nsIID &iid, PyXPCOM_TypeObject *t);
+#endif
+ static void InitType();
+#ifdef VBOX_DEBUG_LIFETIMES
+ static void dumpList(void);
+ static void dumpListToStdOut(void);
+#endif
+
+ virtual ~Py_nsISupports();
+ virtual PyObject *getattr(const char *name);
+ virtual int setattr(const char *name, PyObject *val);
+ // A virtual function to sub-classes can customize the way
+ // nsISupports objects are returned from their methods.
+ // ps is a new object just obtained from some operation performed on us
+ virtual PyObject *MakeInterfaceResult(nsISupports *ps, const nsIID &iid,
+ PRBool bMakeNicePyObject = PR_TRUE) {
+ return PyObjectFromInterface(ps, iid, bMakeNicePyObject);
+ }
+
+protected:
+ // ctor is protected - must create objects via
+ // PyObjectFromInterface()
+ Py_nsISupports(nsISupports *p,
+ const nsIID &iid,
+#ifndef Py_LIMITED_API
+ PyTypeObject *type);
+#else
+ PyXPCOM_TypeObject *type);
+#endif
+
+ // Make a default wrapper for an ISupports (which is an
+ // xpcom.client.Component instance)
+ static PyObject *MakeDefaultWrapper(PyObject *pyis, const nsIID &iid);
+
+#ifdef VBOX_DEBUG_LIFETIMES
+ static DECLCALLBACK(int32_t) initOnceCallback(void *pvUser1);
+
+ RTLISTNODE m_ListEntry; /**< List entry. */
+
+ static RTONCE g_Once; /**< Init list and critsect once. */
+ static RTCRITSECT g_CritSect; /**< Critsect protecting the list. */
+ static RTLISTANCHOR g_List; /**< List of live interfaces.*/
+#endif
+};
+
+// Python/XPCOM IID support
+class PYXPCOM_EXPORT Py_nsIID : public PyObject
+{
+public:
+ Py_nsIID(const nsIID &riid);
+ nsIID m_iid;
+
+ PRBool
+ IsEqual(const nsIID &riid) {
+ return m_iid.Equals(riid);
+ }
+
+ PRBool
+ IsEqual(PyObject *ob) {
+ return ob &&
+#ifndef Py_LIMITED_API
+ ob->ob_type== &type &&
+#else
+ ob->ob_type == s_pType &&
+#endif
+ m_iid.Equals(((Py_nsIID *)ob)->m_iid);
+ }
+
+ PRBool
+ IsEqual(Py_nsIID &iid) {
+ return m_iid.Equals(iid.m_iid);
+ }
+
+ static PyObject *
+ PyObjectFromIID(const nsIID &iid) {
+ return new Py_nsIID(iid);
+ }
+
+ static PRBool IIDFromPyObject(PyObject *ob, nsIID *pRet);
+ /* Python support */
+ static PyObject *PyTypeMethod_getattr(PyObject *self, char *name);
+#if PY_MAJOR_VERSION <= 2
+ static int PyTypeMethod_compare(PyObject *self, PyObject *ob);
+#endif
+ static PyObject *PyTypeMethod_richcompare(PyObject *self, PyObject *ob, int op);
+ static PyObject *PyTypeMethod_repr(PyObject *self);
+#if PY_VERSION_HEX >= 0x03020000
+ static Py_hash_t PyTypeMethod_hash(PyObject *self);
+#else
+ static long PyTypeMethod_hash(PyObject *self);
+#endif
+ static PyObject *PyTypeMethod_str(PyObject *self);
+ static void PyTypeMethod_dealloc(PyObject *self);
+#ifndef Py_LIMITED_API
+ static NS_EXPORT_STATIC_MEMBER_(PyTypeObject) type;
+#else
+ static NS_EXPORT_STATIC_MEMBER_(PyTypeObject *) s_pType;
+ static PyTypeObject *GetTypeObject(void);
+#endif
+ static NS_EXPORT_STATIC_MEMBER_(PyMethodDef) methods[];
+};
+
+///////////////////////////////////////////////////////
+//
+// Helper classes for managing arrays of variants.
+class PythonTypeDescriptor; // Forward declare.
+
+class PYXPCOM_EXPORT PyXPCOM_InterfaceVariantHelper {
+public:
+ PyXPCOM_InterfaceVariantHelper(Py_nsISupports *parent, int methodindex);
+ ~PyXPCOM_InterfaceVariantHelper();
+ PRBool Init(PyObject *obParams);
+ PRBool FillArray();
+
+ PyObject *MakePythonResult();
+
+ nsXPTCVariant *m_var_array;
+ int m_num_array;
+ int m_methodindex;
+protected:
+ PyObject *MakeSinglePythonResult(int index);
+ PRBool FillInVariant(const PythonTypeDescriptor &, int, int);
+ PRBool PrepareOutVariant(const PythonTypeDescriptor &td, int value_index);
+ PRBool SetSizeIs( int var_index, PRBool is_arg1, PRUint32 new_size);
+ PRUint32 GetSizeIs( int var_index, PRBool is_arg1);
+
+ PyObject *m_pyparams; // sequence of actual params passed (ie, not including hidden)
+ PyObject *m_typedescs; // desc of _all_ params, including hidden.
+ PythonTypeDescriptor *m_python_type_desc_array;
+ void **m_buffer_array;
+ Py_nsISupports *m_parent;
+
+};
+
+/*************************************************************************
+**************************************************************************
+
+ Support for IMPLEMENTING interfaces.
+
+**************************************************************************
+*************************************************************************/
+#define NS_IINTERNALPYTHON_IID_STR "AC7459FC-E8AB-4f2e-9C4F-ADDC53393A20"
+#define NS_IINTERNALPYTHON_IID \
+ { 0xac7459fc, 0xe8ab, 0x4f2e, { 0x9c, 0x4f, 0xad, 0xdc, 0x53, 0x39, 0x3a, 0x20 } }
+
+class PyXPCOM_GatewayWeakReference;
+
+// This interface is needed primarily to give us a known vtable base.
+// If we QI a Python object for this interface, we can safely cast the result
+// to a PyG_Base. Any other interface, we do now know which vtable we will get.
+// We also allow the underlying PyObject to be extracted
+class nsIInternalPython : public nsISupports {
+public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IINTERNALPYTHON_IID)
+ // Get the underlying Python object with new reference added
+ virtual PyObject *UnwrapPythonObject(void) = 0;
+};
+
+// This is roughly equivalent to PyGatewayBase in win32com
+//
+class PYXPCOM_EXPORT PyG_Base : public nsIInternalPython, public nsISupportsWeakReference
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSISUPPORTSWEAKREFERENCE
+ PyObject *UnwrapPythonObject(void);
+
+ // A static "constructor" - the real ctor is protected.
+ static nsresult CreateNew(PyObject *pPyInstance,
+ const nsIID &iid,
+ void **ppResult);
+
+ // A utility to auto-wrap an arbitary Python instance
+ // in a COM gateway.
+ static PRBool AutoWrapPythonInstance(PyObject *ob,
+ const nsIID &iid,
+ nsISupports **ppret);
+
+
+ // A helper that creates objects to be passed for nsISupports
+ // objects. See extensive comments in PyG_Base.cpp.
+ PyObject *MakeInterfaceParam(nsISupports *pis,
+ const nsIID *piid,
+ int methodIndex = -1,
+ const XPTParamDescriptor *d = NULL,
+ int paramIndex = -1);
+
+ // A helper that ensures all casting and vtable offsetting etc
+ // done against this object happens in the one spot!
+ virtual void *ThisAsIID( const nsIID &iid ) = 0;
+
+ // Helpers for "native" interfaces.
+ // Not used by the generic stub interface.
+ nsresult HandleNativeGatewayError(const char *szMethodName);
+
+ // These data members used by the converter helper functions - hence public
+ nsIID m_iid;
+ PyObject * m_pPyObject;
+ // We keep a reference count on this object, and the object
+ // itself uses normal refcount rules - thus, it will only
+ // die when we die, and all external references are removed.
+ // This means that once we have created it (and while we
+ // are alive) it will never die.
+ nsCOMPtr<nsIWeakReference> m_pWeakRef;
+#ifdef NS_BUILD_REFCNT_LOGGING
+ char refcntLogRepr[64]; // sigh - I wish I knew how to use the Moz string classes :( OK for debug only tho.
+#endif
+protected:
+ PyG_Base(PyObject *instance, const nsIID &iid);
+ virtual ~PyG_Base();
+ PyG_Base *m_pBaseObject; // A chain to implement identity rules.
+ nsresult InvokeNativeViaPolicy( const char *szMethodName,
+ PyObject **ppResult = NULL,
+ const char *szFormat = NULL,
+ ...
+ );
+ nsresult InvokeNativeViaPolicyInternal( const char *szMethodName,
+ PyObject **ppResult,
+ const char *szFormat,
+ va_list va);
+ nsresult InvokeNativeGetViaPolicy(const char *szPropertyName,
+ PyObject **ppResult = NULL
+ );
+ nsresult InvokeNativeSetViaPolicy(const char *szPropertyName,
+ ...);
+};
+
+class PYXPCOM_EXPORT PyXPCOM_XPTStub : public PyG_Base, public nsXPTCStubBase
+{
+friend class PyG_Base;
+public:
+ NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) \
+ {return PyG_Base::QueryInterface(aIID, aInstancePtr);} \
+ NS_IMETHOD_(nsrefcnt) AddRef(void) {return PyG_Base::AddRef();} \
+ NS_IMETHOD_(nsrefcnt) Release(void) {return PyG_Base::Release();} \
+
+ NS_IMETHOD GetInterfaceInfo(nsIInterfaceInfo** info);
+ // call this method and return result
+ NS_IMETHOD CallMethod(PRUint16 methodIndex,
+ const nsXPTMethodInfo* info,
+ nsXPTCMiniVariant* params);
+
+ virtual void *ThisAsIID(const nsIID &iid);
+protected:
+ PyXPCOM_XPTStub(PyObject *instance, const nsIID &iid) : PyG_Base(instance, iid) {;}
+private:
+};
+
+// For the Gateways we manually implement.
+#define PYGATEWAY_BASE_SUPPORT(INTERFACE, GATEWAY_BASE) \
+ NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) \
+ {return PyG_Base::QueryInterface(aIID, aInstancePtr);} \
+ NS_IMETHOD_(nsrefcnt) AddRef(void) {return PyG_Base::AddRef();} \
+ NS_IMETHOD_(nsrefcnt) Release(void) {return PyG_Base::Release();} \
+ virtual void *ThisAsIID(const nsIID &iid) { \
+ if (iid.Equals(NS_GET_IID(INTERFACE))) return (INTERFACE *)this; \
+ return GATEWAY_BASE::ThisAsIID(iid); \
+ } \
+
+extern PYXPCOM_EXPORT void AddDefaultGateway(PyObject *instance, nsISupports *gateway);
+
+extern PYXPCOM_EXPORT PRInt32 _PyXPCOM_GetGatewayCount(void);
+extern PYXPCOM_EXPORT PRInt32 _PyXPCOM_GetInterfaceCount(void);
+#ifdef VBOX_DEBUG_LIFETIMES
+extern PYXPCOM_EXPORT PRInt32 _PyXPCOM_DumpInterfaces(void);
+#endif
+
+
+// Weak Reference class. This is a true COM object, representing
+// a weak reference to a Python object. For each Python XPCOM object,
+// there is exactly zero or one corresponding weak reference instance.
+// When both are alive, each holds a pointer to the other. When the main
+// object dies due to XPCOM reference counting, it zaps the pointer
+// in its corresponding weak reference object. Thus, the weak-reference
+// can live beyond the object (possibly with a NULL pointer back to the
+// "real" object, but as implemented, the weak reference will never be
+// destroyed before the object
+class PYXPCOM_EXPORT PyXPCOM_GatewayWeakReference : public nsIWeakReference {
+public:
+ PyXPCOM_GatewayWeakReference(PyG_Base *base);
+ virtual ~PyXPCOM_GatewayWeakReference();
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIWEAKREFERENCE
+ PyG_Base *m_pBase; // NO REF COUNT!!!
+#ifdef NS_BUILD_REFCNT_LOGGING
+ char refcntLogRepr[41];
+#endif
+};
+
+
+// Helpers classes for our gateways.
+class PYXPCOM_EXPORT PyXPCOM_GatewayVariantHelper
+{
+public:
+ PyXPCOM_GatewayVariantHelper( PyG_Base *gateway,
+ int methodIndex,
+ const nsXPTMethodInfo *info,
+ nsXPTCMiniVariant* params );
+ ~PyXPCOM_GatewayVariantHelper();
+ PyObject *MakePyArgs();
+ nsresult ProcessPythonResult(PyObject *ob);
+ PyG_Base *m_gateway;
+private:
+ nsresult BackFillVariant( PyObject *ob, int index);
+ PyObject *MakeSingleParam(int index, PythonTypeDescriptor &td);
+ PRBool GetIIDForINTERFACE_ID(int index, const nsIID **ppret);
+ nsresult GetArrayType(PRUint8 index, PRUint8 *ret, nsIID **ppiid);
+ PRUint32 GetSizeIs( int var_index, PRBool is_arg1);
+ PRBool SetSizeIs( int var_index, PRBool is_arg1, PRUint32 new_size);
+ PRBool CanSetSizeIs( int var_index, PRBool is_arg1 );
+ nsIInterfaceInfo *GetInterfaceInfo(); // NOTE: no ref count on result.
+
+
+ nsXPTCMiniVariant* m_params;
+ const nsXPTMethodInfo *m_info;
+ int m_method_index;
+ PythonTypeDescriptor *m_python_type_desc_array;
+ int m_num_type_descs;
+ nsCOMPtr<nsIInterfaceInfo> m_interface_info;
+};
+
+// Misc converters.
+PyObject *PyObject_FromXPTType( const nsXPTType *d);
+// XPTTypeDescriptor derived from XPTType - latter is automatically processed via PyObject_FromXPTTypeDescriptor XPTTypeDescriptor
+PyObject *PyObject_FromXPTTypeDescriptor( const XPTTypeDescriptor *d);
+
+PyObject *PyObject_FromXPTParamDescriptor( const XPTParamDescriptor *d);
+PyObject *PyObject_FromXPTMethodDescriptor( const XPTMethodDescriptor *d);
+PyObject *PyObject_FromXPTConstant( const XPTConstDescriptor *d);
+
+// DLL reference counting functions.
+// Although we maintain the count, we never actually
+// finalize Python when it hits zero!
+void PyXPCOM_DLLAddRef();
+void PyXPCOM_DLLRelease();
+
+/*************************************************************************
+**************************************************************************
+
+ LOCKING AND THREADING
+
+**************************************************************************
+*************************************************************************/
+
+//
+// We have 2 discrete locks in use (when no free-threaded is used, anyway).
+// The first type of lock is the global Python lock. This is the standard lock
+// in use by Python, and must be used as documented by Python. Specifically, no
+// 2 threads may _ever_ call _any_ Python code (including INCREF/DECREF) without
+// first having this thread lock.
+//
+// The second type of lock is a "global framework lock", and used whenever 2 threads
+// of C code need access to global data. This is different than the Python
+// lock - this lock is used when no Python code can ever be called by the
+// threads, but the C code still needs thread-safety.
+
+// We also supply helper classes which make the usage of these locks a one-liner.
+
+// The "framework" lock, implemented as a PRLock
+PYXPCOM_EXPORT void PyXPCOM_AcquireGlobalLock(void);
+PYXPCOM_EXPORT void PyXPCOM_ReleaseGlobalLock(void);
+
+// Helper class for the DLL global lock.
+//
+// This class magically waits for PyXPCOM framework global lock, and releases it
+// when finished.
+// NEVER new one of these objects - only use on the stack!
+class CEnterLeaveXPCOMFramework {
+public:
+ CEnterLeaveXPCOMFramework() {PyXPCOM_AcquireGlobalLock();}
+ ~CEnterLeaveXPCOMFramework() {PyXPCOM_ReleaseGlobalLock();}
+};
+
+// Python thread-lock stuff. Free-threading patches use different semantics, but
+// these are abstracted away here...
+//#include <threadstate.h>
+
+// Helper class for Enter/Leave Python
+//
+// This class magically waits for the Python global lock, and releases it
+// when finished.
+
+// Nested invocations will deadlock, so be careful.
+
+// NEVER new one of these objects - only use on the stack!
+
+PYXPCOM_EXPORT void PyXPCOM_MakePendingCalls();
+PYXPCOM_EXPORT PRBool PyXPCOM_Globals_Ensure();
+
+// For 2.3, use the PyGILState_ calls
+#if (PY_VERSION_HEX >= 0x02030000)
+#define PYXPCOM_USE_PYGILSTATE
+#endif
+
+#ifdef PYXPCOM_USE_PYGILSTATE
+class CEnterLeavePython {
+public:
+ CEnterLeavePython() {
+ state = PyGILState_Ensure();
+ // See "pending calls" comment below. We reach into the Python
+ // implementation to see if we are the first call on the stack.
+# ifndef Py_LIMITED_API
+ if (PyThreadState_Get()->gilstate_counter==1) {
+# else
+ if (state == PyGILState_UNLOCKED) {
+# endif
+ PyXPCOM_MakePendingCalls();
+ }
+ }
+ ~CEnterLeavePython() {
+ PyGILState_Release(state);
+ }
+ PyGILState_STATE state;
+};
+#else
+
+extern PYXPCOM_EXPORT PyInterpreterState *PyXPCOM_InterpreterState;
+PYXPCOM_EXPORT PRBool PyXPCOM_ThreadState_Ensure();
+PYXPCOM_EXPORT void PyXPCOM_ThreadState_Free();
+PYXPCOM_EXPORT void PyXPCOM_ThreadState_Clear();
+PYXPCOM_EXPORT void PyXPCOM_InterpreterLock_Acquire();
+PYXPCOM_EXPORT void PyXPCOM_InterpreterLock_Release();
+
+// Pre 2.3 thread-state dances.
+class CEnterLeavePython {
+public:
+ CEnterLeavePython() {
+ created = PyXPCOM_ThreadState_Ensure();
+ PyXPCOM_InterpreterLock_Acquire();
+ if (created) {
+ // If pending python calls are waiting as we enter Python,
+ // it will generally mean an asynch signal handler, etc.
+ // We can either call it here, or wait for Python to call it
+ // as part of its "even 'n' opcodes" check. If we wait for
+ // Python to check it and the pending call raises an exception,
+ // then it is _our_ code that will fail - this is unfair,
+ // as the signal was raised before we were entered - indeed,
+ // we may be directly responding to the signal!
+ // Thus, we flush all the pending calls here, and report any
+ // exceptions via our normal exception reporting mechanism.
+ // We can then execute our code in the knowledge that only
+ // signals raised _while_ we are executing will cause exceptions.
+ PyXPCOM_MakePendingCalls();
+ }
+ }
+ ~CEnterLeavePython() {
+ // The interpreter state must be cleared
+ // _before_ we release the lock, as some of
+ // the sys. attributes cleared (eg, the current exception)
+ // may need the lock to invoke their destructors -
+ // specifically, when exc_value is a class instance, and
+ // the exception holds the last reference!
+ if ( created )
+ PyXPCOM_ThreadState_Clear();
+ PyXPCOM_InterpreterLock_Release();
+ if ( created )
+ PyXPCOM_ThreadState_Free();
+ }
+private:
+ PRBool created;
+};
+#endif // PYXPCOM_USE_PYGILSTATE
+
+// Our classes.
+// Hrm - So we can't have templates, eh??
+// preprocessor to the rescue, I guess.
+#define PyXPCOM_INTERFACE_DECLARE(ClassName, InterfaceName, Methods ) \
+ \
+extern struct PyMethodDef Methods[]; \
+ \
+class ClassName : public Py_nsISupports \
+{ \
+public: \
+ static PYXPCOM_EXPORT PyXPCOM_TypeObject *type; \
+ static Py_nsISupports *Constructor(nsISupports *pInitObj, const nsIID &iid) { \
+ return new ClassName(pInitObj, iid); \
+ } \
+ static void InitType() { \
+ type = new PyXPCOM_TypeObject( \
+ #InterfaceName, \
+ Py_nsISupports::type, \
+ sizeof(ClassName), \
+ Methods, \
+ Constructor); \
+ const nsIID &iid = NS_GET_IID(InterfaceName); \
+ RegisterInterface(iid, type); \
+ } \
+protected: \
+ ClassName(nsISupports *p, const nsIID &iid) : \
+ Py_nsISupports(p, iid, type) { \
+ /* The IID _must_ be the IID of the interface we are wrapping! */ \
+ NS_ABORT_IF_FALSE(iid.Equals(NS_GET_IID(InterfaceName)), "Bad IID"); \
+ } \
+}; \
+ \
+// End of PyXPCOM_INTERFACE_DECLARE macro
+
+#define PyXPCOM_ATTR_INTERFACE_DECLARE(ClassName, InterfaceName, Methods )\
+ \
+extern struct PyMethodDef Methods[]; \
+ \
+class ClassName : public Py_nsISupports \
+{ \
+public: \
+ static PyXPCOM_TypeObject *type; \
+ static Py_nsISupports *Constructor(nsISupports *pInitObj, const nsIID &iid) { \
+ return new ClassName(pInitObj, iid); \
+ } \
+ static void InitType() { \
+ type = new PyXPCOM_TypeObject( \
+ #InterfaceName, \
+ Py_nsISupports::type, \
+ sizeof(ClassName), \
+ Methods, \
+ Constructor); \
+ const nsIID &iid = NS_GET_IID(InterfaceName); \
+ RegisterInterface(iid, type); \
+} \
+ virtual PyObject *getattr(const char *name); \
+ virtual int setattr(const char *name, PyObject *val); \
+protected: \
+ ClassName(nsISupports *p, const nsIID &iid) : \
+ Py_nsISupports(p, iid, type) { \
+ /* The IID _must_ be the IID of the interface we are wrapping! */ \
+ NS_ABORT_IF_FALSE(iid.Equals(NS_GET_IID(InterfaceName)), "Bad IID"); \
+ } \
+}; \
+ \
+// End of PyXPCOM_ATTR_INTERFACE_DECLARE macro
+
+#define PyXPCOM_INTERFACE_DEFINE(ClassName, InterfaceName, Methods ) \
+PyXPCOM_TypeObject *ClassName::type = NULL;
+
+
+// And the classes
+PyXPCOM_INTERFACE_DECLARE(Py_nsIComponentManager, nsIComponentManager, PyMethods_IComponentManager)
+PyXPCOM_INTERFACE_DECLARE(Py_nsIInterfaceInfoManager, nsIInterfaceInfoManager, PyMethods_IInterfaceInfoManager)
+PyXPCOM_INTERFACE_DECLARE(Py_nsIEnumerator, nsIEnumerator, PyMethods_IEnumerator)
+PyXPCOM_INTERFACE_DECLARE(Py_nsISimpleEnumerator, nsISimpleEnumerator, PyMethods_ISimpleEnumerator)
+PyXPCOM_INTERFACE_DECLARE(Py_nsIInterfaceInfo, nsIInterfaceInfo, PyMethods_IInterfaceInfo)
+PyXPCOM_INTERFACE_DECLARE(Py_nsIInputStream, nsIInputStream, PyMethods_IInputStream)
+PyXPCOM_ATTR_INTERFACE_DECLARE(Py_nsIClassInfo, nsIClassInfo, PyMethods_IClassInfo)
+PyXPCOM_ATTR_INTERFACE_DECLARE(Py_nsIVariant, nsIVariant, PyMethods_IVariant)
+// deprecated, but retained for backward compatibility:
+PyXPCOM_INTERFACE_DECLARE(Py_nsIComponentManagerObsolete, nsIComponentManagerObsolete, PyMethods_IComponentManagerObsolete)
+#endif // __PYXPCOM_H__
diff --git a/src/libs/xpcom18a4/python/src/PyXPCOM_std.h b/src/libs/xpcom18a4/python/src/PyXPCOM_std.h
new file mode 100644
index 00000000..b7b7ff8c
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/PyXPCOM_std.h
@@ -0,0 +1,56 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+// standard include - sets up all the defines used by
+// the mozilla make process - too lazy to work out how to integrate
+// with their make, so this will do!
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+// This header is considered internal - hence
+// we can use it to trigger "exports"
+#define BUILD_PYXPCOM
+
+#include "PyXPCOM.h"
diff --git a/src/libs/xpcom18a4/python/src/Pyxpt_info.cpp b/src/libs/xpcom18a4/python/src/Pyxpt_info.cpp
new file mode 100644
index 00000000..d1df54fe
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/Pyxpt_info.cpp
@@ -0,0 +1,197 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <MarkH@ActiveState.com> (original author)
+ *
+ * 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 ***** */
+
+// Pyxpt_info.cpp - wrappers for the xpt_info objects.
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+#include "PyXPCOM_std.h"
+
+PyObject *PyObject_FromXPTType( const nsXPTType *d)
+{
+ if (d==nsnull) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ // build an object using the same format as a TypeDescriptor.
+ return Py_BuildValue("bzzz",
+ d->flags,
+ NULL, NULL, NULL);
+}
+
+PyObject *PyObject_FromXPTTypeDescriptor( const XPTTypeDescriptor *d)
+{
+ if (d==nsnull) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return Py_BuildValue("bbbh",
+ d->prefix.flags,
+ d->argnum,
+ d->argnum2,
+ d->type.iface // this is actually a union!
+ );
+}
+
+PyObject *PyObject_FromXPTParamDescriptor( const XPTParamDescriptor *d)
+{
+ if (d==nsnull) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ PyObject *ob = PyObject_FromXPTTypeDescriptor(&d->type);
+ PyObject *ret = Py_BuildValue("bO", d->flags, ob);
+ Py_DECREF(ob);
+ return ret;
+}
+
+PyObject *PyObject_FromXPTMethodDescriptor( const XPTMethodDescriptor *d)
+{
+ if (d==nsnull) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ PyObject *ob_params = PyTuple_New(d->num_args);
+ if (ob_params==NULL)
+ return NULL;
+ for (int i=0;i<d->num_args;i++)
+ PyTuple_SET_ITEM(ob_params, i, PyObject_FromXPTParamDescriptor(d->params+i));
+ PyObject *ob_ret = PyObject_FromXPTParamDescriptor(d->result);
+ PyObject *ret = Py_BuildValue("bsOO", d->flags, d->name, ob_params, ob_ret);
+ Py_XDECREF(ob_ret);
+ Py_XDECREF(ob_params);
+ return ret;
+}
+
+PyObject *PyObject_FromXPTConstant( const XPTConstDescriptor *c)
+{
+ if (c==nsnull) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ PyObject *ob_type = PyObject_FromXPTTypeDescriptor(&c->type);
+ if (ob_type==NULL)
+ return NULL;
+ PyObject *v = NULL;
+ switch (c->type.prefix.flags) {
+ case TD_INT8:
+ v = PyInt_FromLong( c->value.i8 );
+ break;
+ case TD_INT16:
+ v = PyInt_FromLong( c->value.i16 );
+ break;
+ case TD_INT32:
+ v = PyInt_FromLong( c->value.i32 );
+ break;
+ case TD_INT64:
+ v = PyLong_FromLongLong(c->value.i64);
+ break;
+ case TD_UINT8:
+ v = PyInt_FromLong( c->value.ui8 );
+ break;
+ case TD_UINT16:
+ v = PyInt_FromLong( c->value.ui16 );
+ break;
+ case TD_UINT32:
+ v = PyInt_FromLong( c->value.ui32 );
+ break;
+ case TD_UINT64:
+ v = PyLong_FromUnsignedLongLong(c->value.ui64);
+ break;
+ case TD_FLOAT:
+ v = PyFloat_FromDouble(c->value.flt);
+ break;
+ case TD_DOUBLE:
+ v = PyFloat_FromDouble(c->value.dbl);
+ break;
+ case TD_BOOL:
+ v = c->value.bul ? Py_True : Py_False;
+ Py_INCREF(v);
+ break;
+ case TD_CHAR:
+#if PY_MAJOR_VERSION <= 2
+ v = PyString_FromStringAndSize(&c->value.ch, 1);
+#else
+ v = PyUnicode_FromStringAndSize(&c->value.ch, 1);
+#endif
+ break;
+ case TD_WCHAR:
+ v = PyObject_FromNSString((PRUnichar *)&c->value.wch, 1);
+ break;
+ // TD_VOID = 13,
+ case TD_PNSIID:
+ v = Py_nsIID::PyObjectFromIID(*c->value.iid);
+ break;
+ // TD_DOMSTRING = 15,
+ case TD_PSTRING:
+#if PY_MAJOR_VERSION <= 2
+ v = PyString_FromString(c->value.str);
+#else
+ v = PyUnicode_FromString(c->value.str);
+#endif
+ break;
+ case TD_PWSTRING:
+ v = PyObject_FromNSString((PRUnichar *)c->value.wstr, nsCRT::strlen((PRUnichar *)c->value.wstr));
+ break;
+ // TD_INTERFACE_TYPE = 18,
+ // TD_INTERFACE_IS_TYPE = 19,
+ // TD_ARRAY = 20,
+ // TD_PSTRING_SIZE_IS = 21,
+ // TD_PWSTRING_SIZE_IS = 22
+ // TD_UTF8STRING = 23,
+ // TD_CSTRING = 24,
+ // TD_ASTRING = 25
+ default:
+#if PY_MAJOR_VERSION <= 2
+ v = PyString_FromString("Unknown type code!!");
+#else
+ v = PyUnicode_FromString("Unknown type code!!");
+#endif
+ break;
+
+ }
+ PyObject *ret = Py_BuildValue("sbO", c->name, ob_type, v);
+ Py_DECREF(ob_type);
+ Py_DECREF(v);
+ return ret;
+}
diff --git a/src/libs/xpcom18a4/python/src/TypeObject.cpp b/src/libs/xpcom18a4/python/src/TypeObject.cpp
new file mode 100644
index 00000000..37cc13d7
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/TypeObject.cpp
@@ -0,0 +1,457 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+#include <nsIInterfaceInfoManager.h>
+#include <nsXPCOM.h>
+#include <nsISupportsPrimitives.h>
+
+#if defined(Py_LIMITED_API) && defined(RT_OS_LINUX)
+# include <features.h>
+# ifdef __GLIBC_PREREQ
+# if __GLIBC_PREREQ(2,9)
+# define PYXPCOM_HAVE_PIPE2
+# include <fcntl.h>
+# endif
+# endif
+#endif
+
+
+#ifndef Py_LIMITED_API
+static PyTypeObject PyInterfaceType_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "interface-type", /* Name of this type */
+ sizeof(PyTypeObject), /* Basic object size */
+ 0, /* Item size for varobject */
+ 0, /*tp_dealloc*/
+ 0, /*tp_print*/
+ PyType_Type.tp_getattr, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ PyType_Type.tp_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /* tp_getattro */
+ 0, /*tp_setattro */
+ 0, /* tp_as_buffer */
+ 0, /* tp_flags */
+ "Define the behavior of a PythonCOM Interface type.",
+};
+
+#else /* Py_LIMITED_API */
+
+/** The offset of PyTypeObject::ob_name. */
+static size_t g_offObTypeNameMember = sizeof(PyVarObject);
+
+/**
+ * Base type object for XPCOM interfaces. Created dynamicially.
+ */
+static PyTypeObject *g_pPyInterfaceTypeObj = NULL;
+
+/**
+ * Gets the base XPCOM interface type object, creating it if needed.
+ */
+static PyTypeObject *PyXPCOM_CreateInterfaceType(void)
+{
+ static char g_szTypeDoc[] = "Define the behavior of a PythonCOM Interface type."; /* need non-const */
+ PyType_Slot aTypeSlots[] = {
+ { Py_tp_doc, g_szTypeDoc },
+ { 0, NULL } /* terminator */
+ };
+ static const char g_szClassNm[] = "interface-type";
+ PyType_Spec TypeSpec = {
+ /* .name: */ g_szClassNm,
+ /* .basicsize: */ 0,
+ /* .itemsize: */ 0,
+ /* .flags: */ Py_TPFLAGS_BASETYPE,
+ /* .slots: */ aTypeSlots,
+ };
+
+ PyObject *exc_typ = NULL, *exc_val = NULL, *exc_tb = NULL;
+ PyErr_Fetch(&exc_typ, &exc_val, &exc_tb); /* goes south in PyType_Ready if we don't clear exceptions first. */
+
+ PyTypeObject *pTypeObj = (PyTypeObject *)PyType_FromSpec(&TypeSpec);
+ assert(pTypeObj);
+
+ PyErr_Restore(exc_typ, exc_val, exc_tb);
+ g_pPyInterfaceTypeObj = pTypeObj;
+
+ /*
+ * Verify/correct g_offObTypeNameMember.
+ *
+ * Using pipe+write to probe the memory content, banking on the kernel
+ * to return EFAULT when we pass it an invalid address.
+ */
+ for (size_t off = sizeof(PyVarObject); off < sizeof(PyVarObject) + 64; off += sizeof(char *)) {
+ const char * const pszProbe = *(const char **)((uintptr_t)(pTypeObj) + off);
+ if (RT_VALID_PTR(pszProbe)) {
+ int fds[2] = { -1, -1 };
+# ifdef PYXPCOM_HAVE_PIPE2
+ int rc = pipe2(fds, O_CLOEXEC);
+# else
+ int rc = pipe(fds);
+# endif
+ if (rc)
+ break;
+
+ ssize_t cbWritten = write(fds[1], pszProbe, sizeof(g_szClassNm));
+ if (cbWritten == (ssize_t)sizeof(g_szClassNm)) {
+ char szReadBack[sizeof(g_szClassNm)];
+ ssize_t offRead = 0;
+ while (offRead < cbWritten) {
+ ssize_t cbRead = read(fds[0], &szReadBack[offRead], cbWritten - offRead);
+ if (cbRead >= 0) {
+ offRead += cbRead;
+ } else if (errno != EINTR)
+ break;
+ }
+ if ( cbWritten == offRead
+ && memcmp(szReadBack, g_szClassNm, sizeof(szReadBack)) == 0) {
+ g_offObTypeNameMember = off;
+ close(fds[0]);
+ close(fds[1]);
+ return pTypeObj;
+ }
+ }
+ close(fds[0]);
+ close(fds[1]);
+ }
+ }
+ assert(0);
+
+ return pTypeObj;
+}
+
+/**
+ * Gets the base XPCOM interface type object, creating it if needed.
+ */
+static PyTypeObject *PyXPCOM_GetInterfaceType(void)
+{
+ PyTypeObject *pTypeObj = g_pPyInterfaceTypeObj;
+ if (pTypeObj)
+ return pTypeObj;
+ return PyXPCOM_CreateInterfaceType();
+}
+
+/**
+ * Get the PyTypeObject::ob_name value.
+ *
+ * @todo This is _horrible_, but there appears to be no simple tp_name getter
+ * till https://bugs.python.org/issue31497 (2017 / 3.7.0). But even then
+ * it is not part of the limited API.
+ */
+const char *PyXPCOMGetObTypeName(PyTypeObject *pTypeObj)
+{
+ return *(const char **)((uintptr_t)(pTypeObj) + g_offObTypeNameMember);
+}
+
+#endif /* Py_LIMITED_API */
+
+/*static*/ PRBool
+PyXPCOM_TypeObject::IsType(PyTypeObject *t)
+{
+#if PY_MAJOR_VERSION <= 2
+ return t->ob_type == &PyInterfaceType_Type;
+#elif !defined(Py_LIMITED_API)
+ return Py_TYPE(t) == &PyInterfaceType_Type;
+#else
+ return Py_TYPE(t) == g_pPyInterfaceTypeObj /* Typically not the case as t->ob_type is &PyType_Type */
+ || PyType_IsSubtype(t, g_pPyInterfaceTypeObj); /* rather than g_pPyInterfaceTypeObj because of PyType_FromSpec(). */
+#endif
+}
+
+////////////////////////////////////////////////////////////////////
+//
+// The type methods
+//
+/*static*/PyObject *
+PyXPCOM_TypeObject::Py_getattr(PyObject *self, char *name)
+{
+ return ((Py_nsISupports *)self)->getattr(name);
+}
+
+/*static*/int
+PyXPCOM_TypeObject::Py_setattr(PyObject *op, char *name, PyObject *v)
+{
+ return ((Py_nsISupports *)op)->setattr(name, v);
+}
+
+// @pymethod int|Py_nsISupports|__cmp__|Implements XPCOM rules for object identity.
+/*static*/int
+PyXPCOM_TypeObject::Py_cmp(PyObject *self, PyObject *other)
+{
+ // @comm NOTE: Copied from COM - have not confirmed these rules are true for XPCOM
+ // @comm As per the XPCOM rules for object identity, both objects are queried for nsISupports, and these values compared.
+ // The only meaningful test is for equality - the result of other comparisons is undefined
+ // (ie, determined by the object's relative addresses in memory.
+ nsISupports *pUnkOther;
+ nsISupports *pUnkThis;
+ if (!Py_nsISupports::InterfaceFromPyObject(self, NS_GET_IID(nsISupports), &pUnkThis, PR_FALSE))
+ return -1;
+ if (!Py_nsISupports::InterfaceFromPyObject(other, NS_GET_IID(nsISupports), &pUnkOther, PR_FALSE)) {
+ pUnkThis->Release();
+ return -1;
+ }
+ int rc = pUnkThis==pUnkOther ? 0 :
+ (pUnkThis < pUnkOther ? -1 : 1);
+ pUnkThis->Release();
+ pUnkOther->Release();
+ return rc;
+}
+
+/*static*/PyObject *
+PyXPCOM_TypeObject::Py_richcmp(PyObject *self, PyObject *other, int op)
+{
+ PyObject *result = NULL;
+ int rc = Py_cmp(self, other);
+ switch (op)
+ {
+ case Py_LT:
+ result = rc < 0 ? Py_True : Py_False;
+ break;
+ case Py_LE:
+ result = rc <= 0 ? Py_True : Py_False;
+ break;
+ case Py_EQ:
+ result = rc == 0 ? Py_True : Py_False;
+ break;
+ case Py_NE:
+ result = rc != 0 ? Py_True : Py_False;
+ break;
+ case Py_GT:
+ result = rc > 0 ? Py_True : Py_False;
+ break;
+ case Py_GE:
+ result = rc >= 0 ? Py_True : Py_False;
+ break;
+ }
+ Py_XINCREF(result);
+ return result;
+}
+
+// @pymethod int|Py_nsISupports|__hash__|Implement a hash-code for the XPCOM object using XPCOM identity rules.
+#if PY_VERSION_HEX >= 0x03020000
+/*static*/Py_hash_t PyXPCOM_TypeObject::Py_hash(PyObject *self)
+#else
+/*static*/long PyXPCOM_TypeObject::Py_hash(PyObject *self)
+#endif
+{
+ // We always return the value of the nsISupports *.
+ nsISupports *pUnkThis;
+ if (!Py_nsISupports::InterfaceFromPyObject(self, NS_GET_IID(nsISupports), &pUnkThis, PR_FALSE))
+ return -1;
+#if PY_VERSION_HEX >= 0x03020000
+ Py_hash_t ret = _Py_HashPointer(pUnkThis);
+#else
+ long ret = _Py_HashPointer(pUnkThis);
+#endif
+ pUnkThis->Release();
+ return ret;
+}
+
+// @method string|Py_nsISupports|__repr__|Called to create a representation of a Py_nsISupports object
+/*static */PyObject *
+PyXPCOM_TypeObject::Py_repr(PyObject *self)
+{
+ // @comm The repr of this object displays both the object's address, and its attached nsISupports's address
+ Py_nsISupports *pis = (Py_nsISupports *)self;
+ // Try and get the IID name.
+ char *iid_repr = nsnull;
+ nsCOMPtr<nsIInterfaceInfoManager> iim(do_GetService(
+ NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
+ if (iim!=nsnull)
+ iim->GetNameForIID(&pis->m_iid, &iid_repr);
+ if (iid_repr==nsnull)
+ // no IIM available, or it doesnt know the name.
+ iid_repr = pis->m_iid.ToString();
+ // XXX - need some sort of buffer overflow.
+ char buf[512];
+#ifdef VBOX
+ snprintf(buf, sizeof(buf), "<XPCOM object (%s) at %p/%p>",
+ iid_repr, (void *)self, (void *)pis->m_obj.get());
+#else
+ sprintf(buf, "<XPCOM object (%s) at 0x%p/0x%p>",
+ iid_repr, (void *)self, (void *)pis->m_obj.get());
+#endif
+ nsMemory::Free(iid_repr);
+#if PY_MAJOR_VERSION <= 2
+ return PyString_FromString(buf);
+#else
+ return PyUnicode_FromString(buf);
+#endif
+}
+
+/*static */PyObject *
+PyXPCOM_TypeObject::Py_str(PyObject *self)
+{
+ Py_nsISupports *pis = (Py_nsISupports *)self;
+ nsresult rv;
+ char *val = NULL;
+ Py_BEGIN_ALLOW_THREADS;
+ { // scope to kill pointer while thread-lock released.
+ nsCOMPtr<nsISupportsCString> ss( do_QueryInterface(pis->m_obj, &rv ));
+ if (NS_SUCCEEDED(rv))
+ rv = ss->ToString(&val);
+ } // end-scope
+ Py_END_ALLOW_THREADS;
+ PyObject *ret;
+ if (NS_FAILED(rv))
+ ret = Py_repr(self);
+ else
+#if PY_MAJOR_VERSION <= 2
+ ret = PyString_FromString(val);
+#else
+ ret = PyUnicode_FromString(val);
+#endif
+ if (val) nsMemory::Free(val);
+ return ret;
+}
+
+/* static */void
+PyXPCOM_TypeObject::Py_dealloc(PyObject *self)
+{
+ delete (Py_nsISupports *)self;
+}
+
+PyXPCOM_TypeObject::PyXPCOM_TypeObject( const char *name, PyXPCOM_TypeObject *pBase, int typeSize, struct PyMethodDef* methodList, PyXPCOM_I_CTOR thector)
+{
+#ifndef Py_LIMITED_API
+ static const PyTypeObject type_template = {
+ PyVarObject_HEAD_INIT(&PyInterfaceType_Type, 0)
+ "XPCOMTypeTemplate", /*tp_name*/
+ sizeof(Py_nsISupports), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ Py_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ Py_getattr, /* tp_getattr */
+ Py_setattr, /* tp_setattr */
+#if PY_MAJOR_VERSION <= 2
+ Py_cmp, /* tp_compare */
+#else
+ 0, /* reserved */
+#endif
+ Py_repr, /* tp_repr */
+ 0, /* tp_as_number*/
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ Py_hash, /* tp_hash */
+ 0, /* tp_call */
+ Py_str, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ 0, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ Py_richcmp, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ };
+
+ *((PyTypeObject *)this) = type_template;
+#else /* Py_LIMITED_API */
+ /* Create the type specs: */
+ PyType_Slot aTypeSlots[] = {
+ { Py_tp_base, PyXPCOM_GetInterfaceType() },
+ { Py_tp_dealloc, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_dealloc },
+ { Py_tp_getattr, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_getattr },
+ { Py_tp_setattr, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_setattr },
+ { Py_tp_repr, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_repr },
+ { Py_tp_hash, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_hash },
+ { Py_tp_str, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_str },
+ { Py_tp_richcompare, (void *)(uintptr_t)&PyXPCOM_TypeObject::Py_richcmp },
+ { 0, NULL } /* terminator */
+ };
+ PyType_Spec TypeSpec = {
+ /* .name: */ name,
+ /* .basicsize: */ typeSize,
+ /* .itemsize: */ 0,
+ /* .flags: */ Py_TPFLAGS_BASETYPE /*?*/,
+ /* .slots: */ aTypeSlots,
+ };
+
+ PyObject *exc_typ = NULL, *exc_val = NULL, *exc_tb = NULL;
+ PyErr_Fetch(&exc_typ, &exc_val, &exc_tb); /* goes south in PyType_Ready if we don't clear exceptions first. */
+
+ m_pTypeObj = (PyTypeObject *)PyType_FromSpec(&TypeSpec);
+ assert(m_pTypeObj);
+
+ PyErr_Restore(exc_typ, exc_val, exc_tb);
+
+ /* Initialize the PyObject part - needed so we can keep instance in a PyDict: */
+ ob_type = PyXPCOM_GetInterfaceType();
+ PyObject_Init(this, ob_type); /* VBox: Needed for 3.9 and up (also works on Python 2.7), includes _Py_NewReferences. @bugref{10079} */
+
+#endif /* Py_LIMITED_API */
+
+ chain.methods = methodList;
+ chain.link = pBase ? &pBase->chain : NULL;
+
+ baseType = pBase;
+ ctor = thector;
+
+#ifndef Py_LIMITED_API
+ // cast away const, as Python doesnt use it.
+ tp_name = (char *)name;
+ tp_basicsize = typeSize;
+#endif
+}
+
+PyXPCOM_TypeObject::~PyXPCOM_TypeObject()
+{
+}
+
diff --git a/src/libs/xpcom18a4/python/src/VariantUtils.cpp b/src/libs/xpcom18a4/python/src/VariantUtils.cpp
new file mode 100644
index 00000000..ac14a2cf
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/VariantUtils.cpp
@@ -0,0 +1,3112 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * Unicode corrections by Shane Hathaway (http://hathawaymix.org),
+ * inspired by Mikhail Sobolev
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+#include <nsIInterfaceInfoManager.h>
+#include <nsAString.h>
+#include <nsString.h>
+#include <nsReadableUtils.h>
+
+// ------------------------------------------------------------------------
+// nsString utilities
+// ------------------------------------------------------------------------
+// one day we may know what they look like.
+inline
+PRBool
+IsNullDOMString( const nsAString& aString )
+{
+ return PR_FALSE;
+}
+
+inline
+PRBool
+IsNullDOMString( const nsACString& aString )
+{
+ return PR_FALSE;
+}
+
+#define PyUnicode_FromPRUnichar(src, size) \
+ PyUnicode_DecodeUTF16((char*)(src),sizeof(PRUnichar)*(size),NULL,NULL)
+
+// Create a zero-terminated PRUnichar buffer from a Python unicode.
+// On success, returns 0. On failure, returns -1 and sets an exception.
+// dest_out must not be null. size_out may be null.
+static int
+PyUnicode_AsPRUnichar(PyObject *obj, PRUnichar **dest_out, PRUint32 *size_out)
+{
+ PRUint32 size;
+ PyObject *s;
+ const void *src;
+ PRUnichar *dest;
+
+ s = PyUnicode_AsUTF16String(obj);
+ if (!s)
+ return -1;
+ // Drop the UTF-16 byte order mark at the beginning of
+ // the string. (See the docs on PyUnicode_AsUTF16String.)
+ // Some Mozilla libraries don't like the mark.
+#if PY_MAJOR_VERSION <= 2
+ size = (PyString_GET_SIZE(s) - 2) / sizeof(PRUnichar);
+ src = PyString_AS_STRING(s) + 2;
+#else
+ if (!PyBytes_Check(s)) {
+ PyErr_SetString(PyExc_TypeError, "internal error in PyXPCOM, parameter must be a bytes object");
+ return -1;
+ }
+ size = (PyBytes_GET_SIZE(s) - 2) / sizeof(PRUnichar);
+ src = PyBytes_AS_STRING(s) + 2;
+#endif
+ dest = (PRUnichar *)nsMemory::Alloc(sizeof(PRUnichar) * (size + 1));
+ if (!dest) {
+ PyErr_NoMemory();
+ Py_DECREF(s);
+ return -1;
+ }
+ memcpy(dest, src, sizeof(PRUnichar) * size);
+ Py_DECREF(s);
+ dest[size] = 0;
+ *dest_out = dest;
+ if (size_out)
+ *size_out = size;
+ return 0;
+}
+
+PyObject *PyObject_FromNSString( const nsACString &s, PRBool bAssumeUTF8 /*= PR_FALSE */)
+{
+ PyObject *ret;
+ if (IsNullDOMString(s)) {
+ ret = Py_None;
+ Py_INCREF(Py_None);
+ } else {
+ if (bAssumeUTF8) {
+ const nsPromiseFlatCString& temp = PromiseFlatCString(s);
+ ret = PyUnicode_DecodeUTF8(temp.get(), temp.Length(), NULL);
+ } else {
+#if PY_MAJOR_VERSION <= 2
+ ret = PyString_FromStringAndSize(NULL, s.Length());
+#else
+ ret = PyUnicode_FromStringAndSize(NULL, s.Length());
+#endif
+ if (!ret)
+ return NULL;
+ // Need "CopyAsciiTo"!?
+ nsACString::const_iterator fromBegin, fromEnd;
+#if PY_MAJOR_VERSION <= 2
+ char* dest = (char *)PyString_AS_STRING(ret);
+#else
+ char* dest = (char *)PyUnicode_AsUTF8(ret);
+#endif
+ copy_string(s.BeginReading(fromBegin), s.EndReading(fromEnd), dest);
+ }
+ }
+ return ret;
+}
+
+PyObject *PyObject_FromNSString( const nsAString &s )
+{
+ PyObject *ret;
+ if (IsNullDOMString(s)) {
+ ret = Py_None;
+ Py_INCREF(Py_None);
+ } else {
+ const nsPromiseFlatString& temp = PromiseFlatString(s);
+ ret = PyUnicode_FromPRUnichar(temp.get(), temp.Length());
+ }
+ return ret;
+}
+
+PyObject *PyObject_FromNSString( const PRUnichar *s,
+ PRUint32 len /* = (PRUint32)-1*/)
+{
+ return PyUnicode_FromPRUnichar(s,
+ len==((PRUint32)-1)? nsCRT::strlen(s) : len);
+}
+
+PRBool PyObject_AsNSString( PyObject *val, nsAString &aStr)
+{
+ if (val == Py_None) {
+ aStr.Truncate();
+ return NS_OK;
+ }
+ PyObject *val_use = NULL;
+ PRBool ok = PR_TRUE;
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ ok = PR_FALSE;
+ }
+ if (ok && (val_use = PyUnicode_FromObject(val))==NULL)
+ ok = PR_FALSE;
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ ok = PR_FALSE;
+ }
+ val_use = val;
+ Py_INCREF(val_use);
+#endif
+ if (ok) {
+ if (PyUnicode_GET_SIZE(val_use) == 0) {
+ aStr.Truncate();
+ }
+ else {
+ PRUint32 nch;
+ PRUnichar *tempo;
+ // can we do this without the copy?
+ if (PyUnicode_AsPRUnichar(val_use, &tempo, &nch) < 0)
+ return PR_FALSE;
+ aStr.Assign(tempo, nch);
+ nsMemory::Free(tempo);
+ }
+ }
+ Py_XDECREF(val_use);
+ return ok;
+}
+
+// Array utilities
+static PRUint32 GetArrayElementSize( PRUint8 t)
+{
+ PRUint32 ret;
+ switch (t & XPT_TDP_TAGMASK) {
+ case nsXPTType::T_U8:
+ case nsXPTType::T_I8:
+ ret = sizeof(PRInt8);
+ break;
+ case nsXPTType::T_I16:
+ case nsXPTType::T_U16:
+ ret = sizeof(PRInt16);
+ break;
+ case nsXPTType::T_I32:
+ case nsXPTType::T_U32:
+ ret = sizeof(PRInt32);
+ break;
+ case nsXPTType::T_I64:
+ case nsXPTType::T_U64:
+ ret = sizeof(PRInt64);
+ break;
+ case nsXPTType::T_FLOAT:
+ ret = sizeof(float);
+ break;
+ case nsXPTType::T_DOUBLE:
+ ret = sizeof(double);
+ break;
+ case nsXPTType::T_BOOL:
+ ret = sizeof(PRBool);
+ break;
+ case nsXPTType::T_CHAR:
+ ret = sizeof(char);
+ break;
+ case nsXPTType::T_WCHAR:
+ ret = sizeof(PRUnichar);
+ break;
+ case nsXPTType::T_IID:
+ case nsXPTType::T_CHAR_STR:
+ case nsXPTType::T_WCHAR_STR:
+ case nsXPTType::T_INTERFACE:
+ case nsXPTType::T_DOMSTRING:
+ case nsXPTType::T_INTERFACE_IS:
+ case nsXPTType::T_PSTRING_SIZE_IS:
+ case nsXPTType::T_CSTRING:
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_UTF8STRING:
+
+ ret = sizeof( void * );
+ break;
+ default:
+ NS_ABORT_IF_FALSE(0, "Unknown array type code!");
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+static nsresult
+GetArrayElementIID(Py_nsISupports* self,
+ nsXPTCVariant* dispatchParams,
+ PRUint16 methodIndex,
+ PRUint8 paramIndex,
+ nsIID *result)
+{
+ nsCOMPtr<nsIInterfaceInfoManager> iim = XPTI_GetInterfaceInfoManager();
+ nsCOMPtr<nsIInterfaceInfo> ii;
+ nsresult rc;
+
+ rc = iim->GetInfoForIID(&self->m_iid, getter_AddRefs(ii));
+ if (NS_FAILED(rc))
+ return rc;
+
+
+ const nsXPTMethodInfo *mi;
+ rc = ii->GetMethodInfo(methodIndex, &mi);
+ if (NS_FAILED(rc))
+ return rc;
+
+ const nsXPTParamInfo& paramInfo = mi->GetParam(paramIndex);
+
+ if (!paramInfo.GetType().IsArray()) {
+ PyXPCOM_LogWarning("Passing non-array to GetArrayElementIID\n");
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ nsXPTType elemType;
+ rc = ii->GetTypeForParam(methodIndex, &paramInfo, 1, &elemType);
+ if (NS_FAILED(rc))
+ return rc;
+
+ PRUint8 tag = elemType.TagPart();
+ if (tag == nsXPTType::T_INTERFACE)
+ {
+ rc = ii->GetIIDForParamNoAlloc(methodIndex, &paramInfo, result);
+ }
+ else if (tag == nsXPTType::T_INTERFACE_IS)
+ {
+ PyXPCOM_LogWarning("Unable to handle T_INTERFACE_IS yet\n");
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ else
+ {
+ // this may be valid case, for arrays of other types
+ // we don't need IID for
+ rc = NS_ERROR_INVALID_ARG;
+ }
+
+ return rc;
+}
+
+
+void FreeSingleArray(void *array_ptr, PRUint32 sequence_size, PRUint8 array_type)
+{
+ // Free each array element - NOT the array itself
+ // Thus, we only need to free arrays or pointers.
+ void **p = (void **)array_ptr;
+ PRUint32 i;
+ switch(array_type & XPT_TDP_TAGMASK) {
+ case nsXPTType::T_IID:
+ case nsXPTType::T_CHAR_STR:
+ case nsXPTType::T_WCHAR_STR:
+ for (i=0; i<sequence_size; i++)
+ if (p[i]) nsMemory::Free(p[i]);
+ break;
+ case nsXPTType::T_INTERFACE:
+ case nsXPTType::T_INTERFACE_IS:
+ for (i=0; i<sequence_size; i++)
+ if (p[i]) {
+ Py_BEGIN_ALLOW_THREADS; // MUST release thread-lock, incase a Python COM object that re-acquires.
+ ((nsISupports *)p[i])->Release();
+ Py_END_ALLOW_THREADS;
+ }
+ break;
+
+ // Ones we know need no deallocation
+ case nsXPTType::T_U8:
+ case nsXPTType::T_I8:
+ case nsXPTType::T_I16:
+ case nsXPTType::T_U16:
+ case nsXPTType::T_I32:
+ case nsXPTType::T_U32:
+ case nsXPTType::T_I64:
+ case nsXPTType::T_U64:
+ case nsXPTType::T_FLOAT:
+ case nsXPTType::T_DOUBLE:
+ case nsXPTType::T_BOOL:
+ case nsXPTType::T_CHAR:
+ case nsXPTType::T_WCHAR:
+ break;
+
+ // And a warning should new type codes appear, as they may need deallocation.
+ default:
+ PyXPCOM_LogWarning("Deallocating unknown type %d (0x%x) - possible memory leak\n");
+ break;
+ }
+}
+
+#define FILL_SIMPLE_POINTER( type, val ) *((type *)pthis) = (type)(val)
+#define BREAK_FALSE {rc=PR_FALSE;break;}
+
+
+PRBool FillSingleArray(void *array_ptr, PyObject *sequence_ob, PRUint32 sequence_size,
+ PRUint32 array_element_size, PRUint8 array_type, nsIID *pIID)
+{
+ PRUint8 *pthis = (PRUint8 *)array_ptr;
+ NS_ABORT_IF_FALSE(pthis, "Don't have a valid array to fill!");
+ PRBool rc = PR_TRUE;
+ // We handle T_U8 specially as a string/Unicode.
+ // If it is NOT a string, we just fall through and allow the standard
+ // sequence unpack code process it (just slower!)
+#if PY_MAJOR_VERSION <= 2
+ if ( array_type == nsXPTType::T_U8 &&
+ (PyString_Check(sequence_ob) || PyUnicode_Check(sequence_ob))) {
+#else
+ if ( array_type == nsXPTType::T_U8 && PyUnicode_Check(sequence_ob)) {
+#endif
+
+ PRBool release_seq;
+ if (PyUnicode_Check(sequence_ob)) {
+ release_seq = PR_TRUE;
+#if PY_MAJOR_VERSION <= 2
+ sequence_ob = PyObject_Str(sequence_ob);
+#else
+ sequence_ob = PyUnicode_AsUTF8String(sequence_ob);
+#endif
+ } else
+ release_seq = PR_FALSE;
+ if (!sequence_ob) // presumably a memory error, or Unicode encoding error.
+ return PR_FALSE;
+#if PY_MAJOR_VERSION <= 2
+ memcpy(pthis, PyString_AS_STRING(sequence_ob), sequence_size);
+#else
+ memcpy(pthis, PyUnicode_AsUTF8(sequence_ob), sequence_size);
+#endif
+ if (release_seq)
+ {
+ Py_DECREF(sequence_ob);
+ }
+ return PR_TRUE;
+ }
+
+ for (PRUint32 i=0; rc && i<sequence_size; i++,pthis += array_element_size) {
+ PyObject *val = PySequence_GetItem(sequence_ob, i);
+ PyObject *val_use = NULL;
+ if (val==NULL)
+ return PR_FALSE;
+ switch(array_type) {
+ case nsXPTType::T_I8:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRInt8, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_I16:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRInt16, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_I32:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRInt32, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_I64:
+ if ((val_use=PyNumber_Long(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRInt64, PyLong_AsLongLong(val_use) );
+ break;
+ case nsXPTType::T_U8:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRUint8, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_U16:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRUint16, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_U32:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRUint32, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_U64:
+ if ((val_use=PyNumber_Long(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRUint64, PyLong_AsUnsignedLongLong(val_use) );
+ break;
+ case nsXPTType::T_FLOAT:
+ if ((val_use=PyNumber_Float(val))==NULL) BREAK_FALSE
+ FILL_SIMPLE_POINTER( float, PyFloat_AsDouble(val_use) );
+ break;
+ case nsXPTType::T_DOUBLE:
+ if ((val_use=PyNumber_Float(val))==NULL) BREAK_FALSE
+ FILL_SIMPLE_POINTER( double, PyFloat_AsDouble(val_use) );
+ break;
+ case nsXPTType::T_BOOL:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE
+ FILL_SIMPLE_POINTER( PRBool, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_CHAR:
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyObject_Str(val))==NULL)
+ BREAK_FALSE;
+ // Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
+ NS_ABORT_IF_FALSE(PyString_Check(val_use), "PyObject_Str didnt return a string object!");
+ FILL_SIMPLE_POINTER( char, *PyString_AS_STRING(val_use) );
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+ FILL_SIMPLE_POINTER( char, *PyUnicode_AsUTF8(val) );
+#endif
+ break;
+
+ case nsXPTType::T_WCHAR:
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+#endif
+ if ((val_use = PyUnicode_FromObject(val)) == NULL)
+ BREAK_FALSE;
+ NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
+ // Lossy!
+#ifndef Py_LIMITED_API
+ FILL_SIMPLE_POINTER( PRUnichar, *PyUnicode_AS_UNICODE(val_use) );
+#else
+ FILL_SIMPLE_POINTER( PRUnichar, PyUnicode_ReadChar(val_use, 0) );
+#endif
+ break;
+
+ case nsXPTType::T_IID: {
+ nsIID iid;
+ if (!Py_nsIID::IIDFromPyObject(val, &iid))
+ BREAK_FALSE;
+ nsIID **pp = (nsIID **)pthis;
+ // If there is an existing IID, free it.
+ if (*pp)
+ nsMemory::Free(*pp);
+ *pp = (nsIID *)nsMemory::Alloc(sizeof(nsIID));
+ if (*pp==NULL) {
+ PyErr_NoMemory();
+ BREAK_FALSE;
+ }
+ memcpy(*pp, &iid, sizeof(iid));
+ break;
+ }
+
+ // case nsXPTType::T_BSTR:
+
+ case nsXPTType::T_CHAR_STR: {
+ // If it is an existing string, free it.
+ char **pp = (char **)pthis;
+ if (*pp)
+ nsMemory::Free(*pp);
+ *pp = nsnull;
+
+ if (val == Py_None)
+ break; // Remains NULL.
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyObject_Str(val))==NULL)
+ BREAK_FALSE;
+ // Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
+ NS_ABORT_IF_FALSE(PyString_Check(val_use), "PyObject_Str didnt return a string object!");
+
+ const char *sz = PyString_AS_STRING(val_use);
+ int nch = PyString_GET_SIZE(val_use);
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyUnicode_AsUTF8String(val))==NULL)
+ BREAK_FALSE;
+
+ const char *sz = PyBytes_AS_STRING(val_use);
+ int nch = PyBytes_GET_SIZE(val_use);
+#endif
+
+ *pp = (char *)nsMemory::Alloc(nch+1);
+ if (*pp==NULL) {
+ PyErr_NoMemory();
+ BREAK_FALSE;
+ }
+ strncpy(*pp, sz, nch+1);
+ break;
+ }
+ case nsXPTType::T_WCHAR_STR: {
+ // If it is an existing string, free it.
+ PRUnichar **pp = (PRUnichar **)pthis;
+ if (*pp)
+ nsMemory::Free(*pp);
+ *pp = nsnull;
+ if (val == Py_None)
+ break; // Remains NULL.
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyUnicode_FromObject(val))==NULL)
+ BREAK_FALSE;
+ NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+ val_use = val;
+ Py_INCREF(val_use);
+#endif
+ if (PyUnicode_AsPRUnichar(val_use, pp, NULL) < 0)
+ BREAK_FALSE;
+ break;
+ }
+ case nsXPTType::T_INTERFACE_IS: // hmm - ignoring the IID can't be good :(
+ case nsXPTType::T_INTERFACE: {
+ // We do allow NULL here, even tho doing so will no-doubt crash some objects.
+ // (but there will certainly be objects out there that will allow NULL :-(
+ nsISupports *pnew;
+ if (!Py_nsISupports::InterfaceFromPyObject(val, NS_GET_IID(nsISupports), &pnew, PR_TRUE))
+ BREAK_FALSE;
+ nsISupports **pp = (nsISupports **)pthis;
+ if (*pp) {
+ Py_BEGIN_ALLOW_THREADS; // MUST release thread-lock, incase a Python COM object that re-acquires.
+ (*pp)->Release();
+ Py_END_ALLOW_THREADS;
+ }
+ *pp = pnew; // ref-count added by InterfaceFromPyObject
+ break;
+ }
+ default:
+ // try and limp along in this case.
+ // leave rc TRUE
+ PyXPCOM_LogWarning("Converting Python object for an array element - The object type (0x%x) is unknown - leaving param alone!\n", array_type);
+ break;
+ }
+ Py_XDECREF(val_use);
+ Py_DECREF(val);
+ }
+ return rc;
+}
+
+static PyObject *UnpackSingleArray(Py_nsISupports *parent, void *array_ptr,
+ PRUint32 sequence_size, PRUint8 array_type, nsIID *iid)
+{
+ if (array_ptr==NULL) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ if (array_type == nsXPTType::T_U8)
+#if PY_MAJOR_VERSION <= 2
+ return PyString_FromStringAndSize( (char *)array_ptr, sequence_size );
+#else
+ return PyBytes_FromStringAndSize( (char *)array_ptr, sequence_size );
+#endif
+
+ PRUint32 array_element_size = GetArrayElementSize(array_type);
+ PyObject *list_ret = PyList_New(sequence_size);
+ PRUint8 *pthis = (PRUint8 *)array_ptr;
+ for (PRUint32 i=0; i<sequence_size; i++,pthis += array_element_size) {
+ PyObject *val = NULL;
+ switch(array_type) {
+ case nsXPTType::T_I8:
+ val = PyInt_FromLong( *((PRInt8 *)pthis) );
+ break;
+ case nsXPTType::T_I16:
+ val = PyInt_FromLong( *((PRInt16 *)pthis) );
+ break;
+ case nsXPTType::T_I32:
+ val = PyInt_FromLong( *((PRInt32 *)pthis) );
+ break;
+ case nsXPTType::T_I64:
+ val = PyLong_FromLongLong( *((PRInt64 *)pthis) );
+ break;
+ // case nsXPTType::T_U8 - handled above!
+ case nsXPTType::T_U16:
+ val = PyInt_FromLong( *((PRUint16 *)pthis) );
+ break;
+ case nsXPTType::T_U32:
+ val = PyInt_FromLong( *((PRUint32 *)pthis) );
+ break;
+ case nsXPTType::T_U64:
+ val = PyLong_FromUnsignedLongLong( *((PRUint64 *)pthis) );
+ break;
+ case nsXPTType::T_FLOAT:
+ val = PyFloat_FromDouble( *((float*)pthis) );
+ break;
+ case nsXPTType::T_DOUBLE:
+ val = PyFloat_FromDouble( *((double*)pthis) );
+ break;
+ case nsXPTType::T_BOOL:
+ val = (*((PRBool *)pthis)) ? Py_True : Py_False;
+ Py_INCREF(val);
+ break;
+ case nsXPTType::T_IID:
+ val = Py_nsIID::PyObjectFromIID( **((nsIID **)pthis) );
+ break;
+
+ case nsXPTType::T_CHAR_STR: {
+ char **pp = (char **)pthis;
+ if (*pp==NULL) {
+ Py_INCREF(Py_None);
+ val = Py_None;
+ } else
+#if PY_MAJOR_VERSION <= 2
+ val = PyString_FromString(*pp);
+#else
+ val = PyUnicode_FromString(*pp);
+#endif
+ break;
+ }
+ case nsXPTType::T_WCHAR_STR: {
+ PRUnichar **pp = (PRUnichar **)pthis;
+ if (*pp==NULL) {
+ Py_INCREF(Py_None);
+ val = Py_None;
+ } else {
+ val = PyUnicode_FromPRUnichar( *pp, nsCRT::strlen(*pp) );
+ }
+ break;
+ }
+ case nsXPTType::T_INTERFACE_IS:
+ case nsXPTType::T_INTERFACE: {
+ nsISupports **pp = (nsISupports **)pthis;
+ // If we have an owning parent, let it create
+ // the object for us.
+ if (iid && iid->Equals(NS_GET_IID(nsIVariant)))
+ val = PyObject_FromVariant(parent, (nsIVariant *)*pp);
+ else if (parent)
+ val = parent->MakeInterfaceResult(*pp, iid ? *iid : NS_GET_IID(nsISupports));
+ else
+ val = Py_nsISupports::PyObjectFromInterface(
+ *pp,
+ iid ? *iid : NS_GET_IID(nsISupports),
+ PR_TRUE);
+ break;
+ }
+ default: {
+ char buf[128];
+ sprintf(buf, "Unknown XPCOM array type flags (0x%x)", array_type);
+ PyXPCOM_LogWarning("%s - returning a string object with this message!\n", buf);
+#if PY_MAJOR_VERSION <= 2
+ val = PyString_FromString(buf);
+#else
+ val = PyUnicode_FromString(buf);
+#endif
+ break;
+ }
+ }
+ if (val==NULL) {
+ NS_ABORT_IF_FALSE(PyErr_Occurred(), "NULL result in array conversion, but no error set!");
+ return NULL;
+ }
+ PyList_SET_ITEM(list_ret, i, val); // ref-count consumed.
+ }
+ return list_ret;
+}
+
+
+// ------------------------------------------------------------------------
+// nsIVariant utilities
+// ------------------------------------------------------------------------
+struct BVFTResult {
+ BVFTResult() {pis = NULL;iid=Py_nsIID_NULL;}
+ nsISupports *pis;
+ nsIID iid;
+};
+
+static PRUint16 BestVariantTypeForPyObject( PyObject *ob, BVFTResult *pdata = NULL)
+{
+ nsISupports *ps = NULL;
+ nsIID iid;
+ // start with some fast concrete checks.
+ if (ob==Py_None)
+ return nsIDataType::VTYPE_EMPTY;
+ if (ob==Py_True || ob == Py_False)
+ return nsIDataType::VTYPE_BOOL;
+ if (PyInt_Check(ob))
+ return nsIDataType::VTYPE_INT32;
+ if (PyLong_Check(ob))
+ return nsIDataType::VTYPE_INT64;
+ if (PyFloat_Check(ob))
+ return nsIDataType::VTYPE_DOUBLE;
+#if PY_MAJOR_VERSION <= 2
+ if (PyString_Check(ob))
+ return nsIDataType::VTYPE_STRING_SIZE_IS;
+#endif
+ if (PyUnicode_Check(ob))
+ return nsIDataType::VTYPE_WSTRING_SIZE_IS;
+ if (PyTuple_Check(ob) || PyList_Check(ob)) {
+ if (PySequence_Length(ob))
+ return nsIDataType::VTYPE_ARRAY;
+ return nsIDataType::VTYPE_EMPTY_ARRAY;
+ }
+ // Now do expensive or abstract checks.
+ if (Py_nsISupports::InterfaceFromPyObject(ob, NS_GET_IID(nsISupports), &ps, PR_TRUE)) {
+ if (pdata) {
+ pdata->pis = ps;
+ pdata->iid = NS_GET_IID(nsISupports);
+ } else
+ ps->Release();
+ return nsIDataType::VTYPE_INTERFACE_IS;
+ } else
+ PyErr_Clear();
+ if (Py_nsIID::IIDFromPyObject(ob, &iid)) {
+ if (pdata)
+ pdata->iid = iid;
+ return nsIDataType::VTYPE_ID;
+ } else
+ PyErr_Clear();
+ if (PySequence_Check(ob)) {
+ if (PySequence_Length(ob))
+ return nsIDataType::VTYPE_ARRAY;
+ return nsIDataType::VTYPE_EMPTY_ARRAY;
+ }
+ return (PRUint16)-1;
+}
+
+nsresult PyObject_AsVariant( PyObject *ob, nsIVariant **aRet)
+{
+ nsresult nr = NS_OK;
+ nsCOMPtr<nsIWritableVariant> v = do_CreateInstance("@mozilla.org/variant;1", &nr);
+ NS_ENSURE_SUCCESS(nr, nr);
+ // *sigh* - I tried the abstract API (PyNumber_Check, etc)
+ // but our COM instances too often qualify.
+ BVFTResult cvt_result;
+ PRUint16 dt = BestVariantTypeForPyObject(ob, &cvt_result);
+ switch (dt) {
+ case nsIDataType::VTYPE_BOOL:
+ nr = v->SetAsBool(ob==Py_True);
+ break;
+ case nsIDataType::VTYPE_INT32:
+ nr = v->SetAsInt32(PyInt_AsLong(ob));
+ break;
+ case nsIDataType::VTYPE_INT64:
+ nr = v->SetAsInt64(PyLong_AsLongLong(ob));
+ break;
+ case nsIDataType::VTYPE_DOUBLE:
+ nr = v->SetAsDouble(PyFloat_AsDouble(ob));
+ break;
+ case nsIDataType::VTYPE_STRING_SIZE_IS:
+ {
+#if PY_MAJOR_VERSION <= 2
+ nr = v->SetAsStringWithSize(PyString_Size(ob), PyString_AsString(ob));
+#else
+ Py_ssize_t cb = 0;
+ const char *psz = PyUnicode_AsUTF8AndSize(ob, &cb);
+ nr = v->SetAsStringWithSize(cb, psz);
+#endif
+ break;
+ }
+ case nsIDataType::VTYPE_WSTRING_SIZE_IS:
+#if PY_VERSION_HEX >= 0x03030000
+ if (PyUnicode_GetLength(ob) == 0) {
+#else
+ if (PyUnicode_GetSize(ob) == 0) {
+#endif
+ nr = v->SetAsWStringWithSize(0, (PRUnichar*)NULL);
+ }
+ else {
+ PRUint32 nch;
+ PRUnichar *p;
+ if (PyUnicode_AsPRUnichar(ob, &p, &nch) < 0) {
+ PyXPCOM_LogWarning("Failed to convert object to unicode", PyXPCOM_ObTypeName(ob));
+ nr = NS_ERROR_UNEXPECTED;
+ break;
+ }
+ nr = v->SetAsWStringWithSize(nch, p);
+ nsMemory::Free(p);
+ }
+ break;
+ case nsIDataType::VTYPE_INTERFACE_IS:
+ {
+ nsISupports *ps = cvt_result.pis;
+ nr = v->SetAsInterface(cvt_result.iid, ps);
+ if (ps) {
+ Py_BEGIN_ALLOW_THREADS; // MUST release thread-lock, incase a Python COM object that re-acquires.
+ ps->Release();
+ Py_END_ALLOW_THREADS;
+ }
+ break;
+ }
+ case nsIDataType::VTYPE_ID:
+ nr = v->SetAsID(cvt_result.iid);
+ break;
+ case nsIDataType::VTYPE_ARRAY:
+ {
+ int seq_length = PySequence_Length(ob);
+ NS_ABORT_IF_FALSE(seq_length!=0, "VTYPE_ARRAY assumes at least one element!");
+ PyObject *first = PySequence_GetItem(ob, 0);
+ if (!first) break;
+ int array_type = BestVariantTypeForPyObject(first);
+ Py_DECREF(first);
+ // Arrays can't handle all types. This means we lost embedded NULLs.
+ // This should really be fixed in XPCOM.
+ if (array_type == nsIDataType::VTYPE_STRING_SIZE_IS) array_type = nsIDataType::VTYPE_CHAR_STR;
+ if (array_type == nsIDataType::VTYPE_WSTRING_SIZE_IS) array_type = nsIDataType::VTYPE_WCHAR_STR;
+ PRUint32 element_size = GetArrayElementSize(array_type);
+ int cb_buffer_pointer = seq_length * element_size;
+ void *buffer_pointer;
+ if ((buffer_pointer = (void *)nsMemory::Alloc(cb_buffer_pointer)) == nsnull) {
+ nr = NS_ERROR_OUT_OF_MEMORY;
+ break;
+ }
+ memset(buffer_pointer, 0, cb_buffer_pointer);
+ if (FillSingleArray(buffer_pointer, ob, seq_length, element_size, array_type, nsnull)) {
+ nr = v->SetAsArray(array_type, &NS_GET_IID(nsISupports), seq_length, buffer_pointer);
+ FreeSingleArray(buffer_pointer, seq_length, array_type);
+ } else
+ nr = NS_ERROR_UNEXPECTED;
+ nsMemory::Free(buffer_pointer);
+ break;
+ }
+ case nsIDataType::VTYPE_EMPTY:
+ nr = v->SetAsEmpty();
+ break;
+ case nsIDataType::VTYPE_EMPTY_ARRAY:
+ nr = v->SetAsEmptyArray();
+ break;
+ case (PRUint16)-1:
+ PyXPCOM_LogWarning("Objects of type '%s' can not be converted to an nsIVariant", PyXPCOM_ObTypeName(ob));
+ nr = NS_ERROR_UNEXPECTED;
+ default:
+ NS_ABORT_IF_FALSE(0, "BestVariantTypeForPyObject() returned a variant type not handled here!");
+ PyXPCOM_LogWarning("Objects of type '%s' can not be converted to an nsIVariant", PyXPCOM_ObTypeName(ob));
+ nr = NS_ERROR_UNEXPECTED;
+ }
+ if (NS_FAILED(nr))
+ return nr;
+ return v->QueryInterface(NS_GET_IID(nsIVariant), (void **)aRet);
+}
+
+static PyObject *MyBool_FromBool(PRBool v)
+{
+ PyObject *ret = v ? Py_True : Py_False;
+ Py_INCREF(ret);
+ return ret;
+}
+
+#define GET_FROM_V(Type, FuncGet, FuncConvert) { \
+ Type t; \
+ if (NS_FAILED(nr = FuncGet( &t ))) goto done;\
+ ret = FuncConvert(t);\
+ break; \
+}
+
+PyObject *PyObject_FromVariantArray( Py_nsISupports *parent, nsIVariant *v)
+{
+ nsresult nr;
+ NS_PRECONDITION(v, "NULL variant!");
+ if (!v)
+ return PyXPCOM_BuildPyException(NS_ERROR_INVALID_POINTER);
+#ifdef NS_DEBUG
+ PRUint16 dt;
+ nr = v->GetDataType(&dt);
+ NS_ABORT_IF_FALSE(dt == nsIDataType::VTYPE_ARRAY, "expected an array variant");
+#endif
+ nsIID iid;
+ void *p;
+ PRUint16 type;
+ PRUint32 count;
+ nr = v->GetAsArray(&type, &iid, &count, &p);
+ if (NS_FAILED(nr)) return PyXPCOM_BuildPyException(nr);
+ PyObject *ret = UnpackSingleArray(parent, p, count, (PRUint8)type, &iid);
+ FreeSingleArray(p, count, (PRUint8)type);
+ nsMemory::Free(p);
+ return ret;
+}
+
+PyObject *PyObject_FromVariant( Py_nsISupports *parent, nsIVariant *v)
+{
+ if (!v) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ PRUint16 dt;
+ nsresult nr;
+ PyObject *ret = NULL;
+ nr = v->GetDataType(&dt);
+ if (NS_FAILED(nr)) goto done;
+ switch (dt) {
+ case nsIDataType::VTYPE_VOID:
+ case nsIDataType::VTYPE_EMPTY:
+ case nsIDataType::VTYPE_EMPTY_ARRAY:
+ ret = Py_None;
+ Py_INCREF(Py_None);
+ break;
+ case nsIDataType::VTYPE_ARRAY:
+ ret = PyObject_FromVariantArray(parent, v);
+ break;
+ case nsIDataType::VTYPE_INT8:
+ case nsIDataType::VTYPE_INT16:
+ case nsIDataType::VTYPE_INT32:
+ GET_FROM_V(PRInt32, v->GetAsInt32, PyInt_FromLong);
+ case nsIDataType::VTYPE_UINT8:
+ case nsIDataType::VTYPE_UINT16:
+ case nsIDataType::VTYPE_UINT32:
+ GET_FROM_V(PRUint32, v->GetAsUint32, PyLong_FromUnsignedLong);
+ case nsIDataType::VTYPE_INT64:
+ GET_FROM_V(PRInt64, v->GetAsInt64, PyLong_FromLongLong);
+ case nsIDataType::VTYPE_UINT64:
+ GET_FROM_V(PRUint64, v->GetAsUint64, PyLong_FromUnsignedLongLong);
+ case nsIDataType::VTYPE_FLOAT:
+ case nsIDataType::VTYPE_DOUBLE:
+ GET_FROM_V(double, v->GetAsDouble, PyFloat_FromDouble);
+ case nsIDataType::VTYPE_BOOL:
+ GET_FROM_V(PRBool, v->GetAsBool, MyBool_FromBool);
+ default:
+ PyXPCOM_LogWarning("Converting variant to Python object - variant type '%d' unknown - using string.\n", dt);
+ // Fall through to the string case
+ case nsIDataType::VTYPE_CHAR:
+ case nsIDataType::VTYPE_CHAR_STR:
+ case nsIDataType::VTYPE_STRING_SIZE_IS:
+ case nsIDataType::VTYPE_CSTRING: {
+ nsCAutoString s;
+ if (NS_FAILED(nr=v->GetAsACString(s))) goto done;
+ ret = PyObject_FromNSString(s);
+ break;
+ }
+ case nsIDataType::VTYPE_WCHAR:
+ case nsIDataType::VTYPE_DOMSTRING:
+ case nsIDataType::VTYPE_WSTRING_SIZE_IS:
+ case nsIDataType::VTYPE_ASTRING: {
+ nsAutoString s;
+ if (NS_FAILED(nr=v->GetAsAString(s))) goto done;
+ ret = PyObject_FromNSString(s);
+ break;
+ }
+ case nsIDataType::VTYPE_ID:
+ GET_FROM_V(nsIID, v->GetAsID, Py_nsIID::PyObjectFromIID);
+ case nsIDataType::VTYPE_INTERFACE: {
+ nsCOMPtr<nsISupports> p;
+ if (NS_FAILED(nr=v->GetAsISupports(getter_AddRefs(p)))) goto done;
+ if (parent)
+ ret = parent->MakeInterfaceResult(p, NS_GET_IID(nsISupports));
+ else
+ ret = Py_nsISupports::PyObjectFromInterface(
+ p, NS_GET_IID(nsISupports), PR_TRUE);
+ break;
+ }
+ case nsIDataType::VTYPE_INTERFACE_IS: {
+ nsCOMPtr<nsISupports> p;
+ nsIID *iid;
+ if (NS_FAILED(nr=v->GetAsInterface(&iid, getter_AddRefs(p)))) goto done;
+ // If the variant itself holds a variant, we should
+ // probably unpack that too?
+ ret = parent->MakeInterfaceResult(p, *iid);
+ break;
+ // case nsIDataType::VTYPE_WCHAR_STR
+ // case nsIDataType::VTYPE_UTF8STRING
+ }
+ }
+done:
+ if (NS_FAILED(nr)) {
+ NS_ABORT_IF_FALSE(ret==NULL, "Have an error, but also a return val!");
+ PyXPCOM_BuildPyException(nr);
+ }
+ return ret;
+}
+
+// ------------------------------------------------------------------------
+// TypeDescriptor helper class
+// ------------------------------------------------------------------------
+class PythonTypeDescriptor {
+public:
+ PythonTypeDescriptor() {
+ param_flags = type_flags = argnum = argnum2 = 0;
+ extra = NULL;
+ is_auto_out = PR_FALSE;
+ is_auto_in = PR_FALSE;
+ have_set_auto = PR_FALSE;
+ }
+ ~PythonTypeDescriptor() {
+ Py_XDECREF(extra);
+ }
+ PRUint8 param_flags;
+ PRUint8 type_flags;
+ PRUint8 argnum; /* used for iid_is and size_is */
+ PRUint8 argnum2; /* used for length_is */
+ PyObject *extra; // The IID object, or the type of the array.
+ // Extra items to help our processing.
+ // Is this auto-filled by some other "in" param?
+ PRBool is_auto_in;
+ // Is this auto-filled by some other "out" param?
+ PRBool is_auto_out;
+ // If is_auto_out, have I already filled it? Used when multiple
+ // params share a size_is fields - first time sets it, subsequent
+ // time check it.
+ PRBool have_set_auto;
+};
+
+static int ProcessPythonTypeDescriptors(PythonTypeDescriptor *pdescs, int num)
+{
+ // Loop over the array, checking all the params marked as having an arg.
+ // If these args nominate another arg as the size_is param, then
+ // we reset the size_is param to _not_ requiring an arg.
+ int i;
+ for (i=0;i<num;i++) {
+ PythonTypeDescriptor &ptd = pdescs[i];
+ // Can't use XPT_TDP_TAG() - it uses a ".flags" reference in the macro.
+ switch (ptd.type_flags & XPT_TDP_TAGMASK) {
+ case nsXPTType::T_ARRAY:
+ NS_ABORT_IF_FALSE(ptd.argnum < num, "Bad dependent index");
+ if (ptd.argnum2 < num) {
+ if (XPT_PD_IS_IN(ptd.param_flags))
+ pdescs[ptd.argnum2].is_auto_in = PR_TRUE;
+ if (XPT_PD_IS_OUT(ptd.param_flags))
+ pdescs[ptd.argnum2].is_auto_out = PR_TRUE;
+ }
+ break;
+ case nsXPTType::T_PSTRING_SIZE_IS:
+ case nsXPTType::T_PWSTRING_SIZE_IS:
+ NS_ABORT_IF_FALSE(ptd.argnum < num, "Bad dependent index");
+ if (ptd.argnum < num) {
+ if (XPT_PD_IS_IN(ptd.param_flags))
+ pdescs[ptd.argnum].is_auto_in = PR_TRUE;
+ if (XPT_PD_IS_OUT(ptd.param_flags))
+ pdescs[ptd.argnum].is_auto_out = PR_TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ int total_params_needed = 0;
+ for (i=0;i<num;i++)
+ if (XPT_PD_IS_IN(pdescs[i].param_flags) && !pdescs[i].is_auto_in && !XPT_PD_IS_DIPPER(pdescs[i].param_flags))
+ total_params_needed++;
+
+ return total_params_needed;
+}
+
+/*************************************************************************
+**************************************************************************
+
+Helpers when CALLING interfaces.
+
+**************************************************************************
+*************************************************************************/
+
+PyXPCOM_InterfaceVariantHelper::PyXPCOM_InterfaceVariantHelper(Py_nsISupports *parent, int methodindex)
+{
+ m_var_array=nsnull;
+ m_buffer_array=nsnull;
+ m_pyparams=nsnull;
+ m_typedescs = nsnull;
+ m_python_type_desc_array = nsnull;
+ m_num_array = 0;
+ m_methodindex = methodindex;
+ // Parent should never die before we do, but let's not take the chance.
+ m_parent = parent;
+ Py_INCREF(parent);
+}
+
+PyXPCOM_InterfaceVariantHelper::~PyXPCOM_InterfaceVariantHelper()
+{
+ Py_DECREF(m_parent);
+ Py_XDECREF(m_pyparams);
+ for (int i=0;i<m_num_array;i++) {
+ if (m_var_array) {
+ nsXPTCVariant &ns_v = m_var_array[i];
+ if (ns_v.IsValInterface()) {
+ if (ns_v.val.p) {
+ Py_BEGIN_ALLOW_THREADS; // MUST release thread-lock, incase a Python COM object that re-acquires.
+ ((nsISupports *)ns_v.val.p)->Release();
+ Py_END_ALLOW_THREADS;
+ }
+ }
+ if (ns_v.IsValDOMString() && ns_v.val.p) {
+ delete (const nsAString *)ns_v.val.p;
+ }
+ if (ns_v.IsValCString() && ns_v.val.p) {
+ delete (const nsACString *)ns_v.val.p;
+ }
+ if (ns_v.IsValUTF8String() && ns_v.val.p) {
+ delete (const nsACString *)ns_v.val.p;
+ }
+ if (ns_v.IsValArray()) {
+ nsXPTCVariant &ns_v = m_var_array[i];
+ if (ns_v.val.p) {
+ PRUint8 array_type = (PRUint8)PyInt_AsLong(m_python_type_desc_array[i].extra);
+ PRUint32 seq_size = GetSizeIs(i, PR_FALSE);
+ FreeSingleArray(ns_v.val.p, seq_size, array_type);
+ }
+ }
+ // IsOwned must be the last check of the loop, as
+ // this frees the underlying data used above (eg, by the array free process)
+ if (ns_v.IsValAllocated() && !ns_v.IsValInterface() && !ns_v.IsValDOMString()) {
+ NS_ABORT_IF_FALSE(ns_v.IsPtrData(), "expecting a pointer to free");
+ nsMemory::Free(ns_v.val.p);
+ }
+ }
+ if (m_buffer_array && m_buffer_array[i])
+ nsMemory::Free(m_buffer_array[i]);
+ }
+ delete [] m_python_type_desc_array;
+ delete [] m_buffer_array;
+ delete [] m_var_array;
+}
+
+PRBool PyXPCOM_InterfaceVariantHelper::Init(PyObject *obParams)
+{
+ PRBool ok = PR_FALSE;
+ int i;
+ int total_params_needed = 0;
+ if (!PySequence_Check(obParams) || PySequence_Length(obParams)!=2) {
+ PyErr_Format(PyExc_TypeError, "Param descriptors must be a sequence of exactly length 2");
+ return PR_FALSE;
+ }
+ PyObject *typedescs = PySequence_GetItem(obParams, 0);
+ if (typedescs==NULL)
+ return PR_FALSE;
+ // NOTE: The length of the typedescs may be different than the
+ // args actually passed. The typedescs always include all
+ // hidden params (such as "size_is"), while the actual
+ // args never include this.
+ m_num_array = PySequence_Length(typedescs);
+ if (PyErr_Occurred()) goto done;
+
+ m_pyparams = PySequence_GetItem(obParams, 1);
+ if (m_pyparams==NULL) goto done;
+
+ m_python_type_desc_array = new PythonTypeDescriptor[m_num_array];
+ if (!m_python_type_desc_array) goto done;
+
+ // Pull apart the type descs and stash them.
+ for (i=0;i<m_num_array;i++) {
+ PyObject *desc_object = PySequence_GetItem(typedescs, i);
+ if (desc_object==NULL)
+ goto done;
+
+ // Pull apart the typedesc tuple back into a structure we can work with.
+ PythonTypeDescriptor &ptd = m_python_type_desc_array[i];
+ PRBool this_ok = PyArg_ParseTuple(desc_object, "bbbbO:type_desc",
+ &ptd.param_flags, &ptd.type_flags, &ptd.argnum, &ptd.argnum2, &ptd.extra);
+ Py_DECREF(desc_object);
+ if (!this_ok) goto done;
+ Py_INCREF(ptd.extra);
+
+ }
+ total_params_needed = ProcessPythonTypeDescriptors(m_python_type_desc_array, m_num_array);
+ // OK - check we got the number of args we expected.
+ // If not, its really an internal error rather than the user.
+ if (PySequence_Length(m_pyparams) != total_params_needed) {
+#ifdef VBOX
+ PyErr_Format(PyExc_ValueError, "The type descriptions indicate %d args are needed, but %ld were provided",
+ total_params_needed, (long)PySequence_Length(m_pyparams));
+#else
+ PyErr_Format(PyExc_ValueError, "The type descriptions indicate %d args are needed, but %d were provided",
+ total_params_needed, PySequence_Length(m_pyparams));
+#endif
+ goto done;
+ }
+
+ // Init the other arrays.
+ m_var_array = new nsXPTCVariant[m_num_array];
+ if (!m_var_array) goto done;
+ /*memset(m_var_array, 0, m_num_array * sizeof(m_var_array[0])); - VBox not needed */
+
+ m_buffer_array = new void *[m_num_array];
+ if (!m_buffer_array) goto done;
+ memset(m_buffer_array, 0, m_num_array * sizeof(m_buffer_array[0]));
+
+ ok = PR_TRUE;
+done:
+ if (!ok && !PyErr_Occurred())
+ PyErr_NoMemory();
+
+ Py_XDECREF(typedescs);
+ return ok;
+}
+
+
+PRBool PyXPCOM_InterfaceVariantHelper::FillArray()
+{
+ int param_index = 0;
+ int i;
+ for (i=0;i<m_num_array;i++) {
+ PythonTypeDescriptor &ptd = m_python_type_desc_array[i];
+ // stash the type_flags into the variant, and remember how many extra bits of info we have.
+ m_var_array[i].type = ptd.type_flags;
+ if (XPT_PD_IS_IN(ptd.param_flags) && !ptd.is_auto_in && !XPT_PD_IS_DIPPER(ptd.param_flags)) {
+ if (!FillInVariant(ptd, i, param_index))
+ return PR_FALSE;
+ param_index++;
+ }
+ if ((XPT_PD_IS_OUT(ptd.param_flags) && !ptd.is_auto_out) || XPT_PD_IS_DIPPER(ptd.param_flags)) {
+ if (!PrepareOutVariant(ptd, i))
+ return PR_FALSE;
+ }
+ }
+ // There may be out "size_is" params we havent touched yet
+ // (ie, as the param itself is marked "out", we never got to
+ // touch the associated "size_is".
+ // Final loop to handle this.
+ for (i=0;i<m_num_array;i++) {
+ PythonTypeDescriptor &ptd = m_python_type_desc_array[i];
+ if (ptd.is_auto_out && !ptd.have_set_auto) {
+ // Call PrepareOutVariant to ensure buffers etc setup.
+ if (!PrepareOutVariant(ptd, i))
+ return PR_FALSE;
+ }
+ }
+ return PR_TRUE;
+}
+
+
+PRBool PyXPCOM_InterfaceVariantHelper::SetSizeIs( int var_index, PRBool is_arg1, PRUint32 new_size)
+{
+ NS_ABORT_IF_FALSE(var_index < m_num_array, "var_index param is invalid");
+ PRUint8 argnum = is_arg1 ?
+ m_python_type_desc_array[var_index].argnum :
+ m_python_type_desc_array[var_index].argnum2;
+ NS_ABORT_IF_FALSE(argnum < m_num_array, "size_is param is invalid");
+ PythonTypeDescriptor &td_size = m_python_type_desc_array[argnum];
+ NS_ABORT_IF_FALSE(td_size.is_auto_in || td_size.is_auto_out, "Setting size_is, but param is not marked as auto!");
+ NS_ABORT_IF_FALSE( (td_size.type_flags & XPT_TDP_TAGMASK) == nsXPTType::T_U32, "size param must be Uint32");
+ nsXPTCVariant &ns_v = m_var_array[argnum];
+
+ if (!td_size.have_set_auto) {
+ ns_v.type = td_size.type_flags;
+ ns_v.val.u32 = new_size;
+ // In case it is "out", setup the necessary pointers.
+ PrepareOutVariant(td_size, argnum);
+ td_size.have_set_auto = PR_TRUE;
+ } else {
+ if (ns_v.val.u32 != new_size) {
+ PyErr_Format(PyExc_ValueError, "Array lengths inconsistent; array size previously set to %d, but second array is of size %d", ns_v.val.u32, new_size);
+ return PR_FALSE;
+ }
+ }
+ return PR_TRUE;
+}
+
+PRUint32 PyXPCOM_InterfaceVariantHelper::GetSizeIs( int var_index, PRBool is_arg1)
+{
+ NS_ABORT_IF_FALSE(var_index < m_num_array, "var_index param is invalid");
+ PRUint8 argnum = is_arg1 ?
+ m_python_type_desc_array[var_index].argnum :
+ m_python_type_desc_array[var_index].argnum2;
+ NS_ABORT_IF_FALSE(argnum < m_num_array, "size_is param is invalid");
+ NS_ABORT_IF_FALSE( (m_python_type_desc_array[argnum].type_flags & XPT_TDP_TAGMASK) == nsXPTType::T_U32, "size param must be Uint32");
+ PRBool is_out = XPT_PD_IS_OUT(m_python_type_desc_array[argnum].param_flags);
+ nsXPTCVariant &ns_v = m_var_array[argnum];
+ return is_out ? *((PRUint32 *)ns_v.ptr) : ns_v.val.u32;
+}
+
+#define MAKE_VALUE_BUFFER(size) \
+ if ((this_buffer_pointer = (void *)nsMemory::Alloc((size))) == nsnull) { \
+ PyErr_NoMemory(); \
+ BREAK_FALSE; \
+ }
+
+PRBool PyXPCOM_InterfaceVariantHelper::FillInVariant(const PythonTypeDescriptor &td, int value_index, int param_index)
+{
+ PRBool rc = PR_TRUE;
+ // Get a reference to the variant we are filling for convenience.
+ nsXPTCVariant &ns_v = m_var_array[value_index];
+ NS_ABORT_IF_FALSE(ns_v.type == td.type_flags, "Expecting variant all setup for us");
+
+ // We used to avoid passing internal buffers to PyString etc objects
+ // for 2 reasons: paranoia (so incorrect external components couldn't break
+ // Python) and simplicity (in vs in-out issues, etc)
+ // However, at least one C++ implemented component (nsITimelineService)
+ // uses a "char *", and keys on the address (assuming that the same
+ // *pointer* is passed rather than value. Therefore, we have a special case
+ // - T_CHAR_STR that is "in" gets the Python string pointer passed.
+ void *&this_buffer_pointer = m_buffer_array[value_index]; // Freed at object destruction with PyMem_Free()
+ NS_ABORT_IF_FALSE(this_buffer_pointer==nsnull, "We appear to already have a buffer");
+ int cb_this_buffer_pointer = 0;
+ if (XPT_PD_IS_IN(td.param_flags)) {
+ NS_ABORT_IF_FALSE(!td.is_auto_in, "Param is 'auto-in', but we are filling it normally!");
+ PyObject *val_use = NULL; // a temp object converters can use, and will be DECREF'd
+ PyObject *val = PySequence_GetItem(m_pyparams, param_index);
+ NS_WARN_IF_FALSE(val, "Have an 'in' param, but no Python value!");
+ if (val==NULL) {
+ PyErr_Format(PyExc_ValueError, "Param %d is marked as 'in', but no value was given", value_index);
+ return PR_FALSE;
+ }
+ switch (XPT_TDP_TAG(ns_v.type)) {
+ case nsXPTType::T_I8:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE
+ ns_v.val.i8 = (PRInt8)PyInt_AsLong(val_use);
+ break;
+ case nsXPTType::T_I16:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE
+ ns_v.val.i16 = (PRInt16)PyInt_AsLong(val_use);
+ break;
+ case nsXPTType::T_I32:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE
+ ns_v.val.i32 = (PRInt32)PyInt_AsLong(val_use);
+ break;
+ case nsXPTType::T_I64:
+ if ((val_use=PyNumber_Long(val))==NULL) BREAK_FALSE
+ ns_v.val.i64 = (PRInt64)PyLong_AsLongLong(val_use);
+ break;
+ case nsXPTType::T_U8:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE
+ ns_v.val.u8 = (PRUint8)PyInt_AsLong(val_use);
+ break;
+ case nsXPTType::T_U16:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE
+ ns_v.val.u16 = (PRUint16)PyInt_AsLong(val_use);
+ break;
+ case nsXPTType::T_U32:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE
+ ns_v.val.u32 = (PRUint32)PyInt_AsLong(val_use);
+ break;
+ case nsXPTType::T_U64:
+ if ((val_use=PyNumber_Long(val))==NULL) BREAK_FALSE
+ ns_v.val.u64 = (PRUint64)PyLong_AsUnsignedLongLong(val_use);
+ break;
+ case nsXPTType::T_FLOAT:
+ if ((val_use=PyNumber_Float(val))==NULL) BREAK_FALSE
+ ns_v.val.f = (float)PyFloat_AsDouble(val_use);
+ break;
+ case nsXPTType::T_DOUBLE:
+ if ((val_use=PyNumber_Float(val))==NULL) BREAK_FALSE
+ ns_v.val.d = PyFloat_AsDouble(val_use);
+ break;
+ case nsXPTType::T_BOOL:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE
+ ns_v.val.b = (PRBool)PyInt_AsLong(val_use);
+ break;
+ case nsXPTType::T_CHAR:{
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyObject_Str(val))==NULL)
+ BREAK_FALSE;
+ // Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
+ NS_ABORT_IF_FALSE(PyString_Check(val_use), "PyObject_Str didnt return a string object!");
+ if (PyString_GET_SIZE(val_use) != 1) {
+ PyErr_SetString(PyExc_ValueError, "Must specify a one character string for a character");
+ BREAK_FALSE;
+ }
+
+ ns_v.val.c = *PyString_AS_STRING(val_use);
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+ if (PyUnicode_GET_SIZE(val) != 1) {
+ PyErr_SetString(PyExc_ValueError, "Must specify a one character string for a character");
+ BREAK_FALSE;
+ }
+
+# ifndef Py_LIMITED_API
+ ns_v.val.c = *PyUnicode_AS_UNICODE(val_use);
+# else
+ ns_v.val.c = PyUnicode_ReadChar(val_use, 0);
+# endif
+#endif
+ break;
+ }
+
+ case nsXPTType::T_WCHAR: {
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+#endif
+ if ((val_use = PyUnicode_FromObject(val))==NULL)
+ BREAK_FALSE;
+ // Sanity check should PyUnicode_FromObject() ever loosen its semantics wrt Unicode!
+ NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a unicode object!");
+ if (PyUnicode_GET_SIZE(val_use) != 1) {
+ PyErr_SetString(PyExc_ValueError, "Must specify a one character string for a character");
+ BREAK_FALSE;
+ }
+ // Lossy!
+#ifndef Py_LIMITED_API
+ ns_v.val.wc = *PyUnicode_AS_UNICODE(val_use);
+#else
+ ns_v.val.wc = PyUnicode_ReadChar(val_use, 0);
+#endif
+ break;
+ }
+ // case nsXPTType::T_VOID: /* fall through */
+ case nsXPTType::T_IID:
+ nsIID iid;
+ MAKE_VALUE_BUFFER(sizeof(nsIID));
+ if (!Py_nsIID::IIDFromPyObject(val, &iid))
+ BREAK_FALSE;
+ memcpy(this_buffer_pointer, &iid, sizeof(iid));
+ ns_v.val.p = this_buffer_pointer;
+ break;
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING: {
+ nsString *s = new nsString();
+ if (!s) {
+ PyErr_NoMemory();
+ BREAK_FALSE;
+ }
+ ns_v.val.p = s;
+ // We created it - flag as such for cleanup.
+ ns_v.flags |= nsXPTCVariant::VAL_IS_DOMSTR;
+
+ if (!PyObject_AsNSString(val, *s))
+ BREAK_FALSE;
+ break;
+ }
+ case nsXPTType::T_CSTRING:
+ case nsXPTType::T_UTF8STRING: {
+ PRBool bIsUTF8 = XPT_TDP_TAG(ns_v.type) == nsXPTType::T_UTF8STRING;
+ if (val==Py_None) {
+ ns_v.val.p = new nsCString();
+ } else {
+#if PY_MAJOR_VERSION <= 2
+ if (PyString_Check(val)) {
+ // strings are assumed to already be UTF8 encoded.
+ val_use = val;
+ Py_INCREF(val);
+ }
+ else
+#endif
+ if (PyUnicode_Check(val)) {
+ // Unicode objects are encoded by us.
+ if (bIsUTF8)
+ val_use = PyUnicode_AsUTF8String(val);
+ else
+#if PY_MAJOR_VERSION <= 2
+ val_use = PyObject_Str(val);
+#else
+ val_use = PyUnicode_AsUTF8String(val);
+#endif
+ } else {
+#if PY_MAJOR_VERSION <= 2
+ PyErr_SetString(PyExc_TypeError, "UTF8 parameters must be string or Unicode objects");
+#else
+ PyErr_SetString(PyExc_TypeError, "UTF8 parameters must be unicode objects");
+#endif
+ BREAK_FALSE;
+ }
+ if (!val_use)
+ BREAK_FALSE;
+#if PY_MAJOR_VERSION <= 2
+ ns_v.val.p = new nsCString(PyString_AS_STRING(val_use),
+ PyString_GET_SIZE(val_use));
+#else
+ ns_v.val.p = new nsCString(PyBytes_AS_STRING(val_use),
+ PyBytes_GET_SIZE(val_use));
+#endif
+ }
+
+ if (!ns_v.val.p) {
+ PyErr_NoMemory();
+ BREAK_FALSE;
+ }
+ // We created it - flag as such for cleanup.
+ ns_v.flags |= bIsUTF8 ? nsXPTCVariant::VAL_IS_UTF8STR : nsXPTCVariant::VAL_IS_CSTR;
+ break;
+ }
+ case nsXPTType::T_CHAR_STR: {
+ if (val==Py_None) {
+ ns_v.val.p = nsnull;
+ break;
+ }
+#if PY_MAJOR_VERSION <= 2
+ // If an "in" char *, and we have a PyString, then pass the
+ // pointer (hoping everyone else plays by the rules too.
+ if (!XPT_PD_IS_OUT(td.param_flags) && PyString_Check(val)) {
+ ns_v.val.p = (void *)PyString_AS_STRING(val);
+ break;
+ }
+
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyObject_Str(val))==NULL)
+ BREAK_FALSE;
+ // Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
+ NS_ABORT_IF_FALSE(PyString_Check(val_use), "PyObject_Str didnt return a string object!");
+
+ cb_this_buffer_pointer = PyString_GET_SIZE(val_use)+1;
+ MAKE_VALUE_BUFFER(cb_this_buffer_pointer);
+ memcpy(this_buffer_pointer, PyString_AS_STRING(val_use), cb_this_buffer_pointer);
+#else
+
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyUnicode_AsUTF8String(val))==NULL)
+ BREAK_FALSE;
+
+ cb_this_buffer_pointer = PyBytes_GET_SIZE(val_use)+1;
+ MAKE_VALUE_BUFFER(cb_this_buffer_pointer);
+ memcpy(this_buffer_pointer, PyBytes_AS_STRING(val_use), cb_this_buffer_pointer);
+#endif
+ ns_v.val.p = this_buffer_pointer;
+ break;
+ }
+
+ case nsXPTType::T_WCHAR_STR: {
+ if (val==Py_None) {
+ ns_v.val.p = nsnull;
+ break;
+ }
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyUnicode_FromObject(val))==NULL)
+ BREAK_FALSE;
+ NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+ val_use = val;
+ Py_INCREF(val_use);
+#endif
+ PRUnichar *sv;
+ PRUint32 nch;
+ if (PyUnicode_AsPRUnichar(val_use, &sv, &nch) < 0)
+ BREAK_FALSE;
+ cb_this_buffer_pointer = (nch + 1) * sizeof(PRUnichar);
+ this_buffer_pointer = sv;
+ ns_v.val.p = this_buffer_pointer;
+ break;
+ }
+ case nsXPTType::T_INTERFACE: {
+ nsIID iid;
+ if (!Py_nsIID::IIDFromPyObject(td.extra, &iid))
+ BREAK_FALSE;
+ if (!Py_nsISupports::InterfaceFromPyObject(
+ val,
+ iid,
+ (nsISupports **)&ns_v.val.p,
+ PR_TRUE))
+ BREAK_FALSE;
+ // We have added a reference - flag as such for cleanup.
+ ns_v.flags |= nsXPTCVariant::VAL_IS_IFACE;
+ break;
+ }
+ case nsXPTType::T_INTERFACE_IS: {
+ nsIID iid;
+ nsXPTCVariant &ns_viid = m_var_array[td.argnum];
+ NS_WARN_IF_FALSE(XPT_TDP_TAG(ns_viid.type)==nsXPTType::T_IID, "The INTERFACE_IS iid describer isnt an IID!");
+ // This is a pretty serious problem, but not Python's fault!
+ // Just return an nsISupports and hope the caller does whatever
+ // QI they need before using it.
+ if (XPT_TDP_TAG(ns_viid.type)==nsXPTType::T_IID &&
+ XPT_PD_IS_IN(ns_viid.type)) {
+ nsIID *piid = (nsIID *)ns_viid.val.p;
+ if (piid==NULL)
+ // Also serious, but like below, not our fault!
+ iid = NS_GET_IID(nsISupports);
+ else
+ iid = *piid;
+ } else
+ // Use NULL IID to avoid a QI in this case.
+ iid = Py_nsIID_NULL;
+ if (!Py_nsISupports::InterfaceFromPyObject(
+ val,
+ iid,
+ (nsISupports **)&ns_v.val.p,
+ PR_TRUE))
+ BREAK_FALSE;
+ // We have added a reference - flag as such for cleanup.
+ ns_v.flags |= nsXPTCVariant::VAL_IS_IFACE;
+ break;
+ }
+ case nsXPTType::T_PSTRING_SIZE_IS: {
+ if (val==Py_None) {
+ ns_v.val.p = nsnull;
+ break;
+ }
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyObject_Str(val))==NULL)
+ BREAK_FALSE;
+ // Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
+ NS_ABORT_IF_FALSE(PyString_Check(val_use), "PyObject_Str didnt return a string object!");
+
+ cb_this_buffer_pointer = PyString_GET_SIZE(val_use);
+ MAKE_VALUE_BUFFER(cb_this_buffer_pointer);
+ memcpy(this_buffer_pointer, PyString_AS_STRING(val_use), cb_this_buffer_pointer);
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyUnicode_AsUTF8String(val))==NULL)
+ BREAK_FALSE;
+
+ cb_this_buffer_pointer = PyBytes_GET_SIZE(val_use);
+ MAKE_VALUE_BUFFER(cb_this_buffer_pointer);
+ memcpy(this_buffer_pointer, PyBytes_AS_STRING(val_use), cb_this_buffer_pointer);
+#endif
+ ns_v.val.p = this_buffer_pointer;
+ rc = SetSizeIs(value_index, PR_TRUE, cb_this_buffer_pointer);
+ break;
+ }
+
+ case nsXPTType::T_PWSTRING_SIZE_IS: {
+ if (val==Py_None) {
+ ns_v.val.p = nsnull;
+ break;
+ }
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyUnicode_FromObject(val))==NULL)
+ BREAK_FALSE;
+ // Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
+ NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyObject_Unicode didnt return a unicode object!");
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+ val_use = val;
+ Py_INCREF(val_use);
+#endif
+ PRUnichar *sv;
+ PRUint32 nch;
+ if (PyUnicode_AsPRUnichar(val_use, &sv, &nch) < 0)
+ BREAK_FALSE;
+ cb_this_buffer_pointer = (nch + 1) * sizeof(PRUnichar);
+ this_buffer_pointer = sv;
+ ns_v.val.p = this_buffer_pointer;
+ rc = SetSizeIs(value_index, PR_TRUE, nch);
+ break;
+ }
+ case nsXPTType::T_ARRAY: {
+ if (val==Py_None) {
+ ns_v.val.p = nsnull;
+ break;
+ }
+ if (!PyInt_Check(td.extra)) {
+ PyErr_SetString(PyExc_TypeError, "The array info is not valid");
+ BREAK_FALSE;
+ }
+ if (!PySequence_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a sequence");
+ BREAK_FALSE;
+ }
+ int array_type = PyInt_AsLong(td.extra);
+ PRUint32 element_size = GetArrayElementSize(array_type);
+ int seq_length = PySequence_Length(val);
+ cb_this_buffer_pointer = seq_length * element_size;
+ if (cb_this_buffer_pointer==0)
+ // prevent assertions allocing zero bytes. Can't use NULL.
+ cb_this_buffer_pointer = 1;
+ MAKE_VALUE_BUFFER(cb_this_buffer_pointer);
+ memset(this_buffer_pointer, 0, cb_this_buffer_pointer);
+ rc = FillSingleArray(this_buffer_pointer, val, seq_length, element_size, array_type&XPT_TDP_TAGMASK, nsnull);
+ if (!rc) break;
+ rc = SetSizeIs(value_index, PR_FALSE, seq_length);
+ if (!rc) break;
+ ns_v.flags |= nsXPTCVariant::VAL_IS_ARRAY;
+ ns_v.val.p = this_buffer_pointer;
+ break;
+ }
+ default:
+ PyErr_Format(PyExc_TypeError, "The object type (0x%x) is unknown", XPT_TDP_TAG(ns_v.type));
+ rc = PR_FALSE;
+ break;
+ }
+ Py_DECREF(val); // Cant be NULL!
+ Py_XDECREF(val_use);
+ }
+ return rc && !PyErr_Occurred();
+}
+
+PRBool PyXPCOM_InterfaceVariantHelper::PrepareOutVariant(const PythonTypeDescriptor &td, int value_index)
+{
+ PRBool rc = PR_TRUE;
+ nsXPTCVariant &ns_v = m_var_array[value_index];
+ void *&this_buffer_pointer = m_buffer_array[value_index]; // Freed at object destruction with PyMem_Free()
+ // Do the out param thang...
+ if (XPT_PD_IS_OUT(td.param_flags) || XPT_PD_IS_DIPPER(td.param_flags)) {
+ NS_ABORT_IF_FALSE(ns_v.ptr == NULL, "already have a pointer!");
+ ns_v.ptr = &ns_v;
+ ns_v.flags |= nsXPTCVariant::PTR_IS_DATA;
+
+ // Special flags based on the data type
+ switch (XPT_TDP_TAG(ns_v.type)) {
+ case nsXPTType::T_I8:
+ case nsXPTType::T_I16:
+ case nsXPTType::T_I32:
+ case nsXPTType::T_I64:
+ case nsXPTType::T_U8:
+ case nsXPTType::T_U16:
+ case nsXPTType::T_U32:
+ case nsXPTType::T_U64:
+ case nsXPTType::T_FLOAT:
+ case nsXPTType::T_DOUBLE:
+ case nsXPTType::T_BOOL:
+ case nsXPTType::T_CHAR:
+ case nsXPTType::T_WCHAR:
+ case nsXPTType::T_VOID:
+ break;
+
+ case nsXPTType::T_INTERFACE:
+ case nsXPTType::T_INTERFACE_IS:
+ NS_ABORT_IF_FALSE(this_buffer_pointer==NULL, "Can't have an interface and a buffer pointer!");
+ ns_v.flags |= nsXPTCVariant::VAL_IS_IFACE;
+ ns_v.flags |= nsXPTCVariant::VAL_IS_ALLOCD;
+ break;
+ case nsXPTType::T_ARRAY:
+ ns_v.flags |= nsXPTCVariant::VAL_IS_ARRAY;
+ ns_v.flags |= nsXPTCVariant::VAL_IS_ALLOCD;
+ // Even if ns_val.p already setup as part of "in" processing,
+ // we need to ensure setup for out.
+ NS_ABORT_IF_FALSE(ns_v.val.p==nsnull || ns_v.val.p==this_buffer_pointer, "Garbage in our pointer?");
+ ns_v.val.p = this_buffer_pointer;
+ this_buffer_pointer = nsnull;
+ break;
+ case nsXPTType::T_PWSTRING_SIZE_IS:
+ case nsXPTType::T_PSTRING_SIZE_IS:
+ case nsXPTType::T_WCHAR_STR:
+ case nsXPTType::T_CHAR_STR:
+ case nsXPTType::T_IID:
+ // If we stashed a value in the this_buffer_pointer, and
+ // we are passing it as an OUT param, we do _not_ want to
+ // treat it as a temporary buffer.
+ // For example, if we pass an IID or string as an IN param,
+ // we allocate a buffer for the value, but this is NOT cleaned up
+ // via normal VARIANT cleanup rules - hence we clean it up ourselves.
+ // If the param is IN/OUT, then the buffer falls under the normal variant
+ // rules (ie, is flagged as VAL_IS_ALLOCD), so we dont clean it as a temporary.
+ // (it may have been changed under us - we free the _new_ value.
+ // Even if ns_val.p already setup as part of "in" processing,
+ // we need to ensure setup for out.
+ NS_ABORT_IF_FALSE(ns_v.val.p==nsnull || ns_v.val.p==this_buffer_pointer, "Garbage in our pointer?");
+ ns_v.val.p = this_buffer_pointer;
+ ns_v.flags |= nsXPTCVariant::VAL_IS_ALLOCD;
+ this_buffer_pointer = nsnull;
+ break;
+ case nsXPTType::T_DOMSTRING:
+ case nsXPTType::T_ASTRING: {
+ NS_ABORT_IF_FALSE(ns_v.val.p==nsnull, "T_DOMTSTRINGS cant be out and have a value (ie, no in/outs are allowed!");
+ NS_ABORT_IF_FALSE(XPT_PD_IS_DIPPER(td.param_flags) && XPT_PD_IS_IN(td.param_flags), "out DOMStrings must really be in dippers!");
+ ns_v.flags |= nsXPTCVariant::VAL_IS_DOMSTR;
+ // Dippers are really treated like "in" params.
+ ns_v.ptr = new nsString();
+ ns_v.val.p = ns_v.ptr; // VAL_IS_* says the .p is what gets freed
+ if (!ns_v.ptr) {
+ PyErr_NoMemory();
+ rc = PR_FALSE;
+ }
+ break;
+ }
+ case nsXPTType::T_CSTRING:
+ case nsXPTType::T_UTF8STRING: {
+ NS_ABORT_IF_FALSE(ns_v.val.p==nsnull, "T_DOMTSTRINGS cant be out and have a value (ie, no in/outs are allowed!");
+ NS_ABORT_IF_FALSE(XPT_PD_IS_DIPPER(td.param_flags) && XPT_PD_IS_IN(td.param_flags), "out DOMStrings must really be in dippers!");
+ ns_v.flags |= ( XPT_TDP_TAG(ns_v.type)==nsXPTType::T_CSTRING ? nsXPTCVariant::VAL_IS_CSTR : nsXPTCVariant::VAL_IS_UTF8STR);
+ ns_v.ptr = new nsCString();
+ ns_v.val.p = ns_v.ptr; // VAL_IS_* says the .p is what gets freed
+ if (!ns_v.ptr) {
+ PyErr_NoMemory();
+ rc = PR_FALSE;
+ }
+ break;
+ }
+ default:
+ NS_ABORT_IF_FALSE(0, "Unknown type - don't know how to prepare the output value");
+ break; // Nothing to do!
+ }
+ }
+ return rc;
+}
+
+
+PyObject *PyXPCOM_InterfaceVariantHelper::MakeSinglePythonResult(int index)
+{
+ nsXPTCVariant &ns_v = m_var_array[index];
+ PyObject *ret = nsnull;
+ NS_ABORT_IF_FALSE(ns_v.IsPtrData() || ns_v.IsValDOMString(), "expecting a pointer if you want a result!");
+
+ // Re-fetch the type descriptor.
+ PythonTypeDescriptor &td = m_python_type_desc_array[index];
+ // Make sure the type tag of the variant hasnt changed on us.
+ NS_ABORT_IF_FALSE(ns_v.type==td.type_flags, "variant type has changed under us!");
+
+ // If the pointer is NULL, we can get out now!
+ if (ns_v.ptr==nsnull) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ switch (XPT_TDP_TAG(ns_v.type)) {
+ case nsXPTType::T_I8:
+ ret = PyInt_FromLong( *((PRInt8 *)ns_v.ptr) );
+ break;
+ case nsXPTType::T_I16:
+ ret = PyInt_FromLong( *((PRInt16 *)ns_v.ptr) );
+ break;
+ case nsXPTType::T_I32:
+ ret = PyInt_FromLong( *((PRInt32 *)ns_v.ptr) );
+ break;
+ case nsXPTType::T_I64:
+ ret = PyLong_FromLongLong( *((PRInt64 *)ns_v.ptr) );
+ break;
+ case nsXPTType::T_U8:
+ ret = PyInt_FromLong( *((PRUint8 *)ns_v.ptr) );
+ break;
+ case nsXPTType::T_U16:
+ ret = PyInt_FromLong( *((PRUint16 *)ns_v.ptr) );
+ break;
+ case nsXPTType::T_U32:
+ ret = PyInt_FromLong( *((PRUint32 *)ns_v.ptr) );
+ break;
+ case nsXPTType::T_U64:
+ ret = PyLong_FromUnsignedLongLong( *((PRUint64 *)ns_v.ptr) );
+ break;
+ case nsXPTType::T_FLOAT:
+ ret = PyFloat_FromDouble( *((float *)ns_v.ptr) );
+ break;
+ case nsXPTType::T_DOUBLE:
+ ret = PyFloat_FromDouble( *((double *)ns_v.ptr) );
+ break;
+ case nsXPTType::T_BOOL:
+ ret = *((PRBool *)ns_v.ptr) ? Py_True : Py_False;
+ Py_INCREF(ret);
+ break;
+ case nsXPTType::T_CHAR:
+#if PY_MAJOR_VERSION <= 2
+ ret = PyString_FromStringAndSize( ((char *)ns_v.ptr), 1 );
+#else
+ ret = PyUnicode_FromStringAndSize( ((char *)ns_v.ptr), 1 );
+#endif
+ break;
+
+ case nsXPTType::T_WCHAR:
+ ret = PyUnicode_FromPRUnichar( ((PRUnichar *)ns_v.ptr), 1 );
+ break;
+// case nsXPTType::T_VOID:
+ case nsXPTType::T_IID:
+ ret = Py_nsIID::PyObjectFromIID( **((nsIID **)ns_v.ptr) );
+ break;
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING: {
+ nsAString *rs = (nsAString *)ns_v.ptr;
+ ret = PyObject_FromNSString(*rs);
+ break;
+ }
+ case nsXPTType::T_UTF8STRING:
+ case nsXPTType::T_CSTRING: {
+ nsCString *rs = (nsCString *)ns_v.ptr;
+ ret = PyObject_FromNSString(*rs, XPT_TDP_TAG(ns_v.type)==nsXPTType::T_UTF8STRING);
+ break;
+ }
+
+ case nsXPTType::T_CHAR_STR:
+ if (*((char **)ns_v.ptr) == NULL) {
+ ret = Py_None;
+ Py_INCREF(Py_None);
+ } else
+#if PY_MAJOR_VERSION <= 2
+ ret = PyString_FromString( *((char **)ns_v.ptr) );
+#else
+ ret = PyUnicode_FromString( *((char **)ns_v.ptr) );
+#endif
+ break;
+
+ case nsXPTType::T_WCHAR_STR: {
+ PRUnichar *us = *((PRUnichar **)ns_v.ptr);
+ if (us == NULL) {
+ ret = Py_None;
+ Py_INCREF(Py_None);
+ } else {
+ ret = PyUnicode_FromPRUnichar( us, nsCRT::strlen(us));
+ }
+ break;
+ }
+ case nsXPTType::T_INTERFACE: {
+ nsIID iid;
+ if (!Py_nsIID::IIDFromPyObject(td.extra, &iid))
+ break;
+ nsISupports *iret = *((nsISupports **)ns_v.ptr);
+ // Our cleanup code manages iret reference ownership, and our
+ // new object takes its own.
+ if (iid.Equals(NS_GET_IID(nsIVariant)))
+ ret = PyObject_FromVariant(m_parent, (nsIVariant *)iret);
+ else
+ ret = m_parent->MakeInterfaceResult(iret, iid);
+ break;
+ }
+ case nsXPTType::T_INTERFACE_IS: {
+ nsIID iid;
+ nsXPTCVariant &ns_viid = m_var_array[td.argnum];
+ NS_WARN_IF_FALSE(XPT_TDP_TAG(ns_viid.type)==nsXPTType::T_IID, "The INTERFACE_IS iid describer isnt an IID!");
+ if (XPT_TDP_TAG(ns_viid.type)==nsXPTType::T_IID) {
+ nsIID *piid = (nsIID *)ns_viid.val.p;
+ if (piid==NULL)
+ // Also serious, but like below, not our fault!
+ iid = NS_GET_IID(nsISupports);
+ else
+ iid = *piid;
+ } else {
+ // This is a pretty serious problem, but not Python's fault!
+ // Just return an nsISupports and hope the caller does whatever
+ // QI they need before using it.
+ NS_ERROR("Failed to get the IID for T_INTERFACE_IS!");
+ iid = NS_GET_IID(nsISupports);
+ }
+ nsISupports *iret = *((nsISupports **)ns_v.ptr);
+ if (iid.Equals(NS_GET_IID(nsIVariant)))
+ ret = PyObject_FromVariant(m_parent, (nsIVariant *)iret);
+ else
+ ret = m_parent->MakeInterfaceResult(iret, iid);
+ break;
+ }
+ case nsXPTType::T_ARRAY: {
+ if ( (* ((void **)ns_v.ptr)) == NULL) {
+ ret = Py_None;
+ Py_INCREF(Py_None);
+ }
+ if (!PyInt_Check(td.extra)) {
+ PyErr_SetString(PyExc_TypeError, "The array info is not valid");
+ break;
+ }
+ PRUint8 array_type = (PRUint8)PyInt_AsLong(td.extra);
+ PRUint32 seq_size = GetSizeIs(index, PR_FALSE);
+ nsXPTCVariant &ns_viid = m_var_array[td.argnum];
+ nsIID iid;
+ nsresult res = GetArrayElementIID(m_parent,
+ m_var_array,
+ m_methodindex,
+ index,
+ &iid);
+ ret = UnpackSingleArray(m_parent, * ((void **)ns_v.ptr),
+ seq_size, array_type&XPT_TDP_TAGMASK,
+ NS_SUCCEEDED(res) ? &iid : NULL);
+ break;
+ }
+
+ case nsXPTType::T_PSTRING_SIZE_IS:
+ if (*((char **)ns_v.ptr) == NULL) {
+ ret = Py_None;
+ Py_INCREF(Py_None);
+ } else {
+ PRUint32 string_size = GetSizeIs(index, PR_TRUE);
+#if PY_MAJOR_VERSION <= 2
+ ret = PyString_FromStringAndSize( *((char **)ns_v.ptr), string_size );
+#else
+ ret = PyUnicode_FromStringAndSize( *((char **)ns_v.ptr), string_size );
+#endif
+ }
+ break;
+
+ case nsXPTType::T_PWSTRING_SIZE_IS:
+ if (*((PRUnichar **)ns_v.ptr) == NULL) {
+ ret = Py_None;
+ Py_INCREF(Py_None);
+ } else {
+ PRUint32 string_size = GetSizeIs(index, PR_TRUE);
+ ret = PyUnicode_FromPRUnichar( *((PRUnichar **)ns_v.ptr), string_size );
+ }
+ break;
+ default:
+ PyErr_Format(PyExc_ValueError, "Unknown XPCOM type code (0x%x)", XPT_TDP_TAG(ns_v.type));
+ /* ret remains nsnull */
+ break;
+ }
+ return ret;
+}
+
+
+PyObject *PyXPCOM_InterfaceVariantHelper::MakePythonResult()
+{
+ // First we count the results.
+ int i = 0;
+ int n_results = 0;
+ PyObject *ret = NULL;
+ PRBool have_retval = PR_FALSE;
+ for (i=0;i<m_num_array;i++) {
+ PythonTypeDescriptor &td = m_python_type_desc_array[i];
+ if (!td.is_auto_out) {
+ if (XPT_PD_IS_OUT(td.param_flags) || XPT_PD_IS_DIPPER(td.param_flags))
+ n_results++;
+ if (XPT_PD_IS_RETVAL(td.param_flags))
+ have_retval = PR_TRUE;
+ }
+ }
+ if (n_results==0) {
+ ret = Py_None;
+ Py_INCREF(ret);
+ } else {
+ if (n_results > 1) {
+ ret = PyTuple_New(n_results);
+ if (ret==NULL)
+ return NULL;
+ }
+ int ret_index = 0;
+ int max_index = m_num_array;
+ // Stick the retval at the front if we have have
+ if (have_retval && n_results > 1) {
+ PyObject *val = MakeSinglePythonResult(m_num_array-1);
+ if (val==NULL) {
+ Py_DECREF(ret);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(ret, 0, val);
+ max_index--;
+ ret_index++;
+
+ }
+ for (i=0;ret_index < n_results && i < max_index;i++) {
+ if (!m_python_type_desc_array[i].is_auto_out) {
+ if (XPT_PD_IS_OUT(m_python_type_desc_array[i].param_flags) || XPT_PD_IS_DIPPER(m_python_type_desc_array[i].param_flags)) {
+ PyObject *val = MakeSinglePythonResult(i);
+ if (val==NULL) {
+ Py_XDECREF(ret);
+ return NULL;
+ }
+ if (n_results > 1) {
+ PyTuple_SET_ITEM(ret, ret_index, val);
+ ret_index++;
+ } else {
+ NS_ABORT_IF_FALSE(ret==NULL, "shouldnt already have a ret!");
+ ret = val;
+ }
+ }
+ }
+ }
+
+ }
+ return ret;
+}
+
+/*************************************************************************
+**************************************************************************
+
+ Helpers when IMPLEMENTING interfaces.
+
+**************************************************************************
+*************************************************************************/
+
+PyXPCOM_GatewayVariantHelper::PyXPCOM_GatewayVariantHelper( PyG_Base *gw, int method_index, const nsXPTMethodInfo *info, nsXPTCMiniVariant* params )
+{
+ m_params = params;
+ m_info = info;
+ // no references added - this class is only alive for
+ // a single gateway invocation
+ m_gateway = gw;
+ m_method_index = method_index;
+ m_python_type_desc_array = NULL;
+ m_num_type_descs = 0;
+}
+
+PyXPCOM_GatewayVariantHelper::~PyXPCOM_GatewayVariantHelper()
+{
+ delete [] m_python_type_desc_array;
+}
+
+PyObject *PyXPCOM_GatewayVariantHelper::MakePyArgs()
+{
+ NS_PRECONDITION(sizeof(XPTParamDescriptor) == sizeof(nsXPTParamInfo), "We depend on nsXPTParamInfo being a wrapper over the XPTParamDescriptor struct");
+ // Setup our array of Python typedescs, and determine the number of objects we
+ // pass to Python.
+ m_num_type_descs = m_info->num_args;
+ m_python_type_desc_array = new PythonTypeDescriptor[m_num_type_descs];
+ if (m_python_type_desc_array==nsnull)
+ return PyErr_NoMemory();
+
+ // First loop to count the number of objects
+ // we pass to Python
+ int i;
+ for (i=0;i<m_info->num_args;i++) {
+ nsXPTParamInfo *pi = (nsXPTParamInfo *)m_info->params+i;
+ PythonTypeDescriptor &td = m_python_type_desc_array[i];
+ td.param_flags = pi->flags;
+ td.type_flags = pi->type.prefix.flags;
+ td.argnum = pi->type.argnum;
+ td.argnum2 = pi->type.argnum2;
+ }
+ int num_args = ProcessPythonTypeDescriptors(m_python_type_desc_array, m_num_type_descs);
+ PyObject *ret = PyTuple_New(num_args);
+ if (ret==NULL)
+ return NULL;
+ int this_arg = 0;
+ for (i=0;i<m_num_type_descs;i++) {
+ PythonTypeDescriptor &td = m_python_type_desc_array[i];
+ if (XPT_PD_IS_IN(td.param_flags) && !td.is_auto_in && !XPT_PD_IS_DIPPER(td.param_flags)) {
+ PyObject *sub = MakeSingleParam( i, td );
+ if (sub==NULL) {
+ Py_DECREF(ret);
+ return NULL;
+ }
+ NS_ABORT_IF_FALSE(this_arg>=0 && this_arg<num_args, "We are going off the end of the array!");
+ PyTuple_SET_ITEM(ret, this_arg, sub);
+ this_arg++;
+ }
+ }
+ return ret;
+}
+
+PRBool PyXPCOM_GatewayVariantHelper::CanSetSizeIs( int var_index, PRBool is_arg1 )
+{
+ NS_ABORT_IF_FALSE(var_index < m_num_type_descs, "var_index param is invalid");
+ PRUint8 argnum = is_arg1 ?
+ m_python_type_desc_array[var_index].argnum :
+ m_python_type_desc_array[var_index].argnum2;
+ NS_ABORT_IF_FALSE(argnum < m_num_type_descs, "size_is param is invalid");
+ return XPT_PD_IS_OUT(m_python_type_desc_array[argnum].param_flags);
+}
+
+PRBool PyXPCOM_GatewayVariantHelper::SetSizeIs( int var_index, PRBool is_arg1, PRUint32 new_size)
+{
+ NS_ABORT_IF_FALSE(var_index < m_num_type_descs, "var_index param is invalid");
+ PRUint8 argnum = is_arg1 ?
+ m_python_type_desc_array[var_index].argnum :
+ m_python_type_desc_array[var_index].argnum2;
+ NS_ABORT_IF_FALSE(argnum < m_num_type_descs, "size_is param is invalid");
+ PythonTypeDescriptor &td_size = m_python_type_desc_array[argnum];
+ NS_ABORT_IF_FALSE( XPT_PD_IS_OUT(td_size.param_flags), "size param must be out if we want to set it!");
+ NS_ABORT_IF_FALSE(td_size.is_auto_out, "Setting size_is, but param is not marked as auto!");
+
+ nsXPTCMiniVariant &ns_v = m_params[argnum];
+ NS_ABORT_IF_FALSE( (td_size.type_flags & XPT_TDP_TAGMASK) == nsXPTType::T_U32, "size param must be Uint32");
+ NS_ABORT_IF_FALSE(ns_v.val.p, "NULL pointer for size_is value!");
+ if (ns_v.val.p) {
+ if (!td_size.have_set_auto) {
+ *((PRUint32 *)ns_v.val.p) = new_size;
+ td_size.have_set_auto = PR_TRUE;
+ } else {
+ if (*((PRUint32 *)ns_v.val.p) != new_size ) {
+ PyErr_Format(PyExc_ValueError, "Array lengths inconsistent; array size previously set to %d, but second array is of size %d", ns_v.val.u32, new_size);
+ return PR_FALSE;
+ }
+ }
+ }
+ return PR_TRUE;
+}
+
+PRUint32 PyXPCOM_GatewayVariantHelper::GetSizeIs( int var_index, PRBool is_arg1)
+{
+ NS_ABORT_IF_FALSE(var_index < m_num_type_descs, "var_index param is invalid");
+ PRUint8 argnum = is_arg1 ?
+ m_python_type_desc_array[var_index].argnum :
+ m_python_type_desc_array[var_index].argnum2;
+ NS_ABORT_IF_FALSE(argnum < m_num_type_descs, "size_is param is invalid");
+ if (argnum >= m_num_type_descs) {
+ PyErr_SetString(PyExc_ValueError, "dont have a valid size_is indicator for this param");
+ return PR_FALSE;
+ }
+ PRBool is_out = XPT_PD_IS_OUT(m_python_type_desc_array[argnum].param_flags);
+ nsXPTCMiniVariant &ns_v = m_params[argnum];
+ NS_ABORT_IF_FALSE( (m_python_type_desc_array[argnum].type_flags & XPT_TDP_TAGMASK) == nsXPTType::T_U32, "size param must be Uint32");
+ return is_out ? *((PRUint32 *)ns_v.val.p) : ns_v.val.u32;
+}
+
+#undef DEREF_IN_OR_OUT
+#define DEREF_IN_OR_OUT( element, ret_type ) (ret_type)(is_out ? *((ret_type *)ns_v.val.p) : (ret_type)(element))
+
+PyObject *PyXPCOM_GatewayVariantHelper::MakeSingleParam(int index, PythonTypeDescriptor &td)
+{
+ NS_PRECONDITION(XPT_PD_IS_IN(td.param_flags), "Must be an [in] param!");
+ nsXPTCMiniVariant &ns_v = m_params[index];
+ PyObject *ret = NULL;
+ PRBool is_out = XPT_PD_IS_OUT(td.param_flags);
+
+ switch (td.type_flags & XPT_TDP_TAGMASK) {
+ case nsXPTType::T_I8:
+ ret = PyInt_FromLong( DEREF_IN_OR_OUT(ns_v.val.i8, PRInt8 ) );
+ break;
+ case nsXPTType::T_I16:
+ ret = PyInt_FromLong( DEREF_IN_OR_OUT(ns_v.val.i16, PRInt16) );
+ break;
+ case nsXPTType::T_I32:
+ ret = PyInt_FromLong( DEREF_IN_OR_OUT(ns_v.val.i32, PRInt32) );
+ break;
+ case nsXPTType::T_I64:
+ ret = PyLong_FromLongLong( DEREF_IN_OR_OUT(ns_v.val.i64, PRInt64) );
+ break;
+ case nsXPTType::T_U8:
+ ret = PyInt_FromLong( DEREF_IN_OR_OUT(ns_v.val.u8, PRUint8) );
+ break;
+ case nsXPTType::T_U16:
+ ret = PyInt_FromLong( DEREF_IN_OR_OUT(ns_v.val.u16, PRUint16) );
+ break;
+ case nsXPTType::T_U32:
+ ret = PyInt_FromLong( DEREF_IN_OR_OUT(ns_v.val.u32, PRUint32) );
+ break;
+ case nsXPTType::T_U64:
+ ret = PyLong_FromUnsignedLongLong( DEREF_IN_OR_OUT(ns_v.val.u64, PRUint64) );
+ break;
+ case nsXPTType::T_FLOAT:
+ ret = PyFloat_FromDouble( DEREF_IN_OR_OUT(ns_v.val.f, float) );
+ break;
+ case nsXPTType::T_DOUBLE:
+ ret = PyFloat_FromDouble( DEREF_IN_OR_OUT(ns_v.val.d, double) );
+ break;
+ case nsXPTType::T_BOOL: {
+ PRBool temp = DEREF_IN_OR_OUT(ns_v.val.b, PRBool);
+ ret = temp ? Py_True : Py_False;
+ Py_INCREF(ret);
+ break;
+ }
+ case nsXPTType::T_CHAR: {
+ char temp = DEREF_IN_OR_OUT(ns_v.val.c, char);
+#if PY_MAJOR_VERSION <= 2
+ ret = PyString_FromStringAndSize(&temp, 1);
+#else
+ ret = PyUnicode_FromStringAndSize(&temp, 1);
+#endif
+ break;
+ }
+ case nsXPTType::T_WCHAR: {
+ PRUnichar temp = (PRUnichar)DEREF_IN_OR_OUT(ns_v.val.wc, PRUnichar);
+ ret = PyUnicode_FromPRUnichar(&temp, 1);
+ break;
+ }
+// case nsXPTType::T_VOID:
+ case nsXPTType::T_IID: {
+ ret = Py_nsIID::PyObjectFromIID( * DEREF_IN_OR_OUT(ns_v.val.p, const nsIID *) );
+ break;
+ }
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING: {
+ NS_ABORT_IF_FALSE(is_out || !XPT_PD_IS_DIPPER(td.param_flags), "DOMStrings can't be inout");
+ const nsAString *rs = (const nsAString *)ns_v.val.p;
+ ret = PyObject_FromNSString(*rs);
+ break;
+ }
+ case nsXPTType::T_CSTRING:
+ case nsXPTType::T_UTF8STRING: {
+ NS_ABORT_IF_FALSE(is_out || !XPT_PD_IS_DIPPER(td.param_flags), "DOMStrings can't be inout");
+ const nsCString *rs = (const nsCString *)ns_v.val.p;
+ ret = PyObject_FromNSString(*rs, (td.type_flags & XPT_TDP_TAGMASK)==nsXPTType::T_UTF8STRING);
+ break;
+ }
+ case nsXPTType::T_CHAR_STR: {
+ char *t = DEREF_IN_OR_OUT(ns_v.val.p, char *);
+ if (t==NULL) {
+ ret = Py_None;
+ Py_INCREF(Py_None);
+ } else
+#if PY_MAJOR_VERSION <= 2
+ ret = PyString_FromString(t);
+#else
+ ret = PyUnicode_FromString(t);
+#endif
+ break;
+ }
+
+ case nsXPTType::T_WCHAR_STR: {
+ PRUnichar *us = DEREF_IN_OR_OUT(ns_v.val.p, PRUnichar *);
+ if (us==NULL) {
+ ret = Py_None;
+ Py_INCREF(Py_None);
+ } else {
+ ret = PyUnicode_FromPRUnichar( us, nsCRT::strlen(us));
+ }
+ break;
+ }
+ case nsXPTType::T_INTERFACE_IS: // our Python code does it :-)
+ case nsXPTType::T_INTERFACE: {
+ nsISupports *iret = DEREF_IN_OR_OUT(ns_v.val.p, nsISupports *);
+ nsXPTParamInfo *pi = (nsXPTParamInfo *)m_info->params+index;
+ ret = m_gateway->MakeInterfaceParam(iret, NULL, m_method_index, pi, index);
+ break;
+ }
+/***
+ nsISupports *iret = DEREF_IN_OR_OUT(ns_v.val.p, nsISupports *);
+ nsXPTParamInfo *pi = (nsXPTParamInfo *)m_info->params+index;
+ nsXPTCMiniVariant &ns_viid = m_params[td.argnum];
+ NS_ABORT_IF_FALSE((m_python_type_desc_array[td.argnum].type_flags & XPT_TDP_TAGMASK) == nsXPTType::T_IID, "The INTERFACE_IS iid describer isnt an IID!");
+ const nsIID * iid = NULL;
+ if (XPT_PD_IS_IN(m_python_type_desc_array[td.argnum].param_flags))
+ // may still be inout!
+ iid = DEREF_IN_OR_OUT(ns_v.val.p, const nsIID *);
+
+ ret = m_gateway->MakeInterfaceParam(iret, iid, m_method_index, pi, index);
+ break;
+ }
+****/
+ case nsXPTType::T_ARRAY: {
+ void *t = DEREF_IN_OR_OUT(ns_v.val.p, void *);
+ if (t==NULL) {
+ // JS may send us a NULL here occasionally - as the
+ // type is array, we silently convert this to a zero
+ // length list, a-la JS.
+ ret = PyList_New(0);
+ } else {
+ PRUint8 array_type;
+ nsIID *piid;
+ nsresult ns = GetArrayType(index, &array_type, &piid);
+ if (NS_FAILED(ns)) {
+ PyXPCOM_BuildPyException(ns);
+ break;
+ }
+ PRUint32 seq_size = GetSizeIs(index, PR_FALSE);
+ ret = UnpackSingleArray(NULL, t, seq_size, array_type&XPT_TDP_TAGMASK, piid);
+ }
+ break;
+ }
+ case nsXPTType::T_PSTRING_SIZE_IS: {
+ char *t = DEREF_IN_OR_OUT(ns_v.val.p, char *);
+ PRUint32 string_size = GetSizeIs(index, PR_TRUE);
+ if (t==NULL) {
+ ret = Py_None;
+ Py_INCREF(Py_None);
+ } else
+#if PY_MAJOR_VERSION <= 2
+ ret = PyString_FromStringAndSize(t, string_size);
+#else
+ ret = PyUnicode_FromStringAndSize(t, string_size);
+#endif
+ break;
+ }
+ case nsXPTType::T_PWSTRING_SIZE_IS: {
+ PRUnichar *t = DEREF_IN_OR_OUT(ns_v.val.p, PRUnichar *);
+ PRUint32 string_size = GetSizeIs(index, PR_TRUE);
+ if (t==NULL) {
+ ret = Py_None;
+ Py_INCREF(Py_None);
+ } else {
+ ret = PyUnicode_FromPRUnichar(t, string_size);
+ }
+ break;
+ }
+ default:
+ // As this is called by external components,
+ // we return _something_ rather than failing before any user code has run!
+ {
+ char buf[128];
+ sprintf(buf, "Unknown XPCOM type flags (0x%x)", td.type_flags);
+ PyXPCOM_LogWarning("%s - returning a string object with this message!\n", buf);
+#if PY_MAJOR_VERSION <= 2
+ ret = PyString_FromString(buf);
+#else
+ ret = PyUnicode_FromString(buf);
+#endif
+ break;
+ }
+ }
+ return ret;
+}
+
+nsresult PyXPCOM_GatewayVariantHelper::GetArrayType(PRUint8 index, PRUint8 *ret, nsIID **iid)
+{
+ nsCOMPtr<nsIInterfaceInfoManager> iim(do_GetService(
+ NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
+ NS_ABORT_IF_FALSE(iim != nsnull, "Cant get interface from IIM!");
+ if (iim==nsnull)
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr<nsIInterfaceInfo> ii;
+ nsresult rc = iim->GetInfoForIID( &m_gateway->m_iid, getter_AddRefs(ii));
+ if (NS_FAILED(rc))
+ return rc;
+ nsXPTType datumType;
+ const nsXPTParamInfo& param_info = m_info->GetParam((PRUint8)index);
+ rc = ii->GetTypeForParam(m_method_index, &param_info, 1, &datumType);
+ if (NS_FAILED(rc))
+ return rc;
+ if (iid) {
+ *iid = (nsIID *)&NS_GET_IID(nsISupports);
+ if (XPT_TDP_TAG(datumType)==nsXPTType::T_INTERFACE ||
+ XPT_TDP_TAG(datumType)==nsXPTType::T_INTERFACE_IS ||
+ XPT_TDP_TAG(datumType)==nsXPTType::T_ARRAY)
+ ii->GetIIDForParam(m_method_index, &param_info, iid);
+ }
+ *ret = datumType.flags;
+ return NS_OK;
+}
+
+PRBool PyXPCOM_GatewayVariantHelper::GetIIDForINTERFACE_ID(int index, const nsIID **ppret)
+{
+ // Not sure if the IID pointed at by by this is allows to be
+ // in or out, so we will allow it.
+ nsXPTParamInfo *pi = (nsXPTParamInfo *)m_info->params+index;
+ nsXPTType typ = pi->GetType();
+ NS_WARN_IF_FALSE(XPT_TDP_TAG(typ) == nsXPTType::T_IID, "INTERFACE_IS IID param isnt an IID!");
+ NS_ABORT_IF_FALSE(typ.IsPointer(), "Expecting to re-fill a pointer value.");
+ if (XPT_TDP_TAG(typ) != nsXPTType::T_IID)
+ *ppret = &NS_GET_IID(nsISupports);
+ else {
+ nsXPTCMiniVariant &ns_v = m_params[index];
+ if (pi->IsOut()) {
+ nsIID **pp = (nsIID **)ns_v.val.p;
+ if (pp && *pp)
+ *ppret = *pp;
+ else
+ *ppret = &NS_GET_IID(nsISupports);
+ } else if (pi->IsIn()) {
+ nsIID *p = (nsIID *)ns_v.val.p;
+ if (p)
+ *ppret = p;
+ else
+ *ppret = &NS_GET_IID(nsISupports);
+ } else {
+ NS_ERROR("Param is not in or out!");
+ *ppret = &NS_GET_IID(nsISupports);
+ }
+ }
+ return PR_TRUE;
+}
+
+nsIInterfaceInfo *PyXPCOM_GatewayVariantHelper::GetInterfaceInfo()
+{
+ if (!m_interface_info) {
+ nsCOMPtr<nsIInterfaceInfoManager> iim(do_GetService(
+ NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID));
+ if (iim)
+ iim->GetInfoForIID(&m_gateway->m_iid, getter_AddRefs(m_interface_info));
+ }
+ return m_interface_info;
+}
+
+#undef FILL_SIMPLE_POINTER
+#define FILL_SIMPLE_POINTER( type, ob ) *((type *)ns_v.val.p) = (type)(ob)
+
+nsresult PyXPCOM_GatewayVariantHelper::BackFillVariant( PyObject *val, int index)
+{
+ nsXPTParamInfo *pi = (nsXPTParamInfo *)m_info->params+index;
+ NS_ABORT_IF_FALSE(pi->IsOut() || pi->IsDipper(), "The value must be marked as [out] (or a dipper) to be back-filled!");
+ NS_ABORT_IF_FALSE(!pi->IsShared(), "Dont know how to back-fill a shared out param");
+ nsXPTCMiniVariant &ns_v = m_params[index];
+
+ nsXPTType typ = pi->GetType();
+ PyObject* val_use = NULL;
+
+ NS_ABORT_IF_FALSE(pi->IsDipper() || ns_v.val.p, "No space for result!");
+ if (!pi->IsDipper() && !ns_v.val.p) return NS_ERROR_INVALID_POINTER;
+
+ PRBool rc = PR_TRUE;
+ switch (XPT_TDP_TAG(typ)) {
+ case nsXPTType::T_I8:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRInt8, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_I16:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRInt16, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_I32:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRInt32, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_I64:
+ if ((val_use=PyNumber_Long(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRInt64, PyLong_AsLongLong(val_use) );
+ break;
+ case nsXPTType::T_U8:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRUint8, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_U16:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRUint16, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_U32:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRUint32, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_U64:
+ if ((val_use=PyNumber_Long(val))==NULL) BREAK_FALSE;
+ FILL_SIMPLE_POINTER( PRUint64, PyLong_AsUnsignedLongLong(val_use) );
+ break;
+ case nsXPTType::T_FLOAT:
+ if ((val_use=PyNumber_Float(val))==NULL) BREAK_FALSE
+ FILL_SIMPLE_POINTER( float, PyFloat_AsDouble(val_use) );
+ break;
+ case nsXPTType::T_DOUBLE:
+ if ((val_use=PyNumber_Float(val))==NULL) BREAK_FALSE
+ FILL_SIMPLE_POINTER( double, PyFloat_AsDouble(val_use) );
+ break;
+ case nsXPTType::T_BOOL:
+ if ((val_use=PyNumber_Int(val))==NULL) BREAK_FALSE
+ FILL_SIMPLE_POINTER( PRBool, PyInt_AsLong(val_use) );
+ break;
+ case nsXPTType::T_CHAR:
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyObject_Str(val))==NULL)
+ BREAK_FALSE;
+ // Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
+ NS_ABORT_IF_FALSE(PyString_Check(val_use), "PyObject_Str didnt return a string object!");
+ FILL_SIMPLE_POINTER( char, *PyString_AS_STRING(val_use) );
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+# ifndef Py_LIMITED_API
+ FILL_SIMPLE_POINTER( char, *PyUnicode_AS_UNICODE(val) );
+# else
+ FILL_SIMPLE_POINTER( char, PyUnicode_ReadChar(val, 0) );
+# endif
+#endif
+ break;
+
+ case nsXPTType::T_WCHAR:
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a Unicode object");
+ BREAK_FALSE;
+ }
+#endif
+ if ((val_use = PyUnicode_FromObject(val))==NULL)
+ BREAK_FALSE;
+ NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
+ // Lossy!
+#ifndef Py_LIMITED_API
+ FILL_SIMPLE_POINTER( PRUnichar, *PyUnicode_AS_UNICODE(val_use) );
+#else
+ FILL_SIMPLE_POINTER( PRUnichar, PyUnicode_ReadChar(val_use, 0) );
+#endif
+ break;
+
+// case nsXPTType::T_VOID:
+ case nsXPTType::T_IID: {
+ nsIID iid;
+ if (!Py_nsIID::IIDFromPyObject(val, &iid))
+ BREAK_FALSE;
+ nsIID **pp = (nsIID **)ns_v.val.p;
+ // If there is an existing [in] IID, free it.
+ if (*pp && pi->IsIn())
+ nsMemory::Free(*pp);
+ *pp = (nsIID *)nsMemory::Alloc(sizeof(nsIID));
+ if (*pp==NULL) {
+ PyErr_NoMemory();
+ BREAK_FALSE;
+ }
+ memcpy(*pp, &iid, sizeof(iid));
+ break;
+ }
+
+ case nsXPTType::T_ASTRING:
+ case nsXPTType::T_DOMSTRING: {
+ nsAString *ws = (nsAString *)ns_v.val.p;
+ NS_ABORT_IF_FALSE(ws->Length() == 0, "Why does this writable string already have chars??");
+ if (!PyObject_AsNSString(val, *ws))
+ BREAK_FALSE;
+ break;
+ }
+ case nsXPTType::T_CSTRING: {
+ nsCString *ws = (nsCString *)ns_v.val.p;
+ NS_ABORT_IF_FALSE(ws->Length() == 0, "Why does this writable string already have chars??");
+ if (val == Py_None) {
+ NS_ABORT_IF_FALSE(0, "dont handle None here yet");
+ } else {
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ val_use = PyObject_Str(val);
+ NS_ABORT_IF_FALSE(PyString_Check(val_use), "PyObject_Str didnt return a string object!");
+ const char *sz = PyString_AS_STRING(val_use);
+ ws->Assign(sz, PyString_GET_SIZE(val_use));
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+ val_use = PyUnicode_AsUTF8String(val);
+ const char *sz = PyBytes_AS_STRING(val_use);
+ ws->Assign(sz, PyBytes_GET_SIZE(val_use));
+#endif
+ }
+ break;
+ }
+ case nsXPTType::T_UTF8STRING: {
+ nsCString *ws = (nsCString *)ns_v.val.p;
+ NS_ABORT_IF_FALSE(ws->Length() == 0, "Why does this writable string already have chars??");
+ if (val == Py_None) {
+ NS_ABORT_IF_FALSE(0, "dont handle None here yet");
+ } else {
+#if PY_MAJOR_VERSION <= 2
+ if (PyString_Check(val)) {
+ val_use = val;
+ Py_INCREF(val);
+ }
+ else
+#endif
+ if (PyUnicode_Check(val)) {
+ val_use = PyUnicode_AsUTF8String(val);
+ } else {
+#if PY_MAJOR_VERSION <= 2
+ PyErr_SetString(PyExc_TypeError, "UTF8 parameters must be string or Unicode objects");
+#else
+ PyErr_SetString(PyExc_TypeError, "UTF8 parameters must be unicode objects");
+#endif
+ BREAK_FALSE;
+ }
+#if PY_MAJOR_VERSION <= 2
+ NS_ABORT_IF_FALSE(PyString_Check(val_use), "must have a string object!");
+ const char *sz = PyString_AS_STRING(val_use);
+ ws->Assign(sz, PyString_GET_SIZE(val_use));
+#else
+ NS_ABORT_IF_FALSE(PyBytes_Check(val_use), "must have a bytes object!");
+ const char *sz = PyBytes_AS_STRING(val_use);
+ ws->Assign(sz, PyBytes_GET_SIZE(val_use));
+#endif
+ }
+ break;
+ }
+
+ case nsXPTType::T_CHAR_STR: {
+ // If it is an existing string, free it.
+ char **pp = (char **)ns_v.val.p;
+ if (*pp && pi->IsIn())
+ nsMemory::Free(*pp);
+ *pp = nsnull;
+
+ if (val == Py_None)
+ break; // Remains NULL.
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyObject_Str(val))==NULL)
+ BREAK_FALSE;
+ // Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
+ NS_ABORT_IF_FALSE(PyString_Check(val_use), "PyObject_Str didnt return a string object!");
+
+ const char *sz = PyString_AS_STRING(val_use);
+ int nch = PyString_GET_SIZE(val_use);
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyUnicode_AsUTF8String(val))==NULL)
+ BREAK_FALSE;
+
+ const char *sz = PyBytes_AS_STRING(val_use);
+ int nch = PyBytes_GET_SIZE(val_use);
+#endif
+
+ *pp = (char *)nsMemory::Alloc(nch+1);
+ if (*pp==NULL) {
+ PyErr_NoMemory();
+ BREAK_FALSE;
+ }
+ strncpy(*pp, sz, nch+1);
+ break;
+ }
+ case nsXPTType::T_WCHAR_STR: {
+ // If it is an existing string, free it.
+ PRUnichar **pp = (PRUnichar **)ns_v.val.p;
+ if (*pp && pi->IsIn())
+ nsMemory::Free(*pp);
+ *pp = nsnull;
+ if (val == Py_None)
+ break; // Remains NULL.
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ val_use = PyUnicode_FromObject(val);
+ NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+ val_use = val;
+ Py_INCREF(val_use);
+#endif
+ if (PyUnicode_AsPRUnichar(val_use, pp, NULL) < 0)
+ BREAK_FALSE;
+ break;
+ }
+ case nsXPTType::T_INTERFACE: {
+ nsISupports *pnew = nsnull;
+ // Find out what IID we are declared to use.
+ nsIID *iid = NULL;
+ nsIInterfaceInfo *ii = GetInterfaceInfo();
+ if (ii)
+ ii->GetIIDForParam(m_method_index, pi, &iid);
+
+ // Get it the "standard" way.
+ // We do allow NULL here, even tho doing so will no-doubt crash some objects.
+ // (but there will certainly be objects out there that will allow NULL :-(
+ nsIID iid_use = iid ? *iid : NS_GET_IID(nsISupports);
+ if (!Py_nsISupports::InterfaceFromPyObject(val, iid_use, &pnew, PR_TRUE))
+ BREAK_FALSE;
+ nsISupports **pp = (nsISupports **)ns_v.val.p;
+ if (*pp && pi->IsIn()) {
+ Py_BEGIN_ALLOW_THREADS; // MUST release thread-lock, incase a Python COM object that re-acquires.
+ (*pp)->Release();
+ Py_END_ALLOW_THREADS;
+ }
+
+ *pp = pnew; // ref-count added by InterfaceFromPyObject
+ break;
+ }
+ case nsXPTType::T_INTERFACE_IS: {
+ const nsIID *piid;
+ if (!GetIIDForINTERFACE_ID(pi->type.argnum, &piid))
+ BREAK_FALSE;
+
+ nsISupports *pnew = nsnull;
+ // Get it the "standard" way.
+ // We do allow NULL here, even tho doing so will no-doubt crash some objects.
+ // (but there will certainly be objects out there that will allow NULL :-(
+ if (!Py_nsISupports::InterfaceFromPyObject(val, *piid, &pnew, PR_TRUE))
+ BREAK_FALSE;
+ nsISupports **pp = (nsISupports **)ns_v.val.p;
+ if (*pp && pi->IsIn()) {
+ Py_BEGIN_ALLOW_THREADS; // MUST release thread-lock, incase a Python COM object that re-acquires.
+ (*pp)->Release();
+ Py_END_ALLOW_THREADS;
+ }
+
+ *pp = pnew; // ref-count added by InterfaceFromPyObject
+ break;
+ }
+
+ case nsXPTType::T_PSTRING_SIZE_IS: {
+ const char *sz = nsnull;
+ PRUint32 nch = 0;
+ if (val != Py_None) {
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyObject_Str(val))==NULL)
+ BREAK_FALSE;
+ // Sanity check should PyObject_Str() ever loosen its semantics wrt Unicode!
+ NS_ABORT_IF_FALSE(PyString_Check(val_use), "PyObject_Str didnt return a string object!");
+
+ sz = PyString_AS_STRING(val_use);
+ nch = PyString_GET_SIZE(val_use);
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+ if ((val_use = PyUnicode_AsUTF8String(val))==NULL)
+ BREAK_FALSE;
+
+ sz = PyBytes_AS_STRING(val_use);
+ nch = PyBytes_GET_SIZE(val_use);
+#endif
+ }
+ PRBool bBackFill = PR_FALSE;
+ PRBool bCanSetSizeIs = CanSetSizeIs(index, PR_TRUE);
+ // If we can not change the size, check our sequence is correct.
+ if (!bCanSetSizeIs) {
+ PRUint32 existing_size = GetSizeIs(index, PR_TRUE);
+ if (nch != existing_size) {
+ PyErr_Format(PyExc_ValueError, "This function is expecting a string of exactly length %d - %d characters were passed", existing_size, nch);
+ BREAK_FALSE;
+ }
+ // It we have an "inout" param, but an "in" count, then
+ // it is probably a buffer the caller expects us to
+ // fill in-place!
+ bBackFill = pi->IsIn();
+ }
+ if (bBackFill) {
+ memcpy(*(char **)ns_v.val.p, sz, nch);
+ } else {
+ // If we have an existing string, free it!
+ char **pp = (char **)ns_v.val.p;
+ if (*pp && pi->IsIn())
+ nsMemory::Free(*pp);
+ *pp = nsnull;
+ if (sz==nsnull) // None specified.
+ break; // Remains NULL.
+ *pp = (char *)nsMemory::Alloc(nch);
+ if (*pp==NULL) {
+ PyErr_NoMemory();
+ BREAK_FALSE;
+ }
+ memcpy(*pp, sz, nch);
+ if (bCanSetSizeIs)
+ rc = SetSizeIs(index, PR_TRUE, nch);
+ else {
+ NS_ABORT_IF_FALSE(GetSizeIs(index, PR_TRUE) == nch, "Can't set sizeis, but string isnt correct size");
+ }
+ }
+ break;
+ }
+
+ case nsXPTType::T_PWSTRING_SIZE_IS: {
+ PRUnichar *sz = nsnull;
+ PRUint32 nch = 0;
+ PRUint32 nbytes = 0;
+
+ if (val != Py_None) {
+#if PY_MAJOR_VERSION <= 2
+ if (!PyString_Check(val) && !PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a string or Unicode object");
+ BREAK_FALSE;
+ }
+ val_use = PyUnicode_FromObject(val);
+ NS_ABORT_IF_FALSE(PyUnicode_Check(val_use), "PyUnicode_FromObject didnt return a Unicode object!");
+#else
+ if (!PyUnicode_Check(val)) {
+ PyErr_SetString(PyExc_TypeError, "This parameter must be a unicode object");
+ BREAK_FALSE;
+ }
+ val_use = val;
+ Py_INCREF(val_use);
+#endif
+ if (PyUnicode_AsPRUnichar(val_use, &sz, &nch) < 0)
+ BREAK_FALSE;
+ nbytes = sizeof(PRUnichar) * nch;
+ }
+ PRBool bBackFill = PR_FALSE;
+ PRBool bCanSetSizeIs = CanSetSizeIs(index, PR_TRUE);
+ // If we can not change the size, check our sequence is correct.
+ if (!bCanSetSizeIs) {
+ // It is a buffer the caller prolly wants us to fill in-place!
+ PRUint32 existing_size = GetSizeIs(index, PR_TRUE);
+ if (nch != existing_size) {
+ PyErr_Format(PyExc_ValueError, "This function is expecting a string of exactly length %d - %d characters were passed", existing_size, nch);
+ BREAK_FALSE;
+ }
+ // It we have an "inout" param, but an "in" count, then
+ // it is probably a buffer the caller expects us to
+ // fill in-place!
+ bBackFill = pi->IsIn();
+ }
+ if (bBackFill) {
+ memcpy(*(PRUnichar **)ns_v.val.p, sz, nbytes);
+ } else {
+ // If it is an existing string, free it.
+ PRUnichar **pp = (PRUnichar **)ns_v.val.p;
+ if (*pp && pi->IsIn())
+ nsMemory::Free(*pp);
+ *pp = sz;
+ sz = nsnull;
+ if (bCanSetSizeIs)
+ rc = SetSizeIs(index, PR_TRUE, nch);
+ else {
+ NS_ABORT_IF_FALSE(GetSizeIs(index, PR_TRUE) == nch, "Can't set sizeis, but string isnt correct size");
+ }
+ }
+ if (sz)
+ nsMemory::Free(sz);
+ break;
+ }
+ case nsXPTType::T_ARRAY: {
+ // If it is an existing array of the correct size, keep it.
+ PRUint32 sequence_size = 0;
+ PRUint8 array_type;
+ nsIID *piid;
+ nsresult ns = GetArrayType(index, &array_type, &piid);
+ if (NS_FAILED(ns))
+ return ns;
+ PRUint32 element_size = GetArrayElementSize(array_type);
+ if (val != Py_None) {
+ if (!PySequence_Check(val)) {
+ PyErr_Format(PyExc_TypeError, "Object for xpcom array must be a sequence, not type '%s'", PyXPCOM_ObTypeName(val));
+ BREAK_FALSE;
+ }
+ sequence_size = PySequence_Length(val);
+ }
+ PRUint32 existing_size = GetSizeIs(index, PR_FALSE);
+ PRBool bBackFill = PR_FALSE;
+ PRBool bCanSetSizeIs = CanSetSizeIs(index, PR_FALSE);
+ // If we can not change the size, check our sequence is correct.
+ if (!bCanSetSizeIs) {
+ // It is a buffer the caller prolly wants us to fill in-place!
+ if (sequence_size != existing_size) {
+ PyErr_Format(PyExc_ValueError, "This function is expecting a sequence of exactly length %d - %d items were passed", existing_size, sequence_size);
+ BREAK_FALSE;
+ }
+ // It we have an "inout" param, but an "in" count, then
+ // it is probably a buffer the caller expects us to
+ // fill in-place!
+ bBackFill = pi->IsIn();
+ }
+ if (bBackFill)
+ rc = FillSingleArray(*(void **)ns_v.val.p, val, sequence_size, element_size, array_type&XPT_TDP_TAGMASK, piid);
+ else {
+ // If it is an existing array, free it.
+ void **pp = (void **)ns_v.val.p;
+ if (*pp && pi->IsIn()) {
+ FreeSingleArray(*pp, existing_size, array_type);
+ nsMemory::Free(*pp);
+ }
+ *pp = nsnull;
+ if (val == Py_None)
+ break; // Remains NULL.
+ size_t nbytes = sequence_size * element_size;
+ if (nbytes==0) nbytes = 1; // avoid assertion about 0 bytes
+ *pp = (void *)nsMemory::Alloc(nbytes);
+ memset(*pp, 0, nbytes);
+ rc = FillSingleArray(*pp, val, sequence_size, element_size, array_type&XPT_TDP_TAGMASK, piid);
+ if (!rc) break;
+ if (bCanSetSizeIs)
+ rc = SetSizeIs(index, PR_FALSE, sequence_size);
+ else {
+ NS_ABORT_IF_FALSE(GetSizeIs(index, PR_FALSE) == sequence_size, "Can't set sizeis, but string isnt correct size");
+ }
+ }
+ break;
+ }
+ default:
+ // try and limp along in this case.
+ // leave rc TRUE
+ PyXPCOM_LogWarning("Converting Python object for an [out] param - The object type (0x%x) is unknown - leaving param alone!\n", XPT_TDP_TAG(typ));
+ break;
+ }
+ Py_XDECREF(val_use);
+ if (!rc)
+ return NS_ERROR_FAILURE;
+ return NS_OK;
+}
+
+nsresult PyXPCOM_GatewayVariantHelper::ProcessPythonResult(PyObject *ret_ob)
+{
+ // NOTE - although we return an nresult, if we leave a Python
+ // exception set, then our caller may take additional action
+ // (ie, translating our nsresult to a more appropriate nsresult
+ // for the Python exception.)
+ NS_PRECONDITION(!PyErr_Occurred(), "Expecting no Python exception to be pending when processing the return result");
+
+ nsresult rc = NS_OK;
+ // If we dont get a tuple back, then the result is only
+ // an int nresult for the underlying function.
+ // (ie, the policy is expected to return (NS_OK, user_retval),
+ // but can also return (say), NS_ERROR_FAILURE
+ if (PyInt_Check(ret_ob))
+ return PyInt_AsLong(ret_ob);
+ // Now it must be the tuple.
+ if (!PyTuple_Check(ret_ob) ||
+ PyTuple_Size(ret_ob)!=2 ||
+ !PyInt_Check(PyTuple_GET_ITEM(ret_ob, 0))) {
+ PyErr_SetString(PyExc_TypeError, "The Python result must be a single integer or a tuple of length==2 and first item an int.");
+ return NS_ERROR_FAILURE;
+ }
+ PyObject *user_result = PyTuple_GET_ITEM(ret_ob, 1);
+ // Count up how many results our function needs.
+ int i;
+ int num_results = 0;
+ int last_result = -1; // optimization if we only have one - this is it!
+ int index_retval = -1;
+ for (i=0;i<m_num_type_descs;i++) {
+ nsXPTParamInfo *pi = (nsXPTParamInfo *)m_info->params+i;
+ if (!m_python_type_desc_array[i].is_auto_out) {
+ if (pi->IsOut() || pi->IsDipper()) {
+ num_results++;
+ last_result = i;
+ }
+ if (pi->IsRetval())
+ index_retval = i;
+ }
+ }
+
+ if (num_results==0) {
+ ; // do nothing
+ } else if (num_results==1) {
+ // May or may not be the nominated retval - who cares!
+ NS_ABORT_IF_FALSE(last_result >=0 && last_result < m_num_type_descs, "Have one result, but dont know its index!");
+ rc = BackFillVariant( user_result, last_result );
+ } else {
+ // Loop over each one, filling as we go.
+ // We allow arbitary sequences here, but _not_ strings
+ // or Unicode!
+ // NOTE - We ALWAYS do the nominated retval first.
+ // The Python pattern is always:
+ // return retval [, byref1 [, byref2 ...] ]
+ // But the retval is often the last param described in the info.
+ if (!PySequence_Check(user_result) ||
+#if PY_MAJOR_VERSION <= 2
+ PyString_Check(user_result) ||
+#else
+ PyBytes_Check(user_result) ||
+#endif
+ PyUnicode_Check(user_result)) {
+ PyErr_SetString(PyExc_TypeError, "This function has multiple results, but a sequence was not given to fill them");
+ return NS_ERROR_FAILURE;
+ }
+ int num_user_results = PySequence_Length(user_result);
+ // If they havent given enough, we dont really care.
+ // although a warning is probably appropriate.
+ if (num_user_results != num_results) {
+ const char *method_name = m_info->GetName();
+ PyXPCOM_LogWarning("The method '%s' has %d out params, but %d were supplied by the Python code\n",
+ method_name,
+ num_results,
+ num_user_results);
+ }
+ int this_py_index = 0;
+ if (index_retval != -1) {
+ // We always return the nominated result first!
+ PyObject *sub = PySequence_GetItem(user_result, 0);
+ if (sub==NULL)
+ return NS_ERROR_FAILURE;
+ rc = BackFillVariant(sub, index_retval);
+ Py_DECREF(sub);
+ this_py_index = 1;
+ }
+ for (i=0;NS_SUCCEEDED(rc) && i<m_info->GetParamCount();i++) {
+ // If weve already done it, or dont need to do it!
+ if (i==index_retval || m_python_type_desc_array[i].is_auto_out)
+ continue;
+ nsXPTParamInfo *pi = (nsXPTParamInfo *)m_info->params+i;
+ if (pi->IsOut()) {
+ PyObject *sub = PySequence_GetItem(user_result, this_py_index);
+ if (sub==NULL)
+ return NS_ERROR_FAILURE;
+ rc = BackFillVariant(sub, i);
+ Py_DECREF(sub);
+ this_py_index++;
+ }
+ }
+ }
+ return rc;
+}
diff --git a/src/libs/xpcom18a4/python/src/dllmain.cpp b/src/libs/xpcom18a4/python/src/dllmain.cpp
new file mode 100644
index 00000000..4cc08578
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/dllmain.cpp
@@ -0,0 +1,352 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM_std.h"
+#include <prthread.h>
+#include "nsIThread.h"
+#include "nsILocalFile.h"
+
+#ifdef XP_WIN
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include "windows.h"
+#endif
+
+static PRInt32 g_cLockCount = 0;
+static PRLock *g_lockMain = nsnull;
+
+PYXPCOM_EXPORT PyObject *PyXPCOM_Error = NULL;
+
+PyXPCOM_INTERFACE_DEFINE(Py_nsIComponentManager, nsIComponentManager, PyMethods_IComponentManager)
+PyXPCOM_INTERFACE_DEFINE(Py_nsIInterfaceInfoManager, nsIInterfaceInfoManager, PyMethods_IInterfaceInfoManager)
+PyXPCOM_INTERFACE_DEFINE(Py_nsIEnumerator, nsIEnumerator, PyMethods_IEnumerator)
+PyXPCOM_INTERFACE_DEFINE(Py_nsISimpleEnumerator, nsISimpleEnumerator, PyMethods_ISimpleEnumerator)
+PyXPCOM_INTERFACE_DEFINE(Py_nsIInterfaceInfo, nsIInterfaceInfo, PyMethods_IInterfaceInfo)
+PyXPCOM_INTERFACE_DEFINE(Py_nsIInputStream, nsIInputStream, PyMethods_IInputStream)
+PyXPCOM_INTERFACE_DEFINE(Py_nsIClassInfo, nsIClassInfo, PyMethods_IClassInfo)
+PyXPCOM_INTERFACE_DEFINE(Py_nsIVariant, nsIVariant, PyMethods_IVariant)
+// deprecated, but retained for backward compatibility:
+PyXPCOM_INTERFACE_DEFINE(Py_nsIComponentManagerObsolete, nsIComponentManagerObsolete, PyMethods_IComponentManagerObsolete)
+
+#ifndef PYXPCOM_USE_PYGILSTATE
+
+////////////////////////////////////////////////////////////
+// Thread-state helpers/global functions.
+// Only used if there is no Python PyGILState_* API
+//
+static PyThreadState *ptsGlobal = nsnull;
+PyInterpreterState *PyXPCOM_InterpreterState = nsnull;
+PRUintn tlsIndex = 0;
+
+
+// This function must be called at some time when the interpreter lock and state is valid.
+// Called by init{module} functions and also COM factory entry point.
+void PyXPCOM_InterpreterState_Ensure()
+{
+ if (PyXPCOM_InterpreterState==NULL) {
+ PyThreadState *threadStateSave = PyThreadState_Swap(NULL);
+ if (threadStateSave==NULL)
+ Py_FatalError("Can not setup interpreter state, as current state is invalid");
+
+ PyXPCOM_InterpreterState = threadStateSave->interp;
+ PyThreadState_Swap(threadStateSave);
+ }
+}
+
+void PyXPCOM_InterpreterState_Free()
+{
+ PyXPCOM_ThreadState_Free();
+ PyXPCOM_InterpreterState = NULL; // Eek - should I be freeing something?
+}
+
+// This structure is stored in the TLS slot. At this stage only a Python thread state
+// is kept, but this may change in the future...
+struct ThreadData{
+ PyThreadState *ts;
+};
+
+// Ensure that we have a Python thread state available to use.
+// If this is called for the first time on a thread, it will allocate
+// the thread state. This does NOT change the state of the Python lock.
+// Returns TRUE if a new thread state was created, or FALSE if a
+// thread state already existed.
+PRBool PyXPCOM_ThreadState_Ensure()
+{
+ ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex);
+ if (pData==NULL) { /* First request on this thread */
+ /* Check we have an interpreter state */
+ if (PyXPCOM_InterpreterState==NULL) {
+ Py_FatalError("Can not setup thread state, as have no interpreter state");
+ }
+ pData = (ThreadData *)nsMemory::Alloc(sizeof(ThreadData));
+ if (!pData)
+ Py_FatalError("Out of memory allocating thread state.");
+ memset(pData, 0, sizeof(*pData));
+ if (NS_FAILED( PR_SetThreadPrivate( tlsIndex, pData ) ) ) {
+ NS_ABORT_IF_FALSE(0, "Could not create thread data for this thread!");
+ Py_FatalError("Could not thread private thread data!");
+ }
+ pData->ts = PyThreadState_New(PyXPCOM_InterpreterState);
+ return PR_TRUE; // Did create a thread state state
+ }
+ return PR_FALSE; // Thread state was previously created
+}
+
+// Asuming we have a valid thread state, acquire the Python lock.
+void PyXPCOM_InterpreterLock_Acquire()
+{
+ ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex);
+ NS_ABORT_IF_FALSE(pData, "Have no thread data for this thread!");
+ PyThreadState *thisThreadState = pData->ts;
+ PyEval_AcquireThread(thisThreadState);
+}
+
+// Asuming we have a valid thread state, release the Python lock.
+void PyXPCOM_InterpreterLock_Release()
+{
+ ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex);
+ NS_ABORT_IF_FALSE(pData, "Have no thread data for this thread!");
+ PyThreadState *thisThreadState = pData->ts;
+ PyEval_ReleaseThread(thisThreadState);
+}
+
+// Free the thread state for the current thread
+// (Presumably previously create with a call to
+// PyXPCOM_ThreadState_Ensure)
+void PyXPCOM_ThreadState_Free()
+{
+ ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex);
+ if (!pData) return;
+ PyThreadState *thisThreadState = pData->ts;
+ PyThreadState_Delete(thisThreadState);
+ PR_SetThreadPrivate(tlsIndex, NULL);
+ nsMemory::Free(pData);
+}
+
+void PyXPCOM_ThreadState_Clear()
+{
+ ThreadData *pData = (ThreadData *)PR_GetThreadPrivate(tlsIndex);
+ PyThreadState *thisThreadState = pData->ts;
+ PyThreadState_Clear(thisThreadState);
+}
+#endif // PYXPCOM_USE_PYGILSTATE
+
+////////////////////////////////////////////////////////////
+// Lock/exclusion global functions.
+//
+void PyXPCOM_AcquireGlobalLock(void)
+{
+ NS_PRECONDITION(g_lockMain != nsnull, "Cant acquire a NULL lock!");
+ PR_Lock(g_lockMain);
+}
+void PyXPCOM_ReleaseGlobalLock(void)
+{
+ NS_PRECONDITION(g_lockMain != nsnull, "Cant release a NULL lock!");
+ PR_Unlock(g_lockMain);
+}
+
+void PyXPCOM_DLLAddRef(void)
+{
+ // Must be thread-safe, although cant have the Python lock!
+ CEnterLeaveXPCOMFramework _celf;
+ PRInt32 cnt = PR_AtomicIncrement(&g_cLockCount);
+ if (cnt==1) { // First call
+ if (!Py_IsInitialized()) {
+ Py_Initialize();
+ // Make sure our Windows framework is all setup.
+ PyXPCOM_Globals_Ensure();
+ // Make sure we have _something_ as sys.argv.
+ if (PySys_GetObject((char*)"argv")==NULL) {
+ PyObject *path = PyList_New(0);
+#if PY_MAJOR_VERSION <= 2
+ PyObject *str = PyString_FromString("");
+#else
+ PyObject *str = PyUnicode_FromString("");
+#endif
+ PyList_Append(path, str);
+ PySys_SetObject((char*)"argv", path);
+ Py_XDECREF(path);
+ Py_XDECREF(str);
+ }
+
+ // Must force Python to start using thread locks, as
+ // we are free-threaded (maybe, I think, sometimes :-)
+ PyEval_InitThreads();
+#ifndef PYXPCOM_USE_PYGILSTATE
+ // Release Python lock, as first thing we do is re-get it.
+ ptsGlobal = PyEval_SaveThread();
+#endif
+ // NOTE: We never finalize Python!!
+ }
+ }
+}
+void PyXPCOM_DLLRelease(void)
+{
+ PR_AtomicDecrement(&g_cLockCount);
+}
+
+void pyxpcom_construct(void)
+{
+ g_lockMain = PR_NewLock();
+#ifndef PYXPCOM_USE_PYGILSTATE
+ PRStatus status;
+ status = PR_NewThreadPrivateIndex( &tlsIndex, NULL );
+ NS_WARN_IF_FALSE(status==0, "Could not allocate TLS storage");
+ if (NS_FAILED(status)) {
+ PR_DestroyLock(g_lockMain);
+ return; // PR_FALSE;
+ }
+#endif // PYXPCOM_USE_PYGILSTATE
+ return; // PR_TRUE;
+}
+
+void pyxpcom_destruct(void)
+{
+ PR_DestroyLock(g_lockMain);
+#ifndef PYXPCOM_USE_PYGILSTATE
+ // I can't locate a way to kill this -
+ // should I pass a dtor to PR_NewThreadPrivateIndex??
+ // TlsFree(tlsIndex);
+#endif // PYXPCOM_USE_PYGILSTATE
+}
+
+// Yet another attempt at cross-platform library initialization and finalization.
+struct DllInitializer {
+ DllInitializer() {
+ pyxpcom_construct();
+ }
+ ~DllInitializer() {
+ pyxpcom_destruct();
+ }
+} dll_initializer;
+
+////////////////////////////////////////////////////////////
+// Other helpers/global functions.
+//
+PRBool PyXPCOM_Globals_Ensure()
+{
+ PRBool rc = PR_TRUE;
+
+#ifndef PYXPCOM_USE_PYGILSTATE
+ PyXPCOM_InterpreterState_Ensure();
+#endif
+
+ // The exception object - we load it from .py code!
+ if (PyXPCOM_Error == NULL) {
+ rc = PR_FALSE;
+ PyObject *mod = NULL;
+
+ mod = PyImport_ImportModule("xpcom");
+ if (mod!=NULL) {
+ PyXPCOM_Error = PyObject_GetAttrString(mod, "Exception");
+ Py_DECREF(mod);
+ }
+ rc = (PyXPCOM_Error != NULL);
+ }
+ if (!rc)
+ return rc;
+
+ static PRBool bHaveInitXPCOM = PR_FALSE;
+ if (!bHaveInitXPCOM) {
+ nsCOMPtr<nsIThread> thread_check;
+ // xpcom appears to assert if already initialized
+ // Is there an official way to determine this?
+ if (NS_FAILED(nsIThread::GetMainThread(getter_AddRefs(thread_check)))) {
+ // not already initialized.
+#ifdef XP_WIN
+ // On Windows, we need to locate the Mozilla bin
+ // directory. This by using locating a Moz DLL we depend
+ // on, and assume it lives in that bin dir. Different
+ // moz build types (eg, xulrunner, suite) package
+ // XPCOM itself differently - but all appear to require
+ // nspr4.dll - so this is what we use.
+ char landmark[MAX_PATH+1];
+ HMODULE hmod = GetModuleHandle("nspr4.dll");
+ if (hmod==NULL) {
+ PyErr_SetString(PyExc_RuntimeError, "We dont appear to be linked against nspr4.dll.");
+ return PR_FALSE;
+ }
+ GetModuleFileName(hmod, landmark, sizeof(landmark)/sizeof(landmark[0]));
+ char *end = landmark + (strlen(landmark)-1);
+ while (end > landmark && *end != '\\')
+ end--;
+ if (end > landmark) *end = '\0';
+
+ nsCOMPtr<nsILocalFile> ns_bin_dir;
+ NS_ConvertASCIItoUCS2 strLandmark(landmark);
+ NS_NewLocalFile(strLandmark, PR_FALSE, getter_AddRefs(ns_bin_dir));
+ nsresult rv = NS_InitXPCOM2(nsnull, ns_bin_dir, nsnull);
+#else
+ // Elsewhere, Mozilla can find it itself (we hope!)
+ nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull);
+#endif // XP_WIN
+ if (NS_FAILED(rv)) {
+ PyErr_SetString(PyExc_RuntimeError, "The XPCOM subsystem could not be initialized");
+ return PR_FALSE;
+ }
+ }
+ // Even if xpcom was already init, we want to flag it as init!
+ bHaveInitXPCOM = PR_TRUE;
+ // Register our custom interfaces.
+
+ Py_nsISupports::InitType();
+ Py_nsIComponentManager::InitType();
+ Py_nsIInterfaceInfoManager::InitType();
+ Py_nsIEnumerator::InitType();
+ Py_nsISimpleEnumerator::InitType();
+ Py_nsIInterfaceInfo::InitType();
+ Py_nsIInputStream::InitType();
+ Py_nsIClassInfo::InitType();
+ Py_nsIVariant::InitType();
+ // for backward compatibility:
+ Py_nsIComponentManagerObsolete::InitType();
+
+ }
+ return rc;
+}
+
diff --git a/src/libs/xpcom18a4/python/src/loader/pyloader.cpp b/src/libs/xpcom18a4/python/src/loader/pyloader.cpp
new file mode 100644
index 00000000..dc116f1d
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/loader/pyloader.cpp
@@ -0,0 +1,435 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+// pyloader
+//
+// Not part of the main Python _xpcom package, but a separate, thin DLL.
+//
+// The main loader and registrar for Python. A thin DLL that is designed to live in
+// the xpcom "components" directory. Simply locates and loads the standard
+// pyxpcom core library and transfers control to that.
+
+#include <PyXPCOM.h>
+
+#include "nsDirectoryServiceDefs.h"
+#include "nsILocalFile.h"
+
+#include "nspr.h" // PR_fprintf
+
+#if (PY_VERSION_HEX >= 0x02030000)
+#define PYXPCOM_USE_PYGILSTATE
+#endif
+
+static char *PyTraceback_AsString(PyObject *exc_tb);
+
+#ifdef XP_WIN
+#include "windows.h"
+#endif
+
+#ifdef XP_UNIX
+#include <dlfcn.h>
+#include <sys/stat.h>
+
+#endif
+
+#include "nsITimelineService.h"
+
+typedef nsresult (*pfnPyXPCOM_NSGetModule)(nsIComponentManager *servMgr,
+ nsIFile* location,
+ nsIModule** result);
+
+
+static void LogError(const char *fmt, ...);
+static void LogDebug(const char *fmt, ...);
+
+// Ensure that any paths guaranteed by this package exist on sys.path
+// Only called once as we are first loaded into the process.
+void AddStandardPaths()
+{
+ // Put {bin}\Python on the path if it exists.
+ nsresult rv;
+ nsCOMPtr<nsIFile> aFile;
+ rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR, getter_AddRefs(aFile));
+ if (NS_FAILED(rv)) {
+ LogError("The Python XPCOM loader could not locate the 'bin' directory\n");
+ return;
+ }
+ aFile->Append(NS_LITERAL_STRING("python"));
+ nsAutoString pathBuf;
+ aFile->GetPath(pathBuf);
+ PyObject *obPath = PySys_GetObject("path");
+ if (!obPath) {
+ LogError("The Python XPCOM loader could not get the Python sys.path variable\n");
+ return;
+ }
+ NS_LossyConvertUCS2toASCII pathCBuf(pathBuf);
+ LogDebug("The Python XPCOM loader is adding '%s' to sys.path\n", pathCBuf.get());
+ PyObject *newStr = PyString_FromString(pathCBuf.get());
+ PyList_Insert(obPath, 0, newStr);
+ Py_XDECREF(newStr);
+ // And now try and get Python to process this directory as a "site dir"
+ // - ie, look for .pth files, etc
+ nsCAutoString cmdBuf(NS_LITERAL_CSTRING("import site;site.addsitedir(r'") + pathCBuf + NS_LITERAL_CSTRING("')\n"));
+ if (0 != PyRun_SimpleString((char *)cmdBuf.get())) {
+ LogError("The directory '%s' could not be added as a site directory", pathCBuf.get());
+ PyErr_Clear();
+ }
+ // and somewhat like Python itself (site, citecustomize), we attempt
+ // to import "sitepyxpcom" ignoring ImportError
+ if (NULL==PyImport_ImportModule("sitepyxpcom")) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ LogError("Failed to import 'sitepyxpcom'");
+ PyErr_Clear();
+ }
+}
+
+////////////////////////////////////////////////////////////
+// This is the main entry point that delegates into Python
+nsresult PyXPCOM_NSGetModule(nsIComponentManager *servMgr,
+ nsIFile* location,
+ nsIModule** result)
+{
+ NS_PRECONDITION(result!=NULL, "null result pointer in PyXPCOM_NSGetModule!");
+ NS_PRECONDITION(location!=NULL, "null nsIFile pointer in PyXPCOM_NSGetModule!");
+ NS_PRECONDITION(servMgr!=NULL, "null servMgr pointer in PyXPCOM_NSGetModule!");
+#ifndef LOADER_LINKS_WITH_PYTHON
+ if (!Py_IsInitialized()) {
+ Py_Initialize();
+ if (!Py_IsInitialized()) {
+ PyXPCOM_LogError("Python initialization failed!\n");
+ return NS_ERROR_FAILURE;
+ }
+ PyEval_InitThreads();
+#ifndef PYXPCOM_USE_PYGILSTATE
+ PyXPCOM_InterpreterState_Ensure();
+#endif
+ PyEval_SaveThread();
+ }
+#endif // LOADER_LINKS_WITH_PYTHON
+ CEnterLeavePython _celp;
+ PyObject *func = NULL;
+ PyObject *obServMgr = NULL;
+ PyObject *obLocation = NULL;
+ PyObject *wrap_ret = NULL;
+ PyObject *args = NULL;
+ PyObject *mod = PyImport_ImportModule("xpcom.server");
+ if (!mod) goto done;
+ func = PyObject_GetAttrString(mod, "NS_GetModule");
+ if (func==NULL) goto done;
+ obServMgr = Py_nsISupports::PyObjectFromInterface(servMgr, NS_GET_IID(nsIComponentManager));
+ if (obServMgr==NULL) goto done;
+ obLocation = Py_nsISupports::PyObjectFromInterface(location, NS_GET_IID(nsIFile));
+ if (obLocation==NULL) goto done;
+ args = Py_BuildValue("OO", obServMgr, obLocation);
+ if (args==NULL) goto done;
+ wrap_ret = PyEval_CallObject(func, args);
+ if (wrap_ret==NULL) goto done;
+ Py_nsISupports::InterfaceFromPyObject(wrap_ret, NS_GET_IID(nsIModule), (nsISupports **)result, PR_FALSE, PR_FALSE);
+done:
+ nsresult nr = NS_OK;
+ if (PyErr_Occurred()) {
+ PyXPCOM_LogError("Obtaining the module object from Python failed.\n");
+ nr = PyXPCOM_SetCOMErrorFromPyException();
+ }
+ Py_XDECREF(func);
+ Py_XDECREF(obServMgr);
+ Py_XDECREF(obLocation);
+ Py_XDECREF(wrap_ret);
+ Py_XDECREF(mod);
+ Py_XDECREF(args);
+ return nr;
+}
+
+extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
+ nsIFile* location,
+ nsIModule** result)
+{
+#ifdef XP_UNIX
+ // *sob* - seems necessary to open the .so as RTLD_GLOBAL
+ dlopen(PYTHON_SO,RTLD_NOW | RTLD_GLOBAL);
+#endif
+ PRBool bDidInitPython = !Py_IsInitialized(); // well, I will next line, anyway :-)
+ if (bDidInitPython) {
+ NS_TIMELINE_START_TIMER("PyXPCOM: Python initializing");
+ Py_Initialize();
+ if (!Py_IsInitialized()) {
+ LogError("Python initialization failed!\n");
+ return NS_ERROR_FAILURE;
+ }
+#ifndef NS_DEBUG
+ Py_OptimizeFlag = 1;
+#endif // NS_DEBUG
+ PyEval_InitThreads();
+ NS_TIMELINE_STOP_TIMER("PyXPCOM: Python initializing");
+ NS_TIMELINE_MARK_TIMER("PyXPCOM: Python initializing");
+ }
+ // Get the Python interpreter state
+ NS_TIMELINE_START_TIMER("PyXPCOM: Python threadstate setup");
+#ifndef PYXPCOM_USE_PYGILSTATE
+ PyThreadState *threadStateCreated = NULL;
+ PyThreadState *threadState = PyThreadState_Swap(NULL);
+ if (threadState==NULL) {
+ // no thread-state - set one up.
+ // *sigh* - what I consider a bug is that Python
+ // will deadlock unless we own the lock before creating
+ // a new interpreter (it appear Py_NewInterpreter has
+ // really only been tested/used with no thread lock
+ PyEval_AcquireLock();
+ threadState = threadStateCreated = Py_NewInterpreter();
+ PyThreadState_Swap(NULL);
+ }
+ PyEval_ReleaseLock();
+ PyEval_AcquireThread(threadState);
+#else
+ PyGILState_STATE state = PyGILState_Ensure();
+#endif // PYXPCOM_USE_PYGILSTATE
+#ifdef MOZ_TIMELINE
+ // If the timeline service is installed, see if we can install our hooks.
+ if (NULL==PyImport_ImportModule("timeline_hook")) {
+ if (!PyErr_ExceptionMatches(PyExc_ImportError))
+ LogError("Failed to import 'timeline_hook'");
+ PyErr_Clear(); // but don't care if we can't.
+ }
+#endif
+ // Add the standard paths always - we may not have been the first to
+ // init Python.
+ AddStandardPaths();
+
+#ifndef PYXPCOM_USE_PYGILSTATE
+ // Abandon the thread-lock, as the first thing Python does
+ // is re-establish the lock (the Python thread-state story SUCKS!!!)
+ if (threadStateCreated) {
+ Py_EndInterpreter(threadStateCreated);
+ PyEval_ReleaseLock(); // see Py_NewInterpreter call above
+ } else {
+ PyEval_ReleaseThread(threadState);
+ PyThreadState *threadStateSave = PyThreadState_Swap(NULL);
+ if (threadStateSave)
+ PyThreadState_Delete(threadStateSave);
+ }
+#else
+ // If we initialized Python, then we will also have acquired the thread
+ // lock. In that case, we want to leave it unlocked, so other threads
+ // are free to run, even if they aren't running Python code.
+ PyGILState_Release(bDidInitPython ? PyGILState_UNLOCKED : state);
+#endif
+
+ NS_TIMELINE_STOP_TIMER("PyXPCOM: Python threadstate setup");
+ NS_TIMELINE_MARK_TIMER("PyXPCOM: Python threadstate setup");
+ NS_TIMELINE_START_TIMER("PyXPCOM: PyXPCOM NSGetModule entry point");
+ nsresult rc = PyXPCOM_NSGetModule(servMgr, location, result);
+ NS_TIMELINE_STOP_TIMER("PyXPCOM: PyXPCOM NSGetModule entry point");
+ NS_TIMELINE_MARK_TIMER("PyXPCOM: PyXPCOM NSGetModule entry point");
+ return rc;
+}
+
+// The internal helper that actually moves the
+// formatted string to the target!
+
+void LogMessage(const char *prefix, const char *pszMessageText)
+{
+ PR_fprintf(PR_STDERR, "%s", pszMessageText);
+}
+
+void LogMessage(const char *prefix, nsACString &text)
+{
+ LogMessage(prefix, nsPromiseFlatCString(text).get());
+}
+
+// A helper for the various logging routines.
+static void VLogF(const char *prefix, const char *fmt, va_list argptr)
+{
+ char buff[512];
+
+ vsprintf(buff, fmt, argptr);
+
+ LogMessage(prefix, buff);
+}
+
+static void LogError(const char *fmt, ...)
+{
+ va_list marker;
+ va_start(marker, fmt);
+ VLogF("PyXPCOM Loader Error: ", fmt, marker);
+ // If we have a Python exception, also log that:
+ PyObject *exc_typ = NULL, *exc_val = NULL, *exc_tb = NULL;
+ PyErr_Fetch( &exc_typ, &exc_val, &exc_tb);
+ if (exc_typ) {
+ nsCAutoString streamout;
+
+ if (exc_tb) {
+ const char *szTraceback = PyTraceback_AsString(exc_tb);
+ if (szTraceback == NULL)
+ streamout += "Can't get the traceback info!";
+ else {
+ streamout += "Traceback (most recent call last):\n";
+ streamout += szTraceback;
+ PyMem_Free((void *)szTraceback);
+ }
+ }
+ PyObject *temp = PyObject_Str(exc_typ);
+ if (temp) {
+ streamout += PyString_AsString(temp);
+ Py_DECREF(temp);
+ } else
+ streamout += "Can convert exception to a string!";
+ streamout += ": ";
+ if (exc_val != NULL) {
+ temp = PyObject_Str(exc_val);
+ if (temp) {
+ streamout += PyString_AsString(temp);
+ Py_DECREF(temp);
+ } else
+ streamout += "Can convert exception value to a string!";
+ }
+ streamout += "\n";
+ LogMessage("PyXPCOM Exception:", streamout);
+ }
+ PyErr_Restore(exc_typ, exc_val, exc_tb);
+ va_end(marker);
+}
+/*** - not currently used - silence compiler warning.
+static void LogWarning(const char *fmt, ...)
+{
+ va_list marker;
+ va_start(marker, fmt);
+ VLogF("PyXPCOM Loader Warning: ", fmt, marker);
+}
+***/
+#ifdef DEBUG
+static void LogDebug(const char *fmt, ...)
+{
+ va_list marker;
+ va_start(marker, fmt);
+ VLogF("PyXPCOM Loader Debug: ", fmt, marker);
+ va_end(marker);
+}
+#else
+static void LogDebug(const char *fmt, ...)
+{
+}
+#endif
+
+/* Obtains a string from a Python traceback.
+ This is the exact same string as "traceback.print_exc" would return.
+
+ Pass in a Python traceback object (probably obtained from PyErr_Fetch())
+ Result is a string which must be free'd using PyMem_Free()
+*/
+#define TRACEBACK_FETCH_ERROR(what) {errMsg = what; goto done;}
+
+char *PyTraceback_AsString(PyObject *exc_tb)
+{
+ char *errMsg = NULL; /* a static that hold a local error message */
+ char *result = NULL; /* a valid, allocated result. */
+ PyObject *modStringIO = NULL;
+ PyObject *modTB = NULL;
+ PyObject *obFuncStringIO = NULL;
+ PyObject *obStringIO = NULL;
+ PyObject *obFuncTB = NULL;
+ PyObject *argsTB = NULL;
+ PyObject *obResult = NULL;
+
+ /* Import the modules we need - cStringIO and traceback */
+ modStringIO = PyImport_ImportModule("cStringIO");
+ if (modStringIO==NULL)
+ TRACEBACK_FETCH_ERROR("cant import cStringIO\n");
+
+ modTB = PyImport_ImportModule("traceback");
+ if (modTB==NULL)
+ TRACEBACK_FETCH_ERROR("cant import traceback\n");
+ /* Construct a cStringIO object */
+ obFuncStringIO = PyObject_GetAttrString(modStringIO, "StringIO");
+ if (obFuncStringIO==NULL)
+ TRACEBACK_FETCH_ERROR("cant find cStringIO.StringIO\n");
+ obStringIO = PyObject_CallObject(obFuncStringIO, NULL);
+ if (obStringIO==NULL)
+ TRACEBACK_FETCH_ERROR("cStringIO.StringIO() failed\n");
+ /* Get the traceback.print_exception function, and call it. */
+ obFuncTB = PyObject_GetAttrString(modTB, "print_tb");
+ if (obFuncTB==NULL)
+ TRACEBACK_FETCH_ERROR("cant find traceback.print_tb\n");
+
+ argsTB = Py_BuildValue("OOO",
+ exc_tb ? exc_tb : Py_None,
+ Py_None,
+ obStringIO);
+ if (argsTB==NULL)
+ TRACEBACK_FETCH_ERROR("cant make print_tb arguments\n");
+
+ obResult = PyObject_CallObject(obFuncTB, argsTB);
+ if (obResult==NULL)
+ TRACEBACK_FETCH_ERROR("traceback.print_tb() failed\n");
+ /* Now call the getvalue() method in the StringIO instance */
+ Py_DECREF(obFuncStringIO);
+ obFuncStringIO = PyObject_GetAttrString(obStringIO, "getvalue");
+ if (obFuncStringIO==NULL)
+ TRACEBACK_FETCH_ERROR("cant find getvalue function\n");
+ Py_DECREF(obResult);
+ obResult = PyObject_CallObject(obFuncStringIO, NULL);
+ if (obResult==NULL)
+ TRACEBACK_FETCH_ERROR("getvalue() failed.\n");
+
+ /* And it should be a string all ready to go - duplicate it. */
+ if (!PyString_Check(obResult))
+ TRACEBACK_FETCH_ERROR("getvalue() did not return a string\n");
+
+ { // a temp scope so I can use temp locals.
+ char *tempResult = PyString_AsString(obResult);
+ result = (char *)PyMem_Malloc(strlen(tempResult)+1);
+ if (result==NULL)
+ TRACEBACK_FETCH_ERROR("memory error duplicating the traceback string");
+
+ strcpy(result, tempResult);
+ } // end of temp scope.
+done:
+ /* All finished - first see if we encountered an error */
+ if (result==NULL && errMsg != NULL) {
+ result = (char *)PyMem_Malloc(strlen(errMsg)+1);
+ if (result != NULL)
+ /* if it does, not much we can do! */
+ strcpy(result, errMsg);
+ }
+ Py_XDECREF(modStringIO);
+ Py_XDECREF(modTB);
+ Py_XDECREF(obFuncStringIO);
+ Py_XDECREF(obStringIO);
+ Py_XDECREF(obFuncTB);
+ Py_XDECREF(argsTB);
+ Py_XDECREF(obResult);
+ return result;
+}
diff --git a/src/libs/xpcom18a4/python/src/module/_xpcom.cpp b/src/libs/xpcom18a4/python/src/module/_xpcom.cpp
new file mode 100644
index 00000000..d40d2b52
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/module/_xpcom.cpp
@@ -0,0 +1,950 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <mhammond@skippinet.com.au> (original author)
+ *
+ * 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 ***** */
+
+//
+// This code is part of the XPCOM extensions for Python.
+//
+// Written May 2000 by Mark Hammond.
+//
+// Based heavily on the Python COM support, which is
+// (c) Mark Hammond and Greg Stein.
+//
+// (c) 2000, ActiveState corp.
+
+#include "PyXPCOM.h"
+#include "nsXPCOM.h"
+#include "nsISupportsPrimitives.h"
+#include "nsIFile.h"
+#include "nsIComponentRegistrar.h"
+#include "nsIComponentManagerObsolete.h"
+#include "nsIConsoleService.h"
+#include "nspr.h" // PR_fprintf
+#ifdef VBOX
+# include "nsEventQueueUtils.h"
+#endif
+
+#ifdef XP_WIN
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include "windows.h"
+#endif
+
+#include "nsIEventQueue.h"
+#include "nsIProxyObjectManager.h"
+
+#define LOADER_LINKS_WITH_PYTHON
+
+#ifndef PYXPCOM_USE_PYGILSTATE
+extern PYXPCOM_EXPORT void PyXPCOM_InterpreterState_Ensure();
+#endif
+
+#ifdef VBOX_PYXPCOM
+# include <iprt/cdefs.h>
+# include <VBox/com/com.h>
+# ifndef MODULE_NAME_SUFFIX
+# define MANGLE_MODULE_NAME(a_szName) a_szName
+# define MANGLE_MODULE_INIT(a_Name) a_Name
+# else
+# define MANGLE_MODULE_NAME(a_szName) a_szName RT_XSTR(MODULE_NAME_SUFFIX)
+# define MANGLE_MODULE_INIT(a_Name) RT_CONCAT(a_Name, MODULE_NAME_SUFFIX)
+# endif
+# if defined(VBOX_PYXPCOM_VERSIONED) && !defined(VBOX_PYXPCOM_MAJOR_VERSIONED)
+# if PY_VERSION_HEX >= 0x030a0000 && PY_VERSION_HEX < 0x030b0000
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython3_10")
+# define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_10)
+
+# elif PY_VERSION_HEX >= 0x03090000 && PY_VERSION_HEX < 0x030a0000
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython3_9")
+# define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_9)
+
+# elif PY_VERSION_HEX >= 0x03080000 && PY_VERSION_HEX < 0x03090000
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython3_8")
+# define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_8)
+
+# elif PY_VERSION_HEX >= 0x03070000 && PY_VERSION_HEX < 0x03080000
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython3_7")
+# define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_7)
+
+# elif PY_VERSION_HEX >= 0x03060000 && PY_VERSION_HEX < 0x03070000
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython3_6")
+# define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_6)
+
+# elif PY_VERSION_HEX >= 0x03050000 && PY_VERSION_HEX < 0x03060000
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython3_5")
+# define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_5)
+
+# elif PY_VERSION_HEX >= 0x03040000 && PY_VERSION_HEX < 0x03050000
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython3_4")
+# define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_4)
+
+# elif PY_VERSION_HEX >= 0x03030000 && PY_VERSION_HEX < 0x03040000
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython3_3")
+# define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_3)
+
+# elif PY_VERSION_HEX >= 0x03020000 && PY_VERSION_HEX < 0x03030000
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython3_2")
+# define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_2)
+
+# elif PY_VERSION_HEX >= 0x03010000 && PY_VERSION_HEX < 0x03020000
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython3_1")
+# define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3_1)
+
+# elif PY_VERSION_HEX >= 0x02080000 && PY_VERSION_HEX < 0x02090000
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython2_8")
+# define initVBoxPython MANGLE_MODULE_INIT(initVBoxPython2_8)
+
+# elif PY_VERSION_HEX >= 0x02070000 && PY_VERSION_HEX < 0x02080000
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython2_7")
+# define initVBoxPython MANGLE_MODULE_INIT(initVBoxPython2_7)
+
+# elif PY_VERSION_HEX >= 0x02060000 && PY_VERSION_HEX < 0x02070000
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython2_6")
+# define initVBoxPython MANGLE_MODULE_INIT(initVBoxPython2_6)
+# else
+# error "Fix module versioning. This Python version is not recognized."
+# endif
+# else
+# if PY_MAJOR_VERSION <= 2 && defined(VBOX_PYXPCOM_MAJOR_VERSIONED)
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython2")
+# define initVBoxPython MANGLE_MODULE_INIT(initVBoxPython2)
+# elif PY_MAJOR_VERSION <= 2
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython")
+# define initVBoxPython MANGLE_MODULE_INIT(initVBoxPython)
+# elif defined(Py_LIMITED_API) || defined(VBOX_PYXPCOM_MAJOR_VERSIONED)
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython3")
+# define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython3)
+# else
+# define MODULE_NAME MANGLE_MODULE_NAME("VBoxPython")
+# define initVBoxPython MANGLE_MODULE_INIT(PyInit_VBoxPython)
+# endif
+# endif
+#else
+#define MODULE_NAME "_xpcom"
+#endif
+
+// "boot-strap" methods - interfaces we need to get the base
+// interface support!
+
+#ifndef VBOX
+/* deprecated, included for backward compatibility */
+static PyObject *
+PyXPCOMMethod_NS_GetGlobalComponentManager(PyObject *self, PyObject *args)
+{
+ if (PyErr_Warn(PyExc_DeprecationWarning, "Use GetComponentManager instead") < 0)
+ return NULL;
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ nsCOMPtr<nsIComponentManager> cm;
+ nsresult rv;
+ Py_BEGIN_ALLOW_THREADS;
+ rv = NS_GetComponentManager(getter_AddRefs(cm));
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(rv) )
+ return PyXPCOM_BuildPyException(rv);
+
+ nsCOMPtr<nsIComponentManagerObsolete> ocm(do_QueryInterface(cm, &rv));
+ if ( NS_FAILED(rv) )
+ return PyXPCOM_BuildPyException(rv);
+
+ return Py_nsISupports::PyObjectFromInterface(ocm, NS_GET_IID(nsIComponentManagerObsolete), PR_FALSE);
+}
+#endif
+
+static PyObject *
+PyXPCOMMethod_GetComponentManager(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ nsCOMPtr<nsIComponentManager> cm;
+ nsresult rv;
+ Py_BEGIN_ALLOW_THREADS;
+ rv = NS_GetComponentManager(getter_AddRefs(cm));
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(rv) )
+ return PyXPCOM_BuildPyException(rv);
+
+ return Py_nsISupports::PyObjectFromInterface(cm, NS_GET_IID(nsIComponentManager), PR_FALSE);
+}
+
+// No xpcom callable way to get at the registrar, even though the interface
+// is scriptable.
+static PyObject *
+PyXPCOMMethod_GetComponentRegistrar(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ nsCOMPtr<nsIComponentRegistrar> cm;
+ nsresult rv;
+ Py_BEGIN_ALLOW_THREADS;
+ rv = NS_GetComponentRegistrar(getter_AddRefs(cm));
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(rv) )
+ return PyXPCOM_BuildPyException(rv);
+
+ return Py_nsISupports::PyObjectFromInterface(cm, NS_GET_IID(nsISupports), PR_FALSE);
+}
+
+static PyObject *
+PyXPCOMMethod_GetServiceManager(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ nsCOMPtr<nsIServiceManager> sm;
+ nsresult rv;
+ Py_BEGIN_ALLOW_THREADS;
+ rv = NS_GetServiceManager(getter_AddRefs(sm));
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(rv) )
+ return PyXPCOM_BuildPyException(rv);
+
+ // Return a type based on the IID.
+ return Py_nsISupports::PyObjectFromInterface(sm, NS_GET_IID(nsIServiceManager));
+}
+
+#ifndef VBOX
+/* deprecated, included for backward compatibility */
+static PyObject *
+PyXPCOMMethod_GetGlobalServiceManager(PyObject *self, PyObject *args)
+{
+ if (PyErr_Warn(PyExc_DeprecationWarning, "Use GetServiceManager instead") < 0)
+ return NULL;
+
+ return PyXPCOMMethod_GetComponentManager(self, args);
+}
+#endif
+
+static PyObject *
+PyXPCOMMethod_XPTI_GetInterfaceInfoManager(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ""))
+ return NULL;
+ nsIInterfaceInfoManager* im;
+ Py_BEGIN_ALLOW_THREADS;
+ im = XPTI_GetInterfaceInfoManager();
+ Py_END_ALLOW_THREADS;
+ if ( im == nsnull )
+ return PyXPCOM_BuildPyException(NS_ERROR_FAILURE);
+
+ /* Return a type based on the IID (with no extra ref) */
+ // Can not auto-wrap the interface info manager as it is critical to
+ // building the support we need for autowrap.
+ PyObject *ret = Py_nsISupports::PyObjectFromInterface(im, NS_GET_IID(nsIInterfaceInfoManager), PR_FALSE);
+ NS_IF_RELEASE(im);
+ return ret;
+}
+
+static PyObject *
+PyXPCOMMethod_XPTC_InvokeByIndex(PyObject *self, PyObject *args)
+{
+ PyObject *obIS, *obParams;
+ nsCOMPtr<nsISupports> pis;
+ int index;
+
+ // We no longer rely on PyErr_Occurred() for our error state,
+ // but keeping this assertion can't hurt - it should still always be true!
+ NS_WARN_IF_FALSE(!PyErr_Occurred(), "Should be no pending Python error!");
+
+ if (!PyArg_ParseTuple(args, "OiO", &obIS, &index, &obParams))
+ return NULL;
+
+ if (!Py_nsISupports::Check(obIS)) {
+ return PyErr_Format(PyExc_TypeError,
+ "First param must be a native nsISupports wrapper (got %s)",
+ PyXPCOM_ObTypeName(obIS));
+ }
+ // Ack! We must ask for the "native" interface supported by
+ // the object, not specifically nsISupports, else we may not
+ // back the same pointer (eg, Python, following identity rules,
+ // will return the "original" gateway when QI'd for nsISupports)
+ if (!Py_nsISupports::InterfaceFromPyObject(
+ obIS,
+ Py_nsIID_NULL,
+ getter_AddRefs(pis),
+ PR_FALSE))
+ return NULL;
+
+ PyXPCOM_InterfaceVariantHelper arg_helper((Py_nsISupports *)obIS, index);
+ if (!arg_helper.Init(obParams))
+ return NULL;
+
+ if (!arg_helper.FillArray())
+ return NULL;
+
+ nsresult r;
+ Py_BEGIN_ALLOW_THREADS;
+ r = XPTC_InvokeByIndex(pis, index, arg_helper.m_num_array, arg_helper.m_var_array);
+/** @todo bird: Maybe we could processing pending XPCOM events here to make
+ * life a bit simpler inside python? */
+ Py_END_ALLOW_THREADS;
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ return arg_helper.MakePythonResult();
+}
+
+static PyObject *
+PyXPCOMMethod_WrapObject(PyObject *self, PyObject *args)
+{
+ PyObject *ob, *obIID;
+ int bWrapClient = 1;
+ if (!PyArg_ParseTuple(args, "OO|i", &ob, &obIID, &bWrapClient))
+ return NULL;
+
+ nsIID iid;
+ if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
+ return NULL;
+
+ nsCOMPtr<nsISupports> ret;
+ nsresult r = PyXPCOM_XPTStub::CreateNew(ob, iid, getter_AddRefs(ret));
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+
+ // _ALL_ wrapped objects are associated with a weak-ref
+ // to their "main" instance.
+ AddDefaultGateway(ob, ret); // inject a weak reference to myself into the instance.
+
+ // Now wrap it in an interface.
+ return Py_nsISupports::PyObjectFromInterface(ret, iid, bWrapClient);
+}
+
+static PyObject *
+PyXPCOMMethod_UnwrapObject(PyObject *self, PyObject *args)
+{
+ PyObject *ob;
+ if (!PyArg_ParseTuple(args, "O", &ob))
+ return NULL;
+
+ nsISupports *uob = NULL;
+ nsIInternalPython *iob = NULL;
+ PyObject *ret = NULL;
+ if (!Py_nsISupports::InterfaceFromPyObject(ob,
+ NS_GET_IID(nsISupports),
+ &uob,
+ PR_FALSE))
+ goto done;
+ if (NS_FAILED(uob->QueryInterface(NS_GET_IID(nsIInternalPython), reinterpret_cast<void **>(&iob)))) {
+ PyErr_SetString(PyExc_ValueError, "This XPCOM object is not implemented by Python");
+ goto done;
+ }
+ ret = iob->UnwrapPythonObject();
+done:
+ Py_BEGIN_ALLOW_THREADS;
+ NS_IF_RELEASE(uob);
+ NS_IF_RELEASE(iob);
+ Py_END_ALLOW_THREADS;
+ return ret;
+}
+
+// @pymethod int|pythoncom|_GetInterfaceCount|Retrieves the number of interface objects currently in existance
+static PyObject *
+PyXPCOMMethod_GetInterfaceCount(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":_GetInterfaceCount"))
+ return NULL;
+ return PyInt_FromLong(_PyXPCOM_GetInterfaceCount());
+ // @comm If is occasionally a good idea to call this function before your Python program
+ // terminates. If this function returns non-zero, then you still have PythonCOM objects
+ // alive in your program (possibly in global variables).
+}
+
+#ifdef VBOX_DEBUG_LIFETIMES
+// @pymethod int|pythoncom|_DumpInterfaces|Dumps the interfaces still in existance to standard output
+static PyObject *
+PyXPCOMMethod_DumpInterfaces(PyObject *self, PyObject *args)
+{
+ if (!PyArg_ParseTuple(args, ":_DumpInterfaces"))
+ return NULL;
+ return PyInt_FromLong(_PyXPCOM_DumpInterfaces());
+}
+#endif
+
+// @pymethod int|pythoncom|_GetGatewayCount|Retrieves the number of gateway objects currently in existance
+static PyObject *
+PyXPCOMMethod_GetGatewayCount(PyObject *self, PyObject *args)
+{
+ // @comm This is the number of Python object that implement COM servers which
+ // are still alive (ie, serving a client). The only way to reduce this count
+ // is to have the process which uses these PythonCOM servers release its references.
+ if (!PyArg_ParseTuple(args, ":_GetGatewayCount"))
+ return NULL;
+ return PyInt_FromLong(_PyXPCOM_GetGatewayCount());
+}
+
+static PyObject *
+PyXPCOMMethod_NS_ShutdownXPCOM(PyObject *self, PyObject *args)
+{
+ // @comm This is the number of Python object that implement COM servers which
+ // are still alive (ie, serving a client). The only way to reduce this count
+ // is to have the process which uses these PythonCOM servers release its references.
+ if (!PyArg_ParseTuple(args, ":NS_ShutdownXPCOM"))
+ return NULL;
+ nsresult nr;
+ Py_BEGIN_ALLOW_THREADS;
+ nr = NS_ShutdownXPCOM(nsnull);
+ Py_END_ALLOW_THREADS;
+
+#ifdef VBOX_DEBUG_LIFETIME
+ Py_nsISupports::dumpList();
+#endif
+
+ // Dont raise an exception - as we are probably shutting down
+ // and dont really case - just return the status
+ return PyInt_FromLong(nr);
+}
+
+static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
+
+// A hack to work around their magic constants!
+static PyObject *
+PyXPCOMMethod_GetProxyForObject(PyObject *self, PyObject *args)
+{
+ PyObject *obQueue, *obIID, *obOb;
+ int flags;
+ if (!PyArg_ParseTuple(args, "OOOi", &obQueue, &obIID, &obOb, &flags))
+ return NULL;
+ nsIID iid;
+ if (!Py_nsIID::IIDFromPyObject(obIID, &iid))
+ return NULL;
+ nsCOMPtr<nsISupports> pob;
+ if (!Py_nsISupports::InterfaceFromPyObject(obOb, iid, getter_AddRefs(pob), PR_FALSE))
+ return NULL;
+ nsIEventQueue *pQueue = NULL;
+ nsIEventQueue *pQueueRelease = NULL;
+
+ if (PyInt_Check(obQueue)) {
+ pQueue = (nsIEventQueue *)PyInt_AsLong(obQueue);
+ } else {
+ if (!Py_nsISupports::InterfaceFromPyObject(obQueue, NS_GET_IID(nsIEventQueue), (nsISupports **)&pQueue, PR_TRUE))
+ return NULL;
+ pQueueRelease = pQueue;
+ }
+
+ nsresult rv_proxy;
+ nsCOMPtr<nsISupports> presult;
+ Py_BEGIN_ALLOW_THREADS;
+ nsCOMPtr<nsIProxyObjectManager> proxyMgr =
+ do_GetService(kProxyObjectManagerCID, &rv_proxy);
+
+ if ( NS_SUCCEEDED(rv_proxy) ) {
+ rv_proxy = proxyMgr->GetProxyForObject(pQueue,
+ iid,
+ pob,
+ flags,
+ getter_AddRefs(presult));
+ }
+ if (pQueueRelease)
+ pQueueRelease->Release();
+ Py_END_ALLOW_THREADS;
+
+ PyObject *result;
+ if (NS_SUCCEEDED(rv_proxy) ) {
+ result = Py_nsISupports::PyObjectFromInterface(presult, iid);
+ } else {
+ result = PyXPCOM_BuildPyException(rv_proxy);
+ }
+ return result;
+}
+
+static PyObject *
+PyXPCOMMethod_MakeVariant(PyObject *self, PyObject *args)
+{
+ PyObject *ob;
+ if (!PyArg_ParseTuple(args, "O:MakeVariant", &ob))
+ return NULL;
+ nsCOMPtr<nsIVariant> pVar;
+ nsresult nr = PyObject_AsVariant(ob, getter_AddRefs(pVar));
+ if (NS_FAILED(nr))
+ return PyXPCOM_BuildPyException(nr);
+ if (pVar == nsnull) {
+ NS_ERROR("PyObject_AsVariant worked but returned a NULL ptr!");
+ return PyXPCOM_BuildPyException(NS_ERROR_UNEXPECTED);
+ }
+ return Py_nsISupports::PyObjectFromInterface(pVar, NS_GET_IID(nsIVariant));
+}
+
+static PyObject *
+PyXPCOMMethod_GetVariantValue(PyObject *self, PyObject *args)
+{
+ PyObject *ob, *obParent = NULL;
+ if (!PyArg_ParseTuple(args, "O|O:GetVariantValue", &ob, &obParent))
+ return NULL;
+
+ nsCOMPtr<nsIVariant> var;
+ if (!Py_nsISupports::InterfaceFromPyObject(ob,
+ NS_GET_IID(nsISupports),
+ getter_AddRefs(var),
+ PR_FALSE))
+ return PyErr_Format(PyExc_ValueError,
+ "Object is not an nsIVariant (got %s)",
+ PyXPCOM_ObTypeName(ob));
+
+ Py_nsISupports *parent = nsnull;
+ if (obParent && obParent != Py_None) {
+ if (!Py_nsISupports::Check(obParent)) {
+ PyErr_SetString(PyExc_ValueError,
+ "Object not an nsISupports wrapper");
+ return NULL;
+ }
+ parent = (Py_nsISupports *)obParent;
+ }
+ return PyObject_FromVariant(parent, var);
+}
+
+PyObject *PyGetSpecialDirectory(PyObject *self, PyObject *args)
+{
+ char *dirname;
+ if (!PyArg_ParseTuple(args, "s:GetSpecialDirectory", &dirname))
+ return NULL;
+ nsCOMPtr<nsIFile> file;
+ nsresult r = NS_GetSpecialDirectory(dirname, getter_AddRefs(file));
+ if ( NS_FAILED(r) )
+ return PyXPCOM_BuildPyException(r);
+ // returned object swallows our reference.
+ return Py_nsISupports::PyObjectFromInterface(file, NS_GET_IID(nsIFile));
+}
+
+PyObject *AllocateBuffer(PyObject *self, PyObject *args)
+{
+ int bufSize;
+ if (!PyArg_ParseTuple(args, "i", &bufSize))
+ return NULL;
+#if PY_MAJOR_VERSION <= 2
+ return PyBuffer_New(bufSize);
+#else
+ return PyBytes_FromStringAndSize(NULL, bufSize);
+#endif
+}
+
+// Writes a message to the console service. This could be done via pure
+// Python code, but is useful when the logging code is actually the
+// xpcom .py framework itself (ie, we don't want our logging framework to
+// call back into the very code generating the log messages!
+PyObject *LogConsoleMessage(PyObject *self, PyObject *args)
+{
+ char *msg;
+ if (!PyArg_ParseTuple(args, "s", &msg))
+ return NULL;
+
+ nsCOMPtr<nsIConsoleService> consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+ if (consoleService)
+ consoleService->LogStringMessage(NS_ConvertASCIItoUCS2(msg).get());
+ else {
+ // This either means no such service, or in shutdown - hardly worth
+ // the warning, and not worth reporting an error to Python about - its
+ // log handler would just need to catch and ignore it.
+ // And as this is only called by this logging setup, any messages should
+ // still go to stderr or a logfile.
+ NS_WARNING("pyxpcom can't log console message.");
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#ifdef VBOX
+
+# include <VBox/com/NativeEventQueue.h>
+# include <iprt/err.h>
+
+static PyObject *
+PyXPCOMMethod_WaitForEvents(PyObject *self, PyObject *args)
+{
+ long lTimeout;
+ if (!PyArg_ParseTuple(args, "l", &lTimeout))
+ return NULL;
+
+ int rc;
+ com::NativeEventQueue* aEventQ = com::NativeEventQueue::getMainEventQueue();
+ NS_WARN_IF_FALSE(aEventQ != nsnull, "Null main event queue");
+ if (!aEventQ)
+ {
+ PyErr_SetString(PyExc_TypeError, "the main event queue is NULL");
+ return NULL;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+
+ RTMSINTERVAL cMsTimeout = (RTMSINTERVAL)lTimeout;
+ if (lTimeout < 0 || (long)cMsTimeout != lTimeout)
+ cMsTimeout = RT_INDEFINITE_WAIT;
+ rc = aEventQ->processEventQueue(cMsTimeout);
+
+ Py_END_ALLOW_THREADS
+ if (RT_SUCCESS(rc))
+ return PyInt_FromLong(0);
+
+ if ( rc == VERR_TIMEOUT
+ || rc == VERR_INTERRUPTED)
+ return PyInt_FromLong(1);
+
+ if (rc == VERR_INVALID_CONTEXT)
+ {
+ PyErr_SetString(PyExc_Exception, "wrong thread, use the main thread");
+ return NULL;
+ }
+
+ return PyInt_FromLong(2);
+}
+
+static PyObject*
+PyXPCOMMethod_InterruptWait(PyObject *self, PyObject *args)
+{
+ com::NativeEventQueue* aEventQ = com::NativeEventQueue::getMainEventQueue();
+ NS_WARN_IF_FALSE(aEventQ != nsnull, "Null main event queue");
+ if (!aEventQ)
+ return NULL;
+
+ int rc = aEventQ->interruptEventQueueProcessing();
+ return PyBool_FromLong(RT_SUCCESS(rc));
+}
+
+static nsresult deinitVBoxPython();
+
+static PyObject*
+PyXPCOMMethod_DeinitCOM(PyObject *self, PyObject *args)
+{
+ nsresult nr;
+ Py_BEGIN_ALLOW_THREADS;
+ nr = deinitVBoxPython();
+ Py_END_ALLOW_THREADS;
+ return PyInt_FromLong(nr);
+}
+
+static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
+
+static PyObject*
+PyXPCOMMethod_AttachThread(PyObject *self, PyObject *args)
+{
+ nsresult rv;
+ PRInt32 result = 0;
+ nsCOMPtr<nsIEventQueueService> eqs;
+
+ // Create the Event Queue for this thread...
+ Py_BEGIN_ALLOW_THREADS;
+ eqs =
+ do_GetService(kEventQueueServiceCID, &rv);
+ Py_END_ALLOW_THREADS;
+ if (NS_FAILED(rv))
+ {
+ result = 1;
+ goto done;
+ }
+
+ Py_BEGIN_ALLOW_THREADS;
+ rv = eqs->CreateThreadEventQueue();
+ Py_END_ALLOW_THREADS;
+ if (NS_FAILED(rv))
+ {
+ result = 2;
+ goto done;
+ }
+
+ done:
+ /** @todo: better throw an exception on error */
+ return PyInt_FromLong(result);
+}
+
+static PyObject*
+PyXPCOMMethod_DetachThread(PyObject *self, PyObject *args)
+{
+ nsresult rv;
+ PRInt32 result = 0;
+ nsCOMPtr<nsIEventQueueService> eqs;
+
+ // Destroy the Event Queue for this thread...
+ Py_BEGIN_ALLOW_THREADS;
+ eqs =
+ do_GetService(kEventQueueServiceCID, &rv);
+ Py_END_ALLOW_THREADS;
+ if (NS_FAILED(rv))
+ {
+ result = 1;
+ goto done;
+ }
+
+ Py_BEGIN_ALLOW_THREADS;
+ rv = eqs->DestroyThreadEventQueue();
+ Py_END_ALLOW_THREADS;
+ if (NS_FAILED(rv))
+ {
+ result = 2;
+ goto done;
+ }
+
+ done:
+ /** @todo: better throw an exception on error */
+ return PyInt_FromLong(result);
+}
+
+#endif /* VBOX */
+
+extern PYXPCOM_EXPORT PyObject *PyXPCOMMethod_IID(PyObject *self, PyObject *args);
+
+static struct PyMethodDef xpcom_methods[]=
+{
+ {"GetComponentManager", PyXPCOMMethod_GetComponentManager, 1},
+ {"GetComponentRegistrar", PyXPCOMMethod_GetComponentRegistrar, 1},
+#ifndef VBOX
+ {"NS_GetGlobalComponentManager", PyXPCOMMethod_NS_GetGlobalComponentManager, 1}, // deprecated
+#endif
+ {"XPTI_GetInterfaceInfoManager", PyXPCOMMethod_XPTI_GetInterfaceInfoManager, 1},
+ {"XPTC_InvokeByIndex", PyXPCOMMethod_XPTC_InvokeByIndex, 1},
+ {"GetServiceManager", PyXPCOMMethod_GetServiceManager, 1},
+#ifndef VBOX
+ {"GetGlobalServiceManager", PyXPCOMMethod_GetGlobalServiceManager, 1}, // deprecated
+ {"IID", PyXPCOMMethod_IID, 1}, // IID is wrong - deprecated - not just IID, but CID, etc.
+#endif
+ {"ID", PyXPCOMMethod_IID, 1}, // This is the official name.
+ {"NS_ShutdownXPCOM", PyXPCOMMethod_NS_ShutdownXPCOM, 1},
+ {"WrapObject", PyXPCOMMethod_WrapObject, 1},
+ {"UnwrapObject", PyXPCOMMethod_UnwrapObject, 1},
+ {"_GetInterfaceCount", PyXPCOMMethod_GetInterfaceCount, 1},
+ {"_GetGatewayCount", PyXPCOMMethod_GetGatewayCount, 1},
+ {"getProxyForObject", PyXPCOMMethod_GetProxyForObject, 1},
+ {"GetProxyForObject", PyXPCOMMethod_GetProxyForObject, 1},
+ {"GetSpecialDirectory", PyGetSpecialDirectory, 1},
+ {"AllocateBuffer", AllocateBuffer, 1},
+ {"LogConsoleMessage", LogConsoleMessage, 1, "Write a message to the xpcom console service"},
+ {"MakeVariant", PyXPCOMMethod_MakeVariant, 1},
+ {"GetVariantValue", PyXPCOMMethod_GetVariantValue, 1},
+#ifdef VBOX
+ {"WaitForEvents", PyXPCOMMethod_WaitForEvents, 1},
+ {"InterruptWait", PyXPCOMMethod_InterruptWait, 1},
+ {"DeinitCOM", PyXPCOMMethod_DeinitCOM, 1},
+ {"AttachThread", PyXPCOMMethod_AttachThread, 1},
+ {"DetachThread", PyXPCOMMethod_DetachThread, 1},
+#endif
+#ifdef VBOX_DEBUG_LIFETIMES
+ {"_DumpInterfaces", PyXPCOMMethod_DumpInterfaces, 1},
+#endif
+ // These should no longer be used - just use the logging.getLogger('pyxpcom')...
+ /* bird: The above comment refers to LogWarning and LogError. Both now removed. */
+ { NULL }
+};
+
+#if PY_MAJOR_VERSION >= 3
+static struct PyModuleDef xpcom_module =
+{
+ PyModuleDef_HEAD_INIT,
+ MODULE_NAME, /* name of module */
+ NULL, /* module documentation */
+ -1, /* size of per-interpreter state or -1 if using globals */
+ xpcom_methods
+};
+#endif
+
+
+#define REGISTER_IID(t) { \
+ PyObject *iid_ob = Py_nsIID::PyObjectFromIID(NS_GET_IID(t)); \
+ PyDict_SetItemString(dict, "IID_"#t, iid_ob); \
+ Py_DECREF(iid_ob); \
+ }
+
+#define REGISTER_INT(val) { \
+ PyObject *ob = PyInt_FromLong(val); \
+ PyDict_SetItemString(dict, #val, ob); \
+ Py_DECREF(ob); \
+ }
+
+
+////////////////////////////////////////////////////////////
+// The module init code.
+//
+#if PY_MAJOR_VERSION <= 2
+extern "C" NS_EXPORT
+void
+#else
+PyObject *
+#endif
+init_xpcom() {
+ PyObject *oModule;
+
+ // ensure the framework has valid state to work with.
+ if (!PyXPCOM_Globals_Ensure())
+#if PY_MAJOR_VERSION <= 2
+ return;
+#else
+ return NULL;
+#endif
+
+ // Must force Python to start using thread locks
+ PyEval_InitThreads();
+
+ // Create the module and add the functions
+#if PY_MAJOR_VERSION <= 2
+ oModule = Py_InitModule(MODULE_NAME, xpcom_methods);
+#else
+ oModule = PyModule_Create(&xpcom_module);
+#endif
+
+ PyObject *dict = PyModule_GetDict(oModule);
+ PyObject *pycom_Error = PyXPCOM_Error;
+ if (pycom_Error == NULL || PyDict_SetItemString(dict, "error", pycom_Error) != 0)
+ {
+ PyErr_SetString(PyExc_MemoryError, "can't define error");
+#if PY_MAJOR_VERSION <= 2
+ return;
+#else
+ return NULL;
+#endif
+ }
+#ifndef Py_LIMITED_API
+ PyDict_SetItemString(dict, "IIDType", (PyObject *)&Py_nsIID::type);
+#else
+ PyDict_SetItemString(dict, "IIDType", (PyObject *)Py_nsIID::GetTypeObject());
+#endif
+
+ REGISTER_IID(nsISupports);
+ REGISTER_IID(nsISupportsCString);
+ REGISTER_IID(nsISupportsString);
+ REGISTER_IID(nsIModule);
+ REGISTER_IID(nsIFactory);
+ REGISTER_IID(nsIWeakReference);
+ REGISTER_IID(nsISupportsWeakReference);
+ REGISTER_IID(nsIClassInfo);
+ REGISTER_IID(nsIServiceManager);
+ REGISTER_IID(nsIComponentRegistrar);
+
+ // Register our custom interfaces.
+ REGISTER_IID(nsIComponentManager);
+ REGISTER_IID(nsIInterfaceInfoManager);
+ REGISTER_IID(nsIEnumerator);
+ REGISTER_IID(nsISimpleEnumerator);
+ REGISTER_IID(nsIInterfaceInfo);
+ REGISTER_IID(nsIInputStream);
+ REGISTER_IID(nsIClassInfo);
+ REGISTER_IID(nsIVariant);
+ // for backward compatibility:
+ REGISTER_IID(nsIComponentManagerObsolete);
+
+ // No good reason not to expose this impl detail, and tests can use it
+ REGISTER_IID(nsIInternalPython);
+ // We have special support for proxies - may as well add their constants!
+ REGISTER_INT(PROXY_SYNC);
+ REGISTER_INT(PROXY_ASYNC);
+ REGISTER_INT(PROXY_ALWAYS);
+ // Build flags that may be useful.
+ PyObject *ob = PyBool_FromLong(
+#ifdef NS_DEBUG
+ 1
+#else
+ 0
+#endif
+ );
+ PyDict_SetItemString(dict, "NS_DEBUG", ob);
+ Py_DECREF(ob);
+#if PY_MAJOR_VERSION >= 3
+ return oModule;
+#endif
+}
+
+#ifdef VBOX_PYXPCOM
+# include <VBox/com/com.h>
+using namespace com;
+
+# include <iprt/initterm.h>
+# include <iprt/string.h>
+# include <iprt/alloca.h>
+# include <iprt/stream.h>
+
+/** Set if NS_ShutdownXPCOM has been called successfully already and we don't
+ * need to do it again during module termination. This avoids assertion in the
+ * VBoxCOM glue code. */
+static bool g_fComShutdownAlready = true;
+
+# if PY_MAJOR_VERSION <= 2
+extern "C" NS_EXPORT
+void
+# else
+/** @todo r=klaus this is hacky, but as Python3 doesn't deal with ELF
+ * visibility, assuming that all globals are visible (which is ugly and not
+ * true in our case). */
+# undef PyMODINIT_FUNC
+# define PyMODINIT_FUNC extern "C" NS_EXPORT PyObject*
+PyMODINIT_FUNC
+# endif
+initVBoxPython() { /* NOTE! This name is redefined at the top of the file! */
+ static bool s_vboxInited = false;
+ if (!s_vboxInited) {
+ int rc = 0; /* Error handling in this code is NON-EXISTING. Sigh. */
+
+# if defined(VBOX_PATH_APP_PRIVATE_ARCH) && defined(VBOX_PATH_SHARED_LIBS)
+ rc = RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
+# else
+ const char *home = getenv("VBOX_PROGRAM_PATH");
+ if (home) {
+ size_t len = strlen(home);
+ char *exepath = (char *)alloca(len + 32);
+ memcpy(exepath, home, len);
+ memcpy(exepath + len, "/pythonfake", sizeof("/pythonfake"));
+ rc = RTR3InitEx(RTR3INIT_VER_CUR, RTR3INIT_FLAGS_DLL | RTR3INIT_FLAGS_UNOBTRUSIVE, 0, NULL, exepath);
+ } else {
+ rc = RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
+ }
+# endif
+
+ rc = com::Initialize();
+ g_fComShutdownAlready = false;
+
+# if PY_MAJOR_VERSION <= 2
+ init_xpcom();
+# else
+ return init_xpcom();
+# endif
+ }
+# if PY_MAJOR_VERSION >= 3
+ return NULL;
+# endif
+}
+
+static
+nsresult deinitVBoxPython()
+{
+ nsresult nr;
+ if (!g_fComShutdownAlready)
+ {
+ nr = com::Shutdown();
+ if (!NS_FAILED(nr))
+ g_fComShutdownAlready = true;
+ }
+ else
+ nr = NS_ERROR_NOT_INITIALIZED;
+ return nr;
+}
+
+#endif /* VBOX_PYXPCOM */
diff --git a/src/libs/xpcom18a4/python/src/readme.html b/src/libs/xpcom18a4/python/src/readme.html
new file mode 100644
index 00000000..b049dbad
--- /dev/null
+++ b/src/libs/xpcom18a4/python/src/readme.html
@@ -0,0 +1,99 @@
+<!-- ***** 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 PyXPCOM.
+ -
+ - The Initial Developer of the Original Code is
+ - ActiveState Tool Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2000-2001
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - 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 LGPL or the GPL. 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 ***** -->
+
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Building the Python XPCOM package</title>
+</head>
+
+<body>
+
+<h1>Building the Python XPCOM package.</h1>
+
+<p>This file describes how to build the Python XPCOM C++ sources.</p>
+<p>There are the following steps</p>
+<ul>
+ <li><a href="#ConfiguringTheEnvironment">Configure environment variables</a></li>
+ <li><a href="#BuildingTheSources">Building the sources</a></li>
+</ul>
+<p>Testing etc is described in the <a href="../readme.html">main readme</a>.</p>
+<h2><a name="ConfiguringTheEnvironment">Configuring environment variables</a></h2>
+<h3> MOZ_SRC&nbsp;</h3>
+<p><b>Windows: </b>Run the standard MOZENV.BAT used to build Mozilla.&nbsp; This
+sets MOZ_SRC</p>
+<p><b>Unix:</b> Set MOZ_SRC to point to the base source directory - assumes
+&quot;mozilla&quot; sub-directory with mozilla directory tree under that. eg: assuming
+<i>/home/user/src/mozilla/dist/...</i>&quot;</p>
+<pre>export MOZ_SRC=/home/user/src</pre>
+<h3>PYTHON_SRC</h3>
+<p><b>Windows:</b> Set <i> PYTHON_SRC</i> to point to the base Python source directory.&nbsp;
+eg: assuming <i>c:\src\python\PCBuild\...</i><pre>set PYTHON_SRC=c:\src\python</pre>
+<p>Unix: Set PYTHON_SRC to point to the base of an &quot;installed&quot; Python
+tree. eg:<pre>export PYTHON_SRC=/usr/local/ActivePython-1.6</pre>
+<h2><a name="BuildingTheSources">Building the sources</a></h2>
+<p>You must ensure some environment variables are setup.&nbsp; The section on <a href="#ConfiguringTheEnvironment">configuring
+environment variables explains how.</a></p>
+<p>There are 2 build processes to run All C++ sources are in the <i>xpcom\src</i>
+ directory.:</p>
+<h3>Windows</h3>
+<ul>
+ <li> Execute &quot;compile.py&quot; in this directory. This will take <i>Setup.in</i>, create an MSDev project, and build
+ <i>..\_xpcom.pyd</i> and <i>..\_xpcom_d.pyd</i>&quot;</li>
+ <li> Change to the <i>loader</i> directory.</li>
+ <li> Run <i>nmake -f makefile.win</i>. This will create <i>pyloader.dll</i>, and
+ automatically copy it to the Mozilla build directory.</li>
+ <a href="#ConfiguringTheEnvironment">
+ </ul>
+ <p>Finally, </a><a href="../readme.html#RunningTheTests">run the tests</a>,
+ where we also test everything imports correctly.</p>
+<h3>Linux</h3>
+<p><b> NOTE:</b> Do not attempt to use &quot;Setup.in&quot; to create a Makefile&nbsp;</p>
+<ul>
+ <li>Run &quot;make&quot; in this directory.&nbsp; This will create <i>../_xpcommodule.so</i></li>
+ <li> Run "make" in the loader directory. This will create <i>libpyloader.so</i>,
+ and copy it to the Mozilla directory.</li>
+ <a href="#ConfiguringTheEnvironment">
+ </ul>
+ <p>Finally, </a><a href="../readme.html#RunningTheTests">running the tests</a>,
+ where we also test everything imports correctly.</p>
+
+</body>
+
+</html>
diff --git a/src/libs/xpcom18a4/python/test/.cvsignore b/src/libs/xpcom18a4/python/test/.cvsignore
new file mode 100644
index 00000000..52e4e611
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/.cvsignore
@@ -0,0 +1,2 @@
+*.pyc
+*.pyo
diff --git a/src/libs/xpcom18a4/python/test/output/test_com_exceptions b/src/libs/xpcom18a4/python/test/output/test_com_exceptions
new file mode 100644
index 00000000..16e4bda1
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/output/test_com_exceptions
@@ -0,0 +1,8 @@
+test_com_exceptions
+** Unhandled exception calling 'int8 do_short(in int16, inout int16, out int16, out retval int16);'
+** Returning nsresult of NS_ERROR_FAILURE
+** Unhandled exception calling 'int8 do_unsigned_short(in uint16, inout uint16, out uint16, out retval uint16);'
+** Returning nsresult of NS_ERROR_FAILURE
+** Unhandled exception calling 'int8 do_unsigned_long_long(in uint64, inout uint64, out uint64, out retval uint64);'
+** Returning nsresult of NS_ERROR_FAILURE
+The xpcom exception tests passed
diff --git a/src/libs/xpcom18a4/python/test/output/test_comfile b/src/libs/xpcom18a4/python/test/output/test_comfile
new file mode 100644
index 00000000..8de43add
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/output/test_comfile
@@ -0,0 +1,7 @@
+test_comfile
+Open as string test worked.
+Open as URL test worked.
+File test using buffers worked.
+Local file read test worked.
+Read the correct data.
+Chunks read the correct data.
diff --git a/src/libs/xpcom18a4/python/test/output/test_components b/src/libs/xpcom18a4/python/test/output/test_components
new file mode 100644
index 00000000..4a6386e7
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/output/test_components
@@ -0,0 +1,4 @@
+test_components
+The interfaces object appeared to work!
+The classes object appeared to work!
+The ID function appeared to work!
diff --git a/src/libs/xpcom18a4/python/test/output/test_isupports_primitives b/src/libs/xpcom18a4/python/test/output/test_isupports_primitives
new file mode 100644
index 00000000..7765ac21
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/output/test_isupports_primitives
@@ -0,0 +1,2 @@
+test_isupports_primitives
+The nsISupports primitive interface tests appeared to work
diff --git a/src/libs/xpcom18a4/python/test/output/test_streams b/src/libs/xpcom18a4/python/test/output/test_streams
new file mode 100644
index 00000000..e81ef151
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/output/test_streams
@@ -0,0 +1 @@
+test_streams
diff --git a/src/libs/xpcom18a4/python/test/output/test_test_component b/src/libs/xpcom18a4/python/test/output/test_test_component
new file mode 100644
index 00000000..c57c1325
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/output/test_test_component
@@ -0,0 +1,4 @@
+test_test_component
+Testing the Python.TestComponent component
+The Python test component worked!
+Javascript could successfully use the Python test component.
diff --git a/src/libs/xpcom18a4/python/test/output/test_weakreferences b/src/libs/xpcom18a4/python/test/output/test_weakreferences
new file mode 100644
index 00000000..b337d26a
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/output/test_weakreferences
@@ -0,0 +1,2 @@
+test_weakreferences
+Weak-reference tests appear to have worked!
diff --git a/src/libs/xpcom18a4/python/test/pyxpcom_test_tools.py b/src/libs/xpcom18a4/python/test/pyxpcom_test_tools.py
new file mode 100755
index 00000000..447c5446
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/pyxpcom_test_tools.py
@@ -0,0 +1,126 @@
+# test tools for the pyxpcom bindings
+from xpcom import _xpcom
+import unittest
+
+# export a "getmemusage()" function that returns a useful "bytes used" count
+# for the current process. Growth in this when doing the same thing over and
+# over implies a leak.
+
+try:
+ import win32api
+ import win32pdh
+ import win32pdhutil
+ have_pdh = 1
+except ImportError:
+ have_pdh = 0
+
+# XXX - win32pdh is slow, particularly finding our current process.
+# A better way would be good.
+
+# Our win32pdh specific functions - they can be at the top-level on all
+# platforms, but will only actually be called if the modules are available.
+def FindMyCounter():
+ pid_me = win32api.GetCurrentProcessId()
+
+ object = "Process"
+ items, instances = win32pdh.EnumObjectItems(None,None,object, -1)
+ for instance in instances:
+ # We use 2 counters - "ID Process" and "Working Set"
+ counter = "ID Process"
+ format = win32pdh.PDH_FMT_LONG
+
+ hq = win32pdh.OpenQuery()
+ path = win32pdh.MakeCounterPath( (None,object,instance, None, -1,"ID Process") )
+ hc1 = win32pdh.AddCounter(hq, path)
+ path = win32pdh.MakeCounterPath( (None,object,instance, None, -1,"Working Set") )
+ hc2 = win32pdh.AddCounter(hq, path)
+ win32pdh.CollectQueryData(hq)
+ type, pid = win32pdh.GetFormattedCounterValue(hc1, format)
+ if pid==pid_me:
+ win32pdh.RemoveCounter(hc1) # not needed any more
+ return hq, hc2
+ # Not mine - close the query and try again
+ win32pdh.RemoveCounter(hc1)
+ win32pdh.RemoveCounter(hc2)
+ win32pdh.CloseQuery(hq)
+ else:
+ raise RuntimeError, "Can't find myself!?"
+
+def CloseCounter(hq, hc):
+ win32pdh.RemoveCounter(hc)
+ win32pdh.CloseQuery(hq)
+
+def GetCounterValue(hq, hc):
+ win32pdh.CollectQueryData(hq)
+ format = win32pdh.PDH_FMT_LONG
+ type, val = win32pdh.GetFormattedCounterValue(hc, format)
+ return val
+
+g_pdh_data = None
+# The pdh function that does the work
+def pdh_getmemusage():
+ global g_pdh_data
+ if g_pdh_data is None:
+ hq, hc = FindMyCounter()
+ g_pdh_data = hq, hc
+ hq, hc = g_pdh_data
+ return GetCounterValue(hq, hc)
+
+# The public bit
+if have_pdh:
+ getmemusage = pdh_getmemusage
+else:
+ def getmemusage():
+ return 0
+
+# Test runner utilities, including some support for builtin leak tests.
+class TestLoader(unittest.TestLoader):
+ def loadTestsFromTestCase(self, testCaseClass):
+ """Return a suite of all tests cases contained in testCaseClass"""
+ leak_tests = []
+ for name in self.getTestCaseNames(testCaseClass):
+ real_test = testCaseClass(name)
+ leak_test = self._getTestWrapper(real_test)
+ leak_tests.append(leak_test)
+ return self.suiteClass(leak_tests)
+ def _getTestWrapper(self, test):
+ # later! see pywin32's win32/test/util.py
+ return test
+ def loadTestsFromModule(self, mod):
+ if hasattr(mod, "suite"):
+ ret = mod.suite()
+ else:
+ ret = unittest.TestLoader.loadTestsFromModule(self, mod)
+ assert ret.countTestCases() > 0, "No tests in %r" % (mod,)
+ return ret
+ def loadTestsFromName(self, name, module=None):
+ test = unittest.TestLoader.loadTestsFromName(self, name, module)
+ if isinstance(test, unittest.TestSuite):
+ pass # hmmm? print "Don't wrap suites yet!", test._tests
+ elif isinstance(test, unittest.TestCase):
+ test = self._getTestWrapper(test)
+ else:
+ print "XXX - what is", test
+ return test
+
+# A base class our tests should derive from (well, one day it will be)
+TestCase = unittest.TestCase
+
+def suite_from_functions(*funcs):
+ suite = unittest.TestSuite()
+ for func in funcs:
+ suite.addTest(unittest.FunctionTestCase(func))
+ return suite
+
+def testmain(*args, **kw):
+ new_kw = kw.copy()
+ if not new_kw.has_key('testLoader'):
+ new_kw['testLoader'] = TestLoader()
+ try:
+ unittest.main(*args, **new_kw)
+ finally:
+ _xpcom.NS_ShutdownXPCOM()
+ ni = _xpcom._GetInterfaceCount()
+ ng = _xpcom._GetGatewayCount()
+ if ni or ng:
+ print "********* WARNING - Leaving with %d/%d objects alive" % (ni,ng)
diff --git a/src/libs/xpcom18a4/python/test/regrtest.py b/src/libs/xpcom18a4/python/test/regrtest.py
new file mode 100644
index 00000000..90d07948
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/regrtest.py
@@ -0,0 +1,91 @@
+# ***** 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 Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <mhammond@skippinet.com.au> (original author)
+#
+# 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 *****
+
+# regrtest.py
+#
+# The Regression Tests for the xpcom package.
+import os
+import sys
+
+import unittest
+
+# A little magic to create a single "test suite" from all test_ files
+# in this dir. A single suite makes for prettier output test :)
+def suite():
+ # Loop over all test_*.py files here
+ try:
+ me = __file__
+ except NameError:
+ me = sys.argv[0]
+ me = os.path.abspath(me)
+ files = os.listdir(os.path.dirname(me))
+ suite = unittest.TestSuite()
+ # XXX - add the others here!
+ #suite.addTest(unittest.FunctionTestCase(import_all))
+ for file in files:
+ base, ext = os.path.splitext(file)
+ if ext=='.py' and os.path.basename(base).startswith("test_"):
+ mod = __import__(base)
+ if hasattr(mod, "suite"):
+ test = mod.suite()
+ else:
+ test = unittest.defaultTestLoader.loadTestsFromModule(mod)
+ suite.addTest(test)
+ return suite
+
+class CustomLoader(unittest.TestLoader):
+ def loadTestsFromModule(self, module):
+ return suite()
+
+try:
+ unittest.TestProgram(testLoader=CustomLoader())(argv=sys.argv)
+finally:
+ from xpcom import _xpcom
+ _xpcom.NS_ShutdownXPCOM() # To get leak stats and otherwise ensure life is good.
+ ni = _xpcom._GetInterfaceCount()
+ ng = _xpcom._GetGatewayCount()
+ if ni or ng:
+ # The old 'regrtest' that was not based purely on unittest did not
+ # do this check at the end - it relied on each module doing it itself.
+ # Thus, these leaks are not new, just newly noticed :) Likely to be
+ # something silly like module globals.
+ if ni == 6 and ng == 1:
+ print "Sadly, there are 6/1 leaks, but these appear normal and benign"
+ else:
+ print "********* WARNING - Leaving with %d/%d objects alive" % (ni,ng)
+ else:
+ print "yay! Our leaks have all vanished!"
diff --git a/src/libs/xpcom18a4/python/test/test_com_exceptions.py b/src/libs/xpcom18a4/python/test/test_com_exceptions.py
new file mode 100755
index 00000000..7813bf98
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_com_exceptions.py
@@ -0,0 +1,124 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is ActiveState Tool Corp.
+# Portions created by ActiveState Tool Corp. are Copyright (C) 2000, 2001
+# ActiveState Tool Corp. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.com> (original author)
+#
+# 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 *****
+
+# Test pyxpcom exception.
+
+from xpcom import components, nsError, ServerException, COMException, logger
+from xpcom.server import WrapObject
+from pyxpcom_test_tools import testmain
+
+import unittest
+import logging
+
+class PythonFailingComponent:
+ # Re-use the test interface for this test.
+ _com_interfaces_ = components.interfaces.nsIPythonTestInterfaceExtra
+
+ def do_boolean(self, p1, p2):
+ # This should cause the caller to see a "silent" NS_ERROR_FAILURE exception.
+ raise ServerException()
+
+ def do_octet(self, p1, p2):
+ # This should cause the caller to see a "silent" NS_ERROR_NOT_IMPLEMENTED exception.
+ raise ServerException(nsError.NS_ERROR_NOT_IMPLEMENTED)
+
+ def do_short(self, p1, p2):
+ # This should cause the caller to see a "debug" NS_ERROR_FAILURE exception.
+ raise COMException(nsError.NS_ERROR_NOT_IMPLEMENTED)
+
+ def do_unsigned_short(self, p1, p2):
+ # This should cause the caller to see a "debug" NS_ERROR_FAILURE exception.
+ raise "Foo"
+
+ def do_long(self, p1, p2):
+ # This should cause the caller to see a "silent" NS_ERROR_FAILURE exception.
+ raise ServerException
+
+ def do_unsigned_long(self, p1, p2):
+ # This should cause the caller to see a "silent" NS_ERROR_NOT_IMPLEMENTED exception.
+ raise ServerException, nsError.NS_ERROR_NOT_IMPLEMENTED
+
+ def do_long_long(self, p1, p2):
+ # This should cause the caller to see a "silent" NS_ERROR_NOT_IMPLEMENTED exception.
+ raise ServerException, (nsError.NS_ERROR_NOT_IMPLEMENTED, "testing")
+
+ def do_unsigned_long_long(self, p1, p2):
+ # Report of a crash in this case - test it!
+ raise ServerException, "A bad exception param"
+
+class TestHandler(logging.Handler):
+ def __init__(self, level=logging.ERROR): # only counting error records
+ logging.Handler.__init__(self, level)
+ self.records = []
+
+ def reset(self):
+ self.records = []
+
+ def handle(self, record):
+ self.records.append(record)
+
+class ExceptionTests(unittest.TestCase):
+
+ def _testit(self, expected_errno, num_tracebacks, func, *args):
+
+ # Screw with the logger
+ old_handlers = logger.handlers
+ test_handler = TestHandler()
+ logger.handlers = [test_handler]
+
+ try:
+ try:
+ apply(func, args)
+ except COMException, what:
+ if what.errno != expected_errno:
+ raise
+ finally:
+ logger.handlers = old_handlers
+ self.failUnlessEqual(num_tracebacks, len(test_handler.records))
+
+ def testEmAll(self):
+ ob = WrapObject( PythonFailingComponent(), components.interfaces.nsIPythonTestInterfaceExtra)
+ self._testit(nsError.NS_ERROR_FAILURE, 0, ob.do_boolean, 0, 0)
+ self._testit(nsError.NS_ERROR_NOT_IMPLEMENTED, 0, ob.do_octet, 0, 0)
+ self._testit(nsError.NS_ERROR_FAILURE, 1, ob.do_short, 0, 0)
+ self._testit(nsError.NS_ERROR_FAILURE, 1, ob.do_unsigned_short, 0, 0)
+ self._testit(nsError.NS_ERROR_FAILURE, 0, ob.do_long, 0, 0)
+ self._testit(nsError.NS_ERROR_NOT_IMPLEMENTED, 0, ob.do_unsigned_long, 0, 0)
+ self._testit(nsError.NS_ERROR_NOT_IMPLEMENTED, 0, ob.do_long_long, 0, 0)
+ self._testit(nsError.NS_ERROR_FAILURE, 1, ob.do_unsigned_long_long, 0, 0)
+
+if __name__=='__main__':
+ testmain()
diff --git a/src/libs/xpcom18a4/python/test/test_comfile.py b/src/libs/xpcom18a4/python/test/test_comfile.py
new file mode 100755
index 00000000..9ffebe37
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_comfile.py
@@ -0,0 +1,49 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond (markh@activestate.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 *****
+
+"""Test the xpcom.file module."""
+from pyxpcom_test_tools import suite_from_functions, testmain
+
+import xpcom.file
+
+# Make this test run under our std test suite
+def suite():
+ return suite_from_functions(xpcom.file._TestAll)
+
+if __name__=='__main__':
+ testmain()
+
diff --git a/src/libs/xpcom18a4/python/test/test_component/_xpidlgen/.done b/src/libs/xpcom18a4/python/test/test_component/_xpidlgen/.done
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_component/_xpidlgen/.done
diff --git a/src/libs/xpcom18a4/python/test/test_component/_xpidlgen/py_test_component.h b/src/libs/xpcom18a4/python/test/test_component/_xpidlgen/py_test_component.h
new file mode 100644
index 00000000..7d0cd8c9
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_component/_xpidlgen/py_test_component.h
@@ -0,0 +1,1411 @@
+/*
+ * DO NOT EDIT. THIS FILE IS GENERATED FROM py_test_component.idl
+ */
+
+#ifndef __gen_py_test_component_h__
+#define __gen_py_test_component_h__
+
+
+#ifndef __gen_nsISupports_h__
+#include "nsISupports.h"
+#endif
+
+#ifndef __gen_nsIVariant_h__
+#include "nsIVariant.h"
+#endif
+
+/* For IDL files that don't want to include root IDL files. */
+#ifndef NS_NO_VTABLE
+#define NS_NO_VTABLE
+#endif
+
+/* starting interface: nsIPythonTestInterface */
+#define NS_IPYTHONTESTINTERFACE_IID_STR "1ecaed4f-e4d5-4ee7-abf0-7d72ae1441d7"
+
+#define NS_IPYTHONTESTINTERFACE_IID \
+ {0x1ecaed4f, 0xe4d5, 0x4ee7, \
+ { 0xab, 0xf0, 0x7d, 0x72, 0xae, 0x14, 0x41, 0xd7 }}
+
+class NS_NO_VTABLE nsIPythonTestInterface : public nsISupports {
+ public:
+
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IPYTHONTESTINTERFACE_IID)
+
+ enum { One = 1 };
+
+ enum { Two = 2 };
+
+ enum { MinusOne = -1 };
+
+ enum { BigLong = 2147483647 };
+
+ enum { BiggerLong = 4294967295 };
+
+ enum { BigULong = 4294967295U };
+
+ /* attribute boolean boolean_value; */
+ NS_IMETHOD GetBoolean_value(PRBool *aBoolean_value) = 0;
+ NS_IMETHOD SetBoolean_value(PRBool aBoolean_value) = 0;
+
+ /* attribute octet octet_value; */
+ NS_IMETHOD GetOctet_value(PRUint8 *aOctet_value) = 0;
+ NS_IMETHOD SetOctet_value(PRUint8 aOctet_value) = 0;
+
+ /* attribute short short_value; */
+ NS_IMETHOD GetShort_value(PRInt16 *aShort_value) = 0;
+ NS_IMETHOD SetShort_value(PRInt16 aShort_value) = 0;
+
+ /* attribute unsigned short ushort_value; */
+ NS_IMETHOD GetUshort_value(PRUint16 *aUshort_value) = 0;
+ NS_IMETHOD SetUshort_value(PRUint16 aUshort_value) = 0;
+
+ /* attribute long long_value; */
+ NS_IMETHOD GetLong_value(PRInt32 *aLong_value) = 0;
+ NS_IMETHOD SetLong_value(PRInt32 aLong_value) = 0;
+
+ /* attribute unsigned long ulong_value; */
+ NS_IMETHOD GetUlong_value(PRUint32 *aUlong_value) = 0;
+ NS_IMETHOD SetUlong_value(PRUint32 aUlong_value) = 0;
+
+ /* attribute long long long_long_value; */
+ NS_IMETHOD GetLong_long_value(PRInt64 *aLong_long_value) = 0;
+ NS_IMETHOD SetLong_long_value(PRInt64 aLong_long_value) = 0;
+
+ /* attribute unsigned long long ulong_long_value; */
+ NS_IMETHOD GetUlong_long_value(PRUint64 *aUlong_long_value) = 0;
+ NS_IMETHOD SetUlong_long_value(PRUint64 aUlong_long_value) = 0;
+
+ /* attribute float float_value; */
+ NS_IMETHOD GetFloat_value(float *aFloat_value) = 0;
+ NS_IMETHOD SetFloat_value(float aFloat_value) = 0;
+
+ /* attribute double double_value; */
+ NS_IMETHOD GetDouble_value(double *aDouble_value) = 0;
+ NS_IMETHOD SetDouble_value(double aDouble_value) = 0;
+
+ /* attribute char char_value; */
+ NS_IMETHOD GetChar_value(char *aChar_value) = 0;
+ NS_IMETHOD SetChar_value(char aChar_value) = 0;
+
+ /* attribute wchar wchar_value; */
+ NS_IMETHOD GetWchar_value(PRUnichar *aWchar_value) = 0;
+ NS_IMETHOD SetWchar_value(PRUnichar aWchar_value) = 0;
+
+ /* attribute string string_value; */
+ NS_IMETHOD GetString_value(char * *aString_value) = 0;
+ NS_IMETHOD SetString_value(const char * aString_value) = 0;
+
+ /* attribute wstring wstring_value; */
+ NS_IMETHOD GetWstring_value(PRUnichar * *aWstring_value) = 0;
+ NS_IMETHOD SetWstring_value(const PRUnichar * aWstring_value) = 0;
+
+ /* attribute AString astring_value; */
+ NS_IMETHOD GetAstring_value(nsAString & aAstring_value) = 0;
+ NS_IMETHOD SetAstring_value(const nsAString & aAstring_value) = 0;
+
+ /* attribute ACString acstring_value; */
+ NS_IMETHOD GetAcstring_value(nsACString & aAcstring_value) = 0;
+ NS_IMETHOD SetAcstring_value(const nsACString & aAcstring_value) = 0;
+
+ /* attribute AUTF8String utf8string_value; */
+ NS_IMETHOD GetUtf8string_value(nsACString & aUtf8string_value) = 0;
+ NS_IMETHOD SetUtf8string_value(const nsACString & aUtf8string_value) = 0;
+
+ /* attribute nsIIDRef iid_value; */
+ NS_IMETHOD GetIid_value(nsIID & *aIid_value) = 0;
+ NS_IMETHOD SetIid_value(const nsIID & aIid_value) = 0;
+
+ /* attribute nsIPythonTestInterface interface_value; */
+ NS_IMETHOD GetInterface_value(nsIPythonTestInterface * *aInterface_value) = 0;
+ NS_IMETHOD SetInterface_value(nsIPythonTestInterface * aInterface_value) = 0;
+
+ /* attribute nsISupports isupports_value; */
+ NS_IMETHOD GetIsupports_value(nsISupports * *aIsupports_value) = 0;
+ NS_IMETHOD SetIsupports_value(nsISupports * aIsupports_value) = 0;
+
+ /* boolean do_boolean (in boolean p1, inout boolean p2, out boolean p3); */
+ NS_IMETHOD Do_boolean(PRBool p1, PRBool *p2, PRBool *p3, PRBool *_retval) = 0;
+
+ /* octet do_octet (in octet p1, inout octet p2, out octet p3); */
+ NS_IMETHOD Do_octet(PRUint8 p1, PRUint8 *p2, PRUint8 *p3, PRUint8 *_retval) = 0;
+
+ /* short do_short (in short p1, inout short p2, out short p3); */
+ NS_IMETHOD Do_short(PRInt16 p1, PRInt16 *p2, PRInt16 *p3, PRInt16 *_retval) = 0;
+
+ /* unsigned short do_unsigned_short (in unsigned short p1, inout unsigned short p2, out unsigned short p3); */
+ NS_IMETHOD Do_unsigned_short(PRUint16 p1, PRUint16 *p2, PRUint16 *p3, PRUint16 *_retval) = 0;
+
+ /* long do_long (in long p1, inout long p2, out long p3); */
+ NS_IMETHOD Do_long(PRInt32 p1, PRInt32 *p2, PRInt32 *p3, PRInt32 *_retval) = 0;
+
+ /* unsigned long do_unsigned_long (in unsigned long p1, inout unsigned long p2, out unsigned long p3); */
+ NS_IMETHOD Do_unsigned_long(PRUint32 p1, PRUint32 *p2, PRUint32 *p3, PRUint32 *_retval) = 0;
+
+ /* long long do_long_long (in long long p1, inout long long p2, out long long p3); */
+ NS_IMETHOD Do_long_long(PRInt64 p1, PRInt64 *p2, PRInt64 *p3, PRInt64 *_retval) = 0;
+
+ /* unsigned long long do_unsigned_long_long (in unsigned long long p1, inout unsigned long long p2, out unsigned long long p3); */
+ NS_IMETHOD Do_unsigned_long_long(PRUint64 p1, PRUint64 *p2, PRUint64 *p3, PRUint64 *_retval) = 0;
+
+ /* float do_float (in float p1, inout float p2, out float p3); */
+ NS_IMETHOD Do_float(float p1, float *p2, float *p3, float *_retval) = 0;
+
+ /* double do_double (in double p1, inout double p2, out double p3); */
+ NS_IMETHOD Do_double(double p1, double *p2, double *p3, double *_retval) = 0;
+
+ /* char do_char (in char p1, inout char p2, out char p3); */
+ NS_IMETHOD Do_char(char p1, char *p2, char *p3, char *_retval) = 0;
+
+ /* wchar do_wchar (in wchar p1, inout wchar p2, out wchar p3); */
+ NS_IMETHOD Do_wchar(PRUnichar p1, PRUnichar *p2, PRUnichar *p3, PRUnichar *_retval) = 0;
+
+ /* string do_string (in string p1, inout string p2, out string p3); */
+ NS_IMETHOD Do_string(const char *p1, char **p2, char **p3, char **_retval) = 0;
+
+ /* wstring do_wstring (in wstring p1, inout wstring p2, out wstring p3); */
+ NS_IMETHOD Do_wstring(const PRUnichar *p1, PRUnichar **p2, PRUnichar **p3, PRUnichar **_retval) = 0;
+
+ /* nsIIDRef do_nsIIDRef (in nsIIDRef p1, inout nsIIDRef p2, out nsIIDRef p3); */
+ NS_IMETHOD Do_nsIIDRef(const nsIID & p1, nsIID & *p2, nsIID & *p3, nsIID & *_retval) = 0;
+
+ /* nsIPythonTestInterface do_nsIPythonTestInterface (in nsIPythonTestInterface p1, inout nsIPythonTestInterface p2, out nsIPythonTestInterface p3); */
+ NS_IMETHOD Do_nsIPythonTestInterface(nsIPythonTestInterface *p1, nsIPythonTestInterface **p2, nsIPythonTestInterface **p3, nsIPythonTestInterface **_retval) = 0;
+
+ /* nsISupports do_nsISupports (in nsISupports p1, inout nsISupports p2, out nsISupports p3); */
+ NS_IMETHOD Do_nsISupports(nsISupports *p1, nsISupports **p2, nsISupports **p3, nsISupports **_retval) = 0;
+
+ /* void do_nsISupportsIs (in nsIIDRef iid, [iid_is (iid), retval] out nsQIResult result); */
+ NS_IMETHOD Do_nsISupportsIs(const nsIID & iid, void * *result) = 0;
+
+};
+
+/* Use this macro when declaring classes that implement this interface. */
+#define NS_DECL_NSIPYTHONTESTINTERFACE \
+ NS_IMETHOD GetBoolean_value(PRBool *aBoolean_value); \
+ NS_IMETHOD SetBoolean_value(PRBool aBoolean_value); \
+ NS_IMETHOD GetOctet_value(PRUint8 *aOctet_value); \
+ NS_IMETHOD SetOctet_value(PRUint8 aOctet_value); \
+ NS_IMETHOD GetShort_value(PRInt16 *aShort_value); \
+ NS_IMETHOD SetShort_value(PRInt16 aShort_value); \
+ NS_IMETHOD GetUshort_value(PRUint16 *aUshort_value); \
+ NS_IMETHOD SetUshort_value(PRUint16 aUshort_value); \
+ NS_IMETHOD GetLong_value(PRInt32 *aLong_value); \
+ NS_IMETHOD SetLong_value(PRInt32 aLong_value); \
+ NS_IMETHOD GetUlong_value(PRUint32 *aUlong_value); \
+ NS_IMETHOD SetUlong_value(PRUint32 aUlong_value); \
+ NS_IMETHOD GetLong_long_value(PRInt64 *aLong_long_value); \
+ NS_IMETHOD SetLong_long_value(PRInt64 aLong_long_value); \
+ NS_IMETHOD GetUlong_long_value(PRUint64 *aUlong_long_value); \
+ NS_IMETHOD SetUlong_long_value(PRUint64 aUlong_long_value); \
+ NS_IMETHOD GetFloat_value(float *aFloat_value); \
+ NS_IMETHOD SetFloat_value(float aFloat_value); \
+ NS_IMETHOD GetDouble_value(double *aDouble_value); \
+ NS_IMETHOD SetDouble_value(double aDouble_value); \
+ NS_IMETHOD GetChar_value(char *aChar_value); \
+ NS_IMETHOD SetChar_value(char aChar_value); \
+ NS_IMETHOD GetWchar_value(PRUnichar *aWchar_value); \
+ NS_IMETHOD SetWchar_value(PRUnichar aWchar_value); \
+ NS_IMETHOD GetString_value(char * *aString_value); \
+ NS_IMETHOD SetString_value(const char * aString_value); \
+ NS_IMETHOD GetWstring_value(PRUnichar * *aWstring_value); \
+ NS_IMETHOD SetWstring_value(const PRUnichar * aWstring_value); \
+ NS_IMETHOD GetAstring_value(nsAString & aAstring_value); \
+ NS_IMETHOD SetAstring_value(const nsAString & aAstring_value); \
+ NS_IMETHOD GetAcstring_value(nsACString & aAcstring_value); \
+ NS_IMETHOD SetAcstring_value(const nsACString & aAcstring_value); \
+ NS_IMETHOD GetUtf8string_value(nsACString & aUtf8string_value); \
+ NS_IMETHOD SetUtf8string_value(const nsACString & aUtf8string_value); \
+ NS_IMETHOD GetIid_value(nsIID & *aIid_value); \
+ NS_IMETHOD SetIid_value(const nsIID & aIid_value); \
+ NS_IMETHOD GetInterface_value(nsIPythonTestInterface * *aInterface_value); \
+ NS_IMETHOD SetInterface_value(nsIPythonTestInterface * aInterface_value); \
+ NS_IMETHOD GetIsupports_value(nsISupports * *aIsupports_value); \
+ NS_IMETHOD SetIsupports_value(nsISupports * aIsupports_value); \
+ NS_IMETHOD Do_boolean(PRBool p1, PRBool *p2, PRBool *p3, PRBool *_retval); \
+ NS_IMETHOD Do_octet(PRUint8 p1, PRUint8 *p2, PRUint8 *p3, PRUint8 *_retval); \
+ NS_IMETHOD Do_short(PRInt16 p1, PRInt16 *p2, PRInt16 *p3, PRInt16 *_retval); \
+ NS_IMETHOD Do_unsigned_short(PRUint16 p1, PRUint16 *p2, PRUint16 *p3, PRUint16 *_retval); \
+ NS_IMETHOD Do_long(PRInt32 p1, PRInt32 *p2, PRInt32 *p3, PRInt32 *_retval); \
+ NS_IMETHOD Do_unsigned_long(PRUint32 p1, PRUint32 *p2, PRUint32 *p3, PRUint32 *_retval); \
+ NS_IMETHOD Do_long_long(PRInt64 p1, PRInt64 *p2, PRInt64 *p3, PRInt64 *_retval); \
+ NS_IMETHOD Do_unsigned_long_long(PRUint64 p1, PRUint64 *p2, PRUint64 *p3, PRUint64 *_retval); \
+ NS_IMETHOD Do_float(float p1, float *p2, float *p3, float *_retval); \
+ NS_IMETHOD Do_double(double p1, double *p2, double *p3, double *_retval); \
+ NS_IMETHOD Do_char(char p1, char *p2, char *p3, char *_retval); \
+ NS_IMETHOD Do_wchar(PRUnichar p1, PRUnichar *p2, PRUnichar *p3, PRUnichar *_retval); \
+ NS_IMETHOD Do_string(const char *p1, char **p2, char **p3, char **_retval); \
+ NS_IMETHOD Do_wstring(const PRUnichar *p1, PRUnichar **p2, PRUnichar **p3, PRUnichar **_retval); \
+ NS_IMETHOD Do_nsIIDRef(const nsIID & p1, nsIID & *p2, nsIID & *p3, nsIID & *_retval); \
+ NS_IMETHOD Do_nsIPythonTestInterface(nsIPythonTestInterface *p1, nsIPythonTestInterface **p2, nsIPythonTestInterface **p3, nsIPythonTestInterface **_retval); \
+ NS_IMETHOD Do_nsISupports(nsISupports *p1, nsISupports **p2, nsISupports **p3, nsISupports **_retval); \
+ NS_IMETHOD Do_nsISupportsIs(const nsIID & iid, void * *result);
+
+/* Use this macro to declare functions that forward the behavior of this interface to another object. */
+#define NS_FORWARD_NSIPYTHONTESTINTERFACE(_to) \
+ NS_IMETHOD GetBoolean_value(PRBool *aBoolean_value) { return _to GetBoolean_value(aBoolean_value); } \
+ NS_IMETHOD SetBoolean_value(PRBool aBoolean_value) { return _to SetBoolean_value(aBoolean_value); } \
+ NS_IMETHOD GetOctet_value(PRUint8 *aOctet_value) { return _to GetOctet_value(aOctet_value); } \
+ NS_IMETHOD SetOctet_value(PRUint8 aOctet_value) { return _to SetOctet_value(aOctet_value); } \
+ NS_IMETHOD GetShort_value(PRInt16 *aShort_value) { return _to GetShort_value(aShort_value); } \
+ NS_IMETHOD SetShort_value(PRInt16 aShort_value) { return _to SetShort_value(aShort_value); } \
+ NS_IMETHOD GetUshort_value(PRUint16 *aUshort_value) { return _to GetUshort_value(aUshort_value); } \
+ NS_IMETHOD SetUshort_value(PRUint16 aUshort_value) { return _to SetUshort_value(aUshort_value); } \
+ NS_IMETHOD GetLong_value(PRInt32 *aLong_value) { return _to GetLong_value(aLong_value); } \
+ NS_IMETHOD SetLong_value(PRInt32 aLong_value) { return _to SetLong_value(aLong_value); } \
+ NS_IMETHOD GetUlong_value(PRUint32 *aUlong_value) { return _to GetUlong_value(aUlong_value); } \
+ NS_IMETHOD SetUlong_value(PRUint32 aUlong_value) { return _to SetUlong_value(aUlong_value); } \
+ NS_IMETHOD GetLong_long_value(PRInt64 *aLong_long_value) { return _to GetLong_long_value(aLong_long_value); } \
+ NS_IMETHOD SetLong_long_value(PRInt64 aLong_long_value) { return _to SetLong_long_value(aLong_long_value); } \
+ NS_IMETHOD GetUlong_long_value(PRUint64 *aUlong_long_value) { return _to GetUlong_long_value(aUlong_long_value); } \
+ NS_IMETHOD SetUlong_long_value(PRUint64 aUlong_long_value) { return _to SetUlong_long_value(aUlong_long_value); } \
+ NS_IMETHOD GetFloat_value(float *aFloat_value) { return _to GetFloat_value(aFloat_value); } \
+ NS_IMETHOD SetFloat_value(float aFloat_value) { return _to SetFloat_value(aFloat_value); } \
+ NS_IMETHOD GetDouble_value(double *aDouble_value) { return _to GetDouble_value(aDouble_value); } \
+ NS_IMETHOD SetDouble_value(double aDouble_value) { return _to SetDouble_value(aDouble_value); } \
+ NS_IMETHOD GetChar_value(char *aChar_value) { return _to GetChar_value(aChar_value); } \
+ NS_IMETHOD SetChar_value(char aChar_value) { return _to SetChar_value(aChar_value); } \
+ NS_IMETHOD GetWchar_value(PRUnichar *aWchar_value) { return _to GetWchar_value(aWchar_value); } \
+ NS_IMETHOD SetWchar_value(PRUnichar aWchar_value) { return _to SetWchar_value(aWchar_value); } \
+ NS_IMETHOD GetString_value(char * *aString_value) { return _to GetString_value(aString_value); } \
+ NS_IMETHOD SetString_value(const char * aString_value) { return _to SetString_value(aString_value); } \
+ NS_IMETHOD GetWstring_value(PRUnichar * *aWstring_value) { return _to GetWstring_value(aWstring_value); } \
+ NS_IMETHOD SetWstring_value(const PRUnichar * aWstring_value) { return _to SetWstring_value(aWstring_value); } \
+ NS_IMETHOD GetAstring_value(nsAString & aAstring_value) { return _to GetAstring_value(aAstring_value); } \
+ NS_IMETHOD SetAstring_value(const nsAString & aAstring_value) { return _to SetAstring_value(aAstring_value); } \
+ NS_IMETHOD GetAcstring_value(nsACString & aAcstring_value) { return _to GetAcstring_value(aAcstring_value); } \
+ NS_IMETHOD SetAcstring_value(const nsACString & aAcstring_value) { return _to SetAcstring_value(aAcstring_value); } \
+ NS_IMETHOD GetUtf8string_value(nsACString & aUtf8string_value) { return _to GetUtf8string_value(aUtf8string_value); } \
+ NS_IMETHOD SetUtf8string_value(const nsACString & aUtf8string_value) { return _to SetUtf8string_value(aUtf8string_value); } \
+ NS_IMETHOD GetIid_value(nsIID & *aIid_value) { return _to GetIid_value(aIid_value); } \
+ NS_IMETHOD SetIid_value(const nsIID & aIid_value) { return _to SetIid_value(aIid_value); } \
+ NS_IMETHOD GetInterface_value(nsIPythonTestInterface * *aInterface_value) { return _to GetInterface_value(aInterface_value); } \
+ NS_IMETHOD SetInterface_value(nsIPythonTestInterface * aInterface_value) { return _to SetInterface_value(aInterface_value); } \
+ NS_IMETHOD GetIsupports_value(nsISupports * *aIsupports_value) { return _to GetIsupports_value(aIsupports_value); } \
+ NS_IMETHOD SetIsupports_value(nsISupports * aIsupports_value) { return _to SetIsupports_value(aIsupports_value); } \
+ NS_IMETHOD Do_boolean(PRBool p1, PRBool *p2, PRBool *p3, PRBool *_retval) { return _to Do_boolean(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_octet(PRUint8 p1, PRUint8 *p2, PRUint8 *p3, PRUint8 *_retval) { return _to Do_octet(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_short(PRInt16 p1, PRInt16 *p2, PRInt16 *p3, PRInt16 *_retval) { return _to Do_short(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_unsigned_short(PRUint16 p1, PRUint16 *p2, PRUint16 *p3, PRUint16 *_retval) { return _to Do_unsigned_short(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_long(PRInt32 p1, PRInt32 *p2, PRInt32 *p3, PRInt32 *_retval) { return _to Do_long(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_unsigned_long(PRUint32 p1, PRUint32 *p2, PRUint32 *p3, PRUint32 *_retval) { return _to Do_unsigned_long(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_long_long(PRInt64 p1, PRInt64 *p2, PRInt64 *p3, PRInt64 *_retval) { return _to Do_long_long(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_unsigned_long_long(PRUint64 p1, PRUint64 *p2, PRUint64 *p3, PRUint64 *_retval) { return _to Do_unsigned_long_long(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_float(float p1, float *p2, float *p3, float *_retval) { return _to Do_float(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_double(double p1, double *p2, double *p3, double *_retval) { return _to Do_double(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_char(char p1, char *p2, char *p3, char *_retval) { return _to Do_char(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_wchar(PRUnichar p1, PRUnichar *p2, PRUnichar *p3, PRUnichar *_retval) { return _to Do_wchar(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_string(const char *p1, char **p2, char **p3, char **_retval) { return _to Do_string(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_wstring(const PRUnichar *p1, PRUnichar **p2, PRUnichar **p3, PRUnichar **_retval) { return _to Do_wstring(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_nsIIDRef(const nsIID & p1, nsIID & *p2, nsIID & *p3, nsIID & *_retval) { return _to Do_nsIIDRef(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_nsIPythonTestInterface(nsIPythonTestInterface *p1, nsIPythonTestInterface **p2, nsIPythonTestInterface **p3, nsIPythonTestInterface **_retval) { return _to Do_nsIPythonTestInterface(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_nsISupports(nsISupports *p1, nsISupports **p2, nsISupports **p3, nsISupports **_retval) { return _to Do_nsISupports(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_nsISupportsIs(const nsIID & iid, void * *result) { return _to Do_nsISupportsIs(iid, result); }
+
+/* Use this macro to declare functions that forward the behavior of this interface to another object in a safe way. */
+#define NS_FORWARD_SAFE_NSIPYTHONTESTINTERFACE(_to) \
+ NS_IMETHOD GetBoolean_value(PRBool *aBoolean_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetBoolean_value(aBoolean_value); } \
+ NS_IMETHOD SetBoolean_value(PRBool aBoolean_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetBoolean_value(aBoolean_value); } \
+ NS_IMETHOD GetOctet_value(PRUint8 *aOctet_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetOctet_value(aOctet_value); } \
+ NS_IMETHOD SetOctet_value(PRUint8 aOctet_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetOctet_value(aOctet_value); } \
+ NS_IMETHOD GetShort_value(PRInt16 *aShort_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetShort_value(aShort_value); } \
+ NS_IMETHOD SetShort_value(PRInt16 aShort_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetShort_value(aShort_value); } \
+ NS_IMETHOD GetUshort_value(PRUint16 *aUshort_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetUshort_value(aUshort_value); } \
+ NS_IMETHOD SetUshort_value(PRUint16 aUshort_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetUshort_value(aUshort_value); } \
+ NS_IMETHOD GetLong_value(PRInt32 *aLong_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetLong_value(aLong_value); } \
+ NS_IMETHOD SetLong_value(PRInt32 aLong_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetLong_value(aLong_value); } \
+ NS_IMETHOD GetUlong_value(PRUint32 *aUlong_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetUlong_value(aUlong_value); } \
+ NS_IMETHOD SetUlong_value(PRUint32 aUlong_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetUlong_value(aUlong_value); } \
+ NS_IMETHOD GetLong_long_value(PRInt64 *aLong_long_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetLong_long_value(aLong_long_value); } \
+ NS_IMETHOD SetLong_long_value(PRInt64 aLong_long_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetLong_long_value(aLong_long_value); } \
+ NS_IMETHOD GetUlong_long_value(PRUint64 *aUlong_long_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetUlong_long_value(aUlong_long_value); } \
+ NS_IMETHOD SetUlong_long_value(PRUint64 aUlong_long_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetUlong_long_value(aUlong_long_value); } \
+ NS_IMETHOD GetFloat_value(float *aFloat_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetFloat_value(aFloat_value); } \
+ NS_IMETHOD SetFloat_value(float aFloat_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetFloat_value(aFloat_value); } \
+ NS_IMETHOD GetDouble_value(double *aDouble_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetDouble_value(aDouble_value); } \
+ NS_IMETHOD SetDouble_value(double aDouble_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetDouble_value(aDouble_value); } \
+ NS_IMETHOD GetChar_value(char *aChar_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetChar_value(aChar_value); } \
+ NS_IMETHOD SetChar_value(char aChar_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetChar_value(aChar_value); } \
+ NS_IMETHOD GetWchar_value(PRUnichar *aWchar_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetWchar_value(aWchar_value); } \
+ NS_IMETHOD SetWchar_value(PRUnichar aWchar_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetWchar_value(aWchar_value); } \
+ NS_IMETHOD GetString_value(char * *aString_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetString_value(aString_value); } \
+ NS_IMETHOD SetString_value(const char * aString_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetString_value(aString_value); } \
+ NS_IMETHOD GetWstring_value(PRUnichar * *aWstring_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetWstring_value(aWstring_value); } \
+ NS_IMETHOD SetWstring_value(const PRUnichar * aWstring_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetWstring_value(aWstring_value); } \
+ NS_IMETHOD GetAstring_value(nsAString & aAstring_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetAstring_value(aAstring_value); } \
+ NS_IMETHOD SetAstring_value(const nsAString & aAstring_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetAstring_value(aAstring_value); } \
+ NS_IMETHOD GetAcstring_value(nsACString & aAcstring_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetAcstring_value(aAcstring_value); } \
+ NS_IMETHOD SetAcstring_value(const nsACString & aAcstring_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetAcstring_value(aAcstring_value); } \
+ NS_IMETHOD GetUtf8string_value(nsACString & aUtf8string_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetUtf8string_value(aUtf8string_value); } \
+ NS_IMETHOD SetUtf8string_value(const nsACString & aUtf8string_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetUtf8string_value(aUtf8string_value); } \
+ NS_IMETHOD GetIid_value(nsIID & *aIid_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetIid_value(aIid_value); } \
+ NS_IMETHOD SetIid_value(const nsIID & aIid_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetIid_value(aIid_value); } \
+ NS_IMETHOD GetInterface_value(nsIPythonTestInterface * *aInterface_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetInterface_value(aInterface_value); } \
+ NS_IMETHOD SetInterface_value(nsIPythonTestInterface * aInterface_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetInterface_value(aInterface_value); } \
+ NS_IMETHOD GetIsupports_value(nsISupports * *aIsupports_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetIsupports_value(aIsupports_value); } \
+ NS_IMETHOD SetIsupports_value(nsISupports * aIsupports_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetIsupports_value(aIsupports_value); } \
+ NS_IMETHOD Do_boolean(PRBool p1, PRBool *p2, PRBool *p3, PRBool *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_boolean(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_octet(PRUint8 p1, PRUint8 *p2, PRUint8 *p3, PRUint8 *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_octet(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_short(PRInt16 p1, PRInt16 *p2, PRInt16 *p3, PRInt16 *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_short(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_unsigned_short(PRUint16 p1, PRUint16 *p2, PRUint16 *p3, PRUint16 *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_unsigned_short(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_long(PRInt32 p1, PRInt32 *p2, PRInt32 *p3, PRInt32 *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_long(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_unsigned_long(PRUint32 p1, PRUint32 *p2, PRUint32 *p3, PRUint32 *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_unsigned_long(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_long_long(PRInt64 p1, PRInt64 *p2, PRInt64 *p3, PRInt64 *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_long_long(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_unsigned_long_long(PRUint64 p1, PRUint64 *p2, PRUint64 *p3, PRUint64 *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_unsigned_long_long(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_float(float p1, float *p2, float *p3, float *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_float(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_double(double p1, double *p2, double *p3, double *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_double(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_char(char p1, char *p2, char *p3, char *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_char(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_wchar(PRUnichar p1, PRUnichar *p2, PRUnichar *p3, PRUnichar *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_wchar(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_string(const char *p1, char **p2, char **p3, char **_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_string(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_wstring(const PRUnichar *p1, PRUnichar **p2, PRUnichar **p3, PRUnichar **_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_wstring(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_nsIIDRef(const nsIID & p1, nsIID & *p2, nsIID & *p3, nsIID & *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_nsIIDRef(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_nsIPythonTestInterface(nsIPythonTestInterface *p1, nsIPythonTestInterface **p2, nsIPythonTestInterface **p3, nsIPythonTestInterface **_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_nsIPythonTestInterface(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_nsISupports(nsISupports *p1, nsISupports **p2, nsISupports **p3, nsISupports **_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_nsISupports(p1, p2, p3, _retval); } \
+ NS_IMETHOD Do_nsISupportsIs(const nsIID & iid, void * *result) { return !_to ? NS_ERROR_NULL_POINTER : _to->Do_nsISupportsIs(iid, result); }
+
+#if 0
+/* Use the code below as a template for the implementation class for this interface. */
+
+/* Header file */
+class nsPythonTestInterface : public nsIPythonTestInterface
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPYTHONTESTINTERFACE
+
+ nsPythonTestInterface();
+
+private:
+ ~nsPythonTestInterface();
+
+protected:
+ /* additional members */
+};
+
+/* Implementation file */
+NS_IMPL_ISUPPORTS1(nsPythonTestInterface, nsIPythonTestInterface)
+
+nsPythonTestInterface::nsPythonTestInterface()
+{
+ /* member initializers and constructor code */
+}
+
+nsPythonTestInterface::~nsPythonTestInterface()
+{
+ /* destructor code */
+}
+
+/* attribute boolean boolean_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetBoolean_value(PRBool *aBoolean_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetBoolean_value(PRBool aBoolean_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute octet octet_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetOctet_value(PRUint8 *aOctet_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetOctet_value(PRUint8 aOctet_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute short short_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetShort_value(PRInt16 *aShort_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetShort_value(PRInt16 aShort_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute unsigned short ushort_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetUshort_value(PRUint16 *aUshort_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetUshort_value(PRUint16 aUshort_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute long long_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetLong_value(PRInt32 *aLong_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetLong_value(PRInt32 aLong_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute unsigned long ulong_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetUlong_value(PRUint32 *aUlong_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetUlong_value(PRUint32 aUlong_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute long long long_long_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetLong_long_value(PRInt64 *aLong_long_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetLong_long_value(PRInt64 aLong_long_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute unsigned long long ulong_long_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetUlong_long_value(PRUint64 *aUlong_long_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetUlong_long_value(PRUint64 aUlong_long_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute float float_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetFloat_value(float *aFloat_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetFloat_value(float aFloat_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute double double_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetDouble_value(double *aDouble_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetDouble_value(double aDouble_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute char char_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetChar_value(char *aChar_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetChar_value(char aChar_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute wchar wchar_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetWchar_value(PRUnichar *aWchar_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetWchar_value(PRUnichar aWchar_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute string string_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetString_value(char * *aString_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetString_value(const char * aString_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute wstring wstring_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetWstring_value(PRUnichar * *aWstring_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetWstring_value(const PRUnichar * aWstring_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute AString astring_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetAstring_value(nsAString & aAstring_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetAstring_value(const nsAString & aAstring_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute ACString acstring_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetAcstring_value(nsACString & aAcstring_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetAcstring_value(const nsACString & aAcstring_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute AUTF8String utf8string_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetUtf8string_value(nsACString & aUtf8string_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetUtf8string_value(const nsACString & aUtf8string_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute nsIIDRef iid_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetIid_value(nsIID & *aIid_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetIid_value(const nsIID & aIid_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute nsIPythonTestInterface interface_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetInterface_value(nsIPythonTestInterface * *aInterface_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetInterface_value(nsIPythonTestInterface * aInterface_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute nsISupports isupports_value; */
+NS_IMETHODIMP nsPythonTestInterface::GetIsupports_value(nsISupports * *aIsupports_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterface::SetIsupports_value(nsISupports * aIsupports_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* boolean do_boolean (in boolean p1, inout boolean p2, out boolean p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_boolean(PRBool p1, PRBool *p2, PRBool *p3, PRBool *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* octet do_octet (in octet p1, inout octet p2, out octet p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_octet(PRUint8 p1, PRUint8 *p2, PRUint8 *p3, PRUint8 *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* short do_short (in short p1, inout short p2, out short p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_short(PRInt16 p1, PRInt16 *p2, PRInt16 *p3, PRInt16 *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* unsigned short do_unsigned_short (in unsigned short p1, inout unsigned short p2, out unsigned short p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_unsigned_short(PRUint16 p1, PRUint16 *p2, PRUint16 *p3, PRUint16 *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* long do_long (in long p1, inout long p2, out long p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_long(PRInt32 p1, PRInt32 *p2, PRInt32 *p3, PRInt32 *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* unsigned long do_unsigned_long (in unsigned long p1, inout unsigned long p2, out unsigned long p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_unsigned_long(PRUint32 p1, PRUint32 *p2, PRUint32 *p3, PRUint32 *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* long long do_long_long (in long long p1, inout long long p2, out long long p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_long_long(PRInt64 p1, PRInt64 *p2, PRInt64 *p3, PRInt64 *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* unsigned long long do_unsigned_long_long (in unsigned long long p1, inout unsigned long long p2, out unsigned long long p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_unsigned_long_long(PRUint64 p1, PRUint64 *p2, PRUint64 *p3, PRUint64 *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* float do_float (in float p1, inout float p2, out float p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_float(float p1, float *p2, float *p3, float *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* double do_double (in double p1, inout double p2, out double p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_double(double p1, double *p2, double *p3, double *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* char do_char (in char p1, inout char p2, out char p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_char(char p1, char *p2, char *p3, char *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* wchar do_wchar (in wchar p1, inout wchar p2, out wchar p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_wchar(PRUnichar p1, PRUnichar *p2, PRUnichar *p3, PRUnichar *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* string do_string (in string p1, inout string p2, out string p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_string(const char *p1, char **p2, char **p3, char **_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* wstring do_wstring (in wstring p1, inout wstring p2, out wstring p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_wstring(const PRUnichar *p1, PRUnichar **p2, PRUnichar **p3, PRUnichar **_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* nsIIDRef do_nsIIDRef (in nsIIDRef p1, inout nsIIDRef p2, out nsIIDRef p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_nsIIDRef(const nsIID & p1, nsIID & *p2, nsIID & *p3, nsIID & *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* nsIPythonTestInterface do_nsIPythonTestInterface (in nsIPythonTestInterface p1, inout nsIPythonTestInterface p2, out nsIPythonTestInterface p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_nsIPythonTestInterface(nsIPythonTestInterface *p1, nsIPythonTestInterface **p2, nsIPythonTestInterface **p3, nsIPythonTestInterface **_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* nsISupports do_nsISupports (in nsISupports p1, inout nsISupports p2, out nsISupports p3); */
+NS_IMETHODIMP nsPythonTestInterface::Do_nsISupports(nsISupports *p1, nsISupports **p2, nsISupports **p3, nsISupports **_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void do_nsISupportsIs (in nsIIDRef iid, [iid_is (iid), retval] out nsQIResult result); */
+NS_IMETHODIMP nsPythonTestInterface::Do_nsISupportsIs(const nsIID & iid, void * *result)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* End of implementation class template. */
+#endif
+
+
+/* starting interface: nsIPythonTestInterfaceExtra */
+#define NS_IPYTHONTESTINTERFACEEXTRA_IID_STR "b38d1538-fe92-42c3-831f-285242edeea4"
+
+#define NS_IPYTHONTESTINTERFACEEXTRA_IID \
+ {0xb38d1538, 0xfe92, 0x42c3, \
+ { 0x83, 0x1f, 0x28, 0x52, 0x42, 0xed, 0xee, 0xa4 }}
+
+class NS_NO_VTABLE nsIPythonTestInterfaceExtra : public nsIPythonTestInterface {
+ public:
+
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IPYTHONTESTINTERFACEEXTRA_IID)
+
+ /* void MultiplyEachItemInIntegerArray (in PRInt32 val, in PRUint32 count, [array, size_is (count)] inout PRInt32 valueArray); */
+ NS_IMETHOD MultiplyEachItemInIntegerArray(PRInt32 val, PRUint32 count, PRInt32 **valueArray) = 0;
+
+ /* void MultiplyEachItemInIntegerArrayAndAppend (in PRInt32 val, inout PRUint32 count, [array, size_is (count)] inout PRInt32 valueArray); */
+ NS_IMETHOD MultiplyEachItemInIntegerArrayAndAppend(PRInt32 val, PRUint32 *count, PRInt32 **valueArray) = 0;
+
+ /* void CompareStringArrays ([array, size_is (count)] in string arr1, [array, size_is (count)] in string arr2, in unsigned long count, [retval] out short result); */
+ NS_IMETHOD CompareStringArrays(const char **arr1, const char **arr2, PRUint32 count, PRInt16 *result) = 0;
+
+ /* void DoubleStringArray (inout PRUint32 count, [array, size_is (count)] inout string valueArray); */
+ NS_IMETHOD DoubleStringArray(PRUint32 *count, char ***valueArray) = 0;
+
+ /* void ReverseStringArray (in PRUint32 count, [array, size_is (count)] inout string valueArray); */
+ NS_IMETHOD ReverseStringArray(PRUint32 count, char ***valueArray) = 0;
+
+ /* void DoubleString (inout PRUint32 count, [size_is (count)] inout string str); */
+ NS_IMETHOD DoubleString(PRUint32 *count, char **str) = 0;
+
+ /* void DoubleString2 (in PRUint32 in_count, [size_is (in_count)] in string in_str, out PRUint32 out_count, [size_is (out_count)] out string out_str); */
+ NS_IMETHOD DoubleString2(PRUint32 in_count, const char *in_str, PRUint32 *out_count, char **out_str) = 0;
+
+ /* void DoubleString3 (in PRUint32 in_count, [size_is (in_count)] in string in_str, out PRUint32 out_count, [size_is (out_count), retval] out string out_str); */
+ NS_IMETHOD DoubleString3(PRUint32 in_count, const char *in_str, PRUint32 *out_count, char **out_str) = 0;
+
+ /* void DoubleString4 ([size_is (count)] in string in_str, inout PRUint32 count, [size_is (count)] out string out_str); */
+ NS_IMETHOD DoubleString4(const char *in_str, PRUint32 *count, char **out_str) = 0;
+
+ /* void UpString (in PRUint32 count, [size_is (count)] inout string str); */
+ NS_IMETHOD UpString(PRUint32 count, char **str) = 0;
+
+ /* void UpString2 (in PRUint32 count, [size_is (count)] in string in_str, [size_is (count)] out string out_str); */
+ NS_IMETHOD UpString2(PRUint32 count, const char *in_str, char **out_str) = 0;
+
+ /* void CopyUTF8String (in AUTF8String in_str, out AUTF8String out_str); */
+ NS_IMETHOD CopyUTF8String(const nsACString & in_str, nsACString & out_str) = 0;
+
+ /* void CopyUTF8String2 (in AUTF8String in_str, out AUTF8String out_str); */
+ NS_IMETHOD CopyUTF8String2(const nsACString & in_str, nsACString & out_str) = 0;
+
+ /* void GetFixedString (in PRUint32 count, [size_is (count)] out string out_str); */
+ NS_IMETHOD GetFixedString(PRUint32 count, char **out_str) = 0;
+
+ /* void DoubleWideString (inout PRUint32 count, [size_is (count)] inout wstring str); */
+ NS_IMETHOD DoubleWideString(PRUint32 *count, PRUnichar **str) = 0;
+
+ /* void DoubleWideString2 (in PRUint32 in_count, [size_is (in_count)] in wstring in_str, out PRUint32 out_count, [size_is (out_count)] out wstring out_str); */
+ NS_IMETHOD DoubleWideString2(PRUint32 in_count, const PRUnichar *in_str, PRUint32 *out_count, PRUnichar **out_str) = 0;
+
+ /* void DoubleWideString3 (in PRUint32 in_count, [size_is (in_count)] in wstring in_str, out PRUint32 out_count, [size_is (out_count), retval] out wstring out_str); */
+ NS_IMETHOD DoubleWideString3(PRUint32 in_count, const PRUnichar *in_str, PRUint32 *out_count, PRUnichar **out_str) = 0;
+
+ /* void DoubleWideString4 ([size_is (count)] in wstring in_str, inout PRUint32 count, [size_is (count)] out wstring out_str); */
+ NS_IMETHOD DoubleWideString4(const PRUnichar *in_str, PRUint32 *count, PRUnichar **out_str) = 0;
+
+ /* void UpWideString (in PRUint32 count, [size_is (count)] inout wstring str); */
+ NS_IMETHOD UpWideString(PRUint32 count, PRUnichar **str) = 0;
+
+ /* void UpWideString2 (in PRUint32 count, [size_is (count)] in wstring in_str, [size_is (count)] out wstring out_str); */
+ NS_IMETHOD UpWideString2(PRUint32 count, const PRUnichar *in_str, PRUnichar **out_str) = 0;
+
+ /* void GetFixedWideString (in PRUint32 count, [size_is (count)] out string out_str); */
+ NS_IMETHOD GetFixedWideString(PRUint32 count, char **out_str) = 0;
+
+ /* void GetStrings (out PRUint32 count, [array, size_is (count), retval] out string str); */
+ NS_IMETHOD GetStrings(PRUint32 *count, char ***str) = 0;
+
+ /* void UpOctetArray (inout PRUint32 count, [array, size_is (count)] inout PRUint8 data); */
+ NS_IMETHOD UpOctetArray(PRUint32 *count, PRUint8 **data) = 0;
+
+ /* void UpOctetArray2 (inout PRUint32 count, [array, size_is (count)] inout PRUint8 data); */
+ NS_IMETHOD UpOctetArray2(PRUint32 *count, PRUint8 **data) = 0;
+
+ /* void CheckInterfaceArray (in PRUint32 count, [array, size_is (count)] in nsISupports data, [retval] out PRBool all_non_null); */
+ NS_IMETHOD CheckInterfaceArray(PRUint32 count, nsISupports **data, PRBool *all_non_null) = 0;
+
+ /* void CopyInterfaceArray (in PRUint32 count, [array, size_is (count)] in nsISupports data, [array, size_is (out_count)] out nsISupports out_data, out PRUint32 out_count); */
+ NS_IMETHOD CopyInterfaceArray(PRUint32 count, nsISupports **data, nsISupports ***out_data, PRUint32 *out_count) = 0;
+
+ /* void GetInterfaceArray (out PRUint32 count, [array, size_is (count)] out nsISupports data); */
+ NS_IMETHOD GetInterfaceArray(PRUint32 *count, nsISupports ***data) = 0;
+
+ /* void ExtendInterfaceArray (inout PRUint32 count, [array, size_is (count)] inout nsISupports data); */
+ NS_IMETHOD ExtendInterfaceArray(PRUint32 *count, nsISupports ***data) = 0;
+
+ /* void CheckIIDArray (in PRUint32 count, [array, size_is (count)] in nsIIDRef data, [retval] out PRBool all_mine); */
+ NS_IMETHOD CheckIIDArray(PRUint32 count, const nsIID & *data, PRBool *all_mine) = 0;
+
+ /* void GetIIDArray (out PRUint32 count, [array, size_is (count)] out nsIIDRef data); */
+ NS_IMETHOD GetIIDArray(PRUint32 *count, nsIID & **data) = 0;
+
+ /* void ExtendIIDArray (inout PRUint32 count, [array, size_is (count)] inout nsIIDRef data); */
+ NS_IMETHOD ExtendIIDArray(PRUint32 *count, nsIID & **data) = 0;
+
+ /* void SumArrays (in PRUint32 count, [array, size_is (count)] in PRInt32 array1, [array, size_is (count)] in PRInt32 array2, [retval] out PRInt32 result); */
+ NS_IMETHOD SumArrays(PRUint32 count, PRInt32 *array1, PRInt32 *array2, PRInt32 *result) = 0;
+
+ /* void GetArrays (out PRUint32 count, [array, size_is (count)] out PRInt32 array1, [array, size_is (count)] out PRInt32 array2); */
+ NS_IMETHOD GetArrays(PRUint32 *count, PRInt32 **array1, PRInt32 **array2) = 0;
+
+ /* void GetFixedArray (in PRUint32 count, [array, size_is (count)] out PRInt32 array1); */
+ NS_IMETHOD GetFixedArray(PRUint32 count, PRInt32 **array1) = 0;
+
+ /* void CopyArray (in PRUint32 count, [array, size_is (count)] in PRInt32 array1, [array, size_is (count)] out PRInt32 array2); */
+ NS_IMETHOD CopyArray(PRUint32 count, PRInt32 *array1, PRInt32 **array2) = 0;
+
+ /* void CopyAndDoubleArray (inout PRUint32 count, [array, size_is (count)] in PRInt32 array1, [array, size_is (count)] out PRInt32 array2); */
+ NS_IMETHOD CopyAndDoubleArray(PRUint32 *count, PRInt32 *array1, PRInt32 **array2) = 0;
+
+ /* void AppendArray (inout PRUint32 count, [array, size_is (count)] in PRInt32 array1, [array, size_is (count)] inout PRInt32 array2); */
+ NS_IMETHOD AppendArray(PRUint32 *count, PRInt32 *array1, PRInt32 **array2) = 0;
+
+ /* void AppendVariant (in nsIVariant variant, inout nsIVariant result); */
+ NS_IMETHOD AppendVariant(nsIVariant *variant, nsIVariant **result) = 0;
+
+ /* nsIVariant CopyVariant (in nsIVariant variant); */
+ NS_IMETHOD CopyVariant(nsIVariant *variant, nsIVariant **_retval) = 0;
+
+ /* nsIVariant SumVariants (in PRUint32 incount, [array, size_is (incount)] in nsIVariant variants); */
+ NS_IMETHOD SumVariants(PRUint32 incount, nsIVariant **variants, nsIVariant **_retval) = 0;
+
+};
+
+/* Use this macro when declaring classes that implement this interface. */
+#define NS_DECL_NSIPYTHONTESTINTERFACEEXTRA \
+ NS_IMETHOD MultiplyEachItemInIntegerArray(PRInt32 val, PRUint32 count, PRInt32 **valueArray); \
+ NS_IMETHOD MultiplyEachItemInIntegerArrayAndAppend(PRInt32 val, PRUint32 *count, PRInt32 **valueArray); \
+ NS_IMETHOD CompareStringArrays(const char **arr1, const char **arr2, PRUint32 count, PRInt16 *result); \
+ NS_IMETHOD DoubleStringArray(PRUint32 *count, char ***valueArray); \
+ NS_IMETHOD ReverseStringArray(PRUint32 count, char ***valueArray); \
+ NS_IMETHOD DoubleString(PRUint32 *count, char **str); \
+ NS_IMETHOD DoubleString2(PRUint32 in_count, const char *in_str, PRUint32 *out_count, char **out_str); \
+ NS_IMETHOD DoubleString3(PRUint32 in_count, const char *in_str, PRUint32 *out_count, char **out_str); \
+ NS_IMETHOD DoubleString4(const char *in_str, PRUint32 *count, char **out_str); \
+ NS_IMETHOD UpString(PRUint32 count, char **str); \
+ NS_IMETHOD UpString2(PRUint32 count, const char *in_str, char **out_str); \
+ NS_IMETHOD CopyUTF8String(const nsACString & in_str, nsACString & out_str); \
+ NS_IMETHOD CopyUTF8String2(const nsACString & in_str, nsACString & out_str); \
+ NS_IMETHOD GetFixedString(PRUint32 count, char **out_str); \
+ NS_IMETHOD DoubleWideString(PRUint32 *count, PRUnichar **str); \
+ NS_IMETHOD DoubleWideString2(PRUint32 in_count, const PRUnichar *in_str, PRUint32 *out_count, PRUnichar **out_str); \
+ NS_IMETHOD DoubleWideString3(PRUint32 in_count, const PRUnichar *in_str, PRUint32 *out_count, PRUnichar **out_str); \
+ NS_IMETHOD DoubleWideString4(const PRUnichar *in_str, PRUint32 *count, PRUnichar **out_str); \
+ NS_IMETHOD UpWideString(PRUint32 count, PRUnichar **str); \
+ NS_IMETHOD UpWideString2(PRUint32 count, const PRUnichar *in_str, PRUnichar **out_str); \
+ NS_IMETHOD GetFixedWideString(PRUint32 count, char **out_str); \
+ NS_IMETHOD GetStrings(PRUint32 *count, char ***str); \
+ NS_IMETHOD UpOctetArray(PRUint32 *count, PRUint8 **data); \
+ NS_IMETHOD UpOctetArray2(PRUint32 *count, PRUint8 **data); \
+ NS_IMETHOD CheckInterfaceArray(PRUint32 count, nsISupports **data, PRBool *all_non_null); \
+ NS_IMETHOD CopyInterfaceArray(PRUint32 count, nsISupports **data, nsISupports ***out_data, PRUint32 *out_count); \
+ NS_IMETHOD GetInterfaceArray(PRUint32 *count, nsISupports ***data); \
+ NS_IMETHOD ExtendInterfaceArray(PRUint32 *count, nsISupports ***data); \
+ NS_IMETHOD CheckIIDArray(PRUint32 count, const nsIID & *data, PRBool *all_mine); \
+ NS_IMETHOD GetIIDArray(PRUint32 *count, nsIID & **data); \
+ NS_IMETHOD ExtendIIDArray(PRUint32 *count, nsIID & **data); \
+ NS_IMETHOD SumArrays(PRUint32 count, PRInt32 *array1, PRInt32 *array2, PRInt32 *result); \
+ NS_IMETHOD GetArrays(PRUint32 *count, PRInt32 **array1, PRInt32 **array2); \
+ NS_IMETHOD GetFixedArray(PRUint32 count, PRInt32 **array1); \
+ NS_IMETHOD CopyArray(PRUint32 count, PRInt32 *array1, PRInt32 **array2); \
+ NS_IMETHOD CopyAndDoubleArray(PRUint32 *count, PRInt32 *array1, PRInt32 **array2); \
+ NS_IMETHOD AppendArray(PRUint32 *count, PRInt32 *array1, PRInt32 **array2); \
+ NS_IMETHOD AppendVariant(nsIVariant *variant, nsIVariant **result); \
+ NS_IMETHOD CopyVariant(nsIVariant *variant, nsIVariant **_retval); \
+ NS_IMETHOD SumVariants(PRUint32 incount, nsIVariant **variants, nsIVariant **_retval);
+
+/* Use this macro to declare functions that forward the behavior of this interface to another object. */
+#define NS_FORWARD_NSIPYTHONTESTINTERFACEEXTRA(_to) \
+ NS_IMETHOD MultiplyEachItemInIntegerArray(PRInt32 val, PRUint32 count, PRInt32 **valueArray) { return _to MultiplyEachItemInIntegerArray(val, count, valueArray); } \
+ NS_IMETHOD MultiplyEachItemInIntegerArrayAndAppend(PRInt32 val, PRUint32 *count, PRInt32 **valueArray) { return _to MultiplyEachItemInIntegerArrayAndAppend(val, count, valueArray); } \
+ NS_IMETHOD CompareStringArrays(const char **arr1, const char **arr2, PRUint32 count, PRInt16 *result) { return _to CompareStringArrays(arr1, arr2, count, result); } \
+ NS_IMETHOD DoubleStringArray(PRUint32 *count, char ***valueArray) { return _to DoubleStringArray(count, valueArray); } \
+ NS_IMETHOD ReverseStringArray(PRUint32 count, char ***valueArray) { return _to ReverseStringArray(count, valueArray); } \
+ NS_IMETHOD DoubleString(PRUint32 *count, char **str) { return _to DoubleString(count, str); } \
+ NS_IMETHOD DoubleString2(PRUint32 in_count, const char *in_str, PRUint32 *out_count, char **out_str) { return _to DoubleString2(in_count, in_str, out_count, out_str); } \
+ NS_IMETHOD DoubleString3(PRUint32 in_count, const char *in_str, PRUint32 *out_count, char **out_str) { return _to DoubleString3(in_count, in_str, out_count, out_str); } \
+ NS_IMETHOD DoubleString4(const char *in_str, PRUint32 *count, char **out_str) { return _to DoubleString4(in_str, count, out_str); } \
+ NS_IMETHOD UpString(PRUint32 count, char **str) { return _to UpString(count, str); } \
+ NS_IMETHOD UpString2(PRUint32 count, const char *in_str, char **out_str) { return _to UpString2(count, in_str, out_str); } \
+ NS_IMETHOD CopyUTF8String(const nsACString & in_str, nsACString & out_str) { return _to CopyUTF8String(in_str, out_str); } \
+ NS_IMETHOD CopyUTF8String2(const nsACString & in_str, nsACString & out_str) { return _to CopyUTF8String2(in_str, out_str); } \
+ NS_IMETHOD GetFixedString(PRUint32 count, char **out_str) { return _to GetFixedString(count, out_str); } \
+ NS_IMETHOD DoubleWideString(PRUint32 *count, PRUnichar **str) { return _to DoubleWideString(count, str); } \
+ NS_IMETHOD DoubleWideString2(PRUint32 in_count, const PRUnichar *in_str, PRUint32 *out_count, PRUnichar **out_str) { return _to DoubleWideString2(in_count, in_str, out_count, out_str); } \
+ NS_IMETHOD DoubleWideString3(PRUint32 in_count, const PRUnichar *in_str, PRUint32 *out_count, PRUnichar **out_str) { return _to DoubleWideString3(in_count, in_str, out_count, out_str); } \
+ NS_IMETHOD DoubleWideString4(const PRUnichar *in_str, PRUint32 *count, PRUnichar **out_str) { return _to DoubleWideString4(in_str, count, out_str); } \
+ NS_IMETHOD UpWideString(PRUint32 count, PRUnichar **str) { return _to UpWideString(count, str); } \
+ NS_IMETHOD UpWideString2(PRUint32 count, const PRUnichar *in_str, PRUnichar **out_str) { return _to UpWideString2(count, in_str, out_str); } \
+ NS_IMETHOD GetFixedWideString(PRUint32 count, char **out_str) { return _to GetFixedWideString(count, out_str); } \
+ NS_IMETHOD GetStrings(PRUint32 *count, char ***str) { return _to GetStrings(count, str); } \
+ NS_IMETHOD UpOctetArray(PRUint32 *count, PRUint8 **data) { return _to UpOctetArray(count, data); } \
+ NS_IMETHOD UpOctetArray2(PRUint32 *count, PRUint8 **data) { return _to UpOctetArray2(count, data); } \
+ NS_IMETHOD CheckInterfaceArray(PRUint32 count, nsISupports **data, PRBool *all_non_null) { return _to CheckInterfaceArray(count, data, all_non_null); } \
+ NS_IMETHOD CopyInterfaceArray(PRUint32 count, nsISupports **data, nsISupports ***out_data, PRUint32 *out_count) { return _to CopyInterfaceArray(count, data, out_data, out_count); } \
+ NS_IMETHOD GetInterfaceArray(PRUint32 *count, nsISupports ***data) { return _to GetInterfaceArray(count, data); } \
+ NS_IMETHOD ExtendInterfaceArray(PRUint32 *count, nsISupports ***data) { return _to ExtendInterfaceArray(count, data); } \
+ NS_IMETHOD CheckIIDArray(PRUint32 count, const nsIID & *data, PRBool *all_mine) { return _to CheckIIDArray(count, data, all_mine); } \
+ NS_IMETHOD GetIIDArray(PRUint32 *count, nsIID & **data) { return _to GetIIDArray(count, data); } \
+ NS_IMETHOD ExtendIIDArray(PRUint32 *count, nsIID & **data) { return _to ExtendIIDArray(count, data); } \
+ NS_IMETHOD SumArrays(PRUint32 count, PRInt32 *array1, PRInt32 *array2, PRInt32 *result) { return _to SumArrays(count, array1, array2, result); } \
+ NS_IMETHOD GetArrays(PRUint32 *count, PRInt32 **array1, PRInt32 **array2) { return _to GetArrays(count, array1, array2); } \
+ NS_IMETHOD GetFixedArray(PRUint32 count, PRInt32 **array1) { return _to GetFixedArray(count, array1); } \
+ NS_IMETHOD CopyArray(PRUint32 count, PRInt32 *array1, PRInt32 **array2) { return _to CopyArray(count, array1, array2); } \
+ NS_IMETHOD CopyAndDoubleArray(PRUint32 *count, PRInt32 *array1, PRInt32 **array2) { return _to CopyAndDoubleArray(count, array1, array2); } \
+ NS_IMETHOD AppendArray(PRUint32 *count, PRInt32 *array1, PRInt32 **array2) { return _to AppendArray(count, array1, array2); } \
+ NS_IMETHOD AppendVariant(nsIVariant *variant, nsIVariant **result) { return _to AppendVariant(variant, result); } \
+ NS_IMETHOD CopyVariant(nsIVariant *variant, nsIVariant **_retval) { return _to CopyVariant(variant, _retval); } \
+ NS_IMETHOD SumVariants(PRUint32 incount, nsIVariant **variants, nsIVariant **_retval) { return _to SumVariants(incount, variants, _retval); }
+
+/* Use this macro to declare functions that forward the behavior of this interface to another object in a safe way. */
+#define NS_FORWARD_SAFE_NSIPYTHONTESTINTERFACEEXTRA(_to) \
+ NS_IMETHOD MultiplyEachItemInIntegerArray(PRInt32 val, PRUint32 count, PRInt32 **valueArray) { return !_to ? NS_ERROR_NULL_POINTER : _to->MultiplyEachItemInIntegerArray(val, count, valueArray); } \
+ NS_IMETHOD MultiplyEachItemInIntegerArrayAndAppend(PRInt32 val, PRUint32 *count, PRInt32 **valueArray) { return !_to ? NS_ERROR_NULL_POINTER : _to->MultiplyEachItemInIntegerArrayAndAppend(val, count, valueArray); } \
+ NS_IMETHOD CompareStringArrays(const char **arr1, const char **arr2, PRUint32 count, PRInt16 *result) { return !_to ? NS_ERROR_NULL_POINTER : _to->CompareStringArrays(arr1, arr2, count, result); } \
+ NS_IMETHOD DoubleStringArray(PRUint32 *count, char ***valueArray) { return !_to ? NS_ERROR_NULL_POINTER : _to->DoubleStringArray(count, valueArray); } \
+ NS_IMETHOD ReverseStringArray(PRUint32 count, char ***valueArray) { return !_to ? NS_ERROR_NULL_POINTER : _to->ReverseStringArray(count, valueArray); } \
+ NS_IMETHOD DoubleString(PRUint32 *count, char **str) { return !_to ? NS_ERROR_NULL_POINTER : _to->DoubleString(count, str); } \
+ NS_IMETHOD DoubleString2(PRUint32 in_count, const char *in_str, PRUint32 *out_count, char **out_str) { return !_to ? NS_ERROR_NULL_POINTER : _to->DoubleString2(in_count, in_str, out_count, out_str); } \
+ NS_IMETHOD DoubleString3(PRUint32 in_count, const char *in_str, PRUint32 *out_count, char **out_str) { return !_to ? NS_ERROR_NULL_POINTER : _to->DoubleString3(in_count, in_str, out_count, out_str); } \
+ NS_IMETHOD DoubleString4(const char *in_str, PRUint32 *count, char **out_str) { return !_to ? NS_ERROR_NULL_POINTER : _to->DoubleString4(in_str, count, out_str); } \
+ NS_IMETHOD UpString(PRUint32 count, char **str) { return !_to ? NS_ERROR_NULL_POINTER : _to->UpString(count, str); } \
+ NS_IMETHOD UpString2(PRUint32 count, const char *in_str, char **out_str) { return !_to ? NS_ERROR_NULL_POINTER : _to->UpString2(count, in_str, out_str); } \
+ NS_IMETHOD CopyUTF8String(const nsACString & in_str, nsACString & out_str) { return !_to ? NS_ERROR_NULL_POINTER : _to->CopyUTF8String(in_str, out_str); } \
+ NS_IMETHOD CopyUTF8String2(const nsACString & in_str, nsACString & out_str) { return !_to ? NS_ERROR_NULL_POINTER : _to->CopyUTF8String2(in_str, out_str); } \
+ NS_IMETHOD GetFixedString(PRUint32 count, char **out_str) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetFixedString(count, out_str); } \
+ NS_IMETHOD DoubleWideString(PRUint32 *count, PRUnichar **str) { return !_to ? NS_ERROR_NULL_POINTER : _to->DoubleWideString(count, str); } \
+ NS_IMETHOD DoubleWideString2(PRUint32 in_count, const PRUnichar *in_str, PRUint32 *out_count, PRUnichar **out_str) { return !_to ? NS_ERROR_NULL_POINTER : _to->DoubleWideString2(in_count, in_str, out_count, out_str); } \
+ NS_IMETHOD DoubleWideString3(PRUint32 in_count, const PRUnichar *in_str, PRUint32 *out_count, PRUnichar **out_str) { return !_to ? NS_ERROR_NULL_POINTER : _to->DoubleWideString3(in_count, in_str, out_count, out_str); } \
+ NS_IMETHOD DoubleWideString4(const PRUnichar *in_str, PRUint32 *count, PRUnichar **out_str) { return !_to ? NS_ERROR_NULL_POINTER : _to->DoubleWideString4(in_str, count, out_str); } \
+ NS_IMETHOD UpWideString(PRUint32 count, PRUnichar **str) { return !_to ? NS_ERROR_NULL_POINTER : _to->UpWideString(count, str); } \
+ NS_IMETHOD UpWideString2(PRUint32 count, const PRUnichar *in_str, PRUnichar **out_str) { return !_to ? NS_ERROR_NULL_POINTER : _to->UpWideString2(count, in_str, out_str); } \
+ NS_IMETHOD GetFixedWideString(PRUint32 count, char **out_str) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetFixedWideString(count, out_str); } \
+ NS_IMETHOD GetStrings(PRUint32 *count, char ***str) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetStrings(count, str); } \
+ NS_IMETHOD UpOctetArray(PRUint32 *count, PRUint8 **data) { return !_to ? NS_ERROR_NULL_POINTER : _to->UpOctetArray(count, data); } \
+ NS_IMETHOD UpOctetArray2(PRUint32 *count, PRUint8 **data) { return !_to ? NS_ERROR_NULL_POINTER : _to->UpOctetArray2(count, data); } \
+ NS_IMETHOD CheckInterfaceArray(PRUint32 count, nsISupports **data, PRBool *all_non_null) { return !_to ? NS_ERROR_NULL_POINTER : _to->CheckInterfaceArray(count, data, all_non_null); } \
+ NS_IMETHOD CopyInterfaceArray(PRUint32 count, nsISupports **data, nsISupports ***out_data, PRUint32 *out_count) { return !_to ? NS_ERROR_NULL_POINTER : _to->CopyInterfaceArray(count, data, out_data, out_count); } \
+ NS_IMETHOD GetInterfaceArray(PRUint32 *count, nsISupports ***data) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetInterfaceArray(count, data); } \
+ NS_IMETHOD ExtendInterfaceArray(PRUint32 *count, nsISupports ***data) { return !_to ? NS_ERROR_NULL_POINTER : _to->ExtendInterfaceArray(count, data); } \
+ NS_IMETHOD CheckIIDArray(PRUint32 count, const nsIID & *data, PRBool *all_mine) { return !_to ? NS_ERROR_NULL_POINTER : _to->CheckIIDArray(count, data, all_mine); } \
+ NS_IMETHOD GetIIDArray(PRUint32 *count, nsIID & **data) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetIIDArray(count, data); } \
+ NS_IMETHOD ExtendIIDArray(PRUint32 *count, nsIID & **data) { return !_to ? NS_ERROR_NULL_POINTER : _to->ExtendIIDArray(count, data); } \
+ NS_IMETHOD SumArrays(PRUint32 count, PRInt32 *array1, PRInt32 *array2, PRInt32 *result) { return !_to ? NS_ERROR_NULL_POINTER : _to->SumArrays(count, array1, array2, result); } \
+ NS_IMETHOD GetArrays(PRUint32 *count, PRInt32 **array1, PRInt32 **array2) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetArrays(count, array1, array2); } \
+ NS_IMETHOD GetFixedArray(PRUint32 count, PRInt32 **array1) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetFixedArray(count, array1); } \
+ NS_IMETHOD CopyArray(PRUint32 count, PRInt32 *array1, PRInt32 **array2) { return !_to ? NS_ERROR_NULL_POINTER : _to->CopyArray(count, array1, array2); } \
+ NS_IMETHOD CopyAndDoubleArray(PRUint32 *count, PRInt32 *array1, PRInt32 **array2) { return !_to ? NS_ERROR_NULL_POINTER : _to->CopyAndDoubleArray(count, array1, array2); } \
+ NS_IMETHOD AppendArray(PRUint32 *count, PRInt32 *array1, PRInt32 **array2) { return !_to ? NS_ERROR_NULL_POINTER : _to->AppendArray(count, array1, array2); } \
+ NS_IMETHOD AppendVariant(nsIVariant *variant, nsIVariant **result) { return !_to ? NS_ERROR_NULL_POINTER : _to->AppendVariant(variant, result); } \
+ NS_IMETHOD CopyVariant(nsIVariant *variant, nsIVariant **_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->CopyVariant(variant, _retval); } \
+ NS_IMETHOD SumVariants(PRUint32 incount, nsIVariant **variants, nsIVariant **_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->SumVariants(incount, variants, _retval); }
+
+#if 0
+/* Use the code below as a template for the implementation class for this interface. */
+
+/* Header file */
+class nsPythonTestInterfaceExtra : public nsIPythonTestInterfaceExtra
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPYTHONTESTINTERFACEEXTRA
+
+ nsPythonTestInterfaceExtra();
+
+private:
+ ~nsPythonTestInterfaceExtra();
+
+protected:
+ /* additional members */
+};
+
+/* Implementation file */
+NS_IMPL_ISUPPORTS1(nsPythonTestInterfaceExtra, nsIPythonTestInterfaceExtra)
+
+nsPythonTestInterfaceExtra::nsPythonTestInterfaceExtra()
+{
+ /* member initializers and constructor code */
+}
+
+nsPythonTestInterfaceExtra::~nsPythonTestInterfaceExtra()
+{
+ /* destructor code */
+}
+
+/* void MultiplyEachItemInIntegerArray (in PRInt32 val, in PRUint32 count, [array, size_is (count)] inout PRInt32 valueArray); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::MultiplyEachItemInIntegerArray(PRInt32 val, PRUint32 count, PRInt32 **valueArray)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void MultiplyEachItemInIntegerArrayAndAppend (in PRInt32 val, inout PRUint32 count, [array, size_is (count)] inout PRInt32 valueArray); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::MultiplyEachItemInIntegerArrayAndAppend(PRInt32 val, PRUint32 *count, PRInt32 **valueArray)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void CompareStringArrays ([array, size_is (count)] in string arr1, [array, size_is (count)] in string arr2, in unsigned long count, [retval] out short result); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::CompareStringArrays(const char **arr1, const char **arr2, PRUint32 count, PRInt16 *result)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void DoubleStringArray (inout PRUint32 count, [array, size_is (count)] inout string valueArray); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::DoubleStringArray(PRUint32 *count, char ***valueArray)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void ReverseStringArray (in PRUint32 count, [array, size_is (count)] inout string valueArray); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::ReverseStringArray(PRUint32 count, char ***valueArray)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void DoubleString (inout PRUint32 count, [size_is (count)] inout string str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::DoubleString(PRUint32 *count, char **str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void DoubleString2 (in PRUint32 in_count, [size_is (in_count)] in string in_str, out PRUint32 out_count, [size_is (out_count)] out string out_str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::DoubleString2(PRUint32 in_count, const char *in_str, PRUint32 *out_count, char **out_str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void DoubleString3 (in PRUint32 in_count, [size_is (in_count)] in string in_str, out PRUint32 out_count, [size_is (out_count), retval] out string out_str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::DoubleString3(PRUint32 in_count, const char *in_str, PRUint32 *out_count, char **out_str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void DoubleString4 ([size_is (count)] in string in_str, inout PRUint32 count, [size_is (count)] out string out_str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::DoubleString4(const char *in_str, PRUint32 *count, char **out_str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void UpString (in PRUint32 count, [size_is (count)] inout string str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::UpString(PRUint32 count, char **str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void UpString2 (in PRUint32 count, [size_is (count)] in string in_str, [size_is (count)] out string out_str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::UpString2(PRUint32 count, const char *in_str, char **out_str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void CopyUTF8String (in AUTF8String in_str, out AUTF8String out_str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::CopyUTF8String(const nsACString & in_str, nsACString & out_str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void CopyUTF8String2 (in AUTF8String in_str, out AUTF8String out_str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::CopyUTF8String2(const nsACString & in_str, nsACString & out_str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void GetFixedString (in PRUint32 count, [size_is (count)] out string out_str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::GetFixedString(PRUint32 count, char **out_str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void DoubleWideString (inout PRUint32 count, [size_is (count)] inout wstring str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::DoubleWideString(PRUint32 *count, PRUnichar **str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void DoubleWideString2 (in PRUint32 in_count, [size_is (in_count)] in wstring in_str, out PRUint32 out_count, [size_is (out_count)] out wstring out_str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::DoubleWideString2(PRUint32 in_count, const PRUnichar *in_str, PRUint32 *out_count, PRUnichar **out_str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void DoubleWideString3 (in PRUint32 in_count, [size_is (in_count)] in wstring in_str, out PRUint32 out_count, [size_is (out_count), retval] out wstring out_str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::DoubleWideString3(PRUint32 in_count, const PRUnichar *in_str, PRUint32 *out_count, PRUnichar **out_str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void DoubleWideString4 ([size_is (count)] in wstring in_str, inout PRUint32 count, [size_is (count)] out wstring out_str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::DoubleWideString4(const PRUnichar *in_str, PRUint32 *count, PRUnichar **out_str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void UpWideString (in PRUint32 count, [size_is (count)] inout wstring str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::UpWideString(PRUint32 count, PRUnichar **str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void UpWideString2 (in PRUint32 count, [size_is (count)] in wstring in_str, [size_is (count)] out wstring out_str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::UpWideString2(PRUint32 count, const PRUnichar *in_str, PRUnichar **out_str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void GetFixedWideString (in PRUint32 count, [size_is (count)] out string out_str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::GetFixedWideString(PRUint32 count, char **out_str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void GetStrings (out PRUint32 count, [array, size_is (count), retval] out string str); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::GetStrings(PRUint32 *count, char ***str)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void UpOctetArray (inout PRUint32 count, [array, size_is (count)] inout PRUint8 data); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::UpOctetArray(PRUint32 *count, PRUint8 **data)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void UpOctetArray2 (inout PRUint32 count, [array, size_is (count)] inout PRUint8 data); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::UpOctetArray2(PRUint32 *count, PRUint8 **data)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void CheckInterfaceArray (in PRUint32 count, [array, size_is (count)] in nsISupports data, [retval] out PRBool all_non_null); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::CheckInterfaceArray(PRUint32 count, nsISupports **data, PRBool *all_non_null)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void CopyInterfaceArray (in PRUint32 count, [array, size_is (count)] in nsISupports data, [array, size_is (out_count)] out nsISupports out_data, out PRUint32 out_count); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::CopyInterfaceArray(PRUint32 count, nsISupports **data, nsISupports ***out_data, PRUint32 *out_count)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void GetInterfaceArray (out PRUint32 count, [array, size_is (count)] out nsISupports data); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::GetInterfaceArray(PRUint32 *count, nsISupports ***data)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void ExtendInterfaceArray (inout PRUint32 count, [array, size_is (count)] inout nsISupports data); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::ExtendInterfaceArray(PRUint32 *count, nsISupports ***data)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void CheckIIDArray (in PRUint32 count, [array, size_is (count)] in nsIIDRef data, [retval] out PRBool all_mine); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::CheckIIDArray(PRUint32 count, const nsIID & *data, PRBool *all_mine)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void GetIIDArray (out PRUint32 count, [array, size_is (count)] out nsIIDRef data); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::GetIIDArray(PRUint32 *count, nsIID & **data)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void ExtendIIDArray (inout PRUint32 count, [array, size_is (count)] inout nsIIDRef data); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::ExtendIIDArray(PRUint32 *count, nsIID & **data)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void SumArrays (in PRUint32 count, [array, size_is (count)] in PRInt32 array1, [array, size_is (count)] in PRInt32 array2, [retval] out PRInt32 result); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::SumArrays(PRUint32 count, PRInt32 *array1, PRInt32 *array2, PRInt32 *result)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void GetArrays (out PRUint32 count, [array, size_is (count)] out PRInt32 array1, [array, size_is (count)] out PRInt32 array2); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::GetArrays(PRUint32 *count, PRInt32 **array1, PRInt32 **array2)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void GetFixedArray (in PRUint32 count, [array, size_is (count)] out PRInt32 array1); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::GetFixedArray(PRUint32 count, PRInt32 **array1)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void CopyArray (in PRUint32 count, [array, size_is (count)] in PRInt32 array1, [array, size_is (count)] out PRInt32 array2); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::CopyArray(PRUint32 count, PRInt32 *array1, PRInt32 **array2)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void CopyAndDoubleArray (inout PRUint32 count, [array, size_is (count)] in PRInt32 array1, [array, size_is (count)] out PRInt32 array2); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::CopyAndDoubleArray(PRUint32 *count, PRInt32 *array1, PRInt32 **array2)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void AppendArray (inout PRUint32 count, [array, size_is (count)] in PRInt32 array1, [array, size_is (count)] inout PRInt32 array2); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::AppendArray(PRUint32 *count, PRInt32 *array1, PRInt32 **array2)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void AppendVariant (in nsIVariant variant, inout nsIVariant result); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::AppendVariant(nsIVariant *variant, nsIVariant **result)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* nsIVariant CopyVariant (in nsIVariant variant); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::CopyVariant(nsIVariant *variant, nsIVariant **_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* nsIVariant SumVariants (in PRUint32 incount, [array, size_is (incount)] in nsIVariant variants); */
+NS_IMETHODIMP nsPythonTestInterfaceExtra::SumVariants(PRUint32 incount, nsIVariant **variants, nsIVariant **_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* End of implementation class template. */
+#endif
+
+
+/* starting interface: nsIPythonTestInterfaceDOMStrings */
+#define NS_IPYTHONTESTINTERFACEDOMSTRINGS_IID_STR "657ae651-a973-4818-8c06-f4b948b3d758"
+
+#define NS_IPYTHONTESTINTERFACEDOMSTRINGS_IID \
+ {0x657ae651, 0xa973, 0x4818, \
+ { 0x8c, 0x06, 0xf4, 0xb9, 0x48, 0xb3, 0xd7, 0x58 }}
+
+class NS_NO_VTABLE nsIPythonTestInterfaceDOMStrings : public nsIPythonTestInterfaceExtra {
+ public:
+
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IPYTHONTESTINTERFACEDOMSTRINGS_IID)
+
+ /* DOMString GetDOMStringResult (in PRInt32 length); */
+ NS_IMETHOD GetDOMStringResult(PRInt32 length, nsAString & _retval) = 0;
+
+ /* void GetDOMStringOut (in PRInt32 length, [retval] out DOMString s); */
+ NS_IMETHOD GetDOMStringOut(PRInt32 length, nsAString & s) = 0;
+
+ /* PRUint32 GetDOMStringLength (in DOMString s); */
+ NS_IMETHOD GetDOMStringLength(const nsAString & s, PRUint32 *_retval) = 0;
+
+ /* PRUint32 GetDOMStringRefLength (in DOMStringRef s); */
+ NS_IMETHOD GetDOMStringRefLength(const nsAString & s, PRUint32 *_retval) = 0;
+
+ /* PRUint32 GetDOMStringPtrLength (in DOMStringPtr s); */
+ NS_IMETHOD GetDOMStringPtrLength(const nsAString * s, PRUint32 *_retval) = 0;
+
+ /* void ConcatDOMStrings (in DOMString s1, in DOMString s2, out DOMString ret); */
+ NS_IMETHOD ConcatDOMStrings(const nsAString & s1, const nsAString & s2, nsAString & ret) = 0;
+
+ /* attribute DOMString domstring_value; */
+ NS_IMETHOD GetDomstring_value(nsAString & aDomstring_value) = 0;
+ NS_IMETHOD SetDomstring_value(const nsAString & aDomstring_value) = 0;
+
+ /* readonly attribute DOMString domstring_value_ro; */
+ NS_IMETHOD GetDomstring_value_ro(nsAString & aDomstring_value_ro) = 0;
+
+};
+
+/* Use this macro when declaring classes that implement this interface. */
+#define NS_DECL_NSIPYTHONTESTINTERFACEDOMSTRINGS \
+ NS_IMETHOD GetDOMStringResult(PRInt32 length, nsAString & _retval); \
+ NS_IMETHOD GetDOMStringOut(PRInt32 length, nsAString & s); \
+ NS_IMETHOD GetDOMStringLength(const nsAString & s, PRUint32 *_retval); \
+ NS_IMETHOD GetDOMStringRefLength(const nsAString & s, PRUint32 *_retval); \
+ NS_IMETHOD GetDOMStringPtrLength(const nsAString * s, PRUint32 *_retval); \
+ NS_IMETHOD ConcatDOMStrings(const nsAString & s1, const nsAString & s2, nsAString & ret); \
+ NS_IMETHOD GetDomstring_value(nsAString & aDomstring_value); \
+ NS_IMETHOD SetDomstring_value(const nsAString & aDomstring_value); \
+ NS_IMETHOD GetDomstring_value_ro(nsAString & aDomstring_value_ro);
+
+/* Use this macro to declare functions that forward the behavior of this interface to another object. */
+#define NS_FORWARD_NSIPYTHONTESTINTERFACEDOMSTRINGS(_to) \
+ NS_IMETHOD GetDOMStringResult(PRInt32 length, nsAString & _retval) { return _to GetDOMStringResult(length, _retval); } \
+ NS_IMETHOD GetDOMStringOut(PRInt32 length, nsAString & s) { return _to GetDOMStringOut(length, s); } \
+ NS_IMETHOD GetDOMStringLength(const nsAString & s, PRUint32 *_retval) { return _to GetDOMStringLength(s, _retval); } \
+ NS_IMETHOD GetDOMStringRefLength(const nsAString & s, PRUint32 *_retval) { return _to GetDOMStringRefLength(s, _retval); } \
+ NS_IMETHOD GetDOMStringPtrLength(const nsAString * s, PRUint32 *_retval) { return _to GetDOMStringPtrLength(s, _retval); } \
+ NS_IMETHOD ConcatDOMStrings(const nsAString & s1, const nsAString & s2, nsAString & ret) { return _to ConcatDOMStrings(s1, s2, ret); } \
+ NS_IMETHOD GetDomstring_value(nsAString & aDomstring_value) { return _to GetDomstring_value(aDomstring_value); } \
+ NS_IMETHOD SetDomstring_value(const nsAString & aDomstring_value) { return _to SetDomstring_value(aDomstring_value); } \
+ NS_IMETHOD GetDomstring_value_ro(nsAString & aDomstring_value_ro) { return _to GetDomstring_value_ro(aDomstring_value_ro); }
+
+/* Use this macro to declare functions that forward the behavior of this interface to another object in a safe way. */
+#define NS_FORWARD_SAFE_NSIPYTHONTESTINTERFACEDOMSTRINGS(_to) \
+ NS_IMETHOD GetDOMStringResult(PRInt32 length, nsAString & _retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetDOMStringResult(length, _retval); } \
+ NS_IMETHOD GetDOMStringOut(PRInt32 length, nsAString & s) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetDOMStringOut(length, s); } \
+ NS_IMETHOD GetDOMStringLength(const nsAString & s, PRUint32 *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetDOMStringLength(s, _retval); } \
+ NS_IMETHOD GetDOMStringRefLength(const nsAString & s, PRUint32 *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetDOMStringRefLength(s, _retval); } \
+ NS_IMETHOD GetDOMStringPtrLength(const nsAString * s, PRUint32 *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetDOMStringPtrLength(s, _retval); } \
+ NS_IMETHOD ConcatDOMStrings(const nsAString & s1, const nsAString & s2, nsAString & ret) { return !_to ? NS_ERROR_NULL_POINTER : _to->ConcatDOMStrings(s1, s2, ret); } \
+ NS_IMETHOD GetDomstring_value(nsAString & aDomstring_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetDomstring_value(aDomstring_value); } \
+ NS_IMETHOD SetDomstring_value(const nsAString & aDomstring_value) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetDomstring_value(aDomstring_value); } \
+ NS_IMETHOD GetDomstring_value_ro(nsAString & aDomstring_value_ro) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetDomstring_value_ro(aDomstring_value_ro); }
+
+#if 0
+/* Use the code below as a template for the implementation class for this interface. */
+
+/* Header file */
+class nsPythonTestInterfaceDOMStrings : public nsIPythonTestInterfaceDOMStrings
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPYTHONTESTINTERFACEDOMSTRINGS
+
+ nsPythonTestInterfaceDOMStrings();
+
+private:
+ ~nsPythonTestInterfaceDOMStrings();
+
+protected:
+ /* additional members */
+};
+
+/* Implementation file */
+NS_IMPL_ISUPPORTS1(nsPythonTestInterfaceDOMStrings, nsIPythonTestInterfaceDOMStrings)
+
+nsPythonTestInterfaceDOMStrings::nsPythonTestInterfaceDOMStrings()
+{
+ /* member initializers and constructor code */
+}
+
+nsPythonTestInterfaceDOMStrings::~nsPythonTestInterfaceDOMStrings()
+{
+ /* destructor code */
+}
+
+/* DOMString GetDOMStringResult (in PRInt32 length); */
+NS_IMETHODIMP nsPythonTestInterfaceDOMStrings::GetDOMStringResult(PRInt32 length, nsAString & _retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void GetDOMStringOut (in PRInt32 length, [retval] out DOMString s); */
+NS_IMETHODIMP nsPythonTestInterfaceDOMStrings::GetDOMStringOut(PRInt32 length, nsAString & s)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* PRUint32 GetDOMStringLength (in DOMString s); */
+NS_IMETHODIMP nsPythonTestInterfaceDOMStrings::GetDOMStringLength(const nsAString & s, PRUint32 *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* PRUint32 GetDOMStringRefLength (in DOMStringRef s); */
+NS_IMETHODIMP nsPythonTestInterfaceDOMStrings::GetDOMStringRefLength(const nsAString & s, PRUint32 *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* PRUint32 GetDOMStringPtrLength (in DOMStringPtr s); */
+NS_IMETHODIMP nsPythonTestInterfaceDOMStrings::GetDOMStringPtrLength(const nsAString * s, PRUint32 *_retval)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* void ConcatDOMStrings (in DOMString s1, in DOMString s2, out DOMString ret); */
+NS_IMETHODIMP nsPythonTestInterfaceDOMStrings::ConcatDOMStrings(const nsAString & s1, const nsAString & s2, nsAString & ret)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* attribute DOMString domstring_value; */
+NS_IMETHODIMP nsPythonTestInterfaceDOMStrings::GetDomstring_value(nsAString & aDomstring_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+NS_IMETHODIMP nsPythonTestInterfaceDOMStrings::SetDomstring_value(const nsAString & aDomstring_value)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* readonly attribute DOMString domstring_value_ro; */
+NS_IMETHODIMP nsPythonTestInterfaceDOMStrings::GetDomstring_value_ro(nsAString & aDomstring_value_ro)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* End of implementation class template. */
+#endif
+
+
+#endif /* __gen_py_test_component_h__ */
diff --git a/src/libs/xpcom18a4/python/test/test_component/py_test_component.html b/src/libs/xpcom18a4/python/test/test_component/py_test_component.html
new file mode 100644
index 00000000..1e17d24c
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_component/py_test_component.html
@@ -0,0 +1,182 @@
+<!-- ***** 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 PyXPCOM.
+ -
+ - The Initial Developer of the Original Code is
+ - ActiveState Tool Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2000-2001
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - 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 LGPL or the GPL. 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 ***** -->
+
+<center><b><font size=+2>Python Component Sample</font></b>
+
+<p>
+<br>
+Last modified
+<script>
+document.write(document.lastModified);
+</script>
+</center>
+
+<p>XPConnect allows JavaScript
+to transparantly access and manipulate XPCOM objects;
+
+<p>Big Deal, I hear you say! But it also works for Python!!!
+
+<p>
+This sample demonstrates accessing a XPCOM object through XPConnect.
+The JavaScript executed when this page loads creates an instance
+of the Python object by
+using the <tt>Components</tt> object, then accesses it through
+the <a href="py_test_component.idl">nsISample</a> interface by calling <tt>QueryInterface</tt>:
+<br>
+<pre>
+netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+var sample = Components.classes["component://mozilla/sample/sample-world"].createInstance();
+sample = sample.QueryInterface(Components.interfaces.nsISample);
+</pre>
+
+<p>
+The buttons on the form are connected to JavaScript event handlers which
+call the methods defined in Python
+
+
+<p><b><a name="Compiling">Compiling the idl</b>
+
+<p>The XPIDL compiler (xpidl on Unix, xpidl.exe on Windows, and a CodeWarrior plugin on Mac)
+is compiled at build time (except on Mac) thus
+you will have to build mozilla in order to test this out. If you
+have already built mozilla then the compiler will be located at <tt>mozilla\dist\WIN32_D.OBJ\bin\xpidl.exe</tt>.
+
+<p>Once you have the XPIDL compiler enter the following command at your
+prompt:
+<br><tt>D:\whereever\xpcom\test\test_component>d:\mozilla\dist\WIN32_D.OBJ\bin\xpidl -I
+d:\mozilla\dist\idl -m typelib py_test_component.idl</tt>. You must then copy the generated .xpt file
+to the mozilla component directory.
+
+<p>The <tt>-I d:\mozilla\dist\idl</tt> points the compiler to the folder
+containing the other idl files, needed because nsISample.idl inherits from
+nsISupports.idl. The <tt>-m typelib</tt> instruction tells the compiler
+to build the .XPT typelib file.</tt>.
+
+<p>
+For more information on compilation see the <a href="http://www.mozilla.org/scriptable/xpidl/">xpidl
+compiler page</a>.
+
+<p><b>Running the sample</b>
+<p><b>NOTE: This doesnt work for me - I get an access denied error using XPConnect!</b>
+<p>Using Mozilla, load this file. Pay attention
+to the console when clicking "write".
+
+<!-- XXX keep in sync with stuff in pre tag below -->
+<script>
+netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+var sample = Components.classes["Python.TestComponent"].createInstance();
+sample = sample.QueryInterface(Components.interfaces.nsIPythonTestInterface);
+dump("sample = " + sample + "\n");
+
+function get()
+{
+ var field = document.getElementById('Value');
+ field.value = sample.str_value;
+}
+
+function set()
+{
+ var field = document.getElementById('Value');
+ sample.str_value = field.value;
+}
+
+function poke()
+{
+ var field = document.getElementById('Value');
+ sample.poke(field.value);
+}
+
+function write()
+{
+ sample.writeValue("here is what I'm writing: ");
+}
+</script>
+
+<p>
+<form name="form">
+<input type="button" value="Get" onclick="get();">
+<input type="button" value="Set" onclick="set();">
+<input type="button" value="Poke" onclick="poke();">
+<input type="text" id="Value">
+<input type="button" value="Write" onclick="write();">
+<form>
+
+<hr>
+
+<p>
+JavaScript and form source:
+
+<!-- XXX keep in sync with actual script -->
+<pre>
+&lt;script&gt;
+netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+var sample = Components.classes["component://Python.TestComponent"].createInstance();
+sample = sample.QueryInterface(Components.interfaces.nsIPythonTestInterface);
+dump("sample = " + sample + "\n");
+
+function get()
+{
+ var field = document.getElementById('Value');
+ field.value = sample.str_value;
+}
+
+function set()
+{
+ var field = document.getElementById('Value');
+ sample.str_value = field.value;
+}
+
+function poke()
+{
+ var field = document.getElementById('Value');
+ sample.poke(field.value);
+}
+
+function write()
+{
+ sample.writeValue("here is what I'm writing: ");
+}
+&lt;/script&gt;
+
+&lt;form name=&quot;form&quot;&gt;
+&lt;input type=&quot;button&quot; value=&quot;Get&quot; onclick=&quot;get();&quot;&gt;
+&lt;input type=&quot;button&quot; value=&quot;Set&quot; onclick=&quot;set();&quot;&gt;
+&lt;input type=&quot;button&quot; value=&quot;Poke&quot; onclick=&quot;poke();&quot;&gt;
+&lt;input type=&quot;text&quot; id=&quot;Value&quot;&gt;
+&lt;input type=&quot;button&quot; value=&quot;Write&quot; onclick=&quot;write();&quot;&gt;
+&lt;form>
+
+</pre>
diff --git a/src/libs/xpcom18a4/python/test/test_component/py_test_component.idl b/src/libs/xpcom18a4/python/test/test_component/py_test_component.idl
new file mode 100644
index 00000000..cd3e1c45
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_component/py_test_component.idl
@@ -0,0 +1,231 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <MarkH@ActiveState.com> (original author)
+ *
+ * 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 ***** */
+
+// NOTE: This is a TEST interface, not a DEMO interface :-)
+// We try to get as many data-types etc exposed, meaning this
+// doesnt really make a good demo of a "simple component"
+#include "nsISupports.idl"
+#include "nsIVariant.idl"
+
+[scriptable, uuid(1ECAED4F-E4D5-4ee7-ABF0-7D72AE1441D7)]
+interface nsIPythonTestInterface : nsISupports
+{
+ // Some constants for us to test - one for every type supported by xpidl
+ const short One = 1;
+ const long Two = 2;
+ const long MinusOne = -1;
+ const long BigLong = 0x7FFFFFFF;
+ const long BiggerLong = 0xFFFFFFFF;
+ const unsigned long BigULong = 0xFFFFFFFF;
+
+ // Declare every type supported as an attribute.
+ attribute boolean boolean_value; // PRBool
+ attribute octet octet_value; // PRUint8
+ attribute short short_value; // PRInt16
+ attribute unsigned short ushort_value; // PRUint16
+ attribute long long_value; // PRInt32
+ attribute unsigned long ulong_value; // PRUint32
+ attribute long long long_long_value; // PRInt64
+ attribute unsigned long long ulong_long_value; // PRUint64
+ attribute float float_value; // float
+ attribute double double_value; // double
+ attribute char char_value; // char
+ attribute wchar wchar_value; // PRUnichar
+ attribute string string_value; // char *
+ attribute wstring wstring_value; // PRUnichar*
+ attribute AString astring_value; // nsAString &
+ attribute ACString acstring_value; // nsACString &
+ attribute AUTF8String utf8string_value; // nsAUTF8String &
+ attribute nsIIDRef iid_value; // an IID
+ attribute nsIPythonTestInterface interface_value; // A specific interface
+ attribute nsISupports isupports_value; // A generic interface
+
+ // Declare every type supported as a method with an "in", "in/out" and "out" params
+ boolean do_boolean(in boolean p1, inout boolean p2, out boolean p3);
+ octet do_octet(in octet p1, inout octet p2, out octet p3);
+ short do_short(in short p1, inout short p2, out short p3);
+ unsigned short do_unsigned_short(in unsigned short p1, inout unsigned short p2, out unsigned short p3);
+ long do_long(in long p1, inout long p2, out long p3);
+ unsigned long do_unsigned_long(in unsigned long p1, inout unsigned long p2, out unsigned long p3);
+ long long do_long_long(in long long p1, inout long long p2, out long long p3);
+ unsigned long long do_unsigned_long_long(in unsigned long long p1, inout unsigned long long p2, out unsigned long long p3);
+ float do_float(in float p1, inout float p2, out float p3);
+ double do_double(in double p1, inout double p2, out double p3);
+ char do_char(in char p1, inout char p2, out char p3);
+ wchar do_wchar(in wchar p1, inout wchar p2, out wchar p3);
+ string do_string(in string p1, inout string p2, out string p3);
+ wstring do_wstring(in wstring p1, inout wstring p2, out wstring p3);
+ nsIIDRef do_nsIIDRef(in nsIIDRef p1, inout nsIIDRef p2, out nsIIDRef p3);
+ nsIPythonTestInterface do_nsIPythonTestInterface(in nsIPythonTestInterface p1, inout nsIPythonTestInterface p2, out nsIPythonTestInterface p3);
+ nsISupports do_nsISupports(in nsISupports p1, inout nsISupports p2, out nsISupports p3);
+ void do_nsISupportsIs(in nsIIDRef iid, [iid_is(iid),retval] out nsQIResult result);
+// Do I really need these??
+// void do_nsISupportsIs2(inout nsIIDRef iid, [iid_is(iid)] inout nsQIResult result);
+// void do_nsISupportsIs3(out nsIIDRef iid, [iid_is(iid)] inout nsQIResult result);
+// void do_nsISupportsIs4(out nsIIDRef iid, [iid_is(iid)] out nsQIResult result);
+};
+
+// Another interface - we use another interface purely for testing purposes -
+// We ensure that the entire interface hierarcy is available correctly.
+[scriptable, uuid(B38D1538-FE92-42c3-831F-285242EDEEA4)]
+interface nsIPythonTestInterfaceExtra : nsIPythonTestInterface
+{
+ // These were copied from the XPCOM test 'xpctest.idl'
+ // (and a few extras added)
+ void MultiplyEachItemInIntegerArray(
+ in PRInt32 val,
+ in PRUint32 count,
+ [array, size_is(count)] inout PRInt32 valueArray);
+ void MultiplyEachItemInIntegerArrayAndAppend(
+ in PRInt32 val,
+ inout PRUint32 count,
+ [array, size_is(count)] inout PRInt32 valueArray);
+
+ // Note that this method shares a single "size_is" between 2 params!
+ void CompareStringArrays([array, size_is(count)] in string arr1,
+ [array, size_is(count)] in string arr2,
+ in unsigned long count,
+ [retval] out short result);
+
+ void DoubleStringArray(inout PRUint32 count,
+ [array, size_is(count)] inout string valueArray);
+ void ReverseStringArray(in PRUint32 count,
+ [array, size_is(count)] inout string valueArray);
+
+ // One count, one inout array.
+ void DoubleString(inout PRUint32 count,
+ [size_is(count)] inout string str);
+ // One in count and in array, plus out count and out array
+ void DoubleString2(in PRUint32 in_count, [size_is(in_count)] in string in_str,
+ out PRUint32 out_count, [size_is(out_count)] out string out_str);
+ // As per DoubleString2, but out string also marked retval
+ void DoubleString3(in PRUint32 in_count, [size_is(in_count)] in string in_str,
+ out PRUint32 out_count, [size_is(out_count), retval] out string out_str);
+ // One in array, one out array, one share inout count.
+ void DoubleString4([size_is(count)] in string in_str, inout PRUint32 count, [size_is(count)] out string out_str);
+ // UpString defines the count as only "in" - meaning the result must be the same size
+ void UpString(in PRUint32 count,
+ [size_is(count)] inout string str);
+ // UpString2 defines count as only "in", and a string as only "out"
+ void UpString2(in PRUint32 count,
+ [size_is(count)] in string in_str,
+ [size_is(count)]out string out_str);
+ void CopyUTF8String(in AUTF8String in_str, out AUTF8String out_str);
+ void CopyUTF8String2(in AUTF8String in_str, out AUTF8String out_str);
+ // Test we can get an "out" array with an "in" size (and the size is not used anywhere as a size for an in!)
+ void GetFixedString(in PRUint32 count, [size_is(count)]out string out_str);
+
+ void DoubleWideString(inout PRUint32 count,
+ [size_is(count)] inout wstring str);
+ void DoubleWideString2(in PRUint32 in_count, [size_is(in_count)] in wstring in_str,
+ out PRUint32 out_count, [size_is(out_count)] out wstring out_str);
+ void DoubleWideString3(in PRUint32 in_count, [size_is(in_count)] in wstring in_str,
+ out PRUint32 out_count, [size_is(out_count), retval] out wstring out_str);
+ void DoubleWideString4([size_is(count)] in wstring in_str, inout PRUint32 count, [size_is(count)] out wstring out_str);
+ // UpWideString defines the count as only "in" - meaning the result must be the same size
+ void UpWideString(in PRUint32 count,
+ [size_is(count)] inout wstring str);
+ // UpWideString2 defines count as only "in", and a string as only "out"
+ void UpWideString2(in PRUint32 count,
+ [size_is(count)] in wstring in_str,
+ [size_is(count)]out wstring out_str);
+ // Test we can get an "out" array with an "in" size (and the size is not used anywhere as a size for an in!)
+ void GetFixedWideString(in PRUint32 count, [size_is(count)]out string out_str);
+
+ void GetStrings(out PRUint32 count,
+ [retval, array, size_is(count)] out string str);
+
+ void UpOctetArray(inout PRUint32 count,
+ [array, size_is(count)] inout PRUint8 data);
+
+ void UpOctetArray2(inout PRUint32 count,
+ [array, size_is(count)] inout PRUint8 data);
+
+ // Arrays of interfaces
+ void CheckInterfaceArray(in PRUint32 count,
+ [array, size_is(count)] in nsISupports data,
+ [retval] out PRBool all_non_null);
+ void CopyInterfaceArray(in PRUint32 count,
+ [array, size_is(count)] in nsISupports data,
+ [array, size_is(out_count)] out nsISupports out_data,
+ out PRUint32 out_count);
+ void GetInterfaceArray(out PRUint32 count,
+ [array, size_is(count)] out nsISupports data);
+ void ExtendInterfaceArray(inout PRUint32 count,
+ [array, size_is(count)] inout nsISupports data);
+
+ // Arrays of IIDs
+ void CheckIIDArray(in PRUint32 count,
+ [array, size_is(count)] in nsIIDRef data,
+ [retval] out PRBool all_mine);
+ void GetIIDArray(out PRUint32 count,
+ [array, size_is(count)] out nsIIDRef data);
+ void ExtendIIDArray(inout PRUint32 count,
+ [array, size_is(count)] inout nsIIDRef data);
+
+ // More specific tests.
+ // Test our count param can be shared as an "in" param.
+ void SumArrays(in PRUint32 count, [array, size_is(count)]in PRInt32 array1, [array, size_is(count)]in PRInt32 array2, [retval]out PRInt32 result);
+ // Test our count param can be shared as an "out" param.
+ void GetArrays(out PRUint32 count, [array, size_is(count)]out PRInt32 array1, [array, size_is(count)]out PRInt32 array2);
+ // Test we can get an "out" array with an "in" size (and the size is not used anywhere as a size for an in!)
+ void GetFixedArray(in PRUint32 count, [array, size_is(count)]out PRInt32 array1);
+ // Test our "in" count param can be shared as one "in", plus one "out" param.
+ void CopyArray(in PRUint32 count, [array, size_is(count)]in PRInt32 array1, [array, size_is(count)]out PRInt32 array2);
+ // Test our "in-out" count param can be shared as one "in", plus one "out" param.
+ void CopyAndDoubleArray(inout PRUint32 count, [array, size_is(count)]in PRInt32 array1, [array, size_is(count)]out PRInt32 array2);
+ // Test our "in-out" count param can be shared as one "in", plus one "in-out" param.
+ void AppendArray(inout PRUint32 count, [array, size_is(count)]in PRInt32 array1, [array, size_is(count)]inout PRInt32 array2);
+ void AppendVariant(in nsIVariant variant, inout nsIVariant result);
+ nsIVariant CopyVariant(in nsIVariant variant);
+ nsIVariant SumVariants(in PRUint32 incount, [array, size_is(incount)]in nsIVariant variants);
+};
+
+// DOM String support is a "recent" (01/2001) addition to XPCOM. These test
+// have their own interface for no real good reason ;-)
+[scriptable, uuid(657ae651-a973-4818-8c06-f4b948b3d758)]
+interface nsIPythonTestInterfaceDOMStrings : nsIPythonTestInterfaceExtra
+{
+ DOMString GetDOMStringResult(in PRInt32 length);
+ void GetDOMStringOut(in PRInt32 length, [retval] out DOMString s);
+ PRUint32 GetDOMStringLength(in DOMString s);
+ PRUint32 GetDOMStringRefLength(in DOMStringRef s);
+ PRUint32 GetDOMStringPtrLength(in DOMStringPtr s);
+ void ConcatDOMStrings(in DOMString s1, in DOMString s2, out DOMString ret);
+ attribute DOMString domstring_value;
+ readonly attribute DOMString domstring_value_ro;
+};
diff --git a/src/libs/xpcom18a4/python/test/test_component/py_test_component.py b/src/libs/xpcom18a4/python/test/test_component/py_test_component.py
new file mode 100755
index 00000000..c0373de9
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_component/py_test_component.py
@@ -0,0 +1,421 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.com> (original author)
+#
+# 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 *****
+
+# NOTE: This is a TEST interface, not a DEMO interface :-)
+# We try to get as many data-types etc exposed, meaning this
+# doesnt really make a good demo of a "simple component"
+
+
+from xpcom import components, verbose
+
+class PythonTestComponent:
+ # Note we only list the "child" interface, not our intermediate interfaces
+ # (which we must, by definition, also support)
+ _com_interfaces_ = components.interfaces.nsIPythonTestInterfaceDOMStrings
+ _reg_clsid_ = "{7EE4BDC6-CB53-42c1-A9E4-616B8E012ABA}"
+ _reg_contractid_ = "Python.TestComponent"
+ def __init__(self):
+ self.boolean_value = 1
+ self.octet_value = 2
+ self.short_value = 3
+ self.ushort_value = 4
+ self.long_value = 5
+ self.ulong_value = 6
+ self.long_long_value = 7
+ self.ulong_long_value = 8
+ self.float_value = 9.0
+ self.double_value = 10.0
+ self.char_value = "a"
+ self.wchar_value = "b"
+ self.string_value = "cee"
+ self.wstring_value = "dee"
+ self.astring_value = "astring"
+ self.acstring_value = "acstring"
+ self.utf8string_value = "utf8string"
+ self.iid_value = self._reg_clsid_
+ self.interface_value = None
+ self.isupports_value = None
+ self.domstring_value = "dom"
+
+ def __del__(self):
+ if verbose:
+ print "Python.TestComponent: __del__ method called - object is destructing"
+
+ def do_boolean(self, p1, p2):
+ # boolean do_boolean(in boolean p1, inout boolean p2, out boolean p3);
+ ret = p1 ^ p2
+ return ret, not ret, ret
+
+ def do_octet(self, p1, p2):
+ # octet do_octet(in octet p1, inout octet p2, out octet p3);
+ return p1+p2, p1-p2, p1*p2
+
+ def do_short(self, p1, p2):
+ # short do_short(in short p1, inout short p2, out short p3);
+ return p1+p2, p1-p2, p1*p2
+
+ def do_unsigned_short(self, p1, p2):
+ # unsigned short do_unsigned_short(in unsigned short p1, inout unsigned short p2, out unsigned short p3);
+ return p1+p2, p1-p2, p1*p2
+ def do_long(self, p1, p2):
+ # long do_long(in long p1, inout long p2, out long p3);
+ return p1+p2, p1-p2, p1*p2
+
+ def do_unsigned_long(self, p1, p2):
+ # unsigned long do_unsigned_long(in unsigned long p1, inout unsigned long p2, out unsigned long p3);
+ return p1+p2, p1-p2, p1*p2
+ def do_long_long(self, p1, p2):
+ # long long do_long_long(in long long p1, inout long long p2, out long long p3);
+ return p1+p2, p1-p2, p1*p2
+ def do_unsigned_long_long(self, p1, p2):
+ # unsigned long long do_unsigned_long_long(in unsigned long long p1, inout unsigned long long p2, out unsigned long long p3);
+ return p1+p2, p1-p2, p1*p2
+ def do_float(self, p1, p2):
+ # float do_float(in float p1, inout float p2, out float p3);
+ return p1+p2, p1-p2, p1*p2
+ def do_double(self, p1, p2):
+ # double do_double(in double p1, inout double p2, out double p3);
+ return p1+p2, p1-p2, p1*p2
+ def do_char(self, p1, p2):
+ # char do_char(in char p1, inout char p2, out char p3);
+ return chr(ord(p1)+ord(p2)), p2, p1
+ def do_wchar(self, p1, p2):
+ # wchar do_wchar(in wchar p1, inout wchar p2, out wchar p3);
+ return chr(ord(p1)+ord(p2)), p2, p1
+ def do_string(self, p1, p2):
+ # string do_string(in string p1, inout string p2, out string p3);
+ ret = ""
+ if p1 is not None: ret = ret + p1
+ if p2 is not None: ret = ret + p2
+ return ret, p1, p2
+ def do_wstring(self, p1, p2):
+ # wstring do_wstring(in wstring p1, inout wstring p2, out wstring p3);
+ ret = u""
+ if p1 is not None: ret = ret + p1
+ if p2 is not None: ret = ret + p2
+ return ret, p1, p2
+ def do_nsIIDRef(self, p1, p2):
+ # nsIIDRef do_nsIIDRef(in nsIIDRef p1, inout nsIIDRef p2, out nsIIDRef p3);
+ return p1, self._reg_clsid_, p2
+ def do_nsIPythonTestInterface(self, p1, p2):
+ # nsIPythonTestInterface do_nsIPythonTestInterface(in nsIPythonTestInterface p1, inout nsIPythonTestInterface p2, out nsIPythonTestInterface p3);
+ return p2, p1, self
+ def do_nsISupports(self, p1, p2):
+ # nsISupports do_nsISupports(in nsISupports p1, inout nsISupports p2, out nsISupports p3);
+ return self, p1, p2
+ def do_nsISupportsIs(self, iid):
+ # void do_nsISupportsIs(in nsIIDRef iid, [iid_is(iid),retval] out nsQIResult result)
+ # Note the framework does the QI etc on us, so there is no real point me doing it.
+ # (However, user code _should_ do the QI - otherwise any errors are deemed "internal" (as they
+ # are raised by the C++ framework), and therefore logged to the console, etc.
+ # A user QI allows the user to fail gracefully, whatever gracefully means for them!
+ return self
+# Do I really need these??
+## def do_nsISupportsIs2(self, iid, interface):
+## # void do_nsISupportsIs2(inout nsIIDRef iid, [iid_is(iid),retval] inout nsQIResult result);
+## return iid, interface
+## def do_nsISupportsIs3(self, interface):
+## # void do_nsISupportsIs3(out nsIIDRef iid, [iid_is(iid)] inout nsQIResult result);
+## return self._com_interfaces_, interface
+## def do_nsISupportsIs4(self):
+## # void do_nsISupportsIs4(out nsIIDRef iid, [iid_is(iid)] out nsQIResult result);
+## return self._com_interfaces_, self
+
+ # Methods from the nsIPythonTestInterfaceExtra interface
+ #
+ def MultiplyEachItemInIntegerArray(self, val, valueArray):
+ # void MultiplyEachItemInIntegerArray(
+ # in PRInt32 val,
+ # in PRUint32 count,
+ # [array, size_is(count)] inout PRInt32 valueArray);
+ # NOTE - the "sizeis" params are never passed to or returned from Python!
+ results = []
+ for item in valueArray:
+ results.append(item * val)
+ return results
+ def MultiplyEachItemInIntegerArrayAndAppend(self, val, valueArray):
+ #void MultiplyEachItemInIntegerArrayAndAppend(
+ # in PRInt32 val,
+ # inout PRUint32 count,
+ # [array, size_is(count)] inout PRInt32 valueArray);
+ results = valueArray[:]
+ for item in valueArray:
+ results.append(item * val)
+ return results
+ def DoubleStringArray(self, valueArray):
+ # void DoubleStringArray(inout PRUint32 count,
+ # [array, size_is(count)] inout string valueArray);
+ results = []
+ for item in valueArray:
+ results.append(item * 2)
+ return results
+
+ def ReverseStringArray(self, valueArray):
+ # void ReverseStringArray(in PRUint32 count,
+ # [array, size_is(count)] inout string valueArray);
+ valueArray.reverse()
+ return valueArray
+
+ # Note that this method shares a single "size_is" between 2 params!
+ def CompareStringArrays(self, ar1, ar2):
+ # void CompareStringArrays([array, size_is(count)] in string arr1,
+ # [array, size_is(count)] in string arr2,
+ # in unsigned long count,
+ # [retval] out short result);
+ return cmp(ar1, ar2)
+
+ def DoubleString(self, val):
+ # void DoubleString(inout PRUint32 count,
+ # [size_is(count)] inout string str);
+ return val * 2
+ def DoubleString2(self, val):
+ # void DoubleString2(in PRUint32 in_count, [size_is(in_count)] in string in_str,
+ # out PRUint32 out_count, [size_is(out_count)] out string out_str);
+ return val * 2
+ def DoubleString3(self, val):
+ # void DoubleString3(in PRUint32 in_count, [size_is(in_count)] in string in_str,
+ # out PRUint32 out_count, [size_is(out_count), retval] string out_str);
+ return val * 2
+ def DoubleString4(self, val):
+ # void DoubleString4([size_is(count)] in string in_str, inout PRUint32 count, [size_is(count)] out string out_str);
+ return val * 2
+ def UpString(self, val):
+ # // UpString defines the count as only "in" - meaning the result must be the same size
+ # void UpString(in PRUint32 count,
+ # [size_is(count)] inout string str);
+ return val.upper()
+ UpString2 = UpString
+ # // UpString2 defines count as only "in", and a string as only "out"
+ # void UpString2(in PRUint32 count,
+ # [size_is(count)] inout string in_str,
+ # [size_is(count)]out string out_str);
+
+ def GetFixedString(self, count):
+ # void GetFixedString(in PRUint32 count, [size_is(count)out string out_str);
+ return "A" * count
+
+ # DoubleWideString functions are identical to DoubleString, except use wide chars!
+ def DoubleWideString(self, val):
+ return val * 2
+ def DoubleWideString2(self, val):
+ return val * 2
+ def DoubleWideString3(self, val):
+ return val * 2
+ def DoubleWideString4(self, val):
+ return val * 2
+ def UpWideString(self, val):
+ return val.upper()
+ UpWideString2 = UpWideString
+ def CopyUTF8String(self, v):
+ return v
+ def CopyUTF8String2(self, v):
+ return v.encode("utf8")
+ # Test we can get an "out" array with an "in" size (and the size is not used anywhere as a size for an in!)
+ def GetFixedWideString(self, count):
+ # void GetFixedWideString(in PRUint32 count, [size_is(count)out string out_str);
+ return u"A" * count
+
+ def GetStrings(self):
+ # void GetStrings(out PRUint32 count,
+ # [retval, array, size_is(count)] out string str);
+ return "Hello from the Python test component".split()
+ # Some tests for our special "PRUint8" support.
+ def UpOctetArray( self, data ):
+ # void UpOctetArray(inout PRUint32 count,
+ # [array, size_is(count)] inout PRUint8 data);
+ return data.upper()
+
+ def UpOctetArray2( self, data ):
+ # void UpOctetArray2(inout PRUint32 count,
+ # [array, size_is(count)] inout PRUint8 data);
+ data = data.upper()
+ # This time we return a list of integers.
+ return map( ord, data )
+
+ # Arrays of interfaces
+ def CheckInterfaceArray(self, interfaces):
+ # void CheckInterfaceArray(in PRUint32 count,
+ # [array, size_is(count)] in nsISupports data,
+ # [retval] out PRBool all_non_null);
+ ret = 1
+ for i in interfaces:
+ if i is None:
+ ret = 0
+ break
+ return ret
+ def CopyInterfaceArray(self, a):
+ return a
+ def GetInterfaceArray(self):
+ # void GetInterfaceArray(out PRUint32 count,
+ # [array, size_is(count)] out nsISupports data);
+ return self, self, self, None
+ def ExtendInterfaceArray(self, data):
+ # void ExtendInterfaceArray(inout PRUint32 count,
+ # [array, size_is(count)] inout nsISupports data);
+ return data * 2
+
+ # Arrays of IIDs
+ def CheckIIDArray(self, data):
+ # void CheckIIDArray(in PRUint32 count,
+ # [array, size_is(count)] in nsIIDRef data,
+ # [retval] out PRBool all_mine);
+ ret = 1
+ for i in data:
+ if i!= self._com_interfaces_ and i != self._reg_clsid_:
+ ret = 0
+ break
+ return ret
+ def GetIIDArray(self):
+ # void GetIIDArray(out PRUint32 count,
+ # [array, size_is(count)] out nsIIDRef data);
+ return self._com_interfaces_, self._reg_clsid_
+ def ExtendIIDArray(self, data):
+ # void ExtendIIDArray(inout PRUint32 count,
+ # [array, size_is(count)] inout nsIIDRef data);
+ return data * 2
+
+ # Test our count param can be shared as an "in" param.
+ def SumArrays(self, array1, array2):
+ # void SumArrays(in PRUint32 count, [array, size_is(count)]in array1, [array, size_is(count)]in array2, [retval]result);
+ if len(array1)!=len(array2):
+ print "SumArrays - not expecting different lengths!"
+ result = 0
+ for i in array1:
+ result = result + i
+ for i in array2:
+ result = result+i
+ return result
+
+ # Test our count param can be shared as an "out" param.
+ def GetArrays(self):
+ # void GetArrays(out PRUint32 count, [array, size_is(count)]out array1, [array, size_is(count)]out array2);
+ return (1,2,3), (4,5,6)
+ # Test we can get an "out" array with an "in" size
+ def GetFixedArray(self, size):
+ # void GetFixedArray(in PRUint32 count, [array, size_is(count)]out PRInt32 array1]);
+ return 0 * size
+
+ # Test our "in" count param can be shared as one "in", plus one "out" param.
+ def CopyArray(self, array1):
+ # void CopyArray(in PRUint32 count, [array, size_is(count)]in array1, [array, size_is(count)]out array2);
+ return array1
+ # Test our "in-out" count param can be shared as one "in", plus one "out" param.
+ def CopyAndDoubleArray(self, array):
+ # void CopyAndDoubleArray(inout PRUint32 count, [array, size_is(count)]in array1, [array, size_is(count)]out array2);
+ return array + array
+ # Test our "in-out" count param can be shared as one "in", plus one "in-out" param.
+ def AppendArray(self, array1, array2):
+ # void AppendArray(inout PRUint32 count, [array, size_is(count)]in array1, [array, size_is(count)]inout array2);
+ rc = array1
+ if array2 is not None:
+ rc.extend(array2)
+ return rc
+ # Test nsIVariant support
+ def AppendVariant(self, invar, inresult):
+ if type(invar)==type([]):
+ invar_use = invar[0]
+ for v in invar[1:]:
+ invar_use += v
+ else:
+ invar_use = invar
+ if type(inresult)==type([]):
+ inresult_use = inresult[0]
+ for v in inresult[1:]:
+ inresult_use += v
+ else:
+ inresult_use = inresult
+ if inresult_use is None and invar_use is None:
+ return None
+ return inresult_use + invar_use
+
+ def CopyVariant(self, invar):
+ return invar
+
+ def SumVariants(self, variants):
+ if len(variants) == 0:
+ return None
+ result = variants[0]
+ for v in variants[1:]:
+ result += v
+ return result
+
+ # Some tests for the "new" (Feb-2001) DOMString type.
+ def GetDOMStringResult( self, length ):
+ # Result: DOMString &
+ if length == -1:
+ return None
+ return "P" * length
+ def GetDOMStringOut( self, length ):
+ # Result: DOMString &
+ if length == -1:
+ return None
+ return "y" * length
+ def GetDOMStringLength( self, param0 ):
+ # Result: uint32
+ # In: param0: DOMString &
+ if param0 is None: return -1
+ return len(param0)
+
+ def GetDOMStringRefLength( self, param0 ):
+ # Result: uint32
+ # In: param0: DOMString &
+ if param0 is None: return -1
+ return len(param0)
+
+ def GetDOMStringPtrLength( self, param0 ):
+ # Result: uint32
+ # In: param0: DOMString *
+ if param0 is None: return -1
+ return len(param0)
+
+ def ConcatDOMStrings( self, param0, param1 ):
+ # Result: void - None
+ # In: param0: DOMString &
+ # In: param1: DOMString &
+ # Out: DOMString &
+ return param0 + param1
+ def get_domstring_value( self ):
+ # Result: DOMString &
+ return self.domstring_value
+ def set_domstring_value( self, param0 ):
+ # Result: void - None
+ # In: param0: DOMString &
+ self.domstring_value = param0
+
+ def get_domstring_value_ro( self ):
+ # Result: DOMString &
+ return self.domstring_value
diff --git a/src/libs/xpcom18a4/python/test/test_components.py b/src/libs/xpcom18a4/python/test/test_components.py
new file mode 100755
index 00000000..80007722
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_components.py
@@ -0,0 +1,109 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <markh@activestate.com> (original author)
+#
+# 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 *****
+
+"""Tests the "xpcom.components" object.
+"""
+
+import xpcom.components
+from pyxpcom_test_tools import suite_from_functions, testmain
+
+if not __debug__:
+ raise RuntimeError, "This test uses assert, so must be run in debug mode"
+
+def test_interfaces():
+ "Test the xpcom.components.interfaces object"
+
+ iid = xpcom.components.interfaces.nsISupports
+ assert iid == xpcom._xpcom.IID_nsISupports, "Got the wrong IID!"
+ iid = xpcom.components.interfaces['nsISupports']
+ assert iid == xpcom._xpcom.IID_nsISupports, "Got the wrong IID!"
+
+ # Test dictionary semantics
+ num_fetched = num_nsisupports = 0
+ for name, iid in xpcom.components.interfaces.items():
+ num_fetched = num_fetched + 1
+ if name == "nsISupports":
+ num_nsisupports = num_nsisupports + 1
+ assert iid == xpcom._xpcom.IID_nsISupports, "Got the wrong IID!"
+ assert xpcom.components.interfaces[name] == iid
+ # Check all the lengths match.
+ assert len(xpcom.components.interfaces.keys()) == len(xpcom.components.interfaces.values()) == \
+ len(xpcom.components.interfaces.items()) == len(xpcom.components.interfaces) == \
+ num_fetched, "The collection lengths were wrong"
+ assert num_nsisupports == 1, "Didnt find exactly 1 nsiSupports!"
+
+def test_classes():
+ # Need a well-known contractID here?
+ prog_id = "@mozilla.org/supports-array;1"
+ clsid = xpcom.components.ID("{bda17d50-0d6b-11d3-9331-00104ba0fd40}")
+
+ # Check we can create the instance (dont check we can do anything with it tho!)
+ klass = xpcom.components.classes[prog_id]
+ instance = klass.createInstance()
+
+ # Test dictionary semantics
+ num_fetched = num_mine = 0
+ for name, klass in xpcom.components.classes.items():
+ num_fetched = num_fetched + 1
+ if name == prog_id:
+ assert klass.clsid == clsid, "Eeek - didn't get the correct IID - got %s" %klass.clsid
+ num_mine = num_mine + 1
+
+# xpcom appears to add charset info to the contractid!?
+# assert xpcom.components.classes[name].contractid == prog_id, "Expected '%s', got '%s'" % (prog_id, xpcom.components.classes[name].contractid)
+ # Check all the lengths match.
+ if len(xpcom.components.classes.keys()) == len(xpcom.components.classes.values()) == \
+ len(xpcom.components.classes.items()) == len(xpcom.components.classes) == \
+ num_fetched:
+ pass
+ else:
+ raise RuntimeError, "The collection lengths were wrong"
+ if num_fetched <= 0:
+ raise RuntimeError, "Didnt get any classes!!!"
+ if num_mine != 1:
+ raise RuntimeError, "Didnt find exactly 1 of my contractid! (%d)" % (num_mine,)
+
+def test_id():
+ id = xpcom.components.ID(str(xpcom._xpcom.IID_nsISupports))
+ assert id == xpcom._xpcom.IID_nsISupports
+
+# Make this test run under our std test suite
+def suite():
+ return suite_from_functions(test_interfaces, test_classes, test_id)
+
+if __name__=='__main__':
+ testmain()
diff --git a/src/libs/xpcom18a4/python/test/test_isupports_primitives.py b/src/libs/xpcom18a4/python/test/test_isupports_primitives.py
new file mode 100755
index 00000000..3d0e7023
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_isupports_primitives.py
@@ -0,0 +1,207 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.com> (original author)
+#
+# 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 *****
+
+# Test our support for the interfaces defined in nsISupportsPrimitives.idl
+#
+# The framework supports nsISupportsCString and nsISupportsString, but
+# only if our class doesnt provide explicit support.
+
+from xpcom import components
+from xpcom import primitives
+import xpcom.server, xpcom.client
+from pyxpcom_test_tools import testmain
+import unittest
+
+class NoSupportsString:
+ _com_interfaces_ = [components.interfaces.nsISupports]
+
+class ImplicitSupportsString:
+ _com_interfaces_ = [components.interfaces.nsISupports]
+ def __str__(self):
+ return "<MyImplicitStrObject>"
+
+class ExplicitSupportsString:
+ _com_interfaces_ = [components.interfaces.nsISupportsPrimitive,
+ components.interfaces.nsISupportsCString]
+ type = components.interfaces.nsISupportsPrimitive.TYPE_CSTRING
+ test_data = "<MyExplicitStrObject>"
+ # __str__ will be ignored by XPCOM, as we have _explicit_ support.
+ def __str__(self):
+ return "<MyImplicitStrObject>"
+ # These are the ones that will be used.
+ def get_data(self):
+ return self.test_data
+ def toString(self):
+ return self.test_data
+
+class ImplicitSupportsUnicode:
+ _com_interfaces_ = [components.interfaces.nsISupports]
+ test_data = u"Copyright \xa9 the initial developer"
+ def __unicode__(self):
+ # An extended character in unicode tests can't hurt!
+ return self.test_data
+
+class ExplicitSupportsUnicode:
+ _com_interfaces_ = [components.interfaces.nsISupportsPrimitive,
+ components.interfaces.nsISupportsString]
+ type = components.interfaces.nsISupportsPrimitive.TYPE_STRING
+ # __unicode__ will be ignored by XPCOM, as we have _explicit_ support.
+ test_data = u"Copyright \xa9 the initial developer"
+ def __unicode__(self):
+ return self.test_data
+ def get_data(self):
+ return self.test_data
+
+class ImplicitSupportsInt:
+ _com_interfaces_ = [components.interfaces.nsISupports]
+ def __int__(self):
+ return 99
+
+class ExplicitSupportsInt:
+ _com_interfaces_ = [components.interfaces.nsISupportsPrimitive,
+ components.interfaces.nsISupportsPRInt32]
+ type = components.interfaces.nsISupportsPrimitive.TYPE_PRINT32
+ def get_data(self):
+ return 99
+
+class ImplicitSupportsLong:
+ _com_interfaces_ = [components.interfaces.nsISupports]
+ def __long__(self):
+ return 99L
+
+class ExplicitSupportsLong:
+ _com_interfaces_ = [components.interfaces.nsISupportsPrimitive,
+ components.interfaces.nsISupportsPRInt64]
+ type = components.interfaces.nsISupportsPrimitive.TYPE_PRINT64
+ def get_data(self):
+ return 99
+
+class ExplicitSupportsFloat:
+ _com_interfaces_ = [components.interfaces.nsISupportsPrimitive,
+ components.interfaces.nsISupportsDouble]
+ type = components.interfaces.nsISupportsPrimitive.TYPE_DOUBLE
+ def get_data(self):
+ return 99.99
+
+class ImplicitSupportsFloat:
+ _com_interfaces_ = [components.interfaces.nsISupports]
+ def __float__(self):
+ return 99.99
+
+class PrimitivesTestCase(unittest.TestCase):
+ def testNoSupports(self):
+ ob = xpcom.server.WrapObject( NoSupportsString(), components.interfaces.nsISupports)
+ if not str(ob).startswith("<XPCOM "):
+ raise RuntimeError, "Wrong str() value: %s" % (ob,)
+
+ def testImplicitString(self):
+ ob = xpcom.server.WrapObject( ImplicitSupportsString(), components.interfaces.nsISupports)
+ self.failUnlessEqual(str(ob), "<MyImplicitStrObject>")
+
+ def testExplicitString(self):
+ ob = xpcom.server.WrapObject( ExplicitSupportsString(), components.interfaces.nsISupports)
+ self.failUnlessEqual(str(ob), "<MyExplicitStrObject>")
+
+ def testImplicitUnicode(self):
+ ob = xpcom.server.WrapObject( ImplicitSupportsUnicode(), components.interfaces.nsISupports)
+ self.failUnlessEqual(unicode(ob), ImplicitSupportsUnicode.test_data)
+
+ def testExplicitUnicode(self):
+ ob = xpcom.server.WrapObject( ExplicitSupportsUnicode(), components.interfaces.nsISupports)
+ self.failUnlessEqual(unicode(ob), ExplicitSupportsUnicode.test_data)
+
+ def testConvertInt(self):
+ # Try our conversions.
+ ob = xpcom.server.WrapObject( ExplicitSupportsString(), components.interfaces.nsISupports)
+ self.failUnlessRaises( ValueError, int, ob)
+
+ def testExplicitInt(self):
+ ob = xpcom.server.WrapObject( ExplicitSupportsInt(), components.interfaces.nsISupports)
+ self.failUnlessAlmostEqual(float(ob), 99.0)
+ self.failUnlessEqual(int(ob), 99)
+
+ def testImplicitInt(self):
+ ob = xpcom.server.WrapObject( ImplicitSupportsInt(), components.interfaces.nsISupports)
+ self.failUnlessAlmostEqual(float(ob), 99.0)
+ self.failUnlessEqual(int(ob), 99)
+
+ def testExplicitLong(self):
+ ob = xpcom.server.WrapObject( ExplicitSupportsLong(), components.interfaces.nsISupports)
+ if long(ob) != 99 or not repr(long(ob)).endswith("L"):
+ raise RuntimeError, "Bad value: %s" % (repr(long(ob)),)
+ self.failUnlessAlmostEqual(float(ob), 99.0)
+
+ def testImplicitLong(self):
+ ob = xpcom.server.WrapObject( ImplicitSupportsLong(), components.interfaces.nsISupports)
+ if long(ob) != 99 or not repr(long(ob)).endswith("L"):
+ raise RuntimeError, "Bad value: %s" % (repr(long(ob)),)
+ self.failUnlessAlmostEqual(float(ob), 99.0)
+
+ def testExplicitFloat(self):
+ ob = xpcom.server.WrapObject( ExplicitSupportsFloat(), components.interfaces.nsISupports)
+ self.failUnlessEqual(float(ob), 99.99)
+ self.failUnlessEqual(int(ob), 99)
+
+ def testImplicitFloat(self):
+ ob = xpcom.server.WrapObject( ImplicitSupportsFloat(), components.interfaces.nsISupports)
+ self.failUnlessEqual(float(ob), 99.99)
+ self.failUnlessEqual(int(ob), 99)
+
+class PrimitivesModuleTestCase(unittest.TestCase):
+ def testExplicitString(self):
+ ob = xpcom.server.WrapObject( ExplicitSupportsString(), components.interfaces.nsISupports)
+ self.failUnlessEqual(primitives.GetPrimitive(ob), "<MyExplicitStrObject>")
+
+ def testExplicitUnicode(self):
+ ob = xpcom.server.WrapObject( ExplicitSupportsUnicode(), components.interfaces.nsISupports)
+ self.failUnlessEqual(primitives.GetPrimitive(ob), ExplicitSupportsUnicode.test_data)
+ self.failUnlessEqual(type(primitives.GetPrimitive(ob)), unicode)
+
+ def testExplicitInt(self):
+ ob = xpcom.server.WrapObject( ExplicitSupportsInt(), components.interfaces.nsISupports)
+ self.failUnlessEqual(primitives.GetPrimitive(ob), 99)
+
+ def testExplicitLong(self):
+ ob = xpcom.server.WrapObject( ExplicitSupportsLong(), components.interfaces.nsISupports)
+ self.failUnlessEqual(primitives.GetPrimitive(ob), 99)
+
+ def testExplicitFloat(self):
+ ob = xpcom.server.WrapObject( ExplicitSupportsFloat(), components.interfaces.nsISupports)
+ self.failUnlessEqual(primitives.GetPrimitive(ob), 99.99)
+
+if __name__=='__main__':
+ testmain()
diff --git a/src/libs/xpcom18a4/python/test/test_misc.py b/src/libs/xpcom18a4/python/test/test_misc.py
new file mode 100755
index 00000000..6cf1b74e
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_misc.py
@@ -0,0 +1,236 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# Activestate Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.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 *****
+
+import xpcom
+import xpcom.client
+import xpcom.server
+import xpcom._xpcom
+import xpcom.components
+import string
+from pyxpcom_test_tools import testmain
+
+import unittest
+
+import traceback, getopt, sys
+
+verbose_level = 0
+
+reportedSampleMissing = 0
+
+def get_sample_component_cpp():
+ global reportedSampleMissing
+ contractid = "@mozilla.org/sample;1" # The C++ version.
+ try:
+ return xpcom.components.classes[contractid].createInstance()
+ except xpcom.COMException:
+ if not reportedSampleMissing:
+ print "***"
+ print "*** This test requires an XPCOM sample component,"
+ print "*** which does not exist. To build this test, you"
+ print "*** should change to the 'mozilla/xpcom/sample' directory,"
+ print "*** and run 'make', then run this test again."
+ print "***"
+ reportedSampleMissing = 1
+ else:
+ print "(skipping - no C++ sample...) ",
+ return None
+
+def get_sample_component_js():
+ # This should *always* exist - no special make process.
+ contractid = "@mozilla.org/jssample;1" # the JS version
+ return xpcom.components.classes[contractid].createInstance()
+
+class TestDumpInterfaces(unittest.TestCase):
+ def testAllInterfaces(self):
+ "Dump every interface under the sun!"
+ import xpcom, xpcom.xpt, xpcom._xpcom
+ iim = xpcom._xpcom.XPTI_GetInterfaceInfoManager()
+
+ if verbose_level:
+ print "Dumping every interface I can find"
+ enum = iim.EnumerateInterfaces()
+ rc = enum.First()
+ num = 0
+ while rc==0:
+ item = enum.CurrentItem(xpcom._xpcom.IID_nsIInterfaceInfo)
+ try:
+ iid = item.GetIID()
+ except xpcom.COMException:
+ if verbose_level:
+ print "Can't dump", item
+ continue # Dont bother dumping this.
+ interface = xpcom.xpt.Interface(iid)
+ num = num + 1
+ text = interface.Describe()
+ if verbose_level:
+ print text
+
+ rc = enum.Next()
+ if num < 200:
+ print "Only found", num, "interfaces - this seems unusually low!"
+
+class TestEnumContractIDs(unittest.TestCase):
+ def testContractIDs(self):
+ """Enumerate all the ContractIDs registered"""
+ enum = xpcom.components.registrar.enumerateContractIDs()
+ n = 0
+ while enum.hasMoreElements():
+ item = enum.getNext(xpcom.components.interfaces.nsISupportsCString)
+ n = n + 1
+ if verbose_level:
+ print "ContractID:", item.data
+ if n < 200:
+ print "Only found", n, "ContractIDs - this seems unusually low!"
+
+class TestSampleComponent(unittest.TestCase):
+ def _doTestSampleComponent(self, test_flat = 0):
+ """Test the standard Netscape 'sample' sample"""
+ c = get_sample_component_cpp()
+ if c is None:
+ return
+ if not test_flat:
+ c = c.queryInterface(xpcom.components.interfaces.nsISample)
+ self.failUnlessEqual(c.value, "initial value")
+ c.value = "new value"
+ self.failUnlessEqual(c.value, "new value")
+ c.poke("poked value")
+ self.failUnlessEqual(c.value, "poked value")
+ c.writeValue("Python just poked:")
+
+ def testSampleComponentFlat(self):
+ """Test the standard Netscape 'sample' sample using interface flattening"""
+ self._doTestSampleComponent(1)
+
+ def testSampleComponentOld(self):
+ """Test the standard Netscape 'sample' sample using explicit QI"""
+ self._doTestSampleComponent(0)
+
+ def _doTestHash(self, c):
+ "Test that hashing COM objects works"
+ d = {}
+ d[c] = None
+ if not d.has_key(c):
+ raise RuntimeError, "Can't get the exact same object back!"
+ if not d.has_key(c.queryInterface(xpcom.components.interfaces.nsISupports)):
+ raise RuntimeError, "Can't get back as nsISupports"
+
+ # And the same in reverse - stick an nsISupports in, and make sure an explicit interface comes back.
+ d = {}
+# contractid = "@mozilla.org/sample;1" # The C++ version.
+# c = xpcom.components.classes[contractid].createInstance() \
+# .queryInterface(xpcom.components.interfaces.nsISupports)
+ d[c] = None
+ if not d.has_key(c):
+ raise RuntimeError, "Can't get the exact same object back!"
+ if not d.has_key(c.queryInterface(xpcom.components.interfaces.nsISample)):
+ raise RuntimeError, "Can't get back as nsISupports"
+
+ def testHashJS(self):
+ c = get_sample_component_js()
+ self._doTestHash(c)
+
+ def testHashCPP(self):
+ c = get_sample_component_cpp()
+ if c is not None:
+ self._doTestHash(c)
+
+
+class TestIIDs(unittest.TestCase):
+ def TestIIDs(self):
+ "Do some basic IID semantic tests."
+ iid_str = "{7ee4bdc6-cb53-42c1-a9e4-616b8e012aba}"
+ IID = xpcom._xpcom.IID
+ self.failUnlessEqual(IID(iid_str), IID(iid_str))
+ self.failUnlessEqual(hash(IID(iid_str)), hash(IID(iid_str)))
+ self.failUnlessEqual(IID(iid_str), IID(iid_str.upper()))
+ self.failUnlessEqual(hash(IID(iid_str)), hash(IID(iid_str.upper())))
+ # If the above work, this shoud too, but WTF
+ dict = {}
+ dict[IID(iid_str)] = None
+ self.failUnless(dict.has_key(IID(iid_str)), "hashes failed in dictionary")
+ self.failUnless(dict.has_key(IID(iid_str.upper())), "uppercase hash failed in dictionary")
+
+class TestRepr(unittest.TestCase):
+ def _doTestRepr(self, progid, interfaces):
+ if isinstance(progid, str):
+ ob = xpcom.components.classes[progid].createInstance()
+ else:
+ ob = progid
+ self.failUnless(repr(ob).find(str(progid)) >= 0, repr(ob))
+ for interface_name in interfaces.split():
+ self.failUnless(repr(ob).find(interface_name) >= 0, repr(ob))
+
+ def testReprPython(self):
+ "Test repr() of Python objects"
+ self._doTestRepr("Python.TestComponent", "nsIPythonTestInterfaceDOMStrings nsIPythonTestInterfaceExtra nsIPythonTestInterface")
+
+ # JS does not provide class-info :(
+ #def testReprJS(self):
+ # self._doTestRepr("@mozilla.org/jssample;1", "nsISample")
+
+ def testReprSample(self):
+ "Test repr() of non-Python objects"
+ ob = get_sample_component_cpp()
+ if ob is None:
+ return
+ self._doTestRepr(ob, "nsISample")
+
+class TestUnwrap(unittest.TestCase):
+ "Test the unwrap facilities"
+ def testUnwrap(self):
+ # First test that a Python object can be unwrapped.
+ ob = xpcom.components.classes["Python.TestComponent"].createInstance()
+ pyob = xpcom.server.UnwrapObject(ob)
+ # This depends on our __repr__ implementation, but that's OK - it
+ # can be updated should our __repr__ change :)
+ self.failUnless(str(pyob).startswith("<component:py_test_component.PythonTestComponent"))
+ # Test that a non-Python implemented object can NOT be unwrapped.
+ ob = get_sample_component_cpp()
+ if ob is None:
+ return
+ self.failUnlessRaises(ValueError, xpcom.server.UnwrapObject, ob)
+
+class TestNonScriptable(unittest.TestCase):
+ def testQI(self):
+ # Test we can QI for a non-scriptable interface. We can't *do* much
+ # with it (other than pass it on), but we should still work and get
+ # a basic wrapper.
+ ob = xpcom.components.classes["Python.TestComponent"].createInstance()
+ ob = ob.queryInterface(xpcom._xpcom.IID_nsIInternalPython)
+
+if __name__=='__main__':
+ testmain()
diff --git a/src/libs/xpcom18a4/python/test/test_streams.py b/src/libs/xpcom18a4/python/test/test_streams.py
new file mode 100755
index 00000000..96ac6559
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_streams.py
@@ -0,0 +1,96 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000,2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.com> (original author)
+#
+# 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 *****
+
+import xpcom
+from xpcom import _xpcom, components, COMException, ServerException, nsError
+from StringIO import StringIO
+import unittest
+from pyxpcom_test_tools import testmain
+
+test_data = "abcdefeghijklmnopqrstuvwxyz"
+
+class koTestSimpleStream:
+ _com_interfaces_ = [components.interfaces.nsIInputStream]
+ # We avoid registering this object - see comments in get_test_inout_? below.
+
+ def __init__(self):
+ self.data=StringIO(test_data)
+ self._non_blocking = False
+
+ def close( self ):
+ pass
+
+ def available( self ):
+ return self.data.len-self.data.pos
+
+ def readStr( self, amount):
+ return self.data.read(amount)
+
+ read=readStr
+
+ def get_observer( self ):
+ raise ServerException(nsError.NS_ERROR_NOT_IMPLEMENTED)
+
+ def set_observer( self, param0 ):
+ raise ServerException(nsError.NS_ERROR_NOT_IMPLEMENTED)
+
+ def isNonBlocking(self):
+ return self._non_blocking
+
+def get_test_input():
+ # We use a couple of internal hacks here that mean we can avoid having the object
+ # registered. This code means that we are still working over the xpcom boundaries, tho
+ # (and the point of this test is not the registration, etc).
+ import xpcom.server, xpcom.client
+ ob = xpcom.server.WrapObject( koTestSimpleStream(), _xpcom.IID_nsISupports)
+ ob = xpcom.client.Component(ob._comobj_, components.interfaces.nsIInputStream)
+ return ob
+
+class StreamTests(unittest.TestCase):
+ def testInput(self):
+ self.do_test_input( get_test_input() )
+
+ def do_test_input(self, myStream):
+ self.failUnlessEqual(str(myStream.read(5)), test_data[:5])
+ self.failUnlessEqual(str(myStream.read(0)), '')
+ self.failUnlessEqual(str(myStream.read(5)), test_data[5:10])
+ self.failUnlessEqual(str(myStream.read(-1)), test_data[10:])
+ self.failIf(myStream.isNonBlocking(), "Expected default to be blocking")
+ # stream observer mechanism has changed - we should test that.
+
+if __name__=='__main__':
+ testmain()
diff --git a/src/libs/xpcom18a4/python/test/test_test_component.js b/src/libs/xpcom18a4/python/test/test_test_component.js
new file mode 100644
index 00000000..54e39382
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_test_component.js
@@ -0,0 +1,138 @@
+/* ***** 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 the Python XPCOM language bindings.
+ *
+ * The Initial Developer of the Original Code is
+ * ActiveState Tool Corp.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mark Hammond <MarkH@ActiveState.com> (original author)
+ *
+ * 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 ***** */
+
+/* Javascript code calling the Python test interface. */
+
+var extended_unicode_string = "The Euro Symbol is '\u20ac'";
+
+function MakeTestInterface()
+{
+ var clazz = Components.classes["Python.TestComponent"];
+ var iface = Components.interfaces.nsIPythonTestInterfaceDOMStrings;
+ return new clazz(iface);
+}
+
+var c = new MakeTestInterface();
+
+if (c.boolean_value != 1)
+ throw("boolean_value has wrong initial value");
+c.boolean_value = false;
+if (c.boolean_value != false)
+ throw("boolean_value has wrong new value");
+
+// Python's own test does thorough testing of all numeric types
+// Wont bother from here!
+
+if (c.char_value != 'a')
+ throw("char_value has wrong initial value");
+c.char_value = 'b';
+if (c.char_value != 'b')
+ throw("char_value has wrong new value");
+
+if (c.wchar_value != 'b')
+ throw("wchar_value has wrong initial value");
+c.wchar_value = 'c';
+if (c.wchar_value != 'c')
+ throw("wchar_value has wrong new value");
+
+if (c.string_value != 'cee')
+ throw("string_value has wrong initial value");
+c.string_value = 'dee';
+if (c.string_value != 'dee')
+ throw("string_value has wrong new value");
+
+if (c.wstring_value != 'dee')
+ throw("wstring_value has wrong initial value");
+c.wstring_value = 'eee';
+if (c.wstring_value != 'eee')
+ throw("wstring_value has wrong new value");
+c.wstring_value = extended_unicode_string;
+if (c.wstring_value != extended_unicode_string)
+ throw("wstring_value has wrong new value");
+
+if (c.domstring_value != 'dom')
+ throw("domstring_value has wrong initial value");
+c.domstring_value = 'New value';
+if (c.domstring_value != 'New value')
+ throw("domstring_value has wrong new value");
+c.domstring_value = extended_unicode_string;
+if (c.domstring_value != extended_unicode_string)
+ throw("domstring_value has wrong new value");
+
+if (c.utf8string_value != 'utf8string')
+ throw("utf8string_value has wrong initial value");
+c.utf8string_value = 'New value';
+if (c.utf8string_value != 'New value')
+ throw("utf8string_value has wrong new value");
+c.utf8string_value = extended_unicode_string;
+if (c.utf8string_value != extended_unicode_string)
+ throw("utf8string_value has wrong new value");
+
+var v = new Object();
+v.value = "Hello"
+var l = new Object();
+l.value = v.value.length;
+c.DoubleString(l, v);
+if ( v.value != "HelloHello")
+ throw("Could not double the string!");
+
+var v = new Object();
+v.value = "Hello"
+var l = new Object();
+l.value = v.value.length;
+c.DoubleWideString(l, v);
+if ( v.value != "HelloHello")
+ throw("Could not double the wide string!");
+
+// Some basic array tests
+var v = new Array()
+v[0] = 1;
+v[2] = 2;
+v[3] = 3;
+var v2 = new Array()
+v2[0] = 4;
+v2[2] = 5;
+v2[3] = 6;
+if (c.SumArrays(v.length, v, v2) != 21)
+ throw("Could not sum an array of integers!");
+
+var count = new Object();
+count.value = 0;
+var out = [];
+c.DoubleStringArray(count, out);
+
+print("javascript successfully tested the Python test component.");
diff --git a/src/libs/xpcom18a4/python/test/test_test_component.py b/src/libs/xpcom18a4/python/test/test_test_component.py
new file mode 100755
index 00000000..dd78133a
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_test_component.py
@@ -0,0 +1,575 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <MarkH@ActiveState.com> (original author)
+#
+# 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 *****
+
+import sys, os, time
+import xpcom.components
+import xpcom._xpcom
+import xpcom.nsError
+
+MakeVariant = xpcom._xpcom.MakeVariant
+
+try:
+ import gc
+except ImportError:
+ gc = None
+
+num_errors = 0
+
+component_iid = xpcom.components.ID("{7EE4BDC6-CB53-42c1-A9E4-616B8E012ABA}")
+new_iid = xpcom.components.ID("{2AF747D3-ECBC-457b-9AF9-5C5D80EDC360}")
+
+contractid = "Python.TestComponent"
+
+really_big_string = "This is really repetitive!" * 10000
+really_big_wstring = u"This is really repetitive!" * 10000
+extended_unicode_string = u"The Euro Symbol is '\u20ac'"
+
+# Exception raised when a -ve integer is converted to an unsigned C integer
+# (via an extension module). This changed in Python 2.2
+if sys.hexversion > 0x02010000:
+ UnsignedMismatchException = TypeError
+else:
+ UnsignedMismatchException = OverflowError
+
+def print_error(error):
+ print error
+ global num_errors
+ num_errors = num_errors + 1
+
+def _test_value(what, got, expecting):
+ ok = got == expecting
+ if type(got)==type(expecting)==type(0.0):
+ ok = abs(got-expecting) < 0.001
+ if not ok:
+ print_error("*** Error %s - got '%r', but expecting '%r'" % (what, got, expecting))
+
+def test_attribute(ob, attr_name, expected_init, new_value, new_value_really = None):
+ if xpcom.verbose:
+ print "Testing attribute %s" % (attr_name,)
+ if new_value_really is None:
+ new_value_really = new_value # Handy for eg bools - set a BOOL to 2, you still get back 1!
+
+ _test_value( "getting initial attribute value (%s)" % (attr_name,), getattr(ob, attr_name), expected_init)
+ setattr(ob, attr_name, new_value)
+ _test_value( "getting new attribute value (%s)" % (attr_name,), getattr(ob, attr_name), new_value_really)
+ # And set it back to the expected init.
+ setattr(ob, attr_name, expected_init)
+ _test_value( "getting back initial attribute value after change (%s)" % (attr_name,), getattr(ob, attr_name), expected_init)
+
+def test_string_attribute(ob, attr_name, expected_init, is_dumb_sz = False, ascii_only = False):
+ test_attribute(ob, attr_name, expected_init, "normal value")
+ val = "a null >\0<"
+ if is_dumb_sz:
+ expected = "a null >" # dumb strings are \0 terminated.
+ else:
+ expected = val
+ test_attribute(ob, attr_name, expected_init, val, expected)
+ test_attribute(ob, attr_name, expected_init, "")
+ test_attribute(ob, attr_name, expected_init, really_big_string)
+ test_attribute(ob, attr_name, expected_init, u"normal unicode value")
+ val = u"a null >\0<"
+ if is_dumb_sz:
+ expected = "a null >" # dumb strings are \0 terminated.
+ else:
+ expected = val
+ test_attribute(ob, attr_name, expected_init, val, expected)
+ test_attribute(ob, attr_name, expected_init, u"")
+ test_attribute(ob, attr_name, expected_init, really_big_wstring)
+ if not ascii_only:
+ test_attribute(ob, attr_name, expected_init, extended_unicode_string)
+
+def test_attribute_failure(ob, attr_name, new_value, expected_exception):
+ try:
+ setattr(ob, attr_name, new_value)
+ print_error("*** Setting attribute '%s' to '%r' didnt yield an exception!" % (attr_name, new_value) )
+ except:
+ exc_typ = sys.exc_info()[0]
+ exc_val = sys.exc_info()[1]
+ ok = issubclass(exc_typ, expected_exception)
+ if not ok:
+ print_error("*** Wrong exception setting '%s' to '%r'- got '%s: %s', expected '%s'" % (attr_name, new_value, exc_typ, exc_val, expected_exception))
+
+
+def test_method(method, args, expected_results):
+ if xpcom.verbose:
+ print "Testing %s%s" % (method.__name__, `args`)
+ ret = method(*args)
+ if ret != expected_results:
+ print_error("calling method %s - expected %r, but got %r" % (method.__name__, expected_results, ret))
+
+def test_int_method(meth):
+ test_method(meth, (0,0), (0,0,0))
+ test_method(meth, (1,1), (2,0,1))
+ test_method(meth, (5,2), (7,3,10))
+# test_method(meth, (2,5), (7,-3,10))
+
+def test_constant(ob, cname, val):
+ v = getattr(ob, cname)
+ if v != val:
+ print_error("Bad value for constant '%s' - got '%r'" % (cname, v))
+ try:
+ setattr(ob, cname, 0)
+ print_error("The object allowed us to set the constant '%s'" % (cname,))
+ except AttributeError:
+ pass
+
+def test_base_interface(c):
+ test_attribute(c, "boolean_value", 1, 0)
+ test_attribute(c, "boolean_value", 1, -1, 1) # Set a bool to anything, you should always get back 0 or 1
+ test_attribute(c, "boolean_value", 1, 4, 1) # Set a bool to anything, you should always get back 0 or 1
+ test_attribute(c, "boolean_value", 1, "1", 1) # This works by virtual of PyNumber_Int - not sure I agree, but...
+ test_attribute_failure(c, "boolean_value", "boo", ValueError)
+ test_attribute_failure(c, "boolean_value", test_base_interface, TypeError)
+
+ test_attribute(c, "octet_value", 2, 5)
+ test_attribute(c, "octet_value", 2, 0)
+ test_attribute(c, "octet_value", 2, 128) # octet is unsigned 8 bit
+ test_attribute(c, "octet_value", 2, 255) # octet is unsigned 8 bit
+ test_attribute(c, "octet_value", 2, -1, 255) # octet is unsigned 8 bit
+ test_attribute_failure(c, "octet_value", "boo", ValueError)
+
+ test_attribute(c, "short_value", 3, 10)
+ test_attribute(c, "short_value", 3, -1) # 16 bit signed
+ test_attribute(c, "short_value", 3, 0xFFFF, -1) # 16 bit signed
+ test_attribute(c, "short_value", 3, 0L)
+ test_attribute(c, "short_value", 3, 1L)
+ test_attribute(c, "short_value", 3, -1L)
+ test_attribute(c, "short_value", 3, 0xFFFFL, -1)
+ test_attribute_failure(c, "short_value", "boo", ValueError)
+
+ test_attribute(c, "ushort_value", 4, 5)
+ test_attribute(c, "ushort_value", 4, 0)
+ test_attribute(c, "ushort_value", 4, -1, 0xFFFF) # 16 bit signed
+ test_attribute(c, "ushort_value", 4, 0xFFFF) # 16 bit signed
+ test_attribute(c, "ushort_value", 4, 0L)
+ test_attribute(c, "ushort_value", 4, 1L)
+ test_attribute(c, "ushort_value", 4, -1L, 0xFFFF)
+ test_attribute_failure(c, "ushort_value", "boo", ValueError)
+
+ test_attribute(c, "long_value", 5, 7)
+ test_attribute(c, "long_value", 5, 0)
+ test_attribute(c, "long_value", 5, -1, -1) # 32 bit signed.
+ test_attribute(c, "long_value", 5, -1) # 32 bit signed.
+ test_attribute(c, "long_value", 5, 0L)
+ test_attribute(c, "long_value", 5, 1L)
+ test_attribute(c, "long_value", 5, -1L)
+ test_attribute_failure(c, "long_value", 0xFFFFL * 0xFFFF, OverflowError) # long int too long to convert
+ test_attribute_failure(c, "long_value", "boo", ValueError)
+
+ test_attribute(c, "ulong_value", 6, 7)
+ test_attribute(c, "ulong_value", 6, 0)
+ test_attribute(c, "ulong_value", 6, -1) # 32 bit signed.
+ test_attribute_failure(c, "ulong_value", "boo", ValueError)
+
+ test_attribute(c, "long_long_value", 7, 8)
+ test_attribute(c, "long_long_value", 7, 0)
+ test_attribute(c, "long_long_value", 7, -1)
+ test_attribute(c, "long_long_value", 7, 0xFFFF)
+ test_attribute(c, "long_long_value", 7, 0xFFFFL * 2)
+ test_attribute_failure(c, "long_long_value", 0xFFFFL * 0xFFFF * 0xFFFF * 0xFFFF, OverflowError) # long int too long to convert
+ test_attribute_failure(c, "long_long_value", "boo", ValueError)
+
+ test_attribute(c, "ulong_long_value", 8, 9)
+ test_attribute(c, "ulong_long_value", 8, 0)
+ test_attribute_failure(c, "ulong_long_value", "boo", ValueError)
+ test_attribute_failure(c, "ulong_long_value", -1, UnsignedMismatchException) # can't convert negative value to unsigned long)
+
+ test_attribute(c, "float_value", 9.0, 10.2)
+ test_attribute(c, "float_value", 9.0, 0)
+ test_attribute(c, "float_value", 9.0, -1)
+ test_attribute(c, "float_value", 9.0, 1L)
+ test_attribute_failure(c, "float_value", "boo", ValueError)
+
+ test_attribute(c, "double_value", 10.0, 9.0)
+ test_attribute(c, "double_value", 10.0, 0)
+ test_attribute(c, "double_value", 10.0, -1)
+ test_attribute(c, "double_value", 10.0, 1L)
+ test_attribute_failure(c, "double_value", "boo", ValueError)
+
+ test_attribute(c, "char_value", "a", "b")
+ test_attribute(c, "char_value", "a", "\0")
+ test_attribute_failure(c, "char_value", "xy", ValueError)
+ test_attribute(c, "char_value", "a", u"c")
+ test_attribute(c, "char_value", "a", u"\0")
+ test_attribute_failure(c, "char_value", u"xy", ValueError)
+
+ test_attribute(c, "wchar_value", "b", "a")
+ test_attribute(c, "wchar_value", "b", "\0")
+ test_attribute_failure(c, "wchar_value", "hi", ValueError)
+ test_attribute(c, "wchar_value", "b", u"a")
+ test_attribute(c, "wchar_value", "b", u"\0")
+ test_attribute_failure(c, "wchar_value", u"hi", ValueError)
+
+ test_string_attribute(c, "string_value", "cee", is_dumb_sz = True, ascii_only = True)
+ test_string_attribute(c, "wstring_value", "dee", is_dumb_sz = True)
+ test_string_attribute(c, "astring_value", "astring")
+ test_string_attribute(c, "acstring_value", "acstring", ascii_only = True)
+
+ test_string_attribute(c, "utf8string_value", "utf8string")
+ # Test a string already encoded gets through correctly.
+ test_attribute(c, "utf8string_value", "utf8string", extended_unicode_string.encode("utf8"), extended_unicode_string)
+
+ # This will fail internal string representation :( Test we don't crash
+ try:
+ c.wstring_value = "a big char >" + chr(129) + "<"
+ print_error("strings with chars > 128 appear to have stopped failing?")
+ except UnicodeError:
+ pass
+
+ test_attribute(c, "iid_value", component_iid, new_iid)
+ test_attribute(c, "iid_value", component_iid, str(new_iid), new_iid)
+ test_attribute(c, "iid_value", component_iid, xpcom._xpcom.ID(new_iid))
+
+ test_attribute_failure(c, "no_attribute", "boo", AttributeError)
+
+ test_attribute(c, "interface_value", None, c)
+ test_attribute_failure(c, "interface_value", 2, TypeError)
+
+ test_attribute(c, "isupports_value", None, c)
+
+ # The methods
+ test_method(c.do_boolean, (0,1), (1,0,1))
+ test_method(c.do_boolean, (1,0), (1,0,1))
+ test_method(c.do_boolean, (1,1), (0,1,0))
+
+ test_int_method(c.do_octet)
+ test_int_method(c.do_short)
+
+ test_int_method(c.do_unsigned_short)
+ test_int_method(c.do_long)
+ test_int_method(c.do_unsigned_long)
+ test_int_method(c.do_long_long)
+ test_int_method(c.do_unsigned_long)
+ test_int_method(c.do_float)
+ test_int_method(c.do_double)
+
+ test_method(c.do_char, ("A", " "), (chr(ord("A")+ord(" ")), " ","A") )
+ test_method(c.do_char, ("A", "\0"), ("A", "\0","A") )
+ test_method(c.do_wchar, ("A", " "), (chr(ord("A")+ord(" ")), " ","A") )
+ test_method(c.do_wchar, ("A", "\0"), ("A", "\0","A") )
+
+ test_method(c.do_string, ("Hello from ", "Python"), ("Hello from Python", "Hello from ", "Python") )
+ test_method(c.do_string, (u"Hello from ", u"Python"), ("Hello from Python", "Hello from ", "Python") )
+ test_method(c.do_string, (None, u"Python"), ("Python", None, "Python") )
+ test_method(c.do_string, (None, really_big_string), (really_big_string, None, really_big_string) )
+ test_method(c.do_string, (None, really_big_wstring), (really_big_string, None, really_big_string) )
+ test_method(c.do_wstring, ("Hello from ", "Python"), ("Hello from Python", "Hello from ", "Python") )
+ test_method(c.do_wstring, (u"Hello from ", u"Python"), ("Hello from Python", "Hello from ", "Python") )
+ test_method(c.do_string, (None, really_big_wstring), (really_big_wstring, None, really_big_wstring) )
+ test_method(c.do_string, (None, really_big_string), (really_big_wstring, None, really_big_wstring) )
+ test_method(c.do_nsIIDRef, (component_iid, new_iid), (component_iid, component_iid, new_iid))
+ test_method(c.do_nsIIDRef, (new_iid, component_iid), (new_iid, component_iid, component_iid))
+ test_method(c.do_nsIPythonTestInterface, (None, None), (None, None, c))
+ test_method(c.do_nsIPythonTestInterface, (c, c), (c, c, c))
+ test_method(c.do_nsISupports, (None, None), (c, None, None))
+ test_method(c.do_nsISupports, (c,c), (c, c, c))
+ test_method(c.do_nsISupportsIs, (xpcom._xpcom.IID_nsISupports,), c)
+ test_method(c.do_nsISupportsIs, (xpcom.components.interfaces.nsIPythonTestInterface,), c)
+## test_method(c.do_nsISupportsIs2, (xpcom.components.interfaces.nsIPythonTestInterface,c), (xpcom.components.interfaces.nsIPythonTestInterface,c))
+## test_method(c.do_nsISupportsIs3, (c,), (xpcom.components.interfaces.nsIPythonTestInterface,c))
+## test_method(c.do_nsISupportsIs4, (), (xpcom.components.interfaces.nsIPythonTestInterface,c))
+ # Test the constants.
+ test_constant(c, "One", 1)
+ test_constant(c, "Two", 2)
+ test_constant(c, "MinusOne", -1)
+ test_constant(c, "BigLong", 0x7FFFFFFF)
+ test_constant(c, "BiggerLong", -1)
+ test_constant(c, "BigULong", -1)
+ # Test the components.Interfaces semantics
+ i = xpcom.components.interfaces.nsIPythonTestInterface
+ test_constant(i, "One", 1)
+ test_constant(i, "Two", 2)
+ test_constant(i, "MinusOne", -1)
+ test_constant(i, "BigLong", 0x7FFFFFFF)
+ test_constant(i, "BigULong", -1)
+
+def test_derived_interface(c, test_flat = 0):
+ val = "Hello\0there"
+ expected = val * 2
+
+ test_method(c.DoubleString, (val,), expected)
+ test_method(c.DoubleString2, (val,), expected)
+ test_method(c.DoubleString3, (val,), expected)
+ test_method(c.DoubleString4, (val,), expected)
+ test_method(c.UpString, (val,), val.upper())
+ test_method(c.UpString2, (val,), val.upper())
+ test_method(c.GetFixedString, (20,), "A"*20)
+ val = u"Hello\0there"
+ expected = val * 2
+ test_method(c.DoubleWideString, (val,), expected)
+ test_method(c.DoubleWideString2, (val,), expected)
+ test_method(c.DoubleWideString3, (val,), expected)
+ test_method(c.DoubleWideString4, (val,), expected)
+ test_method(c.UpWideString, (val,), val.upper())
+ test_method(c.UpWideString2, (val,), val.upper())
+ test_method(c.GetFixedWideString, (20,), u"A"*20)
+ val = extended_unicode_string
+ test_method(c.CopyUTF8String, ("foo",), "foo")
+ test_method(c.CopyUTF8String, (u"foo",), "foo")
+ test_method(c.CopyUTF8String, (val,), val)
+ test_method(c.CopyUTF8String, (val.encode("utf8"),), val)
+ test_method(c.CopyUTF8String2, ("foo",), "foo")
+ test_method(c.CopyUTF8String2, (u"foo",), "foo")
+ test_method(c.CopyUTF8String2, (val,), val)
+ test_method(c.CopyUTF8String2, (val.encode("utf8"),), val)
+ items = [1,2,3,4,5]
+ test_method(c.MultiplyEachItemInIntegerArray, (3, items,), map(lambda i:i*3, items))
+
+ test_method(c.MultiplyEachItemInIntegerArrayAndAppend, (3, items), items + map(lambda i:i*3, items))
+ items = "Hello from Python".split()
+ expected = map( lambda x: x*2, items)
+ test_method(c.DoubleStringArray, (items,), expected)
+
+ test_method(c.CompareStringArrays, (items, items), cmp(items, items))
+ # Can we pass lists and tuples correctly?
+ test_method(c.CompareStringArrays, (items, tuple(items)), cmp(items, items))
+ items2 = ["Not", "the", "same"]
+ test_method(c.CompareStringArrays, (items, items2), cmp(items, items2))
+
+ expected = items[:]
+ expected.reverse()
+ test_method(c.ReverseStringArray, (items,), expected)
+
+ expected = "Hello from the Python test component".split()
+ test_method(c.GetStrings, (), expected)
+
+ val = "Hello\0there"
+ test_method(c.UpOctetArray, (val,), val.upper())
+ test_method(c.UpOctetArray, (unicode(val),), val.upper())
+ # Passing Unicode objects here used to cause us grief.
+ test_method(c.UpOctetArray2, (val,), val.upper())
+
+ test_method(c.CheckInterfaceArray, ((c, c),), 1)
+ test_method(c.CheckInterfaceArray, ((c, None),), 0)
+ test_method(c.CheckInterfaceArray, ((),), 1)
+ test_method(c.CopyInterfaceArray, ((c, c),), [c,c])
+
+ test_method(c.GetInterfaceArray, (), [c,c,c, None])
+ test_method(c.ExtendInterfaceArray, ((c,c,c, None),), [c,c,c,None,c,c,c,None] )
+
+ expected = [xpcom.components.interfaces.nsIPythonTestInterfaceDOMStrings, xpcom.components.classes[contractid].clsid]
+ test_method(c.GetIIDArray, (), expected)
+
+ val = [xpcom.components.interfaces.nsIPythonTestInterfaceExtra, xpcom.components.classes[contractid].clsid]
+ expected = val * 2
+ test_method(c.ExtendIIDArray, (val,), expected)
+
+ test_method(c.GetArrays, (), ( [1,2,3], [4,5,6] ) )
+ test_method(c.CopyArray, ([1,2,3],), [1,2,3] )
+ test_method(c.CopyAndDoubleArray, ([1,2,3],), [1,2,3,1,2,3] )
+ test_method(c.AppendArray, ([1,2,3],), [1,2,3])
+ test_method(c.AppendArray, ([1,2,3],[4,5,6]), [1,2,3,4,5,6])
+
+ test_method(c.CopyVariant, (None,), None)
+ test_method(c.CopyVariant, (1,), 1)
+ test_method(c.CopyVariant, (1.0,), 1.0)
+ test_method(c.CopyVariant, (-1,), -1)
+ test_method(c.CopyVariant, (sys.maxint+1,), sys.maxint+1)
+ test_method(c.CopyVariant, ("foo",), "foo")
+ test_method(c.CopyVariant, (u"foo",), u"foo")
+ test_method(c.CopyVariant, (c,), c)
+ test_method(c.CopyVariant, (component_iid,), component_iid)
+ test_method(c.CopyVariant, ((1,2),), [1,2])
+ test_method(c.CopyVariant, ((1.2,2.1),), [1.2,2.1])
+ test_method(c.CopyVariant, (("foo","bar"),), ["foo", "bar"])
+ test_method(c.CopyVariant, ((component_iid,component_iid),), [component_iid,component_iid])
+ test_method(c.CopyVariant, ((c,c),), [c,c])
+ sup = c.queryInterface(xpcom.components.interfaces.nsISupports)._comobj_
+ test_method(c.CopyVariant, ((sup, sup),), [sup,sup])
+ test_method(c.AppendVariant, (1,2), 3)
+ test_method(c.AppendVariant, ((1,2),(3,4)), 10)
+ test_method(c.AppendVariant, ("bar", "foo"), "foobar")
+ test_method(c.AppendVariant, (None, None), None)
+
+ test_method(c.SumVariants, ([],), None)
+ # Array's dont expose their interface, so we are unable to auto-wrap
+ # variant arrays, as they aren't aware if the IID of the array
+ test_method(c.SumVariants, ([MakeVariant(1),MakeVariant(2),MakeVariant(3)],), 6)
+ test_method(c.SumVariants, ([MakeVariant('foo'), MakeVariant('bar')],), 'foobar')
+
+ if not test_flat:
+ c = c.queryInterface(xpcom.components.interfaces.nsIPythonTestInterfaceDOMStrings)
+# NULL DOM strings don't work yet.
+# test_method(c.GetDOMStringResult, (-1,), None)
+ test_method(c.GetDOMStringResult, (3,), "PPP")
+# test_method(c.GetDOMStringOut, (-1,), None)
+ test_method(c.GetDOMStringOut, (4,), "yyyy")
+ val = "Hello there"
+ test_method(c.GetDOMStringLength, (val,), len(val))
+ test_method(c.GetDOMStringRefLength, (val,), len(val))
+ test_method(c.GetDOMStringPtrLength, (val,), len(val))
+ test_method(c.ConcatDOMStrings, (val,val), val+val)
+ test_attribute(c, "domstring_value", "dom", "new dom")
+ if c.domstring_value_ro != "dom":
+ print "Read-only DOMString not correct - got", c.domstring_ro
+ try:
+ c.dom_string_ro = "new dom"
+ print "Managed to set a readonly attribute - eek!"
+ except AttributeError:
+ pass
+ except:
+ print "Unexpected exception when setting readonly attribute: %s: %s" % (sys.exc_info()[0], sys.exc_info()[1])
+ if c.domstring_value_ro != "dom":
+ print "Read-only DOMString not correct after failed set attempt - got", c.domstring_ro
+
+def do_test_failures():
+ c = xpcom.client.Component(contractid, xpcom.components.interfaces.nsIPythonTestInterfaceExtra)
+ try:
+ ret = c.do_nsISupportsIs( xpcom._xpcom.IID_nsIInterfaceInfoManager )
+ print "*** got", ret, "***"
+ raise RuntimeError, "We worked when using an IID we dont support!?!"
+ except xpcom.Exception, details:
+ if details.errno != xpcom.nsError.NS_ERROR_NO_INTERFACE:
+ raise RuntimeError, "Wrong COM exception type: %r" % (details,)
+
+def test_failures():
+ # This extra stack-frame ensures Python cleans up sys.last_traceback etc
+ do_test_failures()
+
+def test_all():
+ c = xpcom.client.Component(contractid, xpcom.components.interfaces.nsIPythonTestInterface)
+ test_base_interface(c)
+ # Now create an instance using the derived IID, and test that.
+ c = xpcom.client.Component(contractid, xpcom.components.interfaces.nsIPythonTestInterfaceExtra)
+ test_base_interface(c)
+ test_derived_interface(c)
+ # Now create an instance and test interface flattening.
+ c = xpcom.components.classes[contractid].createInstance()
+ test_base_interface(c)
+ test_derived_interface(c, test_flat=1)
+
+ # We had a bug where a "set" of an attribute before a "get" failed.
+ # Don't let it happen again :)
+ c = xpcom.components.classes[contractid].createInstance()
+ c.boolean_value = 0
+
+ # This name is used in exceptions etc - make sure we got it from nsIClassInfo OK.
+ assert c._object_name_ == "Python.TestComponent"
+
+ test_failures()
+
+try:
+ from sys import gettotalrefcount
+except ImportError:
+ # Not a Debug build - assume no references (can't be leaks then :-)
+ def gettotalrefcount():
+ return 0
+
+from pyxpcom_test_tools import getmemusage
+
+def test_from_js():
+ # Ensure we can find the js test script - same dir as this!
+ # Assume the path of sys.argv[0] is where we can find the js test code.
+ # (Running under the regression test is a little painful)
+ script_dir = os.path.split(sys.argv[0])[0]
+ fname = os.path.join( script_dir, "test_test_component.js")
+ if not os.path.isfile(fname):
+ raise RuntimeError, "Can not find '%s'" % (fname,)
+ # Note we _dont_ pump the test output out, as debug "xpcshell" spews
+ # extra debug info that will cause our output comparison to fail.
+ data = os.popen('xpcshell "' + fname + '"').readlines()
+ good = 0
+ for line in data:
+ if line.strip() == "javascript successfully tested the Python test component.":
+ good = 1
+ if not good:
+ print "** The javascript test appeared to fail! Test output follows **"
+ print "".join(data)
+ print "** End of javascript test output **"
+ raise RuntimeError, "test failed"
+
+def doit(num_loops = -1):
+ if "-v" in sys.argv: # Hack the verbose flag for the server
+ xpcom.verbose = 1
+ # Do the test lots of times - can help shake-out ref-count bugs.
+ if num_loops == -1: num_loops = 5
+ for i in xrange(num_loops):
+ test_all()
+
+ if i==0:
+ # First loop is likely to "leak" as we cache things.
+ # Leaking after that is a problem.
+ if gc is not None:
+ gc.collect()
+ num_refs = gettotalrefcount()
+ mem_usage = getmemusage()
+
+ if num_errors:
+ break
+
+ if gc is not None:
+ gc.collect()
+
+ lost = gettotalrefcount() - num_refs
+ # Sometimes we get spurious counts off by 1 or 2.
+ # This can't indicate a real leak, as we have looped
+ # more than twice!
+ if abs(lost)>3: # 2 or 3 :)
+ print "*** Lost %d references" % (lost,)
+
+ # sleep to allow the OS to recover
+ time.sleep(1)
+ mem_lost = getmemusage() - mem_usage
+ # working set size is fickle, and when we were leaking strings, this test
+ # would report a leak of 100MB. So we allow a 3MB buffer - but even this
+ # may still occasionally report spurious warnings. If you are really
+ # worried, bump the counter to a huge value, and if there is a leak it will
+ # show.
+ if mem_lost > 3000000:
+ print "*** Lost %.6f MB of memory" % (mem_lost/1000000.0,)
+
+ assert num_errors==0, "There were %d errors testing the Python component" % (num_errors,)
+
+def suite():
+ from pyxpcom_test_tools import suite_from_functions
+ return suite_from_functions(doit, test_from_js)
+
+if __name__=='__main__':
+ num_iters = 10 # times times is *lots* - we do a fair bit of work!
+ if __name__=='__main__' and len(sys.argv) > 1:
+ num_iters = int(sys.argv[1])
+
+ print "Testing the Python.TestComponent component"
+ doit(num_iters)
+ print "The Python test component worked."
+ test_from_js()
+ print "JS successfully used our Python test component."
+ xpcom._xpcom.NS_ShutdownXPCOM()
+ ni = xpcom._xpcom._GetInterfaceCount()
+ ng = xpcom._xpcom._GetGatewayCount()
+ if ni or ng:
+ print "********* WARNING - Leaving with %d/%d objects alive" % (ni,ng)
diff --git a/src/libs/xpcom18a4/python/test/test_weakreferences.py b/src/libs/xpcom18a4/python/test/test_weakreferences.py
new file mode 100755
index 00000000..9bfb3fbc
--- /dev/null
+++ b/src/libs/xpcom18a4/python/test/test_weakreferences.py
@@ -0,0 +1,114 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <markh@activestate.com> (original author)
+#
+# 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 *****
+
+# test_weakreferences.py - Test our weak reference implementation.
+from xpcom import components, _xpcom
+import xpcom.server, xpcom.client
+from pyxpcom_test_tools import suite_from_functions, testmain
+
+try:
+ from sys import gettotalrefcount
+except ImportError:
+ # Not a Debug build - assume no references (can't be leaks then :-)
+ gettotalrefcount = lambda: 0
+
+num_alive = 0
+
+class koTestSimple:
+ _com_interfaces_ = [components.interfaces.nsIInputStream]
+ def __init__(self):
+ global num_alive
+ num_alive += 1
+ def __del__(self):
+ global num_alive
+ num_alive -= 1
+ def close( self ):
+ pass
+
+def test():
+ ob = xpcom.server.WrapObject( koTestSimple(), components.interfaces.nsIInputStream)
+
+ if num_alive != 1: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
+
+ # Check we can create a weak reference to our object.
+ wr = xpcom.client.WeakReference(ob)
+ if num_alive != 1: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
+
+ # Check we can call methods via the weak reference.
+ if wr() is None: raise RuntimeError, "Our weak-reference is returning None before it should!"
+ wr().close()
+
+ ob = None # This should kill the object.
+ if num_alive != 0: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
+ if wr() is not None: raise RuntimeError, "Our weak-reference is not returning None when it should!"
+
+ # Now a test that we can get a _new_ interface from the weak reference - ie,
+ # an IID the real object has never previously been queried for
+ # (this behaviour previously caused a bug - never again ;-)
+ ob = xpcom.server.WrapObject( koTestSimple(), components.interfaces.nsISupports)
+ if num_alive != 1: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
+ wr = xpcom.client.WeakReference(ob, components.interfaces.nsIInputStream)
+ if num_alive != 1: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
+ wr() # This would die once upon a time ;-)
+ ob = None # This should kill the object.
+ if num_alive != 0: raise RuntimeError, "Eeek - there are %d objects alive" % (num_alive,)
+ if wr() is not None: raise RuntimeError, "Our weak-reference is not returning None when it should!"
+
+def test_refcount(num_loops=-1):
+ # Do the test lots of times - can help shake-out ref-count bugs.
+ if num_loops == -1: num_loops = 10
+ for i in xrange(num_loops):
+ test()
+
+ if i==0:
+ # First loop is likely to "leak" as we cache things.
+ # Leaking after that is a problem.
+ num_refs = gettotalrefcount()
+
+ lost = gettotalrefcount() - num_refs
+ # Sometimes we get spurious counts off by 1 or 2.
+ # This can't indicate a real leak, as we have looped
+ # more than twice!
+ if abs(lost)>2:
+ print "*** Lost %d references" % (lost,)
+
+# Make this test run under our std test suite
+def suite():
+ return suite_from_functions(test_refcount)
+
+if __name__=='__main__':
+ testmain()
diff --git a/src/libs/xpcom18a4/python/tools/regxpcom.py b/src/libs/xpcom18a4/python/tools/regxpcom.py
new file mode 100755
index 00000000..2b7ea6a4
--- /dev/null
+++ b/src/libs/xpcom18a4/python/tools/regxpcom.py
@@ -0,0 +1,68 @@
+# ***** 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 Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <mhammond@skippinet.com.au> (original author)
+#
+# 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 *****
+
+# regxpcom.py - basically the standard regxpcom.cpp ported to Python.
+# In general, you should use regxpcom.exe instead of this.
+
+from xpcom import components, _xpcom
+from xpcom.client import Component
+import sys
+import os
+
+registrar = Component(_xpcom.GetComponentRegistrar(),
+ components.interfaces.nsIComponentRegistrar)
+
+def ProcessArgs(args):
+
+ unregister = 0
+ for arg in args:
+ spec = components.classes['@mozilla.org/file/local;1'].createInstance()
+ spec = spec.QueryInterface(components.interfaces.nsILocalFile)
+ spec.initWithPath(os.path.abspath(arg))
+ if arg == "-u":
+ registrar.autoUnregister(spec)
+ print "Successfully unregistered", spec.path
+ else:
+ registrar.autoRegister(spec)
+ print "Successfully registered", spec.path
+
+if len(sys.argv) < 2:
+ registrar.autoRegister( None)
+else:
+ ProcessArgs(sys.argv[1:])
+
+#_xpcom.NS_ShutdownXPCOM()
diff --git a/src/libs/xpcom18a4/python/tools/tracer_demo.py b/src/libs/xpcom18a4/python/tools/tracer_demo.py
new file mode 100755
index 00000000..045c3db8
--- /dev/null
+++ b/src/libs/xpcom18a4/python/tools/tracer_demo.py
@@ -0,0 +1,113 @@
+# ***** 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 Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <mhammond@skippinet.com.au> (original author)
+#
+# 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 *****
+
+# This is a demo is how to use the xpcom.server "tracer" facility.
+#
+# This demo installs a tracer that uses the Python profiler. It then
+# creates the Python test component, and references some methods
+# and properties. It then dumps the profile statistics.
+
+# This same technique could also be used for debugging, for example.
+
+import profile
+
+p = profile.Profile()
+getters = {}
+setters = {}
+
+# A wrapper around a function - looks like a function,
+# but actually profiles the delegate.
+class TracerDelegate:
+ def __init__(self, callme):
+ self.callme = callme
+ def __call__(self, *args):
+ return p.runcall(self.callme, *args)
+
+# A wrapper around each of our XPCOM objects. All PyXPCOM calls
+# in are made on this object, which creates a TracerDelagate around
+# every function. As the function is called, it collects profile info.
+class Tracer:
+ def __init__(self, ob):
+ self.__dict__['_ob'] = ob
+ def __repr__(self):
+ return "<Tracer around %r>" % (self._ob,)
+ def __str__(self):
+ return "<Tracer around %r>" % (self._ob,)
+ def __getattr__(self, attr):
+ ret = getattr(self._ob, attr) # Attribute error just goes up
+ if callable(ret):
+ return TracerDelegate(ret)
+ else:
+ if not attr.startswith("_com_") and not attr.startswith("_reg_"):
+ getters[attr] = getters.setdefault(attr,0) + 1
+ return ret
+ def __setattr__(self, attr, val):
+ if self.__dict__.has_key(attr):
+ self.__dict__[attr] = val
+ return
+ setters[attr] = setters.setdefault(attr,0) + 1
+ setattr(self._ob, attr, val)
+
+# Installed as a global XPCOM function that if exists, will be called
+# to wrap each XPCOM object created.
+def MakeTracer(ob):
+ # In some cases we may be asked to wrap ourself, so handle that.
+ if isinstance(ob, Tracer):
+ return ob
+ return Tracer(ob)
+
+def test():
+ import xpcom.server, xpcom.components
+ xpcom.server.tracer = MakeTracer
+ contractid = "Python.TestComponent"
+ for i in range(100):
+ c = xpcom.components.classes[contractid].createInstance().queryInterface(xpcom.components.interfaces.nsIPythonTestInterface)
+ c.boolean_value = 0
+ a = c.boolean_value
+ c.do_boolean(0,1)
+ print "Finshed"
+ p.print_stats()
+ print "%-30s%s" % ("Attribute Gets", "Number")
+ print "-" * 36
+ for name, num in getters.items():
+ print "%-30s%d" % (name, num)
+ print "%-30s%s" % ("Attribute Sets", "Number")
+ print "-" * 36
+ for name, num in setters.items():
+ print "%-30s%d" % (name, num)
+
+test()
diff --git a/src/libs/xpcom18a4/python/vboxxpcom.py b/src/libs/xpcom18a4/python/vboxxpcom.py
new file mode 100755
index 00000000..6fd54d53
--- /dev/null
+++ b/src/libs/xpcom18a4/python/vboxxpcom.py
@@ -0,0 +1,83 @@
+"""
+Copyright (C) 2008-2022 Oracle and/or its affiliates.
+
+This file is part of VirtualBox base platform packages, as
+available from https://www.virtualbox.org.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation, in version 3 of the
+License.
+
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, see <https://www.gnu.org/licenses>.
+
+SPDX-License-Identifier: GPL-3.0-only
+"""
+
+import xpcom
+import sys
+import platform
+
+#
+# This code overcomes somewhat unlucky feature of Python, where it searches
+# for binaries in the same place as platfom independent modules, while
+# rest of Python bindings expect _xpcom to be inside xpcom module
+#
+
+_asVBoxPythons = [
+ 'VBoxPython' + str(sys.version_info[0]) + '_' + str(sys.version_info[1]),
+ 'VBoxPython' + str(sys.version_info[0]),
+ 'VBoxPython'
+]
+
+# For Python 3.2 and later use the right ABI flag suffix for the module.
+if sys.hexversion >= 0x030200f0 and sys.abiflags:
+ _asNew = []
+ for sCandidate in _asVBoxPythons:
+ if sCandidate[-1:].isdigit():
+ _asNew.append(sCandidate + sys.abiflags)
+ else:
+ _asNew.append(sCandidate)
+ _asVBoxPythons = _asNew
+ del _asNew
+
+# On platforms where we ship both 32-bit and 64-bit API bindings, we have to
+# look for the right set if we're a 32-bit process.
+if platform.system() in [ 'SunOS', ] and sys.maxsize <= 2**32:
+ _asNew = [ sCandidate + '_x86' for sCandidate in _asVBoxPythons ]
+ _asNew.extend(_asVBoxPythons)
+ _asVBoxPythons = _asNew
+ del _asNew
+
+# On Darwin (aka Mac OS X) we know exactly where things are in a normal
+# VirtualBox installation.
+## @todo Edit this at build time to the actual VBox location set in the make files.
+## @todo We know the location for most hardened builds, not just darwin!
+if platform.system() == 'Darwin':
+ sys.path.append('/Applications/VirtualBox.app/Contents/MacOS')
+
+_oVBoxPythonMod = None
+for m in _asVBoxPythons:
+ try:
+ _oVBoxPythonMod = __import__(m)
+ break
+ except:
+ pass
+ #except Exception as x:
+ # print('m=%s x=%s' % (m, x))
+
+if platform.system() == 'Darwin':
+ sys.path.remove('/Applications/VirtualBox.app/Contents/MacOS')
+
+if _oVBoxPythonMod == None:
+ raise Exception('Cannot find VBoxPython module (tried: %s)' % (', '.join(_asVBoxPythons),))
+
+sys.modules['xpcom._xpcom'] = _oVBoxPythonMod
+xpcom._xpcom = _oVBoxPythonMod
+
diff --git a/src/libs/xpcom18a4/python/xpcom_consts.py b/src/libs/xpcom18a4/python/xpcom_consts.py
new file mode 100644
index 00000000..933f93ef
--- /dev/null
+++ b/src/libs/xpcom18a4/python/xpcom_consts.py
@@ -0,0 +1,272 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Hammond <mhammond@skippinet.com.au> (original author)
+#
+# 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 *****
+
+# Could maybe later have a process that extracted these enums should they change.
+# from nsFileLocations.h
+App_DirectoryBase = 0x00010000
+App_PrefsDirectory30 = App_DirectoryBase + 1
+App_PrefsDirectory40 = App_DirectoryBase + 2
+App_PrefsDirectory50 = App_DirectoryBase + 3
+App_ResDirectory = App_DirectoryBase + 5
+App_UserProfileDirectory30 = App_DirectoryBase + 10
+App_UserProfileDirectory40 = App_DirectoryBase + 11
+App_UserProfileDirectory50 = App_DirectoryBase + 12
+App_DefaultUserProfileRoot30 = App_DirectoryBase + 13
+App_DefaultUserProfileRoot40 = App_DirectoryBase + 14
+App_DefaultUserProfileRoot50 = App_DirectoryBase + 15
+App_ProfileDefaultsFolder30 = App_DirectoryBase + 16
+App_ProfileDefaultsFolder40 = App_DirectoryBase + 17
+App_ProfileDefaultsFolder50 = App_DirectoryBase + 18
+App_PrefDefaultsFolder50 = App_DirectoryBase + 19
+App_DefaultsFolder50 = App_DirectoryBase + 25
+App_ComponentsDirectory = App_DirectoryBase + 30
+App_ChromeDirectory = App_DirectoryBase + 31
+App_PluginsDirectory = App_DirectoryBase + 32
+App_UserChromeDirectory = App_DirectoryBase + 40
+App_FileBase = App_DirectoryBase + 1000
+App_PreferencesFile30 = App_FileBase + 1
+App_PreferencesFile40 = App_FileBase + 2
+App_PreferencesFile50 = App_FileBase + 3
+App_BookmarksFile30 = App_FileBase + 10
+App_BookmarksFile40 = App_FileBase + 11
+App_BookmarksFile50 = App_FileBase + 12
+App_Registry40 = App_FileBase + 20
+App_Registry50 = App_FileBase + 21
+App_LocalStore50 = App_FileBase + 30
+App_History50 = App_FileBase + 40
+App_MailDirectory50 = App_FileBase + 50
+App_ImapMailDirectory50 = App_FileBase + 60
+App_NewsDirectory50 = App_FileBase + 70
+App_MessengerFolderCache50 = App_FileBase + 80
+App_UsersPanels50 = App_FileBase + 90
+App_SearchFile50 = App_FileBase + 100
+App_SearchDirectory50 = App_FileBase + 101
+
+# From nsSpecialSystemDirectory.h
+OS_DriveDirectory = 1
+OS_TemporaryDirectory = 2
+OS_CurrentProcessDirectory= 3
+OS_CurrentWorkingDirectory= 4
+
+XPCOM_CurrentProcessComponentDirectory= 5
+XPCOM_CurrentProcessComponentRegistry= 6
+
+Moz_BinDirectory = 10
+
+Mac_SystemDirectory = 101
+Mac_DesktopDirectory = 102
+Mac_TrashDirectory = 103
+Mac_StartupDirectory = 104
+Mac_ShutdownDirectory = 105
+Mac_AppleMenuDirectory = 106
+Mac_ControlPanelDirectory = 107
+Mac_ExtensionDirectory = 108
+Mac_FontsDirectory = 109
+Mac_PreferencesDirectory = 110
+Mac_DocumentsDirectory = 111
+Mac_InternetSearchDirectory = 112
+
+Win_SystemDirectory = 201
+Win_WindowsDirectory = 202
+
+Win_HomeDirectory = 203
+Win_Desktop = 204
+Win_Programs = 205
+Win_Controls = 206
+Win_Printers = 207
+Win_Personal = 208
+Win_Favorites = 209
+Win_Startup = 210
+Win_Recent = 211
+Win_Sendto = 212
+Win_Bitbucket = 213
+Win_Startmenu = 214
+Win_Desktopdirectory = 215
+Win_Drives = 216
+Win_Network = 217
+Win_Nethood = 218
+Win_Fonts = 219
+Win_Templates = 220
+Win_Common_Startmenu = 221
+Win_Common_Programs = 222
+Win_Common_Startup = 223
+Win_Common_Desktopdirectory = 224
+Win_Appdata = 225
+Win_Printhood = 226
+
+Unix_LocalDirectory = 301
+Unix_LibDirectory = 302
+Unix_HomeDirectory = 303
+
+BeOS_SettingsDirectory = 401
+BeOS_HomeDirectory = 402
+BeOS_DesktopDirectory = 403
+BeOS_SystemDirectory = 404
+
+OS2_SystemDirectory = 501
+
+# Type/Variant related constants.
+TD_INT8 = 0
+TD_INT16 = 1
+TD_INT32 = 2
+TD_INT64 = 3
+TD_UINT8 = 4
+TD_UINT16 = 5
+TD_UINT32 = 6
+TD_UINT64 = 7
+TD_FLOAT = 8
+TD_DOUBLE = 9
+TD_BOOL = 10
+TD_CHAR = 11
+TD_WCHAR = 12
+TD_VOID = 13
+TD_PNSIID = 14
+TD_DOMSTRING = 15
+TD_PSTRING = 16
+TD_PWSTRING = 17
+TD_INTERFACE_TYPE = 18
+TD_INTERFACE_IS_TYPE = 19
+TD_ARRAY = 20
+TD_PSTRING_SIZE_IS = 21
+TD_PWSTRING_SIZE_IS = 22
+TD_UTF8STRING = 23
+TD_CSTRING = 24
+TD_ASTRING = 25
+
+# From xpt_struct.h
+XPT_TDP_POINTER = 0x80
+XPT_TDP_UNIQUE_POINTER = 0x40
+XPT_TDP_REFERENCE = 0x20
+XPT_TDP_FLAGMASK = 0xe0
+XPT_TDP_TAGMASK = (~XPT_TDP_FLAGMASK)
+def XPT_TDP_TAG(tdp): return (tdp & XPT_TDP_TAGMASK)
+
+def XPT_TDP_IS_POINTER(flags): return (flags & XPT_TDP_POINTER)
+def XPT_TDP_IS_UNIQUE_POINTER(flags): return (flags & XPT_TDP_UNIQUE_POINTER)
+def XPT_TDP_IS_REFERENCE(flags): return (flags & XPT_TDP_REFERENCE)
+
+XPT_ID_SCRIPTABLE = 0x80
+XPT_ID_FLAGMASK = 0x80
+XPT_ID_TAGMASK = ~XPT_ID_FLAGMASK
+def XPT_ID_TAG(id): return id & XPT_ID_TAGMASK
+
+def XPT_ID_IS_SCRIPTABLE(flags): return flags & XPT_ID_SCRIPTABLE
+
+XPT_PD_IN = 0x80
+XPT_PD_OUT = 0x40
+XPT_PD_RETVAL = 0x20
+XPT_PD_SHARED = 0x10
+XPT_PD_DIPPER = 0x08
+XPT_PD_FLAGMASK = 0xf0
+
+def XPT_PD_IS_IN(flags): return (flags & XPT_PD_IN)
+def XPT_PD_IS_OUT(flags): return (flags & XPT_PD_OUT)
+def XPT_PD_IS_RETVAL(flags): return (flags & XPT_PD_RETVAL)
+def XPT_PD_IS_SHARED(flags): return (flags & XPT_PD_SHARED)
+def XPT_PD_IS_DIPPER(flags): return (flags & XPT_PD_DIPPER)
+
+XPT_MD_GETTER = 0x80
+XPT_MD_SETTER = 0x40
+XPT_MD_NOTXPCOM = 0x20
+XPT_MD_CTOR = 0x10
+XPT_MD_HIDDEN = 0x08
+XPT_MD_FLAGMASK = 0xf8
+
+def XPT_MD_IS_GETTER(flags): return (flags & XPT_MD_GETTER)
+def XPT_MD_IS_SETTER(flags): return (flags & XPT_MD_SETTER)
+def XPT_MD_IS_NOTXPCOM(flags): return (flags & XPT_MD_NOTXPCOM)
+def XPT_MD_IS_CTOR(flags): return (flags & XPT_MD_CTOR)
+def XPT_MD_IS_HIDDEN(flags): return (flags & XPT_MD_HIDDEN)
+
+# From xptinfo.h
+
+T_I8 = TD_INT8
+T_I16 = TD_INT16
+T_I32 = TD_INT32
+T_I64 = TD_INT64
+T_U8 = TD_UINT8
+T_U16 = TD_UINT16
+T_U32 = TD_UINT32
+T_U64 = TD_UINT64
+T_FLOAT = TD_FLOAT
+T_DOUBLE = TD_DOUBLE
+T_BOOL = TD_BOOL
+T_CHAR = TD_CHAR
+T_WCHAR = TD_WCHAR
+T_VOID = TD_VOID
+T_IID = TD_PNSIID
+T_DOMSTRING = TD_DOMSTRING
+T_CHAR_STR = TD_PSTRING
+T_WCHAR_STR = TD_PWSTRING
+T_INTERFACE = TD_INTERFACE_TYPE
+T_INTERFACE_IS = TD_INTERFACE_IS_TYPE
+T_ARRAY = TD_ARRAY
+T_PSTRING_SIZE_IS = TD_PSTRING_SIZE_IS
+T_PWSTRING_SIZE_IS = TD_PWSTRING_SIZE_IS
+T_UTF8STRING = TD_UTF8STRING
+T_CSTRING = TD_CSTRING
+T_ASTRING = TD_ASTRING
+
+# from nsIVariant
+VTYPE_INT8 = 0
+VTYPE_INT16 = 1
+VTYPE_INT32 = 2
+VTYPE_INT64 = 3
+VTYPE_UINT8 = 4
+VTYPE_UINT16 = 5
+VTYPE_UINT32 = 6
+VTYPE_UINT64 = 7
+VTYPE_FLOAT = 8
+VTYPE_DOUBLE = 9
+VTYPE_BOOL = 10
+VTYPE_CHAR = 11
+VTYPE_WCHAR = 12
+VTYPE_VOID = 13
+VTYPE_ID = 14
+VTYPE_DOMSTRING = 15
+VTYPE_CHAR_STR = 16
+VTYPE_WCHAR_STR = 17
+VTYPE_INTERFACE = 18
+VTYPE_INTERFACE_IS = 19
+VTYPE_ARRAY = 20
+VTYPE_STRING_SIZE_IS = 21
+VTYPE_WSTRING_SIZE_IS = 22
+VTYPE_UTF8STRING = 23
+VTYPE_CSTRING = 24
+VTYPE_ASTRING = 25
+VTYPE_EMPTY_ARRAY = 254
+VTYPE_EMPTY = 255
diff --git a/src/libs/xpcom18a4/python/xpt.py b/src/libs/xpcom18a4/python/xpt.py
new file mode 100755
index 00000000..67021572
--- /dev/null
+++ b/src/libs/xpcom18a4/python/xpt.py
@@ -0,0 +1,471 @@
+# ***** 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 the Python XPCOM language bindings.
+#
+# The Initial Developer of the Original Code is
+# ActiveState Tool Corp.
+# Portions created by the Initial Developer are Copyright (C) 2000, 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# David Ascher <DavidA@ActiveState.com> (original author)
+# Mark Hammond <mhammond@skippinet.com.au>
+#
+# 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 *****
+
+"""
+Program: xpt.py
+
+Task: describe interfaces etc using XPCOM reflection.
+
+Subtasks:
+ output (nearly) exactly the same stuff as xpt_dump, for verification
+ output Python source code that can be used as a template for an interface
+
+Status: Works pretty well if you ask me :-)
+
+Author:
+ David Ascher did an original version that parsed XPT files
+ directly. Mark Hammond changed it to use the reflection interfaces,
+ but kept most of the printing logic.
+
+
+Revision:
+
+ 0.1: March 6, 2000
+ 0.2: April 2000 - Mark removed lots of Davids lovely parsing code in favour
+ of the new xpcom interfaces that provide this info.
+
+ May 2000 - Moved into Perforce - track the log there!
+ Early 2001 - Moved into the Mozilla CVS tree - track the log there!
+
+Todo:
+ Fill out this todo list.
+
+"""
+
+import string, sys
+import xpcom
+import xpcom._xpcom
+
+from .xpcom_consts import *
+
+class Interface:
+ def __init__(self, iid):
+ iim = xpcom._xpcom.XPTI_GetInterfaceInfoManager()
+ if hasattr(iid, "upper"): # Is it a stringy thing.
+ item = iim.GetInfoForName(iid)
+ else:
+ item = iim.GetInfoForIID(iid)
+ self.interface_info = item
+ self.namespace = "" # where does this come from?
+ self.methods = Methods(item)
+ self.constants = Constants(item)
+
+ # delegate attributes to the real interface
+ def __getattr__(self, attr):
+ return getattr(self.interface_info, attr)
+
+ def GetParent(self):
+ try:
+ raw_parent = self.interface_info.GetParent()
+ if raw_parent is None:
+ return None
+ return Interface(raw_parent.GetIID())
+ except xpcom.Exception:
+ # Parent interface is probably not scriptable - assume nsISupports.
+ if xpcom.verbose:
+ # The user may be confused as to why this is happening!
+ print("The parent interface of IID '%s' can not be located - assuming nsISupports")
+ return Interface(xpcom._xpcom.IID_nsISupports)
+
+ def Describe_Python(self):
+ method_reprs = []
+ methods = [m for m in self.methods if not m.IsNotXPCOM()]
+ for m in methods:
+ method_reprs.append(m.Describe_Python())
+ method_joiner = "\n"
+ methods_repr = method_joiner.join(method_reprs)
+ return \
+"""class %s:
+ _com_interfaces_ = xpcom.components.interfaces.%s
+ # If this object needs to be registered, the following 2 are also needed.
+ # _reg_clsid_ = "{a new clsid generated for this object}"
+ # _reg_contractid_ = "The.Object.Name"\n%s""" % (self.GetName(), self.GetIID().name, methods_repr)
+
+ def Describe(self):
+ # Make the IID look like xtp_dump - "(" instead of "{"
+ iid_use = "(" + str(self.GetIID())[1:-1] + ")"
+ s = ' - '+self.namespace+'::'+ self.GetName() + ' ' + iid_use + ':\n'
+
+ parent = self.GetParent()
+ if parent is not None:
+ s = s + ' Parent: ' + parent.namespace + '::' + parent.GetName() + '\n'
+ s = s + ' Flags:\n'
+ if self.IsScriptable(): word = 'TRUE'
+ else: word = 'FALSE'
+ s = s + ' Scriptable: ' + word + '\n'
+ s = s + ' Methods:\n'
+ methods = [m for m in self.methods if not m.IsNotXPCOM()]
+ if len(methods):
+ for m in methods:
+ s = s + ' ' + m.Describe() + '\n'
+ else:
+ s = s + ' No Methods\n'
+ s = s + ' Constants:\n'
+ if self.constants:
+ for c in self.constants:
+ s = s + ' ' + c.Describe() + '\n'
+ else:
+ s = s + ' No Constants\n'
+
+ return s
+
+# A class that allows caching and iterating of methods.
+class Methods:
+ def __init__(self, interface_info):
+ self.interface_info = interface_info
+ try:
+ self.items = [None] * interface_info.GetMethodCount()
+ except xpcom.Exception:
+ if xpcom.verbose:
+ print("** GetMethodCount failed?? - assuming no methods")
+ self.items = []
+ def __len__(self):
+ return len(self.items)
+ def __getitem__(self, index):
+ ret = self.items[index]
+ if ret is None:
+ mi = self.interface_info.GetMethodInfo(index)
+ ret = self.items[index] = Method(mi, index, self.interface_info)
+ return ret
+
+class Method:
+
+ def __init__(self, method_info, method_index, interface_info = None):
+ self.interface_info = interface_info
+ self.method_index = method_index
+ self.flags, self.name, param_descs, self.result_desc = method_info
+ # Build the params.
+ self.params = []
+ pi=0
+ for pd in param_descs:
+ self.params.append( Parameter(pd, pi, method_index, interface_info) )
+ pi = pi + 1
+ # Run over the params setting the "sizeof" params to hidden.
+ for p in self.params:
+ td = p.type_desc
+ tag = XPT_TDP_TAG(td[0])
+ if tag==T_ARRAY and p.IsIn():
+ self.params[td[1]].hidden_indicator = 2
+ elif tag in [T_PSTRING_SIZE_IS, T_PWSTRING_SIZE_IS] and p.IsIn():
+ self.params[td[1]].hidden_indicator = 1
+
+ def IsGetter(self):
+ return (self.flags & XPT_MD_GETTER)
+ def IsSetter(self):
+ return (self.flags & XPT_MD_SETTER)
+ def IsNotXPCOM(self):
+ return (self.flags & XPT_MD_NOTXPCOM)
+ def IsConstructor(self):
+ return (self.flags & XPT_MD_CTOR)
+ def IsHidden(self):
+ return (self.flags & XPT_MD_HIDDEN)
+
+ def Describe_Python(self):
+ if self.method_index < 3: # Ignore QI etc
+ return ""
+ base_name = self.name
+ if self.IsGetter():
+ name = "get_%s" % (base_name,)
+ elif self.IsSetter():
+ name = "set_%s" % (base_name,)
+ else:
+ name = base_name
+ param_decls = ["self"]
+ in_comments = []
+ out_descs = []
+ result_comment = "Result: void - None"
+ for p in self.params:
+ in_desc, in_desc_comments, out_desc, this_result_comment = p.Describe_Python()
+ if in_desc is not None:
+ param_decls.append(in_desc)
+ if in_desc_comments is not None:
+ in_comments.append(in_desc_comments)
+ if out_desc is not None:
+ out_descs.append(out_desc)
+ if this_result_comment is not None:
+ result_comment = this_result_comment
+ joiner = "\n # "
+ in_comment = out_desc = ""
+ if in_comments: in_comment = joiner + joiner.join(in_comments)
+ if out_descs: out_desc = joiner + joiner.join(out_descs)
+
+ return """ def %s( %s ):
+ # %s%s%s
+ pass""" % (name, ", ".join(param_decls), result_comment, in_comment, out_desc)
+
+ def Describe(self):
+ s = ''
+ if self.IsGetter():
+ G = 'G'
+ else:
+ G = ' '
+ if self.IsSetter():
+ S = 'S'
+ else: S = ' '
+ if self.IsHidden():
+ H = 'H'
+ else:
+ H = ' '
+ if self.IsNotXPCOM():
+ N = 'N'
+ else:
+ N = ' '
+ if self.IsConstructor():
+ C = 'C'
+ else:
+ C = ' '
+
+ def desc(a): return a.Describe()
+ method_desc = string.join(list(map(desc, self.params)), ', ')
+ result_type = TypeDescriber(self.result_desc[0], None)
+ return_desc = result_type.Describe()
+ i = string.find(return_desc, 'retval ')
+ if i != -1:
+ return_desc = return_desc[:i] + return_desc[i+len('retval '):]
+ return G+S+H+N+C+' '+return_desc+' '+self.name + '('+ method_desc + ');'
+
+class Parameter:
+ def __init__(self, param_desc, param_index, method_index, interface_info = None):
+ self.param_flags, self.type_desc = param_desc
+ self.hidden_indicator = 0 # Is this a special "size" type param that will be hidden from Python?
+ self.param_index = param_index
+ self.method_index= method_index
+ self.interface_info = interface_info
+ def __repr__(self):
+ return "<param %(param_index)d (method %(method_index)d) - flags = 0x%(param_flags)x, type = %(type_desc)s>" % self.__dict__
+ def IsIn(self):
+ return XPT_PD_IS_IN(self.param_flags)
+ def IsOut(self):
+ return XPT_PD_IS_OUT(self.param_flags)
+ def IsInOut(self):
+ return self.IsIn() and self.IsOut()
+ def IsRetval(self):
+ return XPT_PD_IS_RETVAL(self.param_flags)
+ def IsShared(self):
+ return XPT_PD_IS_SHARED(self.param_flags)
+ def IsDipper(self):
+ return XPT_PD_IS_DIPPER(self.param_flags)
+
+ def Describe_Python(self):
+ name = "param%d" % (self.param_index,)
+ if self.hidden_indicator:
+ # Could remove the comment - Im trying to tell the user where that param has
+ # gone from the signature!
+ return None, "%s is a hidden parameter" % (name,), None, None
+ t = TypeDescriber(self.type_desc[0], self)
+ decl = in_comment = out_comment = result_comment = None
+ type_desc = t.Describe()
+ if self.IsIn() and not self.IsDipper():
+ decl = name
+ extra=""
+ if self.IsOut():
+ extra = "Out"
+ in_comment = "In%s: %s: %s" % (extra, name, type_desc)
+ elif self.IsOut() or self.IsDipper():
+ if self.IsRetval():
+ result_comment = "Result: %s" % (type_desc,)
+ else:
+ out_comment = "Out: %s" % (type_desc,)
+ return decl, in_comment, out_comment, result_comment
+
+ def Describe(self):
+ parts = []
+ if self.IsInOut():
+ parts.append('inout')
+ elif self.IsIn():
+ parts.append('in')
+ elif self.IsOut():
+ parts.append('out')
+
+ if self.IsDipper(): parts.append("dipper")
+ if self.IsRetval(): parts.append('retval')
+ if self.IsShared(): parts.append('shared')
+ t = TypeDescriber(self.type_desc[0], self)
+ type_str = t.Describe()
+ parts.append(type_str)
+ return string.join(parts)
+
+# A class that allows caching and iterating of constants.
+class Constants:
+ def __init__(self, interface_info):
+ self.interface_info = interface_info
+ try:
+ self.items = [None] * interface_info.GetConstantCount()
+ except xpcom.Exception:
+ if xpcom.verbose:
+ print("** GetConstantCount failed?? - assuming no constants")
+ self.items = []
+ def __len__(self):
+ return len(self.items)
+ def __getitem__(self, index):
+ ret = self.items[index]
+ if ret is None:
+ ci = self.interface_info.GetConstant(index)
+ ret = self.items[index] = Constant(ci)
+ return ret
+
+class Constant:
+ def __init__(self, ci):
+ self.name, self.type, self.value = ci
+
+ def Describe(self):
+ return TypeDescriber(self.type, None).Describe() + ' ' +self.name+' = '+str(self.value)+';'
+
+ __str__ = Describe
+
+def MakeReprForInvoke(param):
+ tag = param.type_desc[0] & XPT_TDP_TAGMASK
+ if tag == T_INTERFACE:
+ i_info = param.interface_info
+ try:
+ iid = i_info.GetIIDForParam(param.method_index, param.param_index)
+ except xpcom.Exception:
+ # IID not available (probably not scriptable) - just use nsISupports.
+ iid = xpcom._xpcom.IID_nsISupports
+ return param.type_desc[0], 0, 0, str(iid)
+ elif tag == T_ARRAY:
+ i_info = param.interface_info
+ array_desc = i_info.GetTypeForParam(param.method_index, param.param_index, 1)
+ return param.type_desc[:-1] + array_desc[:1]
+ return param.type_desc
+
+
+class TypeDescriber:
+ def __init__(self, type_flags, param):
+ self.type_flags = type_flags
+ self.tag = XPT_TDP_TAG(self.type_flags)
+ self.param = param
+ def IsPointer(self):
+ return XPT_TDP_IS_POINTER(self.type_flags)
+ def IsUniquePointer(self):
+ return XPT_TDP_IS_UNIQUE_POINTER(self.type_flags)
+ def IsReference(self):
+ return XPT_TDP_IS_REFERENCE(self.type_flags)
+ def repr_for_invoke(self):
+ return (self.type_flags,)
+ def GetName(self):
+ is_ptr = self.IsPointer()
+ data = type_info_map.get(self.tag)
+ if data is None:
+ data = ("unknown",)
+ if self.IsReference():
+ if len(data) > 2:
+ return data[2]
+ return data[0] + " &"
+ if self.IsPointer():
+ if len(data)>1:
+ return data[1]
+ return data[0] + " *"
+ return data[0]
+
+ def Describe(self):
+ if self.tag == T_ARRAY:
+ # NOTE - Adding a type specifier to the array is different from xpt_dump.exe
+ if self.param is None or self.param.interface_info is None:
+ type_desc = "" # Dont have explicit info about the array type :-(
+ else:
+ i_info = self.param.interface_info
+ type_code = i_info.GetTypeForParam(self.param.method_index, self.param.param_index, 1)
+ type_desc = TypeDescriber( type_code[0], None).Describe()
+ return self.GetName() + "[" + type_desc + "]"
+ elif self.tag == T_INTERFACE:
+ if self.param is None or self.param.interface_info is None:
+ return "nsISomething" # Dont have explicit info about the IID :-(
+ i_info = self.param.interface_info
+ m_index = self.param.method_index
+ p_index = self.param.param_index
+ try:
+ iid = i_info.GetIIDForParam(m_index, p_index)
+ return iid.name
+ except xpcom.Exception:
+ return "nsISomething"
+ return self.GetName()
+
+# These are just for output purposes, so should be
+# the same as xpt_dump uses
+type_info_map = {
+ T_I8 : ("int8",),
+ T_I16 : ("int16",),
+ T_I32 : ("int32",),
+ T_I64 : ("int64",),
+ T_U8 : ("uint8",),
+ T_U16 : ("uint16",),
+ T_U32 : ("uint32",),
+ T_U64 : ("uint64",),
+ T_FLOAT : ("float",),
+ T_DOUBLE : ("double",),
+ T_BOOL : ("boolean",),
+ T_CHAR : ("char",),
+ T_WCHAR : ("wchar_t", "wstring"),
+ T_VOID : ("void",),
+ T_IID : ("reserved", "nsIID *", "nsIID &"),
+ T_DOMSTRING : ("DOMString",),
+ T_CHAR_STR : ("reserved", "string"),
+ T_WCHAR_STR : ("reserved", "wstring"),
+ T_INTERFACE : ("reserved", "Interface"),
+ T_INTERFACE_IS : ("reserved", "InterfaceIs *"),
+ T_ARRAY : ("reserved", "Array"),
+ T_PSTRING_SIZE_IS : ("reserved", "string_s"),
+ T_PWSTRING_SIZE_IS : ("reserved", "wstring_s"),
+}
+
+def dump_interface(iid, mode):
+ interface = Interface(iid)
+ describer_name = "Describe"
+ if mode == "xptinfo": mode = None
+ if mode is not None:
+ describer_name = describer_name + "_" + mode.capitalize()
+ describer = getattr(interface, describer_name)
+ print(describer())
+
+if __name__=='__main__':
+ if len(sys.argv) == 1:
+ print("Usage: xpt.py [-xptinfo] interface_name, ...")
+ print(" -info: Dump in a style similar to the xptdump tool")
+ print("Dumping nsISupports and nsIInterfaceInfo")
+ sys.argv.append('nsIInterfaceInfo')
+ sys.argv.append('-xptinfo')
+ sys.argv.append('nsISupports')
+ sys.argv.append('nsIInterfaceInfo')
+
+ mode = "Python"
+ for i in sys.argv[1:]:
+ if i[0] == "-":
+ mode = i[1:]
+ else:
+ dump_interface(i, mode)