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