summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/python/src/PyIID.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/xpcom18a4/python/src/PyIID.cpp')
-rw-r--r--src/libs/xpcom18a4/python/src/PyIID.cpp410
1 files changed, 410 insertions, 0 deletions
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;
+}