1/* Copyright (c) 1996,97 by Lele Gaifax. All Rights Reserved 2 * With various updates by Ronald Oussoren and others ((C) 2002, 2003) 3 * 4 * This software may be used and distributed freely for any purpose 5 * provided that this notice is included unchanged on any and all 6 * copies. The author does not warrant or guarantee this software in 7 * any way. 8 * 9 * This file is part of the PyObjC package. 10 * 11 * Created Mon Oct 28 12:38:18 1996. 12 * 13 */ 14 15#include "pyobjc.h" 16 17int PyObjCPointer_RaiseException = 0; 18 19static void 20PyObjCPointer_dealloc (PyObject* _self) 21{ 22 PyObjCPointer* self = (PyObjCPointer*)_self; 23 Py_DECREF (self->type); 24 PyObject_Free((PyObject*)self); 25} 26 27PyDoc_STRVAR(PyObjCPointer_unpack_doc, 28 "Unpack the pointed value accordingly to its type.\n" 29 "obj.unpack() -> value"); 30static PyObject * 31PyObjCPointer_unpack (PyObject* _self) 32{ 33 PyObjCPointer* self = (PyObjCPointer*)_self; 34 35 if (self->ptr) { 36 const char *type = PyBytes_AS_STRING (self->type); 37 38 if (*type == _C_VOID) { 39 PyErr_SetString (PyObjCExc_Error, 40 "Cannot dereference a pointer to void"); 41 return NULL; 42 } else { 43 return pythonify_c_value (type, self->ptr); 44 } 45 } else { 46 Py_INCREF (Py_None); 47 return Py_None; 48 } 49} 50 51static PyMethodDef PyObjCPointer_methods[] = 52{ 53 { 54 "unpack", 55 (PyCFunction)PyObjCPointer_unpack, 56 METH_NOARGS, 57 PyObjCPointer_unpack_doc 58 }, 59 { 0, 0, 0, 0 } 60}; 61 62static PyMemberDef PyObjCPointer_members[] = { 63 { 64 "type", 65 T_OBJECT, 66 offsetof(PyObjCPointer, type), 67 READONLY, 68 NULL 69 }, 70 { 71 "pointerAsInteger", 72 T_INT, 73 offsetof(PyObjCPointer, ptr), 74 READONLY, 75 NULL 76 }, 77 { 0, 0, 0, 0, 0 } 78}; 79 80PyTypeObject PyObjCPointer_Type = 81{ 82 PyVarObject_HEAD_INIT(&PyType_Type, 0) 83 "PyObjCPointer", /* tp_name */ 84 sizeof (PyObjCPointer), /* tp_basicsize */ 85 sizeof (char), /* tp_itemsize */ 86 87 /* methods */ 88 PyObjCPointer_dealloc, /* tp_dealloc */ 89 0, /* tp_print */ 90 0, /* tp_getattr */ 91 0, /* tp_setattr */ 92 0, /* tp_compare */ 93 0, /* tp_repr */ 94 0, /* tp_as_number */ 95 0, /* tp_as_sequence */ 96 0, /* tp_as_mapping */ 97 0, /* tp_hash */ 98 0, /* tp_call */ 99 0, /* tp_str */ 100 0, /* tp_getattro */ 101 0, /* tp_setattro */ 102 0, /* tp_as_buffer */ 103 Py_TPFLAGS_DEFAULT, /* tp_flags */ 104 "Wrapper around a Objective-C Pointer", /* tp_doc */ 105 0, /* tp_traverse */ 106 0, /* tp_clear */ 107 0, /* tp_richcompare */ 108 0, /* tp_weaklistoffset */ 109 0, /* tp_iter */ 110 0, /* tp_iternext */ 111 PyObjCPointer_methods, /* tp_methods */ 112 PyObjCPointer_members, /* tp_members */ 113 0, /* tp_getset */ 114 0, /* tp_base */ 115 0, /* tp_dict */ 116 0, /* tp_descr_get */ 117 0, /* tp_descr_set */ 118 0, /* tp_dictoffset */ 119 0, /* tp_init */ 120 0, /* tp_alloc */ 121 0, /* tp_new */ 122 0, /* tp_free */ 123 0, /* tp_is_gc */ 124 0, /* tp_bases */ 125 0, /* tp_mro */ 126 0, /* tp_cache */ 127 0, /* tp_subclasses */ 128 0, /* tp_weaklist */ 129 0 /* tp_del */ 130#if PY_VERSION_HEX >= 0x02060000 131 , 0 /* tp_version_tag */ 132#endif 133 134}; 135 136PyObjCPointer * 137PyObjCPointer_New(void *p, const char *t) 138{ 139 Py_ssize_t size = PyObjCRT_SizeOfType (t); 140 const char *typeend = PyObjCRT_SkipTypeSpec (t); 141 PyObjCPointer *self; 142 143 if (PyObjCPointer_RaiseException) { 144 PyErr_Format(PyObjCExc_UnknownPointerError, 145 "pointer of type %s", t); 146 return NULL; 147 } 148 NSLog(@"PyObjCPointer created: at %p of type %s", p, t); 149 150 if (size == -1) { 151 return NULL; 152 } 153 if (typeend == NULL) { 154 return NULL; 155 } 156 157 self = PyObject_NEW_VAR (PyObjCPointer, &PyObjCPointer_Type, size); 158 if (self == NULL) { 159 return NULL; 160 } 161 162 self->type = PyBytes_FromStringAndSize ((char *) t, typeend-t); 163 164 if (size && p) { 165 memcpy ((self->ptr = self->contents), p, size); 166 } else { 167 self->ptr = p; 168 } 169 170 return self; 171} 172