⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 siplib.c

📁 这是关于RFC3261实现sip的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * SIP library code. * * Copyright (c) 2006 * 	Riverbank Computing Limited <info@riverbankcomputing.co.uk> *  * This file is part of SIP. *  * This copy of SIP is licensed for use under the terms of the SIP License * Agreement.  See the file LICENSE for more details. *  * SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */#include <Python.h>#include <stdio.h>#include <stdarg.h>#include <stddef.h>#include <string.h>#include "sip.h"#include "sipint.h"/* * These are the functions that make up the public and private SIP API. */static void sip_api_bad_catcher_result(PyObject *method);static void sip_api_bad_length_for_slice(int seqlen,int slicelen);static PyObject *sip_api_build_result(int *isErr,char *fmt,...);static PyObject *sip_api_call_method(int *isErr,PyObject *method,char *fmt,				     ...);static PyObject *sip_api_class_name(PyObject *self);static int sip_api_convert_from_sequence_index(int idx,int len);static int sip_api_can_convert_to_instance(PyObject *pyObj,					   sipWrapperType *type, int flags);static int sip_api_can_convert_to_mapped_type(PyObject *pyObj,					      const sipMappedType *mt,					      int flags);static void *sip_api_convert_to_instance(PyObject *pyObj, sipWrapperType *type,					 PyObject *transferObj, int flags,					 int *statep, int *iserrp);static void *sip_api_convert_to_mapped_type(PyObject *pyObj,					    const sipMappedType *mt,					    PyObject *transferObj, int flags,					    int *statep, int *iserrp);static void *sip_api_force_convert_to_instance(PyObject *pyObj,					       sipWrapperType *type,					       PyObject *transferObj,					       int flags, int *statep,					       int *iserrp);static void *sip_api_force_convert_to_mapped_type(PyObject *pyObj,						  const sipMappedType *mt,						  PyObject *transferObj,						  int flags, int *statep,						  int *iserrp);static void sip_api_release_instance(void *cpp, sipWrapperType *type,				     int state);static void sip_api_release_mapped_type(void *cpp, const sipMappedType *mt,					int state);static PyObject *sip_api_convert_from_new_instance(void *cpp,						   sipWrapperType *type,						   PyObject *transferObj);static PyObject *sip_api_convert_from_mapped_type(void *cpp,						  const sipMappedType *mt,						  PyObject *transferObj);static void *sip_api_convert_to_cpp(PyObject *sipSelf,sipWrapperType *type,				    int *iserrp);static int sip_api_get_state(PyObject *transferObj);static const sipMappedType *sip_api_find_mapped_type(const char *type);static PyObject *sip_api_get_wrapper(void *cppPtr,sipWrapperType *type);static sipWrapperType *sip_api_map_int_to_class(int typeInt,						const sipIntTypeClassMap *map,						int maplen);static sipWrapperType *sip_api_map_string_to_class(const char *typeString,						   const sipStringTypeClassMap *map,						   int maplen);static int sip_api_parse_result(int *isErr,PyObject *method,PyObject *res,				char *fmt,...);static void sip_api_trace(unsigned mask,const char *fmt,...);static void sip_api_transfer(PyObject *self,int toCpp);static void sip_api_transfer_back(PyObject *self);static void sip_api_transfer_to(PyObject *self,PyObject *owner);static int sip_api_export_module(sipExportedModuleDef *client,				 unsigned api_major,unsigned api_minor,				 PyObject *mod_dict);static int sip_api_parse_args(int *argsParsedp,PyObject *sipArgs,char *fmt,			      ...);static int sip_api_parse_pair(int *argsParsedp,PyObject *sipArg0,			      PyObject *sipArg1,char *fmt,...);static void sip_api_common_ctor(sipMethodCache *cache,int nrmeths);static void sip_api_common_dtor(sipWrapper *sipSelf);static void *sip_api_convert_to_void_ptr(PyObject *obj);static void sip_api_no_function(int argsParsed,char *func);static void sip_api_no_method(int argsParsed,char *classname,char *method);static void sip_api_abstract_method(char *classname,char *method);static void sip_api_bad_class(const char *classname);static void sip_api_bad_set_type(const char *classname,const char *var);static void *sip_api_get_complex_cpp_ptr(sipWrapper *w);static PyObject *sip_api_is_py_method(sip_gilstate_t *gil,sipMethodCache *pymc,				      sipWrapper *sipSelf,char *cname,				      char *mname);static void sip_api_call_hook(char *hookname);static void sip_api_raise_unknown_exception(void);static void sip_api_raise_class_exception(sipWrapperType *type,void *ptr);static void sip_api_raise_sub_class_exception(sipWrapperType *type,void *ptr);static int sip_api_add_class_instance(PyObject *dict,char *name,void *cppPtr,				      sipWrapperType *wt);static int sip_api_add_mapped_type_instance(PyObject *dict,char *name,					    void *cppPtr, sipMappedType *mt);static int sip_api_add_enum_instance(PyObject *dict, char *name, int value,				     PyTypeObject *type);static void sip_api_bad_operator_arg(PyObject *self, PyObject *arg,				     sipPySlotType st);static PyObject *sip_api_pyslot_extend(sipExportedModuleDef *mod,				       sipPySlotType st, sipWrapperType *type,				       PyObject *arg0, PyObject *arg1);static void sip_api_add_delayed_dtor(sipWrapper *w);static unsigned long sip_api_long_as_unsigned_long(PyObject *o);/* * The data structure that represents the SIP API. */static const sipAPIDef sip_api = {	/* This must be first. */	sip_api_export_module,	/*	 * The following are part of the public API.	 */	sip_api_bad_catcher_result,	sip_api_bad_length_for_slice,	sip_api_build_result,	sip_api_call_method,	sip_api_class_name,	sip_api_connect_rx,	sip_api_convert_from_sequence_index,	sip_api_can_convert_to_instance,	sip_api_can_convert_to_mapped_type,	sip_api_convert_to_instance,	sip_api_convert_to_mapped_type,	sip_api_force_convert_to_instance,	sip_api_force_convert_to_mapped_type,	sip_api_release_instance,	sip_api_release_mapped_type,	sip_api_convert_from_instance,	sip_api_convert_from_new_instance,	sip_api_convert_from_mapped_type,	sip_api_convert_to_cpp,	sip_api_get_state,	sip_api_find_mapped_type,	sip_api_disconnect_rx,	sip_api_emit_signal,	sip_api_free,	sip_api_get_sender,	sip_api_get_wrapper,	sip_api_malloc,	sip_api_map_int_to_class,	sip_api_map_string_to_class,	sip_api_parse_result,	sip_api_trace,	sip_api_transfer,	sip_api_transfer_back,	sip_api_transfer_to,	sip_api_wrapper_check,	sip_api_long_as_unsigned_long,	/*	 * The following may be used by Qt support code but by no other	 * handwritten code.	 */	sip_api_convert_from_named_enum,	sip_api_convert_from_void_ptr,	sip_api_free_connection,	sip_api_emit_to_slot,	sip_api_same_connection,	sip_api_convert_rx,	/*	 * The following are not part of the public API.	 */	sip_api_parse_args,	sip_api_parse_pair,	sip_api_common_ctor,	sip_api_common_dtor,	sip_api_convert_to_void_ptr,	sip_api_no_function,	sip_api_no_method,	sip_api_abstract_method,	sip_api_bad_class,	sip_api_bad_set_type,	sip_api_get_cpp_ptr,	sip_api_get_complex_cpp_ptr,	sip_api_is_py_method,	sip_api_call_hook,	sip_api_start_thread,	sip_api_end_thread,	sip_api_raise_unknown_exception,	sip_api_raise_class_exception,	sip_api_raise_sub_class_exception,	sip_api_add_class_instance,	sip_api_add_enum_instance,	sip_api_bad_operator_arg,	sip_api_pyslot_extend,	sip_api_add_delayed_dtor,	sip_api_add_mapped_type_instance,};#define	PARSE_OK	0x00000000		/* Parse is Ok so far. */#define	PARSE_MANY	0x10000000		/* Too many arguments. */#define	PARSE_FEW	0x20000000		/* Too few arguments. */#define	PARSE_TYPE	0x30000000		/* Argument with a bad type. */#define	PARSE_UNBOUND	0x40000000		/* Unbound method. */#define	PARSE_FORMAT	0x50000000		/* Bad format character. */#define	PARSE_RAISED	0x60000000		/* Exception already raised. */#define	PARSE_STICKY	0x80000000		/* The error sticks. */#define	PARSE_MASK	0xf0000000/* * Note that some of the following flags safely share values because they * cannot be used at the same time. */#define	FORMAT_DEREF		0x01	/* The pointer will be dereferenced. */#define	FORMAT_FACTORY		0x02	/* Implement /Factory/ in a VH. */#define	FORMAT_TRANSFER		0x02	/* Implement /Transfer/. */#define	FORMAT_NO_STATE		0x04	/* Don't return the C/C++ state. */#define	FORMAT_TRANSFER_BACK	0x04	/* Implement /TransferBack/. */#define	FORMAT_GET_WRAPPER	0x08	/* Implement /GetWrapper/. */#define	FORMAT_NO_CONVERTORS	0x10	/* Suppress any convertors. */#define	SIP_MC_FOUND	0x01		/* If we have looked for the method. */#define	SIP_MC_ISMETH	0x02		/* If we looked and there was one. */#define	sipFoundMethod(m)	((m) -> mcflags & SIP_MC_FOUND)#define	sipSetFoundMethod(m)	((m) -> mcflags |= SIP_MC_FOUND)#define	sipIsMethod(m)		((m) -> mcflags & SIP_MC_ISMETH)#define	sipSetIsMethod(m)	((m) -> mcflags |= SIP_MC_ISMETH)static PyTypeObject sipWrapperType_Type;static sipWrapperType sipWrapper_Type;static PyTypeObject sipVoidPtr_Type;PyInterpreterState *sipInterpreter = NULL;sipQtAPI *sipQtSupport = NULL;sipWrapperType *sipQObjectClass;/* * Various strings as Python objects created as and when needed. */static PyObject *licenseName = NULL;static PyObject *licenseeName = NULL;static PyObject *typeName = NULL;static PyObject *timestampName = NULL;static PyObject *signatureName = NULL;static sipObjectMap cppPyMap;			/* The C/C++ to Python map. */static sipExportedModuleDef *clientList = NULL;	/* List of registered clients. */static unsigned traceMask = 0;			/* The current trace mask. */static sipTypeDef *currentType = NULL;		/* The type being created. */static void addSlots(sipWrapperType *wt, sipTypeDef *td);static void initSlots(PyTypeObject *to, PyNumberMethods *nb, PySequenceMethods *sq, PyMappingMethods *mp, sipPySlotDef *slots, int force);static void *findSlot(PyObject *self,sipPySlotType st);static void *findSlotInType(sipTypeDef *td, sipPySlotType st);static int objobjargprocSlot(PyObject *self,PyObject *arg1,PyObject *arg2,			     sipPySlotType st);static int intobjargprocSlot(PyObject *self,int arg1,PyObject *arg2,			     sipPySlotType st);static PyObject *buildObject(PyObject *tup,char *fmt,va_list va);static int parsePass1(sipWrapper **selfp,int *selfargp,int *argsParsedp,		      PyObject *sipArgs,char *fmt,va_list va);static int parsePass2(sipWrapper *self,int selfarg,int nrargs,		      PyObject *sipArgs,char *fmt,va_list va);static int getSelfFromArgs(sipWrapperType *type,PyObject *args,int argnr,			   sipWrapper **selfp);static PyObject *createEnumMember(sipTypeDef *td, sipEnumMemberDef *enm);static PyObject *handleGetLazyAttr(PyObject *nameobj,sipWrapperType *wt,				   sipWrapper *w);static int handleSetLazyAttr(PyObject *nameobj,PyObject *valobj,			     sipWrapperType *wt,sipWrapper *w);static int getNonStaticVariables(sipWrapperType *wt,sipWrapper *w,				 PyObject **ndict);static void findLazyAttr(sipWrapperType *wt,char *name,PyMethodDef **pmdp,			 sipEnumMemberDef **enmp,PyMethodDef **vmdp,			 sipTypeDef **in);static int compareMethodName(const void *key,const void *el);static int compareEnumMemberName(const void *key,const void *el);static int checkPointer(void *ptr);static void badArgs(int argsParsed,char *classname,char *method);static void finalise(void);static sipWrapperType *createType(sipExportedModuleDef *client,				  sipTypeDef *type, PyObject *mod_dict);static PyTypeObject *createEnum(sipExportedModuleDef *client, sipEnumDef *ed,				PyObject *mod_dict);static const char *getBaseName(const char *name);static PyObject *getBaseNameObject(const char *name);static PyObject *createTypeDict(PyObject *mname);static sipExportedModuleDef *getClassModule(sipEncodedClassDef *enc,					    sipExportedModuleDef *em);static sipWrapperType *getClassType(sipEncodedClassDef *enc,				    sipExportedModuleDef *em);static sipWrapperType *convertSubClass(sipWrapperType *type,void **cppPtr);static void *getPtrTypeDef(sipWrapper *self, sipTypeDef **td);static int addInstances(PyObject *dict,sipInstancesDef *id);static int addVoidPtrInstances(PyObject *dict,sipVoidPtrInstanceDef *vi);static int addCharInstances(PyObject *dict,sipCharInstanceDef *ci);static int addStringInstances(PyObject *dict,sipStringInstanceDef *si);static int addIntInstances(PyObject *dict, sipIntInstanceDef *ii);static int addLongInstances(PyObject *dict,sipLongInstanceDef *li);static int addUnsignedLongInstances(PyObject *dict, sipUnsignedLongInstanceDef *uli);static int addLongLongInstances(PyObject *dict,sipLongLongInstanceDef *lli);static int addUnsignedLongLongInstances(PyObject *dict, sipUnsignedLongLongInstanceDef *ulli);static int addDoubleInstances(PyObject *dict,sipDoubleInstanceDef *di);static int addEnumInstances(PyObject *dict,sipEnumInstanceDef *ei);static int addSingleEnumInstance(PyObject *dict, char *name, int value,				 PyTypeObject *type);static int addClassInstances(PyObject *dict,sipClassInstanceDef *ci);static int addSingleClassInstance(PyObject *dict,char *name,void *cppPtr,				  sipWrapperType *wt,int initflags);static int addLicense(PyObject *dict,sipLicenseDef *lc);static PyObject *cast(PyObject *self,PyObject *args);static PyObject *setTraceMask(PyObject *self,PyObject *args);static PyObject *wrapInstance(PyObject *self,PyObject *args);static PyObject *unwrapInstance(PyObject *self,PyObject *args);static PyObject *transfer(PyObject *self,PyObject *args);static PyObject *transferback(PyObject *self,PyObject *args);static PyObject *transferto(PyObject *self,PyObject *args);static int sipWrapperType_Check(PyObject *op);static void addToParent(sipWrapper *self, sipWrapper *owner);static void removeFromParent(sipWrapper *self);static int findClassArg(sipExportedModuleDef *emd, const char *name,			size_t len, sipSigArg *at, int indir);static int findMtypeArg(sipMappedType **mttab, const char *name, size_t len,			sipSigArg *at, int indir);static int findEnumArg(sipExportedModuleDef *emd, const char *name, size_t len,		       sipSigArg *at, int indir);static int sameScopedName(const char *pyname, const char *name, size_t len);static int nameEq(const char *with, const char *name, size_t len);static int isExactWrappedType(sipWrapperType *wt);/* * The Python module initialisation function. */#if defined(SIP_STATIC_MODULE)void initsip(void)#elsePyMODINIT_FUNC initsip(void)#endif{	static PyMethodDef methods[] = {		{"cast", cast, METH_VARARGS, NULL},		{"settracemask", setTraceMask, METH_VARARGS, NULL},		{"transfer", transfer, METH_VARARGS, NULL},		{"transferback", transferback, METH_VARARGS, NULL},		{"transferto", transferto, METH_VARARGS, NULL},		{"wrapinstance", wrapInstance, METH_VARARGS, NULL},		{"unwrapinstance", unwrapInstance, METH_VARARGS, NULL},		{NULL, NULL, 0, NULL}	};	int rc;	PyObject *mod, *mod_dict, *obj;#ifdef WITH_THREAD	PyEval_InitThreads();#endif	/* Initialise the types. */	sipWrapperType_Type.tp_base = &PyType_Type;	if (PyType_Ready(&sipWrapperType_Type) < 0)		Py_FatalError("sip: Failed to initialise sip.wrappertype type");	if (PyType_Ready(&sipWrapper_Type.super.type) < 0)		Py_FatalError("sip: Failed to initialise sip.wrapper type");	if (PyType_Ready(&sipVoidPtr_Type) < 0)		Py_FatalError("sip: Failed to initialise sip.voidptr type");	mod = Py_InitModule("sip",methods);	mod_dict = PyModule_GetDict(mod);	/* Publish the SIP API. */	if ((obj = PyCObject_FromVoidPtr((void *)&sip_api,NULL)) == NULL)		Py_FatalError("sip: Failed to create _C_API object");	rc = PyDict_SetItemString(mod_dict,"_C_API",obj);	Py_DECREF(obj);	if (rc < 0)		Py_FatalError("sip: Failed to add _C_API object to module dictionary");	/* Add the SIP version number, but don't worry about errors. */	if ((obj = PyInt_FromLong(SIP_VERSION)) != NULL)	{		PyDict_SetItemString(mod_dict, "SIP_VERSION", obj);		Py_DECREF(obj);	}	if ((obj = PyString_FromString(SIP_VERSION_STR)) != NULL)	{		PyDict_SetItemString(mod_dict, "SIP_VERSION_STR", obj);		Py_DECREF(obj);	}	/* Add the type objects, but don't worry about errors. */	PyDict_SetItemString(mod_dict, "wrappertype", (PyObject *)&sipWrapperType_Type);	PyDict_SetItemString(mod_dict, "wrapper", (PyObject *)&sipWrapper_Type);	PyDict_SetItemString(mod_dict, "voidptr", (PyObject *)&sipVoidPtr_Type);	/* Initialise the module if it hasn't already been done. */	if (sipInterpreter == NULL)	{		Py_AtExit(finalise);		/* Initialise the object map. */		sipOMInit(&cppPyMap);		sipQtSupport = NULL;		/*		 * Get the current interpreter.  This will be shared between		 * all threads.		 */		sipInterpreter = PyThreadState_Get() -> interp;	}}/* * Display a printf() style message to stderr according to the current trace * mask. */static void sip_api_trace(unsigned mask,const char *fmt,...){	va_list ap;	va_start(ap,fmt);	if (mask & traceMask)		vfprintf(stderr,fmt,ap);	va_end(ap);}/* * Set the trace mask. */static PyObject *setTraceMask(PyObject *self,PyObject *args){	unsigned new_mask;	if (PyArg_ParseTuple(args,"I:settracemask",&new_mask))	{		traceMask = new_mask;		Py_INCREF(Py_None);		return Py_None;	}	return NULL;}/* * Transfer the ownership of an instance to C/C++. */static PyObject *transferto(PyObject *self,PyObject *args){	PyObject *w, *owner;	if (PyArg_ParseTuple(args,"O!O:transferto",&sipWrapper_Type,&w,&owner))	{		if (owner == Py_None)			owner = NULL;		else if (!sip_api_wrapper_check(owner))		{			PyErr_Format(PyExc_TypeError,"transferto() argument 2 must be sip.wrapper, not %s",owner->ob_type->tp_name);			return NULL;		}		sip_api_transfer_to(w, owner);		Py_INCREF(Py_None);		return Py_None;	}	return NULL;}/* * Transfer the ownership of an instance to Python. */static PyObject *transferback(PyObject *self,PyObject *args){	PyObject *w;	if (PyArg_ParseTuple(args,"O!:transferback",&sipWrapper_Type,&w))	{		sip_api_transfer_back(w);		Py_INCREF(Py_None);		return Py_None;	}	return NULL;}/* * Transfer the ownership of an instance.  This is deprecated. */static PyObject *transfer(PyObject *self,PyObject *args){	PyObject *w;	int toCpp;	if (PyArg_ParseTuple(args,"O!i:transfer",&sipWrapper_Type,&w,&toCpp))	{		if (toCpp)			sip_api_transfer_to(w, NULL);		else			sip_api_transfer_back(w);		Py_INCREF(Py_None);		return Py_None;	}	return NULL;}/* * Cast an instance to one of it's sub or super-classes by returning a new * Python object with the superclass type wrapping the same C++ instance. */static PyObject *cast(PyObject *self,PyObject *args){	sipWrapper *w;	sipWrapperType *wt, *type;	void *addr;	PyTypeObject *ft, *tt;	if (!PyArg_ParseTuple(args,"O!O!:cast",&sipWrapper_Type,&w,&sipWrapperType_Type,&wt))		return NULL;	ft = ((PyObject *)w) -> ob_type;	tt = (PyTypeObject *)wt;	if (ft == tt || PyType_IsSubtype(tt, ft))		type = NULL;	else if (PyType_IsSubtype(ft, tt))		type = wt;	else	{		PyErr_SetString(PyExc_TypeError,"argument 1 of sip.cast() must be an instance of a sub or super-type of argument 2");		return NULL;	}	if ((addr = sip_api_get_cpp_ptr(w, type)) == NULL)		return NULL;	/*	 * We don't put this new object into the map so that the original	 * object is always found.  It would also totally confuse the map	 * logic.	 */	return sipWrapSimpleInstance(addr,wt,NULL,(w->flags | SIP_NOT_IN_MAP) & ~SIP_PY_OWNED);}/* * Unwrap an instance. */static PyObject *unwrapInstance(PyObject *self,PyObject *args){	sipWrapper *w;	if (PyArg_ParseTuple(args,"O!:unwrapinstance",&sipWrapper_Type,&w))	{		void *addr;		/*		 * We just get the pointer but don't try and cast it (which		 * isn't needed and wouldn't work with the way casts are		 * currently implemented if we are unwrapping something derived		 * from a wrapped class).		 */		if ((addr = sip_api_get_cpp_ptr(w,NULL)) == NULL)			return NULL;		return PyLong_FromVoidPtr(addr);	}	return NULL;}/* * Wrap an instance. */static PyObject *wrapInstance(PyObject *self,PyObject *args){	unsigned long addr;	sipWrapperType *wt;	if (PyArg_ParseTuple(args,"kO!:wrapinstance",&addr,&sipWrapperType_Type,&wt))		return sip_api_convert_from_instance((void *)addr, wt, NULL);	return NULL;}/* * Register a client module.  A negative value is returned and an exception * raised if there was an error.  Not normally needed by handwritten code.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -