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
17static void
18PyObjCPointer_dealloc (PyObject* _self)
19{
20	PyObjCPointer* self = (PyObjCPointer*)_self;
21	Py_DECREF (self->type);
22	PyObject_Free((PyObject*)self);
23}
24
25PyDoc_STRVAR(PyObjCPointer_unpack_doc,
26	"Unpack the pointed value accordingly to its type.\n"
27        "obj.unpack() -> value");
28static PyObject *
29PyObjCPointer_unpack (PyObject* _self)
30{
31	PyObjCPointer* self = (PyObjCPointer*)_self;
32
33	if (self->ptr) {
34		const char *type = PyString_AS_STRING (self->type);
35
36		if (*type == _C_VOID) {
37			PyErr_SetString (PyObjCExc_Error,
38				"Cannot dereference a pointer to void");
39			return NULL;
40		} else {
41			return pythonify_c_value (type, self->ptr);
42		}
43        } else {
44		Py_INCREF (Py_None);
45		return Py_None;
46        }
47}
48
49static PyMethodDef PyObjCPointer_methods[] =
50{
51	{
52		"unpack",
53		(PyCFunction)PyObjCPointer_unpack,
54		METH_NOARGS,
55		PyObjCPointer_unpack_doc
56	},
57	{ 0, 0, 0, 0 }
58};
59
60static PyMemberDef PyObjCPointer_members[] = {
61	{
62		"type",
63		T_OBJECT,
64		offsetof(PyObjCPointer, type),
65		READONLY,
66		NULL
67	},
68	{
69		"pointerAsInteger",
70		T_INT,
71		offsetof(PyObjCPointer, ptr),
72		READONLY,
73		NULL
74	},
75	{ 0, 0, 0, 0, 0 }
76};
77
78PyTypeObject PyObjCPointer_Type =
79{
80	PyObject_HEAD_INIT(&PyType_Type)
81	0,					/* ob_size */
82	"PyObjCPointer",			/* tp_name */
83	sizeof (PyObjCPointer),			/* tp_basicsize */
84	sizeof (char),				/* tp_itemsize */
85
86	/* methods */
87	PyObjCPointer_dealloc,			/* tp_dealloc */
88	0,					/* tp_print */
89	0,					/* tp_getattr */
90	0,					/* tp_setattr */
91	0,					/* tp_compare */
92	0,					/* tp_repr */
93	0,					/* tp_as_number */
94	0,					/* tp_as_sequence */
95	0,					/* tp_as_mapping */
96	0,					/* tp_hash */
97	0,					/* tp_call */
98	0,					/* tp_str */
99	0,					/* tp_getattro */
100	0,					/* tp_setattro */
101	0,					/* tp_as_buffer */
102	Py_TPFLAGS_DEFAULT,			/* tp_flags */
103	"Wrapper around a Objective-C Pointer",	/* tp_doc */
104	0,					/* tp_traverse */
105	0,					/* tp_clear */
106	0,					/* tp_richcompare */
107	0,					/* tp_weaklistoffset */
108	0,					/* tp_iter */
109	0,					/* tp_iternext */
110	PyObjCPointer_methods,			/* tp_methods */
111	PyObjCPointer_members,			/* tp_members */
112	0,					/* tp_getset */
113	0,					/* tp_base */
114	0,					/* tp_dict */
115	0,					/* tp_descr_get */
116	0,					/* tp_descr_set */
117	0,					/* tp_dictoffset */
118	0,					/* tp_init */
119	0,					/* tp_alloc */
120	0,					/* tp_new */
121	0,					/* tp_free */
122	0,					/* tp_is_gc */
123	0,					/* tp_bases */
124	0,					/* tp_mro */
125	0,					/* tp_cache */
126	0,					/* tp_subclasses */
127	0,					/* tp_weaklist */
128	0					/* tp_del */
129#if PY_VERSION_HEX >= 0x02060000
130	, 0                                     /* tp_version_tag */
131#endif
132
133};
134
135PyObjCPointer *
136PyObjCPointer_New(void *p, const char *t)
137{
138	Py_ssize_t size = PyObjCRT_SizeOfType (t);
139	const char *typeend = PyObjCRT_SkipTypeSpec (t);
140	PyObjCPointer *self;
141
142	NSLog(@"PyObjCPointer created: at %p of type %s", p, t);
143
144	if (size == -1) {
145		return NULL;
146	}
147	if (typeend == NULL) {
148		return NULL;
149	}
150
151	self = PyObject_NEW_VAR (PyObjCPointer, &PyObjCPointer_Type, size);
152	if (self == NULL) {
153		return NULL;
154	}
155
156	self->type = PyString_FromStringAndSize ((char *) t, typeend-t);
157
158	if (size && p) {
159		memcpy ((self->ptr = self->contents), p, size);
160	} else {
161		self->ptr = p;
162	}
163
164	return self;
165}
166