1/* Copyright (c) 1996,97,98 by Lele Gaifax.  All Rights Reserved
2 * Copyright (c) 2002-2008 Ronald Oussoren
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 * RCSfile: objc_support.m,v
12 * Revision: 1.24
13 * Date: 1998/08/18 15:35:58
14 *
15 * Created Tue Sep 10 14:16:02 1996.
16 */
17
18#include "pyobjc.h"
19#include <objc/Protocol.h>
20
21#include <unistd.h>
22#include <sys/socket.h>
23#include <netinet/in.h>
24
25#import <Foundation/NSInvocation.h>
26#import <Foundation/NSData.h>
27#import <Foundation/NSValue.h>
28#import <Foundation/NSDecimalNumber.h>
29
30#include <CoreFoundation/CFNumber.h>
31
32/*
33 * Category on NSObject to make sure that every object supports
34 * the method  __pyobjc_PythonObject__, this helps to simplify
35 * pythonify_c_value.
36 */
37@interface NSObject (PyObjCSupport)
38-(PyObject*)__pyobjc_PythonObject__;
39+(PyObject*)__pyobjc_PythonObject__;
40
41-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie;
42+(PyObject*)__pyobjc_PythonTransient__:(int*)cookie;
43@end /* PyObjCSupport */
44
45@implementation NSObject (PyObjCSupport)
46
47-(PyObject*)__pyobjc_PythonObject__
48{
49	PyObject *rval;
50
51	rval = PyObjC_FindPythonProxy(self);
52	if (rval == NULL) {
53		rval = (PyObject *)PyObjCObject_New(self,
54				PyObjCObject_kDEFAULT, YES);
55		PyObjC_RegisterPythonProxy(self, rval);
56	}
57
58	return rval;
59}
60
61+(PyObject*)__pyobjc_PythonObject__
62{
63	PyObject *rval;
64
65	//rval = PyObjC_FindPythonProxy(self);
66	rval = NULL;
67	if (rval == NULL) {
68		rval = (PyObject *)PyObjCClass_New(self);
69		//PyObjC_RegisterPythonProxy(self, rval);
70	}
71
72	return rval;
73}
74
75-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie
76{
77	PyObject* result = PyObjC_FindPythonProxy(self);
78	if (result) {
79		*cookie = 0;
80		return result;
81	}
82
83	*cookie = 1;
84	return PyObjCObject_New(self, PyObjCObject_kSHOULD_NOT_RELEASE, NO);
85}
86
87+(PyObject*)__pyobjc_PythonTransient__:(int*)cookie
88{
89	*cookie = 0;
90	return (PyObject *)PyObjCClass_New(self);
91}
92
93@end /* PyObjCSupport */
94
95@interface NSProxy (PyObjCSupport)
96-(PyObject*)__pyobjc_PythonObject__;
97+(PyObject*)__pyobjc_PythonObject__;
98
99-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie;
100+(PyObject*)__pyobjc_PythonTransient__:(int*)cookie;
101@end /* PyObjCSupport */
102
103@implementation NSProxy (PyObjCSupport)
104
105-(PyObject*)__pyobjc_PythonObject__
106{
107	PyObject *rval;
108
109	rval = PyObjC_FindPythonProxy(self);
110	if (rval == NULL) {
111		rval = (PyObject *)PyObjCObject_New(self,
112				PyObjCObject_kDEFAULT, YES);
113		PyObjC_RegisterPythonProxy(self, rval);
114	}
115	return rval;
116}
117
118+(PyObject*)__pyobjc_PythonObject__
119{
120	PyObject *rval;
121
122	rval = NULL;
123	if (rval == NULL) {
124		rval = (PyObject *)PyObjCClass_New(self);
125	}
126	return rval;
127}
128
129-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie
130{
131	PyObject* result = PyObjC_FindPythonProxy(self);
132	if (result) {
133		*cookie = 0;
134		return result;
135	}
136
137	*cookie = 1;
138	return PyObjCObject_New(self, PyObjCObject_kSHOULD_NOT_RELEASE, NO);
139}
140
141+(PyObject*)__pyobjc_PythonTransient__:(int*)cookie
142{
143	*cookie = 0;
144	return (PyObject *)PyObjCClass_New(self);
145}
146@end /* PyObjCSupport */
147
148@interface Protocol (PyObjCSupport)
149-(PyObject*)__pyobjc_PythonObject__;
150-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie;
151@end /* PyObjCSupport */
152
153@implementation Protocol (PyObjCSupport)
154
155-(PyObject*)__pyobjc_PythonObject__
156{
157	PyObject *rval;
158
159	rval = PyObjC_FindPythonProxy(self);
160	if (rval == NULL) {
161		rval = PyObjCFormalProtocol_ForProtocol(self);
162	}
163	return rval;
164}
165
166-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie
167{
168	PyObject *rval;
169
170	*cookie = 0;
171	rval = PyObjC_FindPythonProxy(self);
172	if (rval == NULL) {
173		rval = PyObjCFormalProtocol_ForProtocol(self);
174	}
175	return rval;
176}
177
178@end /* PyObjCSupport */
179
180@interface Object (PyObjCSupport)
181-(PyObject*)__pyobjc_PythonObject__;
182-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie;
183@end /* PyObjCSupport */
184
185@implementation Object (PyObjCSupport)
186
187-(PyObject*)__pyobjc_PythonObject__
188{
189	PyObject *rval;
190
191	rval = PyObjC_FindPythonProxy(self);
192	if (rval == NULL) {
193		rval = (PyObject *)PyObjCObject_New(self,
194				PyObjCObject_kCLASSIC, NO);
195		PyObjC_RegisterPythonProxy(self, rval);
196	}
197	return rval;
198}
199
200-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie
201{
202	PyObject *rval;
203
204	*cookie = 0;
205	rval = PyObjC_FindPythonProxy(self);
206	if (rval == NULL) {
207		rval = (PyObject *)PyObjCObject_New(self,
208				PyObjCObject_kCLASSIC, NO);
209		PyObjC_RegisterPythonProxy(self, rval);
210	}
211	return rval;
212}
213
214@end /* PyObjCSupport */
215
216@interface NSString (PyObjCSupport)
217-(PyObject*)__pyobjc_PythonObject__;
218-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie;
219@end /* NSString (PyObjCSupport) */
220
221@implementation NSString (PyObjCSupport)
222
223-(PyObject*)__pyobjc_PythonObject__
224{
225	/* Don't register the proxy, see XXX */
226	PyObject *rval = (PyObject *)PyObjCUnicode_New(self);
227	return rval;
228}
229
230-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie
231{
232	*cookie = 0;
233	return (PyObject *)PyObjCUnicode_New(self);
234}
235
236@end /* NSString (PyObjCSupport) */
237
238@interface NSNumber (PyObjCSupport)
239-(PyObject*)__pyobjc_PythonObject__;
240-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie;
241@end /* NSNumber (PyObjCSupport) */
242
243@implementation NSNumber (PyObjCSupport)
244-(PyObject*)__pyobjc_PythonObject__
245{
246	/* FIXME: rewrite PyObjC_NSNumberWrapper in C */
247	PyObject *rval;
248
249
250	/* shortcut for booleans */
251	if (kCFBooleanTrue == (CFBooleanRef)self) {
252		return PyBool_FromLong(1);
253	} else if (kCFBooleanFalse == (CFBooleanRef)self) {
254		return PyBool_FromLong(0);
255	}
256
257	rval = PyObjC_FindPythonProxy(self);
258	if (rval == NULL) {
259		rval= PyObjCObject_New(self,
260				PyObjCObject_kDEFAULT, YES);
261
262		if (PyObjC_NSNumberWrapper && rval) {
263			PyObject *val = rval;
264			rval = PyObject_CallFunctionObjArgs(
265					PyObjC_NSNumberWrapper, val, NULL);
266			Py_DECREF(val);
267		}
268	}
269	return rval;
270}
271
272-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie
273{
274	*cookie = 0;
275	return [self __pyobjc_PythonObject__];
276}
277@end
278
279@interface NSDecimalNumber (PyObjCSupport)
280-(PyObject*)__pyobjc_PythonObject__;
281-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie;
282@end /* NSDecimalNumber (PyObjCSupport) */
283
284@implementation NSDecimalNumber (PyObjCSupport)
285-(PyObject*)__pyobjc_PythonObject__
286{
287	PyObject *rval;
288
289	rval = PyObjC_FindPythonProxy(self);
290	if (rval == NULL) {
291		rval = (PyObject *)PyObjCObject_New(self,
292				PyObjCObject_kDEFAULT, YES);
293		PyObjC_RegisterPythonProxy(self, rval);
294	}
295
296	return rval;
297}
298
299-(PyObject*)__pyobjc_PythonTransient__:(int*)cookie
300{
301	*cookie = 0;
302	return [self __pyobjc_PythonObject__];
303}
304@end
305
306#ifndef MAX
307static inline Py_ssize_t
308MAX(Py_ssize_t x, Py_ssize_t y)
309{
310	return x > y ? x : y;
311}
312#endif
313
314static inline Py_ssize_t
315ROUND(Py_ssize_t v, Py_ssize_t a)
316{
317	if (v % a == 0) {
318		return v;
319	} else {
320		return v + a - (v % a);
321	}
322}
323
324
325const char*
326PyObjCRT_SkipTypeQualifiers (const char* type)
327{
328	PyObjC_Assert(type != NULL, NULL);
329
330	while (
331			*type == _C_CONST ||
332			*type == _C_IN ||
333			*type == _C_INOUT ||
334			*type == _C_OUT ||
335			*type == _C_BYCOPY ||
336			*type == _C_BYREF ||
337			*type == _C_ONEWAY ||
338			*type == 'O') {
339		type++;
340	}
341	while (*type && isdigit(*type)) type++;
342	return type;
343}
344
345const char *
346PyObjCRT_SkipTypeSpec (const char *type)
347{
348	PyObjC_Assert(type != NULL, NULL);
349
350	type = PyObjCRT_SkipTypeQualifiers (type);
351
352	switch (*type) {
353	case '"':
354		/* Embedded name in ivar or compound type */
355		type++;
356		while (*type != '\0' && *type != '"') type++;
357		break;
358
359	/* The following are one character type codes */
360	case _C_UNDEF:
361	case _C_CLASS:
362	case _C_SEL:
363	case _C_CHR:
364	case _C_UCHR:
365	case _C_CHARPTR:
366#ifdef _C_ATOM
367	case _C_ATOM:
368#endif
369#ifdef _C_BOOL
370	case _C_BOOL:
371#endif
372	case _C_SHT:
373	case _C_USHT:
374	case _C_INT:
375	case _C_UINT:
376	case _C_LNG:
377	case _C_ULNG:
378	case _C_FLT:
379	case _C_DBL:
380	case _C_VOID:
381	case _C_LNG_LNG:
382	case _C_ULNG_LNG:
383	case _C_UNICHAR:
384	case _C_CHAR_AS_TEXT:
385	case _C_CHAR_AS_INT:
386	case _C_NSBOOL:
387		++type;
388		break;
389
390	case _C_BFLD:
391		while (isdigit (*++type));
392		break;
393
394	case _C_ID:
395		++type;
396		if (*type == '?') {
397			/* Block pointer */
398			type++;
399                }
400		break;
401
402	case _C_ARY_B:
403		/* skip digits, typespec and closing ']' */
404
405		while (isdigit (*++type));
406		type = PyObjCRT_SkipTypeSpec (type);
407		assert (type == NULL || *type == _C_ARY_E);
408		if (type) type++;
409		break;
410
411	case _C_STRUCT_B:
412		/* skip name, and elements until closing '}'  */
413		while (*type != _C_STRUCT_E && *type++ != '=');
414		while (type && *type != _C_STRUCT_E) {
415			if (*type == '"') {
416				/* embedded field names */
417				type = strchr(type+1, '"');
418				if (type != NULL) {
419					type++;
420				} else {
421					return NULL;
422				}
423			}
424			type = PyObjCRT_SkipTypeSpec (type);
425		}
426		if (type) type++;
427		break;
428
429	case _C_UNION_B:
430		/* skip name, and elements until closing ')'  */
431		while (*type != _C_UNION_E && *type++ != '=');
432		while (type && *type != _C_UNION_E) {
433			if (*type == '"') {
434				/* embedded field names */
435				type = strchr(type+1, '"');
436				if (type != NULL) {
437					type++;
438				} else {
439					return NULL;
440				}
441			}
442			type = PyObjCRT_SkipTypeSpec (type);
443		}
444		if (type) type++;
445		break;
446
447	case _C_PTR:
448	case _C_CONST:
449	case _C_IN:
450	case _C_INOUT:
451	case _C_OUT:
452	case _C_BYCOPY:
453	case _C_BYREF:
454	case _C_ONEWAY:
455
456		/* Just skip the following typespec */
457		type = PyObjCRT_SkipTypeSpec (type+1);
458		break;
459
460
461	default:
462		PyErr_Format(PyObjCExc_InternalError,
463			"PyObjCRT_SkipTypeSpec: Unhandled type '%#x' %s", *type, type);
464		return NULL;
465	}
466
467	/* The compiler inserts a number after the actual signature,
468	 * this number may or may not be usefull depending on the compiler
469	 * version. We never use it.
470	 */
471	while (type && *type && isdigit(*type)) type++;
472	return type;
473}
474
475const char *
476PyObjCRT_NextField(const char *type)
477{
478	PyObjC_Assert(type != NULL, NULL);
479
480	type = PyObjCRT_SkipTypeQualifiers (type);
481
482	switch (*type) {
483	/* The following are one character type codes */
484	case _C_UNDEF:
485	case _C_CLASS:
486	case _C_SEL:
487	case _C_CHR:
488	case _C_UCHR:
489	case _C_CHARPTR:
490#ifdef _C_ATOM
491	case _C_ATOM:
492#endif
493#ifdef _C_BOOL
494	case _C_BOOL:
495#endif
496	case _C_SHT:
497	case _C_USHT:
498	case _C_INT:
499	case _C_UINT:
500	case _C_LNG:
501	case _C_ULNG:
502	case _C_FLT:
503	case _C_DBL:
504	case _C_VOID:
505	case _C_LNG_LNG:
506	case _C_ULNG_LNG:
507	case _C_UNICHAR:
508	case _C_CHAR_AS_TEXT:
509	case _C_CHAR_AS_INT:
510	case _C_NSBOOL:
511	case _C_BFLD: /* Not really 1 character, but close enough  */
512		++type;
513		break;
514
515	case _C_ID:
516		++type;
517		break;
518
519	case _C_ARY_B:
520		/* skip digits, typespec and closing ']' */
521
522		while (isdigit (*++type));
523		type = PyObjCRT_SkipTypeSpec (type);
524		assert (type == NULL || *type == _C_ARY_E);
525		if (type) type++;
526		break;
527
528	case _C_STRUCT_B:
529		/* skip name, and elements until closing '}'  */
530		while (*type != _C_STRUCT_E && *type++ != '=');
531		while (type && *type != _C_STRUCT_E) {
532			if (*type == '"') {
533				/* embedded field names */
534				type = strchr(type+1, '"');
535				if (type != NULL) {
536					type++;
537				} else {
538					return NULL;
539				}
540			}
541			type = PyObjCRT_SkipTypeSpec (type);
542		}
543		if (type) type++;
544		break;
545
546	case _C_UNION_B:
547		/* skip name, and elements until closing ')'  */
548		while (*type != _C_UNION_E && *type++ != '=');
549		while (type && *type != _C_UNION_E) {
550			if (*type == '"') {
551				/* embedded field names */
552				type = strchr(type+1, '"');
553				if (type != NULL) {
554					type++;
555				} else {
556					return NULL;
557				}
558			}
559			type = PyObjCRT_SkipTypeSpec (type);
560		}
561		if (type) type++;
562		break;
563
564	case _C_PTR:
565	case _C_CONST:
566	case _C_IN:
567	case _C_INOUT:
568	case _C_OUT:
569	case _C_BYCOPY:
570	case _C_BYREF:
571	case _C_ONEWAY:
572
573		/* Just skip the following typespec */
574		type = PyObjCRT_NextField(type+1);
575		break;
576
577
578	default:
579		PyErr_Format(PyObjCExc_InternalError,
580			"PyObjCRT_SkipTypeSpec: Unhandled type '%#x'", *type);
581		return NULL;
582	}
583
584	/* The compiler inserts a number after the actual signature,
585	 * this number may or may not be usefull depending on the compiler
586	 * version. We never use it.
587	 */
588	while (type && *type && isdigit(*type)) type++;
589	return type;
590}
591
592/*
593Return the alignment of an object specified by type
594*/
595
596/*
597*  On MacOS X, the elements of a struct are aligned differently inside the
598*  struct than outside. That is, the maximum alignment of any struct field
599*  (except the first) is 4, doubles outside of a struct have an alignment of
600*  8.
601*
602*  Other platform don't seem to have this inconsistency.
603*
604*  XXX: sizeof_struct, alignof_struct and {de,}pythonify_c_struct should
605*  probably be moved to platform dependend files. As long as this is the
606*  only platform dependent code this isn't worth the effort.
607*/
608
609static inline Py_ssize_t
610PyObjC_EmbeddedAlignOfType (const char*  type)
611{
612	PyObjC_Assert(type != NULL, -1);
613
614	Py_ssize_t align = PyObjCRT_AlignOfType(type);
615
616#if defined(__i386__) || defined(__x86_64__)
617	return align;
618
619#else
620	if (align < 4 || align == 16) {
621		return align;
622	} else {
623		return 4;
624	}
625#endif
626}
627
628Py_ssize_t
629PyObjCRT_AlignOfType (const char *type)
630{
631	PyObjC_Assert(type != NULL, -1);
632
633	switch (*type) {
634	case _C_VOID:  return __alignof__(char);
635	case _C_ID:    return __alignof__ (id);
636	case _C_CLASS: return __alignof__ (Class);
637	case _C_SEL:   return __alignof__ (SEL);
638	case _C_CHR:   return __alignof__ (char);
639	case _C_UCHR:  return __alignof__ (unsigned char);
640	case _C_SHT:   return __alignof__ (short);
641	case _C_USHT:  return __alignof__ (unsigned short);
642#ifdef _C_BOOL
643	case _C_BOOL:   return __alignof__ (bool);
644#endif
645	case _C_UNICHAR:	return __alignof__(UniChar);
646	case _C_CHAR_AS_TEXT:	return __alignof__(char);
647	case _C_CHAR_AS_INT:	return __alignof__(char);
648	case _C_NSBOOL:		return __alignof__(BOOL);
649	case _C_INT:   return __alignof__ (int);
650	case _C_UINT:  return __alignof__ (unsigned int);
651	case _C_LNG:   return __alignof__ (long);
652	case _C_ULNG:  return __alignof__ (unsigned long);
653	case _C_FLT:   return __alignof__ (float);
654	case _C_DBL:
655#if defined(__APPLE__) && defined(__i386__)
656		/* The ABI says natural alignment is 4 bytes, but
657		 * GCC's __alignof__ says 8. The latter is wrong.
658		 */
659		return 4;
660#else
661		return __alignof__ (double);
662#endif
663
664	case _C_CHARPTR: return __alignof__ (char *);
665#ifdef _C_ATOM
666	case _C_ATOM: return __alignof__ (char *);
667#endif
668	case _C_PTR:   return __alignof__ (void *);
669#if defined(__APPLE__) && defined(__i386__)
670		/* The ABI says natural alignment is 4 bytes, but
671		 * GCC's __alignof__ says 8. The latter is wrong.
672		 */
673	case _C_LNG_LNG: return 4;
674	case _C_ULNG_LNG: return 4;
675#else
676	case _C_LNG_LNG: return __alignof__(long long);
677	case _C_ULNG_LNG: return __alignof__(unsigned long long);
678#endif
679
680	case _C_ARY_B:
681		while (isdigit(*++type)) /* do nothing */;
682		return PyObjCRT_AlignOfType (type);
683
684	case _C_STRUCT_B:
685	{
686		struct { int x; double y; } fooalign;
687		while(*type != _C_STRUCT_E && *type++ != '=') /* do nothing */;
688		if (*type != _C_STRUCT_E) {
689			int have_align = 0;
690			Py_ssize_t align = 0;
691
692			while (type != NULL && *type != _C_STRUCT_E) {
693				if (*type == '"') {
694					type = strchr(type+1, '"');
695					if (type) type++;
696				}
697				if (have_align) {
698					align = MAX(align,
699					   PyObjC_EmbeddedAlignOfType(type));
700				} else {
701					align = PyObjCRT_AlignOfType(type);
702					have_align = 1;
703				}
704				type = PyObjCRT_SkipTypeSpec(type);
705			}
706			if (type == NULL) return -1;
707			return align;
708		} else {
709			return __alignof__ (fooalign);
710		}
711	}
712
713	case _C_UNION_B:
714	{
715		int maxalign = 0;
716		type++;
717		while (*type != _C_UNION_E)
718		{
719			int item_align = PyObjCRT_AlignOfType(type);
720			if (item_align == -1) return -1;
721			maxalign = MAX (maxalign, item_align);
722			type = PyObjCRT_SkipTypeSpec (type);
723		}
724		return maxalign;
725	}
726
727	case _C_CONST:
728	case _C_IN:
729	case _C_INOUT:
730	case _C_OUT:
731	case _C_BYCOPY:
732	case _C_BYREF:
733	case _C_ONEWAY:
734		return PyObjCRT_AlignOfType(type+1);
735
736	case _C_BFLD:
737		return 1;
738
739	case _C_UNDEF:
740		return __alignof__(void*);
741
742	default:
743		PyErr_Format(PyObjCExc_InternalError,
744			"PyObjCRT_AlignOfType: Unhandled type '%#x' %s", *type, type);
745		return -1;
746	}
747}
748
749/*
750The aligned size if the size rounded up to the nearest alignment.
751*/
752
753Py_ssize_t
754PyObjCRT_AlignedSize (const char *type)
755{
756	PyObjC_Assert(type != NULL, -1);
757
758	Py_ssize_t size = PyObjCRT_SizeOfType (type);
759	Py_ssize_t align = PyObjCRT_AlignOfType (type);
760
761	if (size == -1 || align == -1) return -1;
762	return ROUND(size, align);
763}
764
765/*
766return the size of an object specified by type
767*/
768
769Py_ssize_t
770PyObjCRT_SizeOfType (const char *type)
771{
772	PyObjC_Assert(type != NULL, -1);
773
774	Py_ssize_t itemSize;
775	switch (*type) {
776	case _C_VOID:    return 1; // More convenient than the correct value.
777	case _C_ID:      return sizeof(id);
778	case _C_CLASS:   return sizeof(Class);
779	case _C_SEL:     return sizeof(SEL);
780	case _C_CHR:     return sizeof(char);
781	case _C_UCHR:    return sizeof(unsigned char);
782	case _C_SHT:     return sizeof(short);
783	case _C_USHT:    return sizeof(unsigned short);
784#ifdef _C_BOOL
785	case _C_BOOL:    return sizeof(bool);
786#endif
787	case _C_INT:     return sizeof(int);
788	case _C_UINT:    return sizeof(unsigned int);
789	case _C_LNG:     return sizeof(long);
790	case _C_ULNG:    return sizeof(unsigned long);
791	case _C_FLT:     return sizeof(float);
792	case _C_DBL:     return sizeof(double);
793	case _C_LNG_LNG:  return sizeof(long long);
794	case _C_ULNG_LNG: return sizeof(unsigned long long);
795	case _C_UNICHAR:	return sizeof(UniChar);
796	case _C_CHAR_AS_TEXT:	return sizeof(char);
797	case _C_CHAR_AS_INT:	return sizeof(char);
798	case _C_NSBOOL:		return sizeof(BOOL);
799
800	case _C_PTR:
801	case _C_CHARPTR:
802#ifdef _C_ATOM
803	case _C_ATOM:
804#endif
805		return sizeof(char*);
806
807	case _C_ARY_B:
808	{
809		Py_ssize_t len = atoi(type+1);
810		Py_ssize_t item_align;
811		while (isdigit(*++type))
812			;
813		item_align = PyObjCRT_AlignedSize(type);
814		if (item_align == -1) return -1;
815		return len*item_align;
816	}
817	break;
818
819	case _C_STRUCT_B:
820	{
821		Py_ssize_t acc_size = 0;
822		int have_align =  0;
823		Py_ssize_t align;
824		Py_ssize_t max_align = 0;
825
826		/* This is an awfull hack... */
827		/*   struct sockaddr is a generic type with several supported
828		 *   specific types. Annoyingly enough not all of those have the
829		 *   same size.
830		 *   This file has crude support for this scheme as its almost
831		 *   impossible to implement this nicely using our C/Python
832		 *   API.
833		 */
834		if (strncmp(type,
835			@encode(struct sockaddr),
836			sizeof(@encode(struct sockaddr)-1)) == 0) {
837
838			return sizeof(struct sockaddr_in6);
839		}
840
841		while (*type != _C_STRUCT_E && *type++ != '=')
842			; /* skip "<name>=" */
843		while (*type != _C_STRUCT_E) {
844			if (*type == '"') {
845				type = strchr(type+1, '"');
846				if (type) type++;
847			}
848			if (have_align) {
849				align = PyObjC_EmbeddedAlignOfType(type);
850				if (align == -1) return -1;
851			} else {
852				align = PyObjCRT_AlignOfType(type);
853				if (align == -1) return -1;
854				have_align = 1;
855			}
856			max_align = MAX(align, max_align);
857			acc_size = ROUND (acc_size, align);
858
859			itemSize = PyObjCRT_SizeOfType (type);
860			if (itemSize == -1) return -1;
861			acc_size += itemSize;
862			type = PyObjCRT_SkipTypeSpec (type);
863		}
864		if (max_align) {
865			acc_size = ROUND(acc_size, max_align);
866		}
867		return acc_size;
868	}
869
870	case _C_UNION_B:
871	{
872		Py_ssize_t max_size = 0;
873		type++;
874		/* Skip name part: */
875		while (*type != _C_UNION_E && *type++ != '=');
876
877		/* Calculate size: */
878		while (*type != _C_UNION_E) {
879			itemSize = PyObjCRT_SizeOfType (type);
880			if (itemSize == -1) return -1;
881			max_size = MAX (max_size, itemSize);
882			type = PyObjCRT_SkipTypeSpec (type);
883		}
884		return max_size;
885	}
886
887	case _C_CONST:
888	case _C_IN:
889	case _C_INOUT:
890	case _C_OUT:
891	case _C_BYCOPY:
892	case _C_BYREF:
893	case _C_ONEWAY:
894		return PyObjCRT_SizeOfType(type+1);
895
896	case _C_BFLD:
897		{
898			int i = strtol(type+1, NULL, 10);
899			return (i+7)/8;
900		}
901		break;
902
903	case _C_UNDEF:
904		return sizeof(void*);
905
906	default:
907		PyErr_Format(PyObjCExc_InternalError,
908			"PyObjCRT_SizeOfType: Unhandled type '0x%x', %s",
909			*type, type);
910		return -1;
911	}
912}
913
914PyObject *
915pythonify_c_array_nullterminated(const char* type, void* datum, BOOL alreadyRetained, BOOL alreadyCFRetained)
916{
917	PyObjC_Assert(type != NULL, NULL);
918	PyObjC_Assert(datum != NULL, NULL);
919
920	Py_ssize_t count = 0;
921	Py_ssize_t sizeofitem = PyObjCRT_SizeOfType (type);
922	unsigned char* curdatum = datum;
923
924	type = PyObjCRT_SkipTypeQualifiers(type);
925	switch (*type) {
926	case _C_CHARPTR:
927		while (*(char**)curdatum != NULL) {
928			count ++;
929			curdatum += sizeofitem;
930		}
931		break;
932
933	case _C_ID:
934		while (*(id*)curdatum != NULL) {
935			count ++;
936			curdatum += sizeofitem;
937		}
938		break;
939
940	case _C_PTR:
941		while (*(void**)curdatum != NULL) {
942			count ++;
943			curdatum += sizeofitem;
944		}
945		break;
946
947	case _C_UCHR:
948		while (*(unsigned char*)curdatum != 0) {
949			count ++;
950			curdatum += sizeofitem;
951		}
952		break;
953
954	case _C_VOID:
955	case _C_CHR:
956		return PyBytes_FromString((char*)curdatum);
957		break;
958
959	case _C_CHAR_AS_TEXT:
960		return PyBytes_FromString((char*)curdatum);
961		break;
962
963	case _C_USHT:
964		while (*(unsigned short*)curdatum != 0) {
965			count ++;
966			curdatum += sizeofitem;
967		}
968		break;
969	case _C_SHT:
970		while (*(short*)curdatum != 0) {
971			count ++;
972			curdatum += sizeofitem;
973		}
974		break;
975
976	case _C_UINT:
977		while (*(unsigned int*)curdatum != 0) {
978			count ++;
979			curdatum += sizeofitem;
980		}
981		break;
982	case _C_INT:
983		while (*(int*)curdatum != 0) {
984			count ++;
985			curdatum += sizeofitem;
986		}
987		break;
988
989	case _C_ULNG:
990		while (*(unsigned long*)curdatum != 0) {
991			count ++;
992			curdatum += sizeofitem;
993		}
994		break;
995	case _C_LNG:
996		while (*(long*)curdatum != 0) {
997			count ++;
998			curdatum += sizeofitem;
999		}
1000		break;
1001
1002	case _C_ULNG_LNG:
1003		while (*(unsigned long long*)curdatum != 0) {
1004			count ++;
1005			curdatum += sizeofitem;
1006		}
1007		break;
1008	case _C_LNG_LNG:
1009		while (*(long long*)curdatum != 0) {
1010			count ++;
1011			curdatum += sizeofitem;
1012		}
1013		break;
1014
1015	case _C_UNICHAR:
1016		while (*(UniChar*)curdatum != 0) {
1017			count ++;
1018			curdatum += sizeofitem;
1019		}
1020		break;
1021
1022	case _C_CHAR_AS_INT:
1023		while (*(char*)curdatum != 0) {
1024			count ++;
1025			curdatum += sizeofitem;
1026		}
1027		break;
1028
1029
1030	default:
1031		PyErr_Format(PyExc_TypeError,
1032			"Cannot deal with NULL-terminated array of %s",
1033			type);
1034		return NULL;
1035	}
1036	if (*type == _C_UNICHAR) {
1037		return PyUnicode_FromUnicode((Py_UNICODE*)datum, count);
1038	}
1039
1040	return  PyObjC_CArrayToPython2(type, datum, count, alreadyRetained, alreadyCFRetained);
1041}
1042
1043
1044
1045/*#F Returns a tuple of objects representing the content of a C array
1046of type @var{type} pointed by @var{datum}. */
1047static PyObject *
1048pythonify_c_array (const char *type, void *datum)
1049{
1050	PyObjC_Assert(type != NULL, NULL);
1051	PyObjC_Assert(datum != NULL, NULL);
1052
1053	PyObject *ret;
1054	Py_ssize_t nitems, itemidx, sizeofitem;
1055	unsigned char* curdatum;
1056
1057	nitems = atoi (type+1);
1058	while (isdigit (*++type))
1059		;
1060	sizeofitem = PyObjCRT_SizeOfType (type);
1061	if (sizeofitem == -1) return NULL;
1062
1063	ret = PyTuple_New (nitems);
1064	if (!ret) return NULL;
1065
1066	curdatum = datum;
1067	for (itemidx=0; itemidx < nitems; itemidx++) {
1068		PyObject *pyitem = NULL;
1069
1070		pyitem = pythonify_c_value (type, curdatum);
1071
1072		if (pyitem) {
1073			PyTuple_SET_ITEM (ret, itemidx, pyitem);
1074		} else {
1075			Py_DECREF(ret);
1076			return NULL;
1077		}
1078
1079		curdatum += sizeofitem;
1080	}
1081
1082	return ret;
1083}
1084
1085/*#F Returns a tuple of objects representing the content of a C structure
1086of type @var{type} pointed by @var{datum}. */
1087static PyObject *
1088pythonify_c_struct (const char *type, void *datum)
1089{
1090	PyObjC_Assert(type != NULL, NULL);
1091	PyObjC_Assert(datum != NULL, NULL);
1092
1093	PyObject *ret;
1094	Py_ssize_t offset, itemidx;
1095	const char *item;
1096	int have_align = 0;
1097	Py_ssize_t align;
1098	int haveTuple;
1099	const char* type_start = type;
1100	const char* type_end = PyObjCRT_SkipTypeSpec(type);
1101	const char* type_real_start = type;
1102	Py_ssize_t type_real_length = type_end - type_start;
1103
1104	/* Hacked up support for socket addresses */
1105	if (strncmp(type, @encode(struct sockaddr), sizeof(@encode(struct sockaddr)-1)) == 0) {
1106		return PyObjC_SockAddrToPython(datum);
1107	}
1108
1109	if (IS_FSREF(type)) {
1110		return PyObjC_decode_fsref(datum);
1111	}
1112
1113	if (IS_FSSPEC(type)) {
1114		return PyObjC_decode_fsspec(datum);
1115	}
1116
1117	/* Skip back over digits at end of type in function prototypes */
1118	while (type_real_length > 0 && isdigit(type_start[type_real_length-1])) {
1119		type_real_length --;
1120	}
1121
1122	/* The compiler adds useless digits at the end of the signature */
1123	while (type_end != type_start+1 && type_end[-1] != _C_STRUCT_E) {
1124		type_end--;
1125	}
1126
1127	while (*type != _C_STRUCT_E && *type++ != '=') {
1128		/* skip "<name>=" */
1129	}
1130
1131	haveTuple = 0;
1132	const char* oc_typestr = NULL;
1133	ret = PyObjC_CreateRegisteredStruct(type_start,
1134			type_end-type_start, &oc_typestr);
1135	if (ret == NULL) {
1136		int nitems;
1137
1138		nitems = 0;
1139		item = type;
1140		while (*item != _C_STRUCT_E) {
1141			nitems ++;
1142			if (*item == '"') {
1143				item = strchr(item+1, '"');
1144				if (item) item ++;
1145			}
1146			item = PyObjCRT_SkipTypeSpec(item);
1147		}
1148
1149		haveTuple = 1;
1150		ret = PyTuple_New (nitems);
1151		if (!ret) return NULL;
1152
1153		item = type;
1154	} else {
1155		item = type;
1156
1157		if (oc_typestr != NULL) {
1158			item = oc_typestr + 1;
1159			while (*item && *item != '=') {
1160				item++;
1161			}
1162			if (*item) {
1163				item++;
1164			}
1165		}
1166	}
1167
1168
1169	offset = itemidx = 0;
1170	while (*item != _C_STRUCT_E) {
1171		PyObject *pyitem;
1172
1173		if (*item == '"') {
1174			item = strchr(item+1, '"');
1175			if (item) item ++;
1176		}
1177
1178		if (!have_align) {
1179			align = PyObjCRT_AlignOfType(item);
1180			have_align = 1;
1181		} else {
1182			align = PyObjC_EmbeddedAlignOfType(item);
1183		}
1184
1185		offset = ROUND(offset, align);
1186
1187		pyitem = pythonify_c_value (item, ((char*)datum)+offset);
1188
1189		if (pyitem) {
1190			if (haveTuple) {
1191				PyTuple_SET_ITEM (ret, itemidx, pyitem);
1192			} else {
1193				int r;
1194				r = PySequence_SetItem(ret, itemidx, pyitem);
1195				Py_DECREF(pyitem);
1196				if (r == -1) {
1197					Py_DECREF(ret);
1198					return NULL;
1199				}
1200			}
1201		} else {
1202			Py_DECREF(ret);
1203			return NULL;
1204		}
1205
1206		itemidx++;
1207		offset += PyObjCRT_SizeOfType (item);
1208		item = PyObjCRT_SkipTypeSpec (item);
1209	}
1210
1211	if (haveTuple) {
1212		PyObject *converted;
1213		converted = [OC_PythonObject __pythonifyStruct:ret withType:type_real_start length:type_real_length];
1214		Py_DECREF(ret);
1215		return converted;
1216	} else {
1217		return ret;
1218	}
1219}
1220
1221int
1222depythonify_c_return_array_count(const char* rettype, Py_ssize_t count, PyObject* arg, void* resp, BOOL already_retained, BOOL already_cfretained)
1223{
1224	PyObjC_Assert(rettype != NULL, -1);
1225	PyObjC_Assert(arg != NULL, -1);
1226	PyObjC_Assert(resp != NULL, -1);
1227
1228	/* Use an NSMutableData object to store the bytes, that way we can autorelease the data because we
1229	 * cannot free it otherwise.
1230	 */
1231	PyObject* seq = PySequence_Fast(arg, "Sequence required");
1232	if (seq == NULL) {
1233		return -1;
1234	}
1235	if (count == -1) {
1236		count = PySequence_Fast_GET_SIZE(seq);
1237	}
1238
1239	NSMutableData* data = [NSMutableData dataWithLength:count * PyObjCRT_SizeOfType(rettype)];
1240	*(void**)resp = [data mutableBytes];
1241	int r = depythonify_c_array_count(rettype, count, YES, seq, [data mutableBytes], already_retained, already_cfretained);
1242	Py_DECREF(seq);
1243
1244	return r;
1245}
1246
1247
1248int
1249depythonify_c_return_array_nullterminated(const char* rettype, PyObject* arg, void* resp, BOOL already_retained, BOOL already_cfretained)
1250{
1251	PyObjC_Assert(rettype != NULL, -1);
1252	PyObjC_Assert(arg != NULL, -1);
1253	PyObjC_Assert(resp != NULL, -1);
1254
1255	/* Use an NSMutableData object to store the bytes, that way we can autorelease the data because we
1256	 * cannot free it otherwise.
1257	 */
1258	if (*rettype == _C_CHR || *rettype == _C_CHAR_AS_TEXT || *rettype == _C_VOID) {
1259		if (PyBytes_Check(arg)) {
1260			NSMutableData* data = [NSMutableData dataWithBytes: PyBytes_AsString(arg)
1261						     length: PyBytes_Size(arg)];
1262			*(void**)resp = [data mutableBytes];
1263			return 0;
1264#ifdef PyByteArray_Check
1265		} else if (PyByteArray_Check(arg)) {
1266			NSMutableData* data = [NSMutableData dataWithBytes: PyByteArray_AsString(arg)
1267						     length: PyByteArray_Size(arg)];
1268			*(void**)resp = [data mutableBytes];
1269			return 0;
1270#endif
1271		}
1272	}
1273
1274
1275	PyObject* seq = PySequence_Fast(arg, "Sequence required");
1276	if (seq == NULL) {
1277		return -1;
1278	}
1279
1280	Py_ssize_t count = PySequence_Fast_GET_SIZE(seq);
1281
1282	/* The data is 0-filled, which means we won't have to add the terminated ourselves */
1283	NSMutableData* data = [NSMutableData dataWithLength:(count + 1) * PyObjCRT_SizeOfType(rettype)];
1284	*(void**)resp = [data mutableBytes];
1285	int result =  depythonify_c_array_count(rettype, count, YES, seq, [data mutableBytes], already_retained, already_cfretained);
1286	Py_DECREF(seq);
1287	return result;
1288}
1289
1290
1291int
1292depythonify_c_array_count(const char* type, Py_ssize_t nitems, BOOL strict, PyObject* value, void* datum, BOOL already_retained, BOOL already_cfretained)
1293{
1294	PyObjC_Assert(type != NULL, -1);
1295	PyObjC_Assert(value != NULL, -1);
1296	PyObjC_Assert(datum != NULL, -1);
1297
1298	Py_ssize_t itemidx, sizeofitem;
1299	unsigned char* curdatum;
1300	PyObject* seq;
1301
1302	sizeofitem = PyObjCRT_AlignedSize (type);
1303	if (sizeofitem == -1) {
1304		PyErr_Format(PyExc_ValueError,
1305			"cannot depythonify array of unknown type");
1306		return -1;
1307	}
1308
1309	if (sizeofitem == 1 && PyBytes_Check(value)) {
1310		/* Special casing for strings */
1311		if (strict) {
1312			if (PyBytes_Size(value) != nitems) {
1313				PyErr_Format(PyExc_ValueError,
1314					"depythonifying array of %"PY_FORMAT_SIZE_T"d items, got one of %"PY_FORMAT_SIZE_T"d",
1315					nitems, PyBytes_Size(value));
1316				return -1;
1317			}
1318		} else {
1319			if (PyBytes_Size(value) < nitems) {
1320				PyErr_Format(PyExc_ValueError,
1321					"depythonifying array of %"PY_FORMAT_SIZE_T"d items, got one of %"PY_FORMAT_SIZE_T"d",
1322					nitems, PyBytes_Size(value));
1323				return -1;
1324			}
1325		}
1326
1327		memcpy(datum, PyBytes_AS_STRING(value), nitems);
1328		return 0;
1329	}
1330
1331	seq = PySequence_Fast(value, "depythonifying array, got no sequence");
1332	if (seq == NULL) {
1333		return -1;
1334	}
1335
1336	if (strict) {
1337		if (PySequence_Fast_GET_SIZE(seq) != nitems) {
1338			PyErr_Format(PyExc_ValueError,
1339				"depythonifying array of %"PY_FORMAT_SIZE_T"d items, got one of %"PY_FORMAT_SIZE_T"d",
1340				nitems, PySequence_Fast_GET_SIZE(seq));
1341			Py_DECREF(seq);
1342			return -1;
1343		}
1344	} else {
1345		if (PySequence_Fast_GET_SIZE(seq) < nitems) {
1346			PyErr_Format(PyExc_ValueError,
1347				"depythonifying array of %"PY_FORMAT_SIZE_T"d items, got one of %"PY_FORMAT_SIZE_T"d",
1348				nitems, PySequence_Fast_GET_SIZE(seq));
1349			Py_DECREF(seq);
1350			return -1;
1351		}
1352	}
1353
1354	curdatum = datum;
1355	for (itemidx=0; itemidx < nitems; itemidx++) {
1356		PyObject *pyarg = PySequence_Fast_GET_ITEM(seq, itemidx);
1357		int err;
1358
1359		err = depythonify_c_value (type, pyarg, curdatum);
1360		if (err == -1) {
1361			Py_DECREF(seq);
1362			return err;
1363		}
1364
1365		if (already_retained) {
1366			[*(NSObject**)curdatum retain];
1367
1368		} else if (already_cfretained) {
1369			CFRetain(*(NSObject**)curdatum);
1370
1371		}
1372
1373		curdatum += sizeofitem;
1374	}
1375
1376	if (*type == _C_CHARPTR) {
1377		/* We're depythonifying a list of strings, make sure the originals stay
1378		 * around long enough.
1379		 */
1380		[[[OC_PythonObject alloc] initWithObject:seq] autorelease];
1381	}
1382	Py_DECREF(seq);
1383	return 0;
1384}
1385
1386Py_ssize_t
1387c_array_nullterminated_size(PyObject* object, PyObject** seq)
1388{
1389	PyObjC_Assert(object != NULL, -1);
1390	PyObjC_Assert(seq != NULL, -1);
1391
1392	*seq = PySequence_Fast(object, "depythonifying array, got no sequence");
1393	if (*seq == NULL) {
1394		return -1;
1395	}
1396
1397	return PySequence_Fast_GET_SIZE(*seq) + 1;
1398}
1399
1400int
1401depythonify_c_array_nullterminated(const char* type, Py_ssize_t count, PyObject* value, void* datum, BOOL already_retained, BOOL already_cfretained)
1402{
1403	PyObjC_Assert(type != NULL, -1);
1404	PyObjC_Assert(value != NULL, -1);
1405	PyObjC_Assert(datum != NULL, -1);
1406
1407	/* XXX: we can do better than this: just clear the last item */
1408	/* Clear memory: */
1409	memset(datum, 0, count * PyObjCRT_SizeOfType(type));
1410
1411	if (count == 1) {
1412		return 0;
1413	}
1414
1415	/* Then copy the actual values */
1416	return depythonify_c_array_count(type, count-1, YES, value, datum, already_retained, already_cfretained);
1417}
1418
1419/*#F Extracts the elements from the tuple @var{arg} and fills a C array
1420of type @var{type} pointed by @var{datum}. Returns an error message, or
1421NULL on success. */
1422static int
1423depythonify_c_array (const char *type, PyObject *arg, void *datum)
1424{
1425	PyObjC_Assert(type != NULL, -1);
1426	PyObjC_Assert(arg != NULL, -1);
1427	PyObjC_Assert(datum != NULL, -1);
1428
1429	Py_ssize_t nitems, itemidx, sizeofitem;
1430	unsigned char* curdatum;
1431	PyObject* seq;
1432
1433	nitems = atoi (type+1);
1434	while (isdigit (*++type))
1435		;
1436	sizeofitem = PyObjCRT_AlignedSize (type);
1437	if (sizeofitem == -1) {
1438		PyErr_Format(PyExc_ValueError,
1439			"cannot depythonify array of unknown type");
1440		return -1;
1441	}
1442
1443	seq = PySequence_Fast(arg, "depythonifying array, got no sequence");
1444	if (seq == NULL) {
1445		return -1;
1446	}
1447
1448	if (nitems != PySequence_Fast_GET_SIZE(seq)) {
1449		PyErr_Format(PyExc_ValueError,
1450			"depythonifying array of %"PY_FORMAT_SIZE_T"d items, got one of %"PY_FORMAT_SIZE_T"d",
1451			nitems, PySequence_Fast_GET_SIZE(seq));
1452		Py_DECREF(seq);
1453		return -1;
1454	}
1455
1456	curdatum = datum;
1457	for (itemidx=0; itemidx < nitems; itemidx++) {
1458		PyObject *pyarg = PySequence_Fast_GET_ITEM(seq, itemidx);
1459		int err;
1460
1461		err = depythonify_c_value (type, pyarg, curdatum);
1462		if (err == -1) {
1463			Py_DECREF(seq);
1464			return err;
1465		}
1466
1467		curdatum += sizeofitem;
1468	}
1469
1470	Py_DECREF(seq);
1471	return 0;
1472}
1473
1474/*#F Extracts the elements from the tuple @var{arg} and fills a C structure
1475of type @var{type} pointed by @var{datum}. Returns an error message, or
1476NULL on success. */
1477static int
1478depythonify_c_struct(const char *types, PyObject *arg, void *datum)
1479{
1480	PyObjC_Assert(types != NULL, -1);
1481	PyObjC_Assert(arg != NULL, -1);
1482	PyObjC_Assert(datum != NULL, -1);
1483
1484	Py_ssize_t nitems, offset, itemidx;
1485	int have_align = 0;
1486	Py_ssize_t align;
1487	const char *type;
1488	PyObject* seq;
1489
1490	/* Hacked in support for sockaddr structs */
1491	if (strncmp(types, @encode(struct sockaddr), sizeof(@encode(struct sockaddr)-1)) == 0) {
1492		return PyObjC_SockAddrFromPython(arg, datum);
1493	}
1494
1495	if (IS_FSREF(types)) {
1496		if (PyObjC_encode_fsref(arg, datum) == 0) {
1497			return 0;
1498		}
1499		PyErr_Clear();
1500	}
1501	if (IS_FSSPEC(types)) {
1502		if (PyObjC_encode_fsspec(arg, datum) == 0) {
1503			return 0;
1504		}
1505		PyErr_Clear();
1506	}
1507
1508	while (*types != _C_STRUCT_E && *types++ != '='); /* skip "<name>=" */
1509
1510	type=types;
1511	nitems=0;
1512	while (*type != _C_STRUCT_E) {
1513		if (*type == '"') {
1514			type = strchr(type+1, '"');
1515			type++;
1516		}
1517		nitems++;
1518		type = PyObjCRT_SkipTypeSpec (type);
1519	}
1520
1521	seq = PySequence_Fast(arg, "depythonifying struct, got no sequence");
1522	if (seq == NULL) {
1523		return -1;
1524	}
1525
1526	if (nitems != PySequence_Fast_GET_SIZE(seq)) {
1527		Py_DECREF(seq);
1528		PyErr_Format(PyExc_ValueError,
1529			"depythonifying struct of %"PY_FORMAT_SIZE_T"d members, got tuple of %"PY_FORMAT_SIZE_T"d",
1530			nitems, PyTuple_Size (arg));
1531		return -1;
1532	}
1533
1534	type=types;
1535	offset = itemidx = 0;
1536
1537	while (*type != _C_STRUCT_E) {
1538		PyObject *argument;
1539
1540		if (*type == '"') {
1541			type = strchr(type+1, '"');
1542			type++;
1543		}
1544
1545
1546		argument = PySequence_Fast_GET_ITEM(seq, itemidx);
1547		int error;
1548		if (!have_align) {
1549			align = PyObjCRT_AlignOfType(type);
1550			have_align = 1;
1551		} else {
1552			align = PyObjC_EmbeddedAlignOfType(type);
1553		}
1554
1555		offset = ROUND(offset, align);
1556
1557		error = depythonify_c_value(type, argument,
1558				((char*)datum)+offset);
1559		if (error == -1) {
1560			Py_DECREF(seq);
1561			return error;
1562		}
1563
1564		itemidx++;
1565		offset += PyObjCRT_SizeOfType (type);
1566		type = PyObjCRT_SkipTypeSpec (type);
1567	}
1568	Py_DECREF(seq);
1569	return 0;
1570}
1571
1572PyObject *
1573pythonify_c_value (const char *type, void *datum)
1574{
1575	PyObjC_Assert(type != NULL, NULL);
1576	PyObjC_Assert(datum != NULL, NULL);
1577
1578	PyObject *retobject = NULL;
1579
1580	type = PyObjCRT_SkipTypeQualifiers (type);
1581
1582	switch (*type) {
1583	case _C_UNICHAR:
1584		{
1585			Py_UNICODE	c  = (Py_UNICODE)(*(UniChar*)datum);
1586			retobject = PyUnicode_FromUnicode(&c, 1);
1587		}
1588		break;
1589
1590	case _C_CHAR_AS_TEXT:
1591		retobject = PyBytes_FromStringAndSize((char*)datum, 1);
1592		break;
1593
1594	case _C_CHR:
1595	case _C_CHAR_AS_INT:
1596		/*
1597		 * We don't return a string because BOOL is an alias for
1598		 * char (at least on MacOS X)
1599		 */
1600		retobject = (PyObject*)PyInt_FromLong ((int)(*(char*)datum));
1601		break;
1602
1603	case _C_UCHR:
1604		retobject = (PyObject*)PyInt_FromLong (
1605			(long)(*(unsigned char*)datum));
1606		break;
1607
1608	case _C_CHARPTR:
1609#ifdef _C_ATOM
1610	case _C_ATOM:
1611#endif
1612	{
1613		char *cp = *(char **) datum;
1614
1615		if (cp == NULL) {
1616			Py_INCREF(Py_None);
1617			retobject = Py_None;
1618		} else {
1619			retobject = (PyObject*)PyBytes_FromString(cp);
1620		}
1621		break;
1622	}
1623
1624#ifdef _C_BOOL
1625	case _C_BOOL:
1626		retobject = (PyObject *) PyBool_FromLong (*(bool*) datum);
1627		break;
1628#endif
1629
1630	case _C_NSBOOL:
1631		retobject = (PyObject *) PyBool_FromLong (*(BOOL*) datum);
1632		break;
1633
1634	case _C_INT:
1635		retobject = (PyObject *) PyInt_FromLong (*(int*) datum);
1636		break;
1637
1638	case _C_UINT:
1639#if __LP64__
1640		retobject = (PyObject*)PyInt_FromLong (
1641			*(unsigned int *) datum);
1642
1643#else
1644		if (*(unsigned int*)datum > LONG_MAX) {
1645			retobject = (PyObject*)PyLong_FromUnsignedLongLong(
1646				*(unsigned int*)datum);
1647		} else {
1648			retobject = (PyObject*)PyInt_FromLong (
1649				*(unsigned int *) datum);
1650		}
1651#endif
1652		break;
1653
1654	case _C_SHT:
1655		retobject = (PyObject *) PyInt_FromLong (*(short *) datum);
1656		break;
1657
1658	case _C_USHT:
1659		retobject = (PyObject *) PyInt_FromLong (
1660			*(unsigned short *) datum);
1661		break;
1662
1663	case _C_LNG_LNG:
1664#ifndef __LP64__ /* else: fall-through to _C_LNG case */
1665		retobject = (PyObject*)PyLong_FromLongLong(*(long long*)datum);
1666		break;
1667#endif
1668
1669	case _C_LNG:
1670		retobject = (PyObject *) PyInt_FromLong(*(long *) datum);
1671		break;
1672
1673	case _C_ULNG_LNG:
1674#ifndef __LP64__ /* else: fallthrough to the ULNG case */
1675		retobject = (PyObject*)PyLong_FromUnsignedLongLong(
1676				*(unsigned long long*)datum);
1677		break;
1678#endif
1679
1680	case _C_ULNG:
1681#if PY_MAJOR_VERSION == 2
1682		if (*(unsigned long*)datum > LONG_MAX) {
1683			retobject = (PyObject*)PyLong_FromUnsignedLongLong(
1684				*(unsigned long*)datum);
1685		} else {
1686			retobject = (PyObject*)PyInt_FromLong (
1687				*(unsigned long*) datum);
1688		}
1689#else
1690		retobject = PyLong_FromUnsignedLong(*(unsigned long*)datum);
1691#endif
1692		break;
1693
1694
1695
1696	case _C_FLT:
1697		retobject = (PyObject *) PyFloat_FromDouble (*(float*) datum);
1698		break;
1699
1700	case _C_DBL:
1701		retobject = (PyObject *) PyFloat_FromDouble (*(double*) datum);
1702		break;
1703
1704	case _C_ID:
1705	{
1706		id obj = *(id *) datum;
1707
1708#if 1
1709		/* In theory this is a no-op, in practice this gives us EOF 4.5
1710		 * support.
1711		 *
1712		 * EOF can return references to 'to-be-restored' objects,
1713		 * calling any method on them fully restores them, 'self' is
1714		 * the safest method to call.
1715		 */
1716		obj = [obj self];
1717#endif
1718
1719		if (obj == nil) {
1720			retobject = Py_None;
1721			Py_INCREF (retobject);
1722		} else {
1723			retobject = [obj  __pyobjc_PythonObject__];
1724		}
1725		break;
1726	}
1727
1728	case _C_SEL:
1729		if (*(SEL*)datum == NULL) {
1730			retobject = Py_None;
1731			Py_INCREF(retobject);
1732		} else {
1733			retobject = PyText_FromString(sel_getName(*(SEL*)datum));
1734		}
1735		break;
1736
1737	case _C_CLASS:
1738	{
1739		Class c = *(Class *) datum;
1740
1741		if (c == Nil) {
1742			retobject = Py_None;
1743			Py_INCREF (retobject);
1744		} else {
1745			retobject = (PyObject *) PyObjCClass_New(c);
1746		}
1747		break;
1748	}
1749
1750	case _C_PTR:
1751		if (type[1] == _C_VOID) {
1752			/* A void*. These are treated like unsigned integers. */
1753			retobject = (PyObject*)PyLong_FromUnsignedLongLong(
1754				*(unsigned long*)datum);
1755
1756		} else if (*(void**)datum == NULL) {
1757			retobject = Py_None;
1758			Py_INCREF(retobject);
1759
1760		} else {
1761			retobject = PyObjCPointerWrapper_ToPython(type, datum);
1762			if (retobject == NULL && !PyErr_Occurred()) {
1763				retobject = (PyObject*)PyObjCPointer_New(
1764					*(void**) datum, type+1);
1765			}
1766		}
1767		break;
1768
1769	case _C_UNION_B:
1770	{
1771		Py_ssize_t size = PyObjCRT_SizeOfType (type);
1772		if (size == -1) return NULL;
1773		retobject = PyBytes_FromStringAndSize ((void*)datum, size);
1774		break;
1775	}
1776
1777	case _C_STRUCT_B:
1778		retobject = pythonify_c_struct (type, datum);
1779		break;
1780
1781	case _C_ARY_B:
1782		retobject = pythonify_c_array (type, datum);
1783		break;
1784
1785	case _C_VOID:
1786		retobject = Py_None;
1787		Py_INCREF (retobject);
1788		break;
1789
1790	default:
1791		PyErr_Format(PyObjCExc_Error,
1792			"pythonify_c_value: unhandled value type (%c|%d|%s)",
1793			*type, *type, type);
1794		break;
1795	}
1796
1797	return retobject;
1798}
1799
1800
1801Py_ssize_t
1802PyObjCRT_SizeOfReturnType(const char* type)
1803{
1804	PyObjC_Assert(type != NULL, -1);
1805
1806#if 1 /* def __ppc__ */
1807	switch(*type) {
1808	case _C_CHR:
1809	case _C_BOOL:
1810	case _C_UCHR:
1811	case _C_SHT:
1812	case _C_USHT:
1813	case _C_UNICHAR:
1814	case _C_CHAR_AS_TEXT:
1815	case _C_CHAR_AS_INT:
1816	case _C_NSBOOL:
1817		return sizeof(long);
1818	default:
1819		return PyObjCRT_SizeOfType(type);
1820	}
1821#else
1822		return PyObjCRT_SizeOfType(type);
1823#endif
1824}
1825
1826/*
1827* Convert a python value to a basic C unsigned integer value.
1828*/
1829static int
1830depythonify_unsigned_int_value(
1831		PyObject* argument, char* descr,
1832		unsigned long long* out, unsigned long long max)
1833{
1834	PyObjC_Assert(argument != NULL, -1);
1835	PyObjC_Assert(descr != NULL, -1);
1836	PyObjC_Assert(out != NULL, -1);
1837
1838#if PY_MAJOR_VERSION == 2
1839	if (PyInt_Check (argument)) {
1840		long temp = PyInt_AsLong(argument);
1841		if (PyErr_Occurred()) {
1842			return -1;
1843		}
1844		if (temp < 0) {
1845			if (PyErr_WarnEx(
1846				PyExc_DeprecationWarning,
1847				"converting negative value to unsigned integer",
1848				1) < 0) {
1849
1850				return -1;
1851			}
1852		}
1853		if ((unsigned long long)temp > max) {
1854			PyErr_Format(PyExc_ValueError,
1855				"depythonifying '%s', got '%s' of "
1856				"wrong magnitude (max %llu, value %llu)", descr,
1857					Py_TYPE(argument)->tp_name,
1858					max, temp);
1859			return -1;
1860		}
1861		*out = temp;
1862		return 0;
1863
1864	} else
1865#endif
1866	if (PyLong_Check(argument)) {
1867		*out = PyLong_AsUnsignedLongLong(argument);
1868		if (*out == (unsigned long long)-1 && PyErr_Occurred()) {
1869			PyErr_Clear();
1870
1871			*out = (unsigned long long)PyLong_AsLongLong(argument);
1872			if (*out == (unsigned long long)-1 && PyErr_Occurred()) {
1873				PyErr_Format(PyExc_ValueError,
1874					"depythonifying '%s', got '%s' of "
1875					"wrong magnitude (max %llu, value %llu)",
1876					descr,
1877					Py_TYPE(argument)->tp_name,
1878					max, *out);
1879				return -1;
1880			}
1881
1882			if ((long long)*out < 0) {
1883				if (PyErr_WarnEx(
1884					PyExc_DeprecationWarning,
1885					"converting negative value to unsigned integer",
1886					1) < 0) {
1887
1888					return -1;
1889				}
1890			}
1891		}
1892
1893		if (*out > max) {
1894			PyErr_Format(PyExc_ValueError,
1895				"depythonifying '%s', got '%s' of "
1896				"wrong magnitude (max %llu, value %llu)", descr,
1897				Py_TYPE(argument)->tp_name,
1898				max, *out);
1899			return -1;
1900		}
1901		return 0;
1902
1903	} else {
1904		PyObject* tmp;
1905
1906		if (
1907#if PY_MAJOR_VERSION == 2
1908			PyString_Check(argument) ||
1909#else
1910			PyBytes_Check(argument) ||
1911#endif
1912#ifdef PyByteArray_Check
1913			PyByteArray_Check(argument) ||
1914#endif
1915			PyUnicode_Check(argument)) {
1916
1917			PyErr_Format(PyExc_ValueError,
1918				"depythonifying '%s', got '%s'",
1919					descr,
1920					Py_TYPE(argument)->tp_name);
1921			return -1;
1922		}
1923
1924		tmp = PyNumber_Long(argument);
1925		if (tmp != NULL) {
1926			*out = PyLong_AsUnsignedLongLong(tmp);
1927			if (*out == (unsigned long long)-1 && PyErr_Occurred()) {
1928				PyErr_Clear();
1929
1930				*out = PyLong_AsLong(tmp);
1931				if (*out == (unsigned long long)-1 && PyErr_Occurred()) {
1932					Py_DECREF(tmp);
1933					return -1;
1934				}
1935				if ((long long)*out < 0) {
1936					if (PyErr_WarnEx(
1937						PyExc_DeprecationWarning,
1938						"converting negative value to unsigned integer",
1939						1) < 0) {
1940						Py_DECREF(tmp);
1941
1942						return -1;
1943					}
1944				}
1945			}
1946			Py_DECREF(tmp);
1947
1948			if (*out <= max) {
1949				return 0;
1950			}
1951		}
1952
1953		PyErr_Format(PyExc_ValueError,
1954			"depythonifying '%s', got '%s'",
1955				descr,
1956				Py_TYPE(argument)->tp_name);
1957		return -1;
1958	}
1959}
1960
1961/*
1962* Convert a python value to a basic C signed integer value.
1963*/
1964static int
1965depythonify_signed_int_value(
1966		PyObject* argument, char* descr,
1967		long long* out, long long min, long long max)
1968{
1969	PyObjC_Assert(argument != NULL, -1);
1970	PyObjC_Assert(descr != NULL, -1);
1971	PyObjC_Assert(out != NULL, -1);
1972
1973#if PY_MAJOR_VERSION == 2
1974	if (PyInt_Check (argument)) {
1975		*out = (long long)PyInt_AsLong(argument);
1976		if (PyErr_Occurred()) {
1977			return -1;
1978		}
1979		if (*out < min || *out > max) {
1980			PyErr_Format(PyExc_ValueError,
1981				"depythonifying '%s', got '%s' of "
1982				"wrong magnitude", descr,
1983					Py_TYPE(argument)->tp_name);
1984			return -1;
1985		}
1986		return 0;
1987
1988	} else
1989#endif
1990	if (PyLong_Check(argument)) {
1991		*out = PyLong_AsLongLong(argument);
1992		if (PyErr_Occurred()) {
1993			PyErr_Format(PyExc_ValueError,
1994				"depythonifying '%s', got '%s' of "
1995				"wrong magnitude", descr,
1996					Py_TYPE(argument)->tp_name);
1997			return -1;
1998		}
1999
2000		if (*out < min || *out > max) {
2001			PyErr_Format(PyExc_ValueError,
2002				"depythonifying '%s', got '%s' of "
2003				"wrong magnitude", descr,
2004					Py_TYPE(argument)->tp_name);
2005			return -1;
2006		}
2007		return 0;
2008
2009	} else {
2010		PyObject* tmp;
2011
2012		if (
2013#if PY_MAJOR_VERSION == 2
2014			PyString_Check(argument) ||
2015#else
2016			PyBytes_Check(argument) ||
2017#endif
2018#ifdef PyByteArray_Check
2019			PyByteArray_Check(argument) ||
2020#endif
2021			PyUnicode_Check(argument)) {
2022
2023			PyErr_Format(PyExc_ValueError,
2024				"depythonifying '%s', got '%s' of %"PY_FORMAT_SIZE_T"d",
2025					descr,
2026					Py_TYPE(argument)->tp_name,
2027					PyObject_Size(argument));
2028			return -1;
2029		}
2030
2031
2032		tmp = PyNumber_Long(argument);
2033		if (tmp != NULL) {
2034			*out = PyLong_AsLongLong(tmp);
2035			Py_DECREF(tmp);
2036
2037			if (PyErr_Occurred()) {
2038				return -1;
2039			}
2040
2041			if (*out >= min && *out <= max) {
2042				return 0;
2043			}
2044		}
2045
2046		PyErr_Format(PyExc_ValueError,
2047			"depythonifying '%s', got '%s'",
2048				descr,
2049				Py_TYPE(argument)->tp_name);
2050		return -1;
2051	}
2052}
2053
2054int depythonify_c_return_value(
2055const char* type, PyObject* argument, void* datum)
2056{
2057	PyObjC_Assert(type != NULL, -1);
2058	PyObjC_Assert(argument != NULL, -1);
2059	PyObjC_Assert(datum != NULL, -1);
2060
2061#ifdef __ppc__
2062	long long temp;
2063	unsigned long long utemp;
2064	int       r;
2065
2066	/* Small integers are promoted to integers when returning them */
2067	switch (*type) {
2068#ifdef _C_BOOL
2069	case _C_BOOL:
2070	case _C_NSBOOL:
2071		if (PyObject_IsTrue(argument)) {
2072			*(int*) datum = YES;
2073		} else {
2074			*(int*) datum = NO;
2075		}
2076		return 0;
2077
2078#endif
2079	case _C_CHAR_AS_INT:
2080		r = depythonify_signed_int_value(argument, "char",
2081			&temp, CHAR_MIN, CHAR_MAX);
2082		if (r == 0) {
2083			*(int*)datum = temp;
2084		}
2085		return r;
2086
2087	case _C_CHAR_AS_TEXT:
2088		if (PyBytes_Check(argument) && PyBytes_Size(argument) == 1) {
2089			*(int*) datum = PyBytes_AsString (argument)[0];
2090			return 0;
2091#ifdef PyByteArray_Check
2092		} else if (PyByteArray_Check(argument) && PyByteArray_Size(argument) == 1) {
2093			*(int*) datum = PyByteArray_AsString (argument)[0];
2094			return 0;
2095#endif
2096		} else {
2097			PyErr_Format(PyExc_ValueError,
2098				"Expecting byte string of length 1, got '%s'",
2099				Py_TYPE(argument)->tp_name);
2100			return -1;
2101		}
2102		break;
2103
2104	case _C_CHR:
2105		if (PyBytes_Check(argument) && PyBytes_Size(argument) == 1) {
2106			*(int*) datum = PyBytes_AsString (argument)[0];
2107			return 0;
2108#ifdef PyByteArray_Check
2109		} else if (PyByteArray_Check(argument) && PyByteArray_Size(argument) == 1) {
2110			*(int*) datum = PyByteArray_AsString (argument)[0];
2111			return 0;
2112#endif
2113		}
2114
2115		r = depythonify_signed_int_value(argument, "char",
2116			&temp, CHAR_MIN, CHAR_MAX);
2117		if (r == 0) {
2118			*(int*)datum = temp;
2119		}
2120		return r;
2121
2122	case _C_UNICHAR:
2123		if (PyUnicode_Check(argument) && PyUnicode_GetSize(argument) == 1) {
2124			*(int*)datum = (int)(*PyUnicode_AsUnicode(argument));
2125			return 0;
2126
2127#if PY_MAJOR_VERSION == 2
2128		} else if (PyString_Check(argument)) {
2129			PyObject* u = PyUnicode_FromObject(argument);
2130			if (u == NULL) {
2131				return -1;
2132			}
2133			if (PyUnicode_Check(u) && PyUnicode_GetSize(u) == 1) {
2134				*(int*)datum = (int)(*PyUnicode_AsUnicode(u));
2135				Py_DECREF(u);
2136				return 0;
2137			}
2138			Py_DECREF(u);
2139#endif
2140		}
2141		PyErr_Format(PyExc_ValueError, "Expecting unicode string of length 1, got a '%s'",
2142				Py_TYPE(argument)->tp_name);
2143		return -1;
2144
2145	case _C_UCHR:
2146		if (PyBytes_Check(argument) && PyBytes_Size(argument) == 1) {
2147			*(unsigned int*) datum =
2148				PyBytes_AsString (argument)[0];
2149			return 0;
2150		}
2151		r = depythonify_unsigned_int_value(argument, "unsigned char",
2152			&utemp, UCHAR_MAX);
2153		if (r == 0) {
2154			*(unsigned int*)datum = utemp;
2155		}
2156		return r;
2157
2158	case _C_SHT:
2159		r = depythonify_signed_int_value(argument, "short",
2160			&temp, SHRT_MIN, SHRT_MAX);
2161		if (r == 0) {
2162			*(int*)datum = temp;
2163		}
2164		return r;
2165
2166	case _C_USHT:
2167		r = depythonify_unsigned_int_value(argument, "unsigned short",
2168			&utemp, USHRT_MAX);
2169		if (r == 0) {
2170			*(unsigned int*)datum = utemp;
2171		}
2172		return r;
2173
2174	default:
2175		return depythonify_c_value(type, argument, datum);
2176	}
2177
2178#else
2179	return depythonify_c_value(type, argument, datum);
2180#endif
2181}
2182
2183PyObject *
2184pythonify_c_return_value (const char *type, void *datum)
2185{
2186	PyObjC_Assert(type != NULL, NULL);
2187	PyObjC_Assert(datum != NULL, NULL);
2188
2189#ifdef __ppc__
2190	/*
2191 	 * On PowerPC short and char return values are returned
2192 	 * as full-size ints.
2193	 */
2194	static  const char intType[] = { _C_INT, 0 };
2195	static  const char uintType[] = { _C_UINT, 0 };
2196
2197	switch(*type) {
2198	case _C_BOOL:
2199	case _C_NSBOOL:
2200		return PyBool_FromLong(*(int*)datum);
2201
2202	case _C_CHR:
2203	case _C_CHAR_AS_INT:
2204	case _C_SHT:
2205		return pythonify_c_value(intType, datum);
2206	case _C_UCHR: case _C_USHT:
2207		return pythonify_c_value(uintType, datum);
2208
2209	case _C_CHAR_AS_TEXT:
2210		{
2211			char ch = *(int*)datum;
2212			return PyBytes_FromStringAndSize(&ch, 1);
2213		}
2214
2215	case _C_UNICHAR:
2216		{
2217			Py_UNICODE ch = *(int*)datum;
2218			return PyUnicode_FromUnicode(&ch, 1);
2219		}
2220
2221	default:
2222		return pythonify_c_value(type, datum);
2223	}
2224
2225#else
2226	return pythonify_c_value(type, datum);
2227
2228#endif
2229}
2230
2231
2232int
2233depythonify_c_value (const char *type, PyObject *argument, void *datum)
2234{
2235	PyObjC_Assert(type != NULL, -1);
2236	PyObjC_Assert(argument != NULL, -1);
2237	PyObjC_Assert(datum != NULL, -1);
2238
2239	if (argument == NULL) abort();
2240
2241	/* Pass by reference output arguments are sometimes passed a NULL
2242	 * pointer, this surpresses a core dump.
2243	 */
2244	long long temp;
2245	unsigned long long utemp;
2246	int       r;
2247
2248	if (!datum) return 0;
2249
2250	type = PyObjCRT_SkipTypeQualifiers (type);
2251
2252	switch (*type) {
2253#ifdef _C_ATOM
2254	case _C_ATOM:
2255#endif
2256	case _C_CHARPTR:
2257
2258		if (PyBytes_Check(argument)) {
2259			*(char**)datum = PyBytes_AsString(argument);
2260			if (*(char**)datum == NULL) {
2261				return -1;
2262			}
2263
2264#ifdef PyByteArray_Check
2265		} else if (PyByteArray_Check(argument)) {
2266			*(char**)datum = PyByteArray_AsString(argument);
2267			if (*(char**)datum == NULL) {
2268				return -1;
2269			}
2270#endif
2271		} else if (argument == Py_None) {
2272			*(char**)datum = NULL;
2273
2274		} else {
2275			PyErr_Format(PyExc_ValueError,
2276				"depythonifying 'charptr', got '%s'",
2277					Py_TYPE(argument)->tp_name);
2278			return -1;
2279		}
2280		break;
2281
2282	case _C_CHR:
2283		if (PyBytes_Check(argument) && PyBytes_Size(argument) == 1) {
2284			*(char*) datum = PyBytes_AsString (argument)[0];
2285			return 0;
2286#ifdef PyByteArray_Check
2287		} else if (PyByteArray_Check(argument) && PyByteArray_Size(argument) == 1) {
2288			*(char*) datum = PyByteArray_AsString (argument)[0];
2289			return 0;
2290#endif
2291		}
2292
2293		r = depythonify_signed_int_value(argument, "char",
2294			&temp, CHAR_MIN, CHAR_MAX);
2295		if (r == 0) {
2296			*(char*)datum = temp;
2297		}
2298		return r;
2299
2300	case _C_CHAR_AS_INT:
2301		r = depythonify_signed_int_value(argument, "char",
2302			&temp, CHAR_MIN, CHAR_MAX);
2303		if (r == 0) {
2304			*(char*)datum = temp;
2305		}
2306		return r;
2307
2308	case _C_CHAR_AS_TEXT:
2309
2310		if (PyBytes_Check(argument) && PyBytes_Size(argument) == 1) {
2311			*(char*) datum = PyBytes_AsString (argument)[0];
2312			return 0;
2313#ifdef PyByteArray_Check
2314		} else if (PyByteArray_Check(argument) && PyByteArray_Size(argument) == 1) {
2315			*(char*) datum = PyByteArray_AsString (argument)[0];
2316			return 0;
2317#endif
2318		} else {
2319			PyErr_Format(PyExc_ValueError,
2320					"Expecting byte string of length 1, got a '%s'",
2321					Py_TYPE(argument)->tp_name);
2322			return -1;
2323		}
2324
2325	case _C_UCHR:
2326		if (PyBytes_Check(argument) && PyBytes_Size(argument) == 1) {
2327			*(unsigned char*) datum =
2328				PyBytes_AsString (argument)[0];
2329			return 0;
2330#ifdef PyByteArray_Check
2331		} else if (PyByteArray_Check(argument) && PyByteArray_Size(argument) == 1) {
2332			*(unsigned char*) datum = PyByteArray_AsString (argument)[0];
2333			return 0;
2334#endif
2335		}
2336		r = depythonify_unsigned_int_value(argument, "unsigned char",
2337			&utemp, UCHAR_MAX);
2338		if (r == 0) {
2339			*(unsigned char*)datum = utemp;
2340		}
2341		return r;
2342
2343	case _C_SHT:
2344		r = depythonify_signed_int_value(argument, "short",
2345			&temp, SHRT_MIN, SHRT_MAX);
2346		if (r == 0) {
2347			*(short*)datum = temp;
2348		}
2349		return r;
2350
2351	case _C_USHT:
2352		r = depythonify_unsigned_int_value(argument, "unsigned short",
2353			&utemp, USHRT_MAX);
2354		if (r == 0) {
2355			*(unsigned short*)datum = utemp;
2356		}
2357		return r;
2358
2359#ifdef _C_BOOL
2360	case _C_BOOL:
2361		*(bool*)datum = PyObject_IsTrue(argument);
2362		return 0;
2363#endif
2364
2365	case _C_NSBOOL:
2366		*(BOOL*)datum = PyObject_IsTrue(argument);
2367		return 0;
2368
2369	case _C_UNICHAR:
2370		if (PyUnicode_Check(argument) && PyUnicode_GetSize(argument) == 1) {
2371			*(UniChar*)datum = (UniChar)(*PyUnicode_AsUnicode(argument));
2372			return 0;
2373#if PY_MAJOR_VERSION == 2
2374		} else if (PyString_Check(argument)) {
2375			PyObject* u = PyUnicode_FromObject(argument);
2376			if (u == NULL) {
2377				return -1;
2378			}
2379			if (PyUnicode_Check(u) && PyUnicode_GetSize(u) == 1) {
2380				*(UniChar*)datum = (UniChar)(*PyUnicode_AsUnicode(u));
2381				Py_DECREF(u);
2382				return 0;
2383			}
2384			Py_DECREF(u);
2385#endif
2386		}
2387		PyErr_Format(PyExc_ValueError, "Expecting unicode string of length 1, got a '%s'",
2388				Py_TYPE(argument)->tp_name);
2389		return -1;
2390
2391	case _C_INT:
2392		r = depythonify_signed_int_value(argument, "int",
2393			&temp, INT_MIN, INT_MAX);
2394		if (r == 0) {
2395			*(int*)datum = temp;
2396		}
2397		return r;
2398
2399	case _C_UINT:
2400		r = depythonify_unsigned_int_value(argument, "unsigned int",
2401			&utemp, UINT_MAX);
2402		if (r == 0) {
2403			*(unsigned int*)datum = utemp;
2404		}
2405		return r;
2406
2407	case _C_LNG:
2408		r = depythonify_signed_int_value(argument, "long",
2409			&temp, LONG_MIN, LONG_MAX);
2410		if (r == 0) {
2411			*(long*)datum = temp;
2412		}
2413		return r;
2414
2415	case _C_ULNG:
2416		r = depythonify_unsigned_int_value(argument, "unsigned long",
2417			&utemp, ULONG_MAX);
2418		if (r == 0) {
2419			*(unsigned long*)datum = utemp;
2420		}
2421		return r;
2422
2423	case _C_LNG_LNG:
2424		r = depythonify_signed_int_value(argument, "long long",
2425			&temp, LLONG_MIN, LLONG_MAX);
2426		if (r == 0) {
2427			*(long long*)datum = temp;
2428		}
2429		return r;
2430
2431	case _C_ULNG_LNG:
2432		r = depythonify_unsigned_int_value(argument,
2433			"unsigned long long", &utemp, ULLONG_MAX);
2434		if (r == 0) {
2435			*(unsigned long long*)datum = utemp;
2436		}
2437		return r;
2438
2439	case _C_ID:
2440		/*
2441			XXX
2442
2443			This should, for values other than Py_None, always return the same id
2444			for the same PyObject for as long as that id lives.  I think that the
2445			implementation of this should be moved to OC_PythonObject,
2446			which would itself have a map of PyObject->id.  The dealloc
2447			of each of these custom objects should notify OC_PythonObject
2448			to remove map entry.  We need to significantly change how immutable types
2449			are bridged, and create OC_PythonString, OC_PythonBool, etc. which are
2450			subclasses of what they should be from the the Objective C side.
2451
2452			If we don't do this, we break binary plist serialization, and likely
2453			other things, which assume that foo[bar] is foo[bar] for the duration of
2454			the serialization process.  I would imagine that other things also
2455			assume this kind of invariant, so we should do it here rather than in every
2456			container object.
2457		*/
2458
2459
2460		return [OC_PythonObject wrapPyObject:argument toId:(id *)datum];
2461
2462	case _C_CLASS:
2463		if (PyObjCClass_Check(argument))  {
2464			*(Class*) datum = PyObjCClass_GetClass(argument);
2465
2466		} else if (argument == Py_None) {
2467			*(Class*) datum = nil;
2468
2469		} else if (PyType_Check(argument) && PyType_IsSubtype((PyTypeObject*)argument, &PyObjCClass_Type)) {
2470			*(Class*) datum = PyObjCClass_GetClass(PyObjCClass_ClassForMetaClass(argument));
2471
2472		} else {
2473			PyErr_Format(PyExc_ValueError,
2474				"depythonifying 'Class', got '%s'",
2475					Py_TYPE(argument)->tp_name);
2476			return -1;
2477		}
2478		break;
2479
2480	case _C_SEL:
2481		if (argument == Py_None) {
2482			*(SEL*)datum = NULL;
2483		} else if (PyObjCSelector_Check (argument)) {
2484			*(SEL *) datum = PyObjCSelector_GetSelector(argument);
2485		} else if (PyUnicode_Check(argument)) {
2486			PyObject* bytes = PyUnicode_AsEncodedString(argument, NULL, NULL);
2487			if (bytes == NULL) {
2488				return -1;
2489			}
2490			char *selname = PyBytes_AsString (bytes);
2491			SEL sel;
2492
2493			if (*selname == '\0') {
2494				*(SEL*)datum = NULL;
2495				Py_DECREF(bytes);
2496			} else {
2497				sel = sel_getUid (selname);
2498				Py_DECREF(bytes);
2499
2500				if (sel)  {
2501					*(SEL*) datum = sel;
2502				} else {
2503					PyErr_Format(PyExc_ValueError,
2504						"depythonifying 'SEL', cannot "
2505						"register string with runtime");
2506					return -1;
2507				}
2508			}
2509
2510		} else if (PyBytes_Check(argument)) {
2511			char *selname = PyBytes_AsString (argument);
2512			SEL sel;
2513
2514			if (*selname == '\0') {
2515				*(SEL*)datum = NULL;
2516			} else {
2517				sel = sel_getUid (selname);
2518
2519				if (sel)  {
2520					*(SEL*) datum = sel;
2521				} else {
2522					PyErr_Format(PyExc_ValueError,
2523						"depythonifying 'SEL', cannot "
2524						"register string with runtime");
2525					return -1;
2526				}
2527			}
2528#ifdef PyByteArray_Check
2529		} else if (PyByteArray_Check(argument)) {
2530			char *selname = PyByteArray_AsString (argument);
2531			SEL sel;
2532
2533			if (*selname == '\0') {
2534				*(SEL*)datum = NULL;
2535			} else {
2536				sel = sel_getUid (selname);
2537
2538				if (sel)  {
2539					*(SEL*) datum = sel;
2540				} else {
2541					PyErr_Format(PyExc_ValueError,
2542						"depythonifying 'SEL', cannot "
2543						"register string with runtime");
2544					return -1;
2545				}
2546			}
2547#endif
2548		} else {
2549			PyErr_Format(PyExc_ValueError,
2550				"depythonifying 'SEL', got '%s'",
2551					Py_TYPE(argument)->tp_name);
2552			return -1;
2553		}
2554		break;
2555
2556
2557	case _C_PTR:
2558		if (argument == Py_None) {
2559			*(void**)datum = NULL;
2560			return 0;
2561		}
2562		if (type[1] == _C_VOID) {
2563			r = depythonify_unsigned_int_value(argument,
2564				"unsigned long",
2565				&utemp, ULONG_MAX);
2566			if (r == 0) {
2567				*(void**)datum = (void*)(unsigned long)utemp;
2568			}
2569			return r;
2570
2571		}
2572		r = PyObjCPointerWrapper_FromPython(type, argument, datum);
2573		if (r == -1) {
2574			if (PyErr_Occurred()) {
2575				return -1;
2576			} else if (PyObjCPointer_Check (argument)) {
2577				*(void **) datum = PyObjCPointer_Ptr(argument);
2578			} else {
2579				PyErr_Format(PyExc_ValueError,
2580					"depythonifying 'pointer', got '%s'",
2581						Py_TYPE(argument)->tp_name);
2582				return -1;
2583			}
2584		}
2585		break;
2586
2587	case _C_FLT:
2588		if (PyFloat_Check (argument)) {
2589			*(float *) datum = (float)PyFloat_AsDouble (argument);
2590#if PY_MAJOR_VERSION == 2
2591		} else if (PyInt_Check (argument)) {
2592			*(float *) datum = (float) PyInt_AsLong (argument);
2593#endif
2594		} else if (PyLong_Check (argument)) {
2595			*(float*) datum = (float) PyLong_AsDouble(argument);
2596			if (*(float*)datum == -1 && PyErr_Occurred()) {
2597				return -1;
2598			}
2599		} else if (
2600#if PY_MAJOR_VERSION == 2
2601				PyString_Check(argument) ||
2602#else
2603				PyBytes_Check(argument) ||
2604#ifdef PyByteArray_Check
2605				PyByteArray_Check(argument) ||
2606#endif
2607#endif
2608				PyUnicode_Check(argument)) {
2609			PyErr_Format(PyExc_ValueError,
2610				"depythonifying 'float', got '%s'",
2611					Py_TYPE(argument)->tp_name);
2612			return -1;
2613		} else {
2614			PyObject* tmp = PyNumber_Float(argument);
2615			if (tmp != NULL) {
2616				double dblval = PyFloat_AsDouble(tmp);
2617				Py_DECREF(tmp);
2618				*(float*) datum = dblval;
2619				return 0;
2620			}
2621
2622			PyErr_Format(PyExc_ValueError,
2623				"depythonifying 'float', got '%s'",
2624					Py_TYPE(argument)->tp_name);
2625			return -1;
2626		}
2627		break;
2628
2629	case _C_DBL:
2630		if (PyFloat_Check (argument)) {
2631			*(double *) datum = PyFloat_AsDouble (argument);
2632#if PY_MAJOR_VERSION == 2
2633		} else if (PyInt_Check (argument)) {
2634			*(double *) datum = (double) PyInt_AsLong (argument);
2635#endif
2636		} else if (PyLong_Check (argument)) {
2637			*(double *) datum = PyLong_AsDouble (argument);
2638			if (*(double*)datum == -1 && PyErr_Occurred()) {
2639				return -1;
2640			}
2641		} else if (
2642#if PY_MAJOR_VERSION == 2
2643				PyString_Check(argument) ||
2644#else
2645				PyBytes_Check(argument) ||
2646#endif
2647#ifdef PyByteArray_Check
2648				PyByteArray_Check(argument) ||
2649#endif
2650				PyUnicode_Check(argument)) {
2651			PyErr_Format(PyExc_ValueError,
2652				"depythonifying 'float', got '%s'",
2653					Py_TYPE(argument)->tp_name);
2654			return -1;
2655		} else {
2656			PyObject* tmp = PyNumber_Float(argument);
2657			if (tmp != NULL) {
2658				double dblval = PyFloat_AsDouble(tmp);
2659				Py_DECREF(tmp);
2660				*(double*) datum = dblval;
2661				return 0;
2662			}
2663
2664			PyErr_Format(PyExc_ValueError,
2665				"depythonifying 'double', got '%s'",
2666					Py_TYPE(argument)->tp_name);
2667			return -1;
2668		}
2669		break;
2670
2671	case _C_UNION_B:
2672		if (PyBytes_Check (argument)) {
2673			Py_ssize_t expected_size = PyObjCRT_SizeOfType (type);
2674
2675			if (expected_size == -1) {
2676				PyErr_Format(PyExc_ValueError,
2677					"depythonifying 'union' of "
2678					"unknown size");
2679				return -1;
2680			} else if (expected_size != PyBytes_Size (argument)) {
2681				PyErr_Format(PyExc_ValueError,
2682					"depythonifying 'union' of size %"PY_FORMAT_SIZE_T"d, "
2683					"got byte string of %"PY_FORMAT_SIZE_T"d",
2684						   expected_size,
2685						   PyBytes_Size (argument));
2686				return -1;
2687			} else {
2688				memcpy ((void *) datum,
2689					PyBytes_AS_STRING (argument),
2690				expected_size);
2691			}
2692		} else {
2693			PyErr_Format(PyExc_ValueError,
2694				"depythonifying 'union', got '%s'",
2695					Py_TYPE(argument)->tp_name);
2696			return -1;
2697		}
2698		break;
2699
2700	case _C_STRUCT_B:
2701		return depythonify_c_struct (type, argument, datum);
2702
2703	case _C_ARY_B:
2704		return depythonify_c_array (type, argument, datum);
2705
2706	default:
2707		PyErr_Format(PyExc_ValueError,
2708			"depythonifying unknown typespec %#x", *type);
2709		return -1;
2710	}
2711	return 0;
2712}
2713
2714const char*
2715PyObjCRT_RemoveFieldNames(char* buf, const char* type)
2716{
2717	PyObjC_Assert(buf != NULL, NULL);
2718	PyObjC_Assert(type != NULL, NULL);
2719
2720	const char* end;
2721	if (*type == '"') {
2722		type++;
2723		while (*type++ != '"') {}
2724	}
2725	end = PyObjCRT_SkipTypeQualifiers(type);
2726	if (end == NULL) {
2727		return NULL;
2728	}
2729	switch (*end) {
2730	case _C_STRUCT_B:
2731		/* copy struct header */
2732		while (*end && *end != '=' && *end != _C_STRUCT_E) {
2733			end++;
2734		}
2735		if (*end == '\0') {
2736			PyErr_SetString(PyExc_ValueError, "Bad type string");
2737			return NULL;
2738		}
2739		if (*end == _C_STRUCT_E) {
2740			end ++;
2741			memcpy(buf, type, end-type);
2742			buf[end-type] = '\0';
2743			return end;
2744		}
2745		end++;
2746		memcpy(buf, type, end-type);
2747		buf += end - type;
2748		type = end;
2749
2750		/* RemoveFieldNames until reaching end of struct */
2751		while (*type != _C_STRUCT_E) {
2752			end = PyObjCRT_RemoveFieldNames(buf, type);
2753			if (end == NULL) return NULL;
2754			buf += strlen(buf);
2755			type = end;
2756		}
2757		buf[0] = _C_STRUCT_E;
2758		buf[1] = '\0';
2759		return type+1;
2760
2761	case _C_ARY_B:
2762		/* copy array header */
2763		end ++;
2764		while(isdigit(*end)) { end++; }
2765
2766		memcpy(buf, type, end-type);
2767		buf += end - type;
2768		type = end;
2769		if (*type == _C_ARY_E) {
2770			buf[0] = _C_ARY_E;
2771			buf[1] = '\0';
2772			return type;
2773		}
2774
2775		/* RemoveFieldName until reaching end of array */
2776		end = PyObjCRT_RemoveFieldNames(buf, type);
2777		if (end == NULL) return NULL;
2778
2779		if (*end != _C_ARY_E) {
2780			PyErr_SetString(PyExc_ValueError, "bad type string");
2781			return NULL;
2782		}
2783
2784		buf += strlen(buf);
2785		/*type += end - type;*/
2786		buf[0] = _C_ARY_E;
2787		buf[1] = '\0';
2788		return end + 1;
2789		break;
2790
2791	default:
2792		end = PyObjCRT_SkipTypeSpec(end);
2793		if (end == NULL) return NULL;
2794
2795		memcpy(buf, type, end-type);
2796		buf[end-type] = '\0';
2797		return end;
2798	}
2799}
2800
2801
2802PyObject* PyObjCObject_NewTransient(id objc_object, int* cookie)
2803{
2804	return [(NSObject*)objc_object __pyobjc_PythonTransient__:cookie];
2805}
2806
2807void PyObjCObject_ReleaseTransient(PyObject* proxy, int cookie)
2808{
2809	if (cookie && Py_REFCNT(proxy) != 1) {
2810		CFRetain(PyObjCObject_GetObject(proxy));
2811		((PyObjCObject*)proxy)-> flags &= ~PyObjCObject_kSHOULD_NOT_RELEASE;
2812	}
2813	Py_DECREF(proxy);
2814}
2815
2816BOOL PyObjC_signatures_compatible(const char* type1, const char* type2)
2817{
2818	/* Ignore type modifiers */
2819	type1 = PyObjCRT_SkipTypeQualifiers(type1);
2820	type2 = PyObjCRT_SkipTypeQualifiers(type2);
2821
2822	if (*type1 == _C_ARY_B) {
2823		if (type2[0] == _C_PTR) {
2824			type1++;
2825			while (isdigit(*type1)) type1++;
2826			return PyObjC_signatures_compatible(type1, type2+1);
2827		} else if (type2[0] == _C_ARY_B) {
2828			type1++;
2829			while (isdigit(*type1)) type1++;
2830			type2++;
2831			while (isdigit(*type2)) type2++;
2832			return PyObjC_signatures_compatible(type1, type2);
2833		}
2834		return NO;
2835	}
2836
2837
2838	if (PyObjCRT_SizeOfType(type1) != PyObjCRT_SizeOfType(type2)) {
2839		return NO;
2840	}
2841	switch (*type1) {
2842	case _C_FLT: case _C_DBL:
2843		switch (*type2) {
2844		case _C_FLT: case _C_DBL:
2845			return YES;
2846	 	default:
2847			return NO;
2848		}
2849
2850	case _C_ID:
2851		if (*type2 == _C_ID) {
2852			return YES;
2853		}
2854		if (type2[0] == _C_PTR && type2[1] == _C_VOID) {
2855			return YES;
2856		}
2857		return NO;
2858
2859	case _C_CHARPTR:
2860		if (*type2 == _C_CHARPTR) {
2861			return YES;
2862		} else if (*type2 == _C_PTR) {
2863			return PyObjC_signatures_compatible("c", type2+1);
2864		} else {
2865			return NO;
2866		}
2867
2868	case _C_PTR:
2869		if (type1[1] == _C_VOID && type2[0] == _C_ID) {
2870			return YES;
2871		}
2872		if (*type2 == _C_CHARPTR) {
2873			return PyObjC_signatures_compatible(type1+1, "c");
2874		}
2875		if (*type2 != _C_PTR) {
2876			return NO;
2877		}
2878		if (type1[1] == _C_VOID || type2[1] == _C_VOID) {
2879			return YES;
2880		}
2881		return PyObjC_signatures_compatible(type1+1, type2+1);
2882
2883
2884	default:
2885		switch (*type2) {
2886		case _C_ID: case _C_PTR: return NO;
2887		case _C_FLT: case _C_DBL: return NO;
2888		default: return YES;
2889		}
2890	}
2891}
2892