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 /* The following are one character type codes */ 354 case _C_UNDEF: 355 case _C_CLASS: 356 case _C_SEL: 357 case _C_CHR: 358 case _C_UCHR: 359 case _C_CHARPTR: 360#ifdef _C_ATOM 361 case _C_ATOM: 362#endif 363#ifdef _C_BOOL 364 case _C_BOOL: 365#endif 366 case _C_SHT: 367 case _C_USHT: 368 case _C_INT: 369 case _C_UINT: 370 case _C_LNG: 371 case _C_ULNG: 372 case _C_FLT: 373 case _C_DBL: 374 case _C_VOID: 375 case _C_LNG_LNG: 376 case _C_ULNG_LNG: 377 case _C_UNICHAR: 378 case _C_CHAR_AS_TEXT: 379 case _C_CHAR_AS_INT: 380 case _C_NSBOOL: 381 ++type; 382 break; 383 384 case _C_BFLD: 385 while (isdigit (*++type)); 386 break; 387 388 case _C_ID: 389 ++type; 390 if (*type == '?') { 391 /* Block pointer */ 392 type++; 393 } 394 if (*type == '"') { 395 /* embedded field name in an ivar_type */ 396 type=strchr(type+1, '"'); 397 if (type != NULL) { 398 type++; 399 } 400 } 401 break; 402 403 case _C_ARY_B: 404 /* skip digits, typespec and closing ']' */ 405 406 while (isdigit (*++type)); 407 type = PyObjCRT_SkipTypeSpec (type); 408 assert (type == NULL || *type == _C_ARY_E); 409 if (type) type++; 410 break; 411 412 case _C_STRUCT_B: 413 /* skip name, and elements until closing '}' */ 414 while (*type != _C_STRUCT_E && *type++ != '='); 415 while (type && *type != _C_STRUCT_E) { 416 if (*type == '"') { 417 /* embedded field names */ 418 type = strchr(type+1, '"'); 419 if (type != NULL) { 420 type++; 421 } else { 422 return NULL; 423 } 424 } 425 type = PyObjCRT_SkipTypeSpec (type); 426 } 427 if (type) type++; 428 break; 429 430 case _C_UNION_B: 431 /* skip name, and elements until closing ')' */ 432 while (*type != _C_UNION_E && *type++ != '='); 433 while (type && *type != _C_UNION_E) { 434 if (*type == '"') { 435 /* embedded field names */ 436 type = strchr(type+1, '"'); 437 if (type != NULL) { 438 type++; 439 } else { 440 return NULL; 441 } 442 } 443 type = PyObjCRT_SkipTypeSpec (type); 444 } 445 if (type) type++; 446 break; 447 448 case _C_PTR: 449 case _C_CONST: 450 case _C_IN: 451 case _C_INOUT: 452 case _C_OUT: 453 case _C_BYCOPY: 454 case _C_BYREF: 455 case _C_ONEWAY: 456 457 /* Just skip the following typespec */ 458 type = PyObjCRT_SkipTypeSpec (type+1); 459 break; 460 461 462 default: 463 PyErr_Format(PyObjCExc_InternalError, 464 "PyObjCRT_SkipTypeSpec: Unhandled type '%#x' %s", *type, type); 465 return NULL; 466 } 467 468 /* The compiler inserts a number after the actual signature, 469 * this number may or may not be usefull depending on the compiler 470 * version. We never use it. 471 */ 472 while (type && *type && isdigit(*type)) type++; 473 return type; 474} 475 476const char * 477PyObjCRT_NextField(const char *type) 478{ 479 PyObjC_Assert(type != NULL, NULL); 480 481 type = PyObjCRT_SkipTypeQualifiers (type); 482 483 switch (*type) { 484 /* The following are one character type codes */ 485 case _C_UNDEF: 486 case _C_CLASS: 487 case _C_SEL: 488 case _C_CHR: 489 case _C_UCHR: 490 case _C_CHARPTR: 491#ifdef _C_ATOM 492 case _C_ATOM: 493#endif 494#ifdef _C_BOOL 495 case _C_BOOL: 496#endif 497 case _C_SHT: 498 case _C_USHT: 499 case _C_INT: 500 case _C_UINT: 501 case _C_LNG: 502 case _C_ULNG: 503 case _C_FLT: 504 case _C_DBL: 505 case _C_VOID: 506 case _C_LNG_LNG: 507 case _C_ULNG_LNG: 508 case _C_UNICHAR: 509 case _C_CHAR_AS_TEXT: 510 case _C_CHAR_AS_INT: 511 case _C_NSBOOL: 512 case _C_BFLD: /* Not really 1 character, but close enough */ 513 ++type; 514 break; 515 516 case _C_ID: 517 ++type; 518 break; 519 520 case _C_ARY_B: 521 /* skip digits, typespec and closing ']' */ 522 523 while (isdigit (*++type)); 524 type = PyObjCRT_SkipTypeSpec (type); 525 assert (type == NULL || *type == _C_ARY_E); 526 if (type) type++; 527 break; 528 529 case _C_STRUCT_B: 530 /* skip name, and elements until closing '}' */ 531 while (*type != _C_STRUCT_E && *type++ != '='); 532 while (type && *type != _C_STRUCT_E) { 533 if (*type == '"') { 534 /* embedded field names */ 535 type = strchr(type+1, '"'); 536 if (type != NULL) { 537 type++; 538 } else { 539 return NULL; 540 } 541 } 542 type = PyObjCRT_SkipTypeSpec (type); 543 } 544 if (type) type++; 545 break; 546 547 case _C_UNION_B: 548 /* skip name, and elements until closing ')' */ 549 while (*type != _C_UNION_E && *type++ != '='); 550 while (type && *type != _C_UNION_E) { 551 if (*type == '"') { 552 /* embedded field names */ 553 type = strchr(type+1, '"'); 554 if (type != NULL) { 555 type++; 556 } else { 557 return NULL; 558 } 559 } 560 type = PyObjCRT_SkipTypeSpec (type); 561 } 562 if (type) type++; 563 break; 564 565 case _C_PTR: 566 case _C_CONST: 567 case _C_IN: 568 case _C_INOUT: 569 case _C_OUT: 570 case _C_BYCOPY: 571 case _C_BYREF: 572 case _C_ONEWAY: 573 574 /* Just skip the following typespec */ 575 type = PyObjCRT_NextField(type+1); 576 break; 577 578 579 default: 580 PyErr_Format(PyObjCExc_InternalError, 581 "PyObjCRT_SkipTypeSpec: Unhandled type '%#x'", *type); 582 return NULL; 583 } 584 585 /* The compiler inserts a number after the actual signature, 586 * this number may or may not be usefull depending on the compiler 587 * version. We never use it. 588 */ 589 while (type && *type && isdigit(*type)) type++; 590 return type; 591} 592 593/* 594Return the alignment of an object specified by type 595*/ 596 597/* 598* On MacOS X, the elements of a struct are aligned differently inside the 599* struct than outside. That is, the maximum alignment of any struct field 600* (except the first) is 4, doubles outside of a struct have an alignment of 601* 8. 602* 603* Other platform don't seem to have this inconsistency. 604* 605* XXX: sizeof_struct, alignof_struct and {de,}pythonify_c_struct should 606* probably be moved to platform dependend files. As long as this is the 607* only platform dependent code this isn't worth the effort. 608*/ 609 610static inline Py_ssize_t 611PyObjC_EmbeddedAlignOfType (const char* type) 612{ 613 PyObjC_Assert(type != NULL, -1); 614 615 Py_ssize_t align = PyObjCRT_AlignOfType(type); 616 617#if defined(__i386__) || defined(__x86_64__) 618 return align; 619 620#else 621 if (align < 4 || align == 16) { 622 return align; 623 } else { 624 return 4; 625 } 626#endif 627} 628 629Py_ssize_t 630PyObjCRT_AlignOfType (const char *type) 631{ 632 PyObjC_Assert(type != NULL, -1); 633 634 switch (*type) { 635 case _C_VOID: return __alignof__(char); 636 case _C_ID: return __alignof__ (id); 637 case _C_CLASS: return __alignof__ (Class); 638 case _C_SEL: return __alignof__ (SEL); 639 case _C_CHR: return __alignof__ (char); 640 case _C_UCHR: return __alignof__ (unsigned char); 641 case _C_SHT: return __alignof__ (short); 642 case _C_USHT: return __alignof__ (unsigned short); 643#ifdef _C_BOOL 644 case _C_BOOL: return __alignof__ (bool); 645#endif 646 case _C_UNICHAR: return __alignof__(UniChar); 647 case _C_CHAR_AS_TEXT: return __alignof__(char); 648 case _C_CHAR_AS_INT: return __alignof__(char); 649 case _C_NSBOOL: return __alignof__(BOOL); 650 case _C_INT: return __alignof__ (int); 651 case _C_UINT: return __alignof__ (unsigned int); 652 case _C_LNG: return __alignof__ (long); 653 case _C_ULNG: return __alignof__ (unsigned long); 654 case _C_FLT: return __alignof__ (float); 655 case _C_DBL: 656#if defined(__APPLE__) && defined(__i386__) 657 /* The ABI says natural alignment is 4 bytes, but 658 * GCC's __alignof__ says 8. The latter is wrong. 659 */ 660 return 4; 661#else 662 return __alignof__ (double); 663#endif 664 665 case _C_CHARPTR: return __alignof__ (char *); 666#ifdef _C_ATOM 667 case _C_ATOM: return __alignof__ (char *); 668#endif 669 case _C_PTR: return __alignof__ (void *); 670#if defined(__APPLE__) && defined(__i386__) 671 /* The ABI says natural alignment is 4 bytes, but 672 * GCC's __alignof__ says 8. The latter is wrong. 673 */ 674 case _C_LNG_LNG: return 4; 675 case _C_ULNG_LNG: return 4; 676#else 677 case _C_LNG_LNG: return __alignof__(long long); 678 case _C_ULNG_LNG: return __alignof__(unsigned long long); 679#endif 680 681 case _C_ARY_B: 682 while (isdigit(*++type)) /* do nothing */; 683 return PyObjCRT_AlignOfType (type); 684 685 case _C_STRUCT_B: 686 { 687 struct { int x; double y; } fooalign; 688 while(*type != _C_STRUCT_E && *type++ != '=') /* do nothing */; 689 if (*type != _C_STRUCT_E) { 690 int have_align = 0; 691 Py_ssize_t align = 0; 692 693 while (type != NULL && *type != _C_STRUCT_E) { 694 if (*type == '"') { 695 type = strchr(type+1, '"'); 696 if (type) type++; 697 } 698 if (have_align) { 699 align = MAX(align, 700 PyObjC_EmbeddedAlignOfType(type)); 701 } else { 702 align = PyObjCRT_AlignOfType(type); 703 have_align = 1; 704 } 705 type = PyObjCRT_SkipTypeSpec(type); 706 } 707 if (type == NULL) return -1; 708 return align; 709 } else { 710 return __alignof__ (fooalign); 711 } 712 } 713 714 case _C_UNION_B: 715 { 716 int maxalign = 0; 717 type++; 718 while (*type != _C_UNION_E) 719 { 720 int item_align = PyObjCRT_AlignOfType(type); 721 if (item_align == -1) return -1; 722 maxalign = MAX (maxalign, item_align); 723 type = PyObjCRT_SkipTypeSpec (type); 724 } 725 return maxalign; 726 } 727 728 case _C_CONST: 729 case _C_IN: 730 case _C_INOUT: 731 case _C_OUT: 732 case _C_BYCOPY: 733 case _C_BYREF: 734 case _C_ONEWAY: 735 return PyObjCRT_AlignOfType(type+1); 736 737 case _C_BFLD: 738 return 1; 739 740 case _C_UNDEF: 741 return __alignof__(void*); 742 743 default: 744 printf("alignoftype\n"); 745 abort(); 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 while (*type != _C_UNION_E) { 878 itemSize = PyObjCRT_SizeOfType (type); 879 if (itemSize == -1) return -1; 880 max_size = MAX (max_size, itemSize); 881 type = PyObjCRT_SkipTypeSpec (type); 882 } 883 return max_size; 884 } 885 886 case _C_CONST: 887 case _C_IN: 888 case _C_INOUT: 889 case _C_OUT: 890 case _C_BYCOPY: 891 case _C_BYREF: 892 case _C_ONEWAY: 893 return PyObjCRT_SizeOfType(type+1); 894 895 case _C_BFLD: 896 { 897 int i = strtol(type+1, NULL, 10); 898 return (i+7)/8; 899 } 900 break; 901 902 case _C_UNDEF: 903 return sizeof(void*); 904 905 default: 906 PyErr_Format(PyObjCExc_InternalError, 907 "PyObjCRT_SizeOfType: Unhandled type '%#x', %s", *type, type); 908 return -1; 909 } 910} 911 912PyObject * 913pythonify_c_array_nullterminated(const char* type, void* datum, BOOL alreadyRetained, BOOL alreadyCFRetained) 914{ 915 PyObjC_Assert(type != NULL, NULL); 916 PyObjC_Assert(datum != NULL, NULL); 917 918 Py_ssize_t count = 0; 919 Py_ssize_t sizeofitem = PyObjCRT_SizeOfType (type); 920 unsigned char* curdatum = datum; 921 922 type = PyObjCRT_SkipTypeQualifiers(type); 923 switch (*type) { 924 case _C_CHARPTR: 925 while (*(char**)curdatum != NULL) { 926 count ++; 927 curdatum += sizeofitem; 928 } 929 break; 930 931 case _C_ID: 932 while (*(id*)curdatum != NULL) { 933 count ++; 934 curdatum += sizeofitem; 935 } 936 break; 937 938 case _C_PTR: 939 while (*(void**)curdatum != NULL) { 940 count ++; 941 curdatum += sizeofitem; 942 } 943 break; 944 945 case _C_UCHR: 946 while (*(unsigned char*)curdatum != 0) { 947 count ++; 948 curdatum += sizeofitem; 949 } 950 break; 951 952 case _C_VOID: 953 case _C_CHR: 954 case _C_CHAR_AS_TEXT: 955 return PyString_FromString((char*)curdatum); 956 break; 957 958 case _C_USHT: 959 while (*(unsigned short*)curdatum != 0) { 960 count ++; 961 curdatum += sizeofitem; 962 } 963 break; 964 case _C_SHT: 965 while (*(short*)curdatum != 0) { 966 count ++; 967 curdatum += sizeofitem; 968 } 969 break; 970 971 case _C_UINT: 972 while (*(unsigned int*)curdatum != 0) { 973 count ++; 974 curdatum += sizeofitem; 975 } 976 break; 977 case _C_INT: 978 while (*(int*)curdatum != 0) { 979 count ++; 980 curdatum += sizeofitem; 981 } 982 break; 983 984 case _C_ULNG: 985 while (*(unsigned long*)curdatum != 0) { 986 count ++; 987 curdatum += sizeofitem; 988 } 989 break; 990 case _C_LNG: 991 while (*(long*)curdatum != 0) { 992 count ++; 993 curdatum += sizeofitem; 994 } 995 break; 996 997 case _C_ULNG_LNG: 998 while (*(unsigned long long*)curdatum != 0) { 999 count ++; 1000 curdatum += sizeofitem; 1001 } 1002 break; 1003 case _C_LNG_LNG: 1004 while (*(long long*)curdatum != 0) { 1005 count ++; 1006 curdatum += sizeofitem; 1007 } 1008 break; 1009 1010 case _C_UNICHAR: 1011 while (*(UniChar*)curdatum != 0) { 1012 count ++; 1013 curdatum += sizeofitem; 1014 } 1015 break; 1016 1017 case _C_CHAR_AS_INT: 1018 while (*(char*)curdatum != 0) { 1019 count ++; 1020 curdatum += sizeofitem; 1021 } 1022 break; 1023 1024 1025 default: 1026 PyErr_Format(PyExc_TypeError, 1027 "Cannot deal with NULL-terminated array of %s", 1028 type); 1029 return NULL; 1030 } 1031 1032 return PyObjC_CArrayToPython2(type, datum, count, alreadyRetained, alreadyCFRetained); 1033} 1034 1035 1036 1037/*#F Returns a tuple of objects representing the content of a C array 1038of type @var{type} pointed by @var{datum}. */ 1039static PyObject * 1040pythonify_c_array (const char *type, void *datum) 1041{ 1042 PyObjC_Assert(type != NULL, NULL); 1043 PyObjC_Assert(datum != NULL, NULL); 1044 1045 PyObject *ret; 1046 Py_ssize_t nitems, itemidx, sizeofitem; 1047 unsigned char* curdatum; 1048 1049 nitems = atoi (type+1); 1050 while (isdigit (*++type)) 1051 ; 1052 sizeofitem = PyObjCRT_SizeOfType (type); 1053 if (sizeofitem == -1) return NULL; 1054 1055 ret = PyTuple_New (nitems); 1056 if (!ret) return NULL; 1057 1058 curdatum = datum; 1059 for (itemidx=0; itemidx < nitems; itemidx++) { 1060 PyObject *pyitem = NULL; 1061 1062 pyitem = pythonify_c_value (type, curdatum); 1063 1064 if (pyitem) { 1065 PyTuple_SET_ITEM (ret, itemidx, pyitem); 1066 } else { 1067 Py_DECREF(ret); 1068 return NULL; 1069 } 1070 1071 curdatum += sizeofitem; 1072 } 1073 1074 return ret; 1075} 1076 1077/*#F Returns a tuple of objects representing the content of a C structure 1078of type @var{type} pointed by @var{datum}. */ 1079static PyObject * 1080pythonify_c_struct (const char *type, void *datum) 1081{ 1082 PyObjC_Assert(type != NULL, NULL); 1083 PyObjC_Assert(datum != NULL, NULL); 1084 1085 PyObject *ret; 1086 Py_ssize_t offset, itemidx; 1087 const char *item; 1088 int have_align = 0; 1089 Py_ssize_t align; 1090 int haveTuple; 1091 const char* type_start = type; 1092 const char* type_end = PyObjCRT_SkipTypeSpec(type); 1093 const char* type_real_start = type; 1094 Py_ssize_t type_real_length = type_end - type_start; 1095 1096 /* Hacked up support for socket addresses */ 1097 if (strncmp(type, @encode(struct sockaddr), sizeof(@encode(struct sockaddr)-1)) == 0) { 1098 return PyObjC_SockAddrToPython(datum); 1099 } 1100 1101 if (IS_FSREF(type)) { 1102 return PyObjC_decode_fsref(datum); 1103 } 1104 1105 if (IS_FSSPEC(type)) { 1106 return PyObjC_decode_fsspec(datum); 1107 } 1108 1109 /* Skip back over digits at end of type in function prototypes */ 1110 while (type_real_length > 0 && isdigit(type_start[type_real_length-1])) { 1111 type_real_length --; 1112 } 1113 1114 /* The compiler adds useless digits at the end of the signature */ 1115 while (type_end != type_start+1 && type_end[-1] != _C_STRUCT_E) { 1116 type_end--; 1117 } 1118 1119 while (*type != _C_STRUCT_E && *type++ != '=') { 1120 /* skip "<name>=" */ 1121 } 1122 1123 haveTuple = 0; 1124 const char* oc_typestr = NULL; 1125 ret = PyObjC_CreateRegisteredStruct(type_start, 1126 type_end-type_start, &oc_typestr); 1127 if (ret == NULL) { 1128 int nitems; 1129 1130 nitems = 0; 1131 item = type; 1132 while (*item != _C_STRUCT_E) { 1133 nitems ++; 1134 if (*item == '"') { 1135 item = strchr(item+1, '"'); 1136 if (item) item ++; 1137 } 1138 item = PyObjCRT_SkipTypeSpec(item); 1139 } 1140 1141 haveTuple = 1; 1142 ret = PyTuple_New (nitems); 1143 if (!ret) return NULL; 1144 1145 item = type; 1146 } else { 1147 item = type; 1148 1149 if (oc_typestr != NULL) { 1150 item = oc_typestr + 1; 1151 while (*item && *item != '=') { 1152 item++; 1153 } 1154 if (*item) { 1155 item++; 1156 } 1157 } 1158 } 1159 1160 1161 offset = itemidx = 0; 1162 while (*item != _C_STRUCT_E) { 1163 PyObject *pyitem; 1164 1165 if (*item == '"') { 1166 item = strchr(item+1, '"'); 1167 if (item) item ++; 1168 } 1169 1170 if (!have_align) { 1171 align = PyObjCRT_AlignOfType(item); 1172 have_align = 1; 1173 } else { 1174 align = PyObjC_EmbeddedAlignOfType(item); 1175 } 1176 1177 offset = ROUND(offset, align); 1178 1179 pyitem = pythonify_c_value (item, ((char*)datum)+offset); 1180 1181 if (pyitem) { 1182 if (haveTuple) { 1183 PyTuple_SET_ITEM (ret, itemidx, pyitem); 1184 } else { 1185 int r; 1186 r = PySequence_SetItem(ret, itemidx, pyitem); 1187 Py_DECREF(pyitem); 1188 if (r == -1) { 1189 Py_DECREF(ret); 1190 return NULL; 1191 } 1192 } 1193 } else { 1194 Py_DECREF(ret); 1195 return NULL; 1196 } 1197 1198 itemidx++; 1199 offset += PyObjCRT_SizeOfType (item); 1200 item = PyObjCRT_SkipTypeSpec (item); 1201 } 1202 1203 if (haveTuple) { 1204 PyObject *converted; 1205 converted = [OC_PythonObject __pythonifyStruct:ret withType:type_real_start length:type_real_length]; 1206 Py_DECREF(ret); 1207 return converted; 1208 } else { 1209 return ret; 1210 } 1211} 1212 1213int 1214depythonify_c_return_array_count(const char* rettype, Py_ssize_t count, PyObject* arg, void* resp, BOOL already_retained, BOOL already_cfretained) 1215{ 1216 PyObjC_Assert(rettype != NULL, -1); 1217 PyObjC_Assert(arg != NULL, -1); 1218 PyObjC_Assert(resp != NULL, -1); 1219 1220 /* Use an NSMutableData object to store the bytes, that way we can autorelease the data because we 1221 * cannot free it otherwise. 1222 */ 1223 PyObject* seq = PySequence_Fast(arg, "Sequence required"); 1224 if (seq == NULL) { 1225 return -1; 1226 } 1227 if (count == -1) { 1228 count = PySequence_Fast_GET_SIZE(seq); 1229 } 1230 1231 NSMutableData* data = [NSMutableData dataWithLength:count * PyObjCRT_SizeOfType(rettype)]; 1232 *(void**)resp = [data mutableBytes]; 1233 int r = depythonify_c_array_count(rettype, count, YES, seq, [data mutableBytes], already_retained, already_cfretained); 1234 Py_DECREF(seq); 1235 1236 return r; 1237} 1238 1239 1240int 1241depythonify_c_return_array_nullterminated(const char* rettype, PyObject* arg, void* resp, BOOL already_retained, BOOL already_cfretained) 1242{ 1243 PyObjC_Assert(rettype != NULL, -1); 1244 PyObjC_Assert(arg != NULL, -1); 1245 PyObjC_Assert(resp != NULL, -1); 1246 1247 /* Use an NSMutableData object to store the bytes, that way we can autorelease the data because we 1248 * cannot free it otherwise. 1249 */ 1250 PyObject* seq = PySequence_Fast(arg, "Sequence required"); 1251 if (seq == NULL) { 1252 return -1; 1253 } 1254 1255 Py_ssize_t count = PySequence_Fast_GET_SIZE(seq); 1256 1257 /* The data is 0-filled, which means we won't have to add the terminated ourselves */ 1258 NSMutableData* data = [NSMutableData dataWithLength:(count + 1) * PyObjCRT_SizeOfType(rettype)]; 1259 *(void**)resp = [data mutableBytes]; 1260 int result = depythonify_c_array_count(rettype, count, YES, seq, [data mutableBytes], already_retained, already_cfretained); 1261 Py_DECREF(seq); 1262 return result; 1263} 1264 1265 1266int 1267depythonify_c_array_count(const char* type, Py_ssize_t nitems, BOOL strict, PyObject* value, void* datum, BOOL already_retained, BOOL already_cfretained) 1268{ 1269 PyObjC_Assert(type != NULL, -1); 1270 PyObjC_Assert(value != NULL, -1); 1271 PyObjC_Assert(datum != NULL, -1); 1272 1273 Py_ssize_t itemidx, sizeofitem; 1274 unsigned char* curdatum; 1275 PyObject* seq; 1276 1277 sizeofitem = PyObjCRT_AlignedSize (type); 1278 if (sizeofitem == -1) { 1279 PyErr_Format(PyExc_ValueError, 1280 "cannot depythonify array of unknown type"); 1281 return -1; 1282 } 1283 1284 if (sizeofitem == 1 && PyString_Check(value)) { 1285 /* Special casing for strings */ 1286 if (strict) { 1287 if (PyString_Size(value) != nitems) { 1288 PyErr_Format(PyExc_ValueError, 1289 "depythonifying array of %"PY_FORMAT_SIZE_T"d items, got one of %"PY_FORMAT_SIZE_T"d", 1290 nitems, PyString_Size(value)); 1291 return -1; 1292 } 1293 } else { 1294 if (PyString_Size(value) < nitems) { 1295 PyErr_Format(PyExc_ValueError, 1296 "depythonifying array of %"PY_FORMAT_SIZE_T"d items, got one of %"PY_FORMAT_SIZE_T"d", 1297 nitems, PyString_Size(value)); 1298 return -1; 1299 } 1300 } 1301 1302 memcpy(datum, PyString_AS_STRING(value), nitems); 1303 } 1304 1305 seq = PySequence_Fast(value, "depythonifying array, got no sequence"); 1306 if (seq == NULL) { 1307 return -1; 1308 } 1309 1310 if (strict) { 1311 if (PySequence_Fast_GET_SIZE(seq) != nitems) { 1312 PyErr_Format(PyExc_ValueError, 1313 "depythonifying array of %"PY_FORMAT_SIZE_T"d items, got one of %"PY_FORMAT_SIZE_T"d", 1314 nitems, PySequence_Fast_GET_SIZE(seq)); 1315 Py_DECREF(seq); 1316 return -1; 1317 } 1318 } else { 1319 if (PySequence_Fast_GET_SIZE(seq) < 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, PySequence_Fast_GET_SIZE(seq)); 1323 Py_DECREF(seq); 1324 return -1; 1325 } 1326 } 1327 1328 curdatum = datum; 1329 for (itemidx=0; itemidx < nitems; itemidx++) { 1330 PyObject *pyarg = PySequence_Fast_GET_ITEM(seq, itemidx); 1331 int err; 1332 1333 err = depythonify_c_value (type, pyarg, curdatum); 1334 if (err == -1) { 1335 Py_DECREF(seq); 1336 return err; 1337 } 1338 1339 if (already_retained) { 1340 [*(NSObject**)curdatum retain]; 1341 1342 } else if (already_cfretained) { 1343 CFRetain(*(NSObject**)curdatum); 1344 1345 } 1346 1347 curdatum += sizeofitem; 1348 } 1349 1350 if (*type == _C_CHARPTR) { 1351 /* We're depythonifying a list of strings, make sure the originals stay 1352 * around long enough. 1353 */ 1354 [OC_PythonObject newWithObject:seq]; 1355 } 1356 Py_DECREF(seq); 1357 return 0; 1358} 1359 1360Py_ssize_t 1361c_array_nullterminated_size(PyObject* object, PyObject** seq) 1362{ 1363 PyObjC_Assert(object != NULL, -1); 1364 PyObjC_Assert(seq != NULL, -1); 1365 1366 *seq = PySequence_Fast(object, "depythonifying array, got no sequence"); 1367 if (*seq == NULL) { 1368 return -1; 1369 } 1370 1371 return PySequence_Fast_GET_SIZE(*seq) + 1; 1372} 1373 1374int 1375depythonify_c_array_nullterminated(const char* type, Py_ssize_t count, PyObject* value, void* datum, BOOL already_retained, BOOL already_cfretained) 1376{ 1377 PyObjC_Assert(type != NULL, -1); 1378 PyObjC_Assert(value != NULL, -1); 1379 PyObjC_Assert(datum != NULL, -1); 1380 1381 /* XXX: we can do better than this: just clear the last item */ 1382 /* Clear memory: */ 1383 memset(datum, 0, count * PyObjCRT_SizeOfType(type)); 1384 1385 if (count == 1) { 1386 return 0; 1387 } 1388 1389 /* Then copy the actual values */ 1390 return depythonify_c_array_count(type, count-1, YES, value, datum, already_retained, already_cfretained); 1391} 1392 1393/*#F Extracts the elements from the tuple @var{arg} and fills a C array 1394of type @var{type} pointed by @var{datum}. Returns an error message, or 1395NULL on success. */ 1396static int 1397depythonify_c_array (const char *type, PyObject *arg, void *datum) 1398{ 1399 PyObjC_Assert(type != NULL, -1); 1400 PyObjC_Assert(arg != NULL, -1); 1401 PyObjC_Assert(datum != NULL, -1); 1402 1403 Py_ssize_t nitems, itemidx, sizeofitem; 1404 unsigned char* curdatum; 1405 PyObject* seq; 1406 1407 nitems = atoi (type+1); 1408 while (isdigit (*++type)) 1409 ; 1410 sizeofitem = PyObjCRT_AlignedSize (type); 1411 if (sizeofitem == -1) { 1412 PyErr_Format(PyExc_ValueError, 1413 "cannot depythonify array of unknown type"); 1414 return -1; 1415 } 1416 1417 seq = PySequence_Fast(arg, "depythonifying array, got no sequence"); 1418 if (seq == NULL) { 1419 return -1; 1420 } 1421 1422 if (nitems != PySequence_Fast_GET_SIZE(seq)) { 1423 PyErr_Format(PyExc_ValueError, 1424 "depythonifying array of %"PY_FORMAT_SIZE_T"d items, got one of %"PY_FORMAT_SIZE_T"d", 1425 nitems, PySequence_Fast_GET_SIZE(seq)); 1426 Py_DECREF(seq); 1427 return -1; 1428 } 1429 1430 curdatum = datum; 1431 for (itemidx=0; itemidx < nitems; itemidx++) { 1432 PyObject *pyarg = PySequence_Fast_GET_ITEM(seq, itemidx); 1433 int err; 1434 1435 err = depythonify_c_value (type, pyarg, curdatum); 1436 if (err == -1) { 1437 Py_DECREF(seq); 1438 return err; 1439 } 1440 1441 curdatum += sizeofitem; 1442 } 1443 1444 Py_DECREF(seq); 1445 return 0; 1446} 1447 1448/*#F Extracts the elements from the tuple @var{arg} and fills a C structure 1449of type @var{type} pointed by @var{datum}. Returns an error message, or 1450NULL on success. */ 1451static int 1452depythonify_c_struct(const char *types, PyObject *arg, void *datum) 1453{ 1454 PyObjC_Assert(types != NULL, -1); 1455 PyObjC_Assert(arg != NULL, -1); 1456 PyObjC_Assert(datum != NULL, -1); 1457 1458 Py_ssize_t nitems, offset, itemidx; 1459 int have_align = 0; 1460 Py_ssize_t align; 1461 const char *type; 1462 PyObject* seq; 1463 1464 /* Hacked in support for sockaddr structs */ 1465 if (strncmp(types, @encode(struct sockaddr), sizeof(@encode(struct sockaddr)-1)) == 0) { 1466 return PyObjC_SockAddrFromPython(arg, datum); 1467 } 1468 1469 if (IS_FSREF(types)) { 1470 if (PyObjC_encode_fsref(arg, datum) == 0) { 1471 return 0; 1472 } 1473 PyErr_Clear(); 1474 } 1475 if (IS_FSSPEC(types)) { 1476 if (PyObjC_encode_fsspec(arg, datum) == 0) { 1477 return 0; 1478 } 1479 PyErr_Clear(); 1480 } 1481 1482 while (*types != _C_STRUCT_E && *types++ != '='); /* skip "<name>=" */ 1483 1484 type=types; 1485 nitems=0; 1486 while (*type != _C_STRUCT_E) { 1487 if (*type == '"') { 1488 type = strchr(type+1, '"'); 1489 type++; 1490 } 1491 nitems++; 1492 type = PyObjCRT_SkipTypeSpec (type); 1493 } 1494 1495 seq = PySequence_Fast(arg, "depythonifying struct, got no sequence"); 1496 if (seq == NULL) { 1497 return -1; 1498 } 1499 1500 if (nitems != PySequence_Fast_GET_SIZE(seq)) { 1501 Py_DECREF(seq); 1502 PyErr_Format(PyExc_ValueError, 1503 "depythonifying struct of %"PY_FORMAT_SIZE_T"d members, got tuple of %"PY_FORMAT_SIZE_T"d", 1504 nitems, PyTuple_Size (arg)); 1505 return -1; 1506 } 1507 1508 type=types; 1509 offset = itemidx = 0; 1510 1511 while (*type != _C_STRUCT_E) { 1512 PyObject *argument; 1513 1514 if (*type == '"') { 1515 type = strchr(type+1, '"'); 1516 type++; 1517 } 1518 1519 1520 argument = PySequence_Fast_GET_ITEM(seq, itemidx); 1521 int error; 1522 if (!have_align) { 1523 align = PyObjCRT_AlignOfType(type); 1524 have_align = 1; 1525 } else { 1526 align = PyObjC_EmbeddedAlignOfType(type); 1527 } 1528 1529 offset = ROUND(offset, align); 1530 1531 error = depythonify_c_value(type, argument, 1532 ((char*)datum)+offset); 1533 if (error == -1) { 1534 Py_DECREF(seq); 1535 return error; 1536 } 1537 1538 itemidx++; 1539 offset += PyObjCRT_SizeOfType (type); 1540 type = PyObjCRT_SkipTypeSpec (type); 1541 } 1542 Py_DECREF(seq); 1543 return 0; 1544} 1545 1546PyObject * 1547pythonify_c_value (const char *type, void *datum) 1548{ 1549 PyObjC_Assert(type != NULL, NULL); 1550 PyObjC_Assert(datum != NULL, NULL); 1551 1552 PyObject *retobject = NULL; 1553 1554 type = PyObjCRT_SkipTypeQualifiers (type); 1555 1556 switch (*type) { 1557 case _C_UNICHAR: 1558 { 1559 Py_UNICODE c = (Py_UNICODE)(*(UniChar*)datum); 1560 retobject = PyUnicode_FromUnicode(&c, 1); 1561 } 1562 break; 1563 1564 case _C_CHAR_AS_TEXT: 1565 retobject = PyString_FromStringAndSize((char*)datum, 1); 1566 break; 1567 1568 case _C_CHR: 1569 case _C_CHAR_AS_INT: 1570 /* 1571 * We don't return a string because BOOL is an alias for 1572 * char (at least on MacOS X) 1573 */ 1574 retobject = (PyObject*)PyInt_FromLong ((int)(*(char*)datum)); 1575 break; 1576 1577 case _C_UCHR: 1578 retobject = (PyObject*)PyInt_FromLong ( 1579 (long)(*(unsigned char*)datum)); 1580 break; 1581 1582 case _C_CHARPTR: 1583#ifdef _C_ATOM 1584 case _C_ATOM: 1585#endif 1586 { 1587 char *cp = *(char **) datum; 1588 1589 if (cp == NULL) { 1590 Py_INCREF(Py_None); 1591 retobject = Py_None; 1592 } else { 1593 retobject = (PyObject*)PyString_FromString(cp); 1594 } 1595 break; 1596 } 1597 1598#ifdef _C_BOOL 1599 case _C_BOOL: 1600 retobject = (PyObject *) PyBool_FromLong (*(bool*) datum); 1601 break; 1602#endif 1603 1604 case _C_NSBOOL: 1605 retobject = (PyObject *) PyBool_FromLong (*(BOOL*) datum); 1606 break; 1607 1608 case _C_INT: 1609 retobject = (PyObject *) PyInt_FromLong (*(int*) datum); 1610 break; 1611 1612 case _C_UINT: 1613#if __LP64__ 1614 retobject = (PyObject*)PyInt_FromLong ( 1615 *(unsigned int *) datum); 1616 1617#else 1618 if (*(unsigned int*)datum > LONG_MAX) { 1619 retobject = (PyObject*)PyLong_FromUnsignedLongLong( 1620 *(unsigned int*)datum); 1621 } else { 1622 retobject = (PyObject*)PyInt_FromLong ( 1623 *(unsigned int *) datum); 1624 } 1625#endif 1626 break; 1627 1628 case _C_SHT: 1629 retobject = (PyObject *) PyInt_FromLong (*(short *) datum); 1630 break; 1631 1632 case _C_USHT: 1633 retobject = (PyObject *) PyInt_FromLong ( 1634 *(unsigned short *) datum); 1635 break; 1636 1637 case _C_LNG_LNG: 1638#ifndef __LP64__ /* else: fall-through to _C_LNG case */ 1639 retobject = (PyObject*)PyLong_FromLongLong(*(long long*)datum); 1640 break; 1641#endif 1642 1643 case _C_LNG: 1644 retobject = (PyObject *) PyInt_FromLong(*(long *) datum); 1645 break; 1646 1647 case _C_ULNG_LNG: 1648#ifndef __LP64__ /* else: fallthrough to the ULNG case */ 1649 retobject = (PyObject*)PyLong_FromUnsignedLongLong( 1650 *(unsigned long long*)datum); 1651 break; 1652#endif 1653 1654 case _C_ULNG: 1655 if (*(unsigned long*)datum > LONG_MAX) { 1656 retobject = (PyObject*)PyLong_FromUnsignedLongLong( 1657 *(unsigned long*)datum); 1658 } else { 1659 retobject = (PyObject*)PyInt_FromLong ( 1660 *(unsigned long*) datum); 1661 } 1662 break; 1663 1664 1665 1666 case _C_FLT: 1667 retobject = (PyObject *) PyFloat_FromDouble (*(float*) datum); 1668 break; 1669 1670 case _C_DBL: 1671 retobject = (PyObject *) PyFloat_FromDouble (*(double*) datum); 1672 break; 1673 1674 case _C_ID: 1675 { 1676 id obj = *(id *) datum; 1677 1678#if 1 1679 /* In theory this is a no-op, in practice this gives us EOF 4.5 1680 * support. 1681 * 1682 * EOF can return references to 'to-be-restored' objects, 1683 * calling any method on them fully restores them, 'self' is 1684 * the safest method to call. 1685 */ 1686 obj = [obj self]; 1687#endif 1688 1689 if (obj == nil) { 1690 retobject = Py_None; 1691 Py_INCREF (retobject); 1692 } else { 1693 retobject = [obj __pyobjc_PythonObject__]; 1694 } 1695 break; 1696 } 1697 1698 case _C_SEL: 1699 if (*(SEL*)datum == NULL) { 1700 retobject = Py_None; 1701 Py_INCREF(retobject); 1702 } else { 1703 retobject = PyString_FromString(sel_getName(*(SEL*)datum)); 1704 } 1705 break; 1706 1707 case _C_CLASS: 1708 { 1709 Class c = *(Class *) datum; 1710 1711 if (c == Nil) { 1712 retobject = Py_None; 1713 Py_INCREF (retobject); 1714 } else { 1715 retobject = (PyObject *) PyObjCClass_New(c); 1716 } 1717 break; 1718 } 1719 1720 case _C_PTR: 1721 if (type[1] == _C_VOID) { 1722 /* A void*. These are treated like unsigned integers. */ 1723 retobject = (PyObject*)PyLong_FromUnsignedLongLong( 1724 *(unsigned long*)datum); 1725 1726 } else if (*(void**)datum == NULL) { 1727 retobject = Py_None; 1728 Py_INCREF(retobject); 1729 1730 } else { 1731 retobject = PyObjCPointerWrapper_ToPython(type, datum); 1732 if (retobject == NULL && !PyErr_Occurred()) { 1733 retobject = (PyObject*)PyObjCPointer_New( 1734 *(void**) datum, type+1); 1735 } 1736 } 1737 break; 1738 1739 case _C_UNION_B: 1740 { 1741 Py_ssize_t size = PyObjCRT_SizeOfType (type); 1742 if (size == -1) return NULL; 1743 retobject = PyString_FromStringAndSize ((void*)datum, size); 1744 break; 1745 } 1746 1747 case _C_STRUCT_B: 1748 retobject = pythonify_c_struct (type, datum); 1749 break; 1750 1751 case _C_ARY_B: 1752 retobject = pythonify_c_array (type, datum); 1753 break; 1754 1755 case _C_VOID: 1756 retobject = Py_None; 1757 Py_INCREF (retobject); 1758 break; 1759 1760 default: 1761 PyErr_Format(PyObjCExc_Error, 1762 "pythonify_c_value: unhandled value type (%c|%d|%s)", 1763 *type, *type, type); 1764 break; 1765 } 1766 1767 return retobject; 1768} 1769 1770 1771Py_ssize_t 1772PyObjCRT_SizeOfReturnType(const char* type) 1773{ 1774 PyObjC_Assert(type != NULL, -1); 1775 1776#if 1 /* def __ppc__ */ 1777 switch(*type) { 1778 case _C_CHR: 1779 case _C_BOOL: 1780 case _C_UCHR: 1781 case _C_SHT: 1782 case _C_USHT: 1783 case _C_UNICHAR: 1784 case _C_CHAR_AS_TEXT: 1785 case _C_CHAR_AS_INT: 1786 case _C_NSBOOL: 1787 return sizeof(long); 1788 default: 1789 return PyObjCRT_SizeOfType(type); 1790 } 1791#else 1792 return PyObjCRT_SizeOfType(type); 1793#endif 1794} 1795 1796/* 1797* Convert a python value to a basic C unsigned integer value. 1798*/ 1799static int 1800depythonify_unsigned_int_value( 1801 PyObject* argument, char* descr, 1802 unsigned long long* out, unsigned long long max) 1803{ 1804 PyObjC_Assert(argument != NULL, -1); 1805 PyObjC_Assert(descr != NULL, -1); 1806 PyObjC_Assert(out != NULL, -1); 1807 1808 if (PyInt_Check (argument)) { 1809 long temp = PyInt_AsLong(argument); 1810 if (PyErr_Occurred()) { 1811 return -1; 1812 } 1813#if 0 1814 /* Strict checking is nice, but a lot of constants are used 1815 * as unsigned, but are actually negative numbers in the 1816 * metadata files. 1817 */ 1818 if (temp < 0) { 1819 PyErr_Format(PyExc_ValueError, 1820 "depythonifying '%s', got negative '%s'", 1821 descr, 1822 argument->ob_type->tp_name); 1823 return -1; 1824 1825 } else 1826#endif 1827 if ((unsigned long long)temp > max) { 1828 PyErr_Format(PyExc_ValueError, 1829 "depythonifying '%s', got '%s' of " 1830 "wrong magnitude", descr, 1831 argument->ob_type->tp_name); 1832 return -1; 1833 } 1834 *out = temp; 1835 return 0; 1836 1837 } else if (PyLong_Check(argument)) { 1838 *out = PyLong_AsUnsignedLongLong(argument); 1839 if (PyErr_Occurred()) { 1840 PyErr_Format(PyExc_ValueError, 1841 "depythonifying '%s', got '%s' of " 1842 "wrong magnitude", descr, 1843 argument->ob_type->tp_name); 1844 return -1; 1845 } 1846 1847 if (*out > max) { 1848 PyErr_Format(PyExc_ValueError, 1849 "depythonifying '%s', got '%s' of " 1850 "wrong magnitude", descr, 1851 argument->ob_type->tp_name); 1852 return -1; 1853 } 1854 return 0; 1855 1856 } else { 1857 PyObject* tmp; 1858 1859 if (PyString_Check(argument) || PyUnicode_Check(argument)) { 1860 PyErr_Format(PyExc_ValueError, 1861 "depythonifying '%s', got '%s'", 1862 descr, 1863 argument->ob_type->tp_name); 1864 return -1; 1865 } 1866 1867 tmp = PyNumber_Long(argument); 1868 if (tmp != NULL) { 1869 *out = PyLong_AsUnsignedLongLong(tmp); 1870 if (PyErr_Occurred()) { 1871 return -1; 1872 } 1873 Py_DECREF(tmp); 1874 1875 if (*out <= max) { 1876 return 0; 1877 } 1878 } 1879 1880 PyErr_Format(PyExc_ValueError, 1881 "depythonifying '%s', got '%s'", 1882 descr, 1883 argument->ob_type->tp_name); 1884 return -1; 1885 } 1886} 1887 1888/* 1889* Convert a python value to a basic C signed integer value. 1890*/ 1891static int 1892depythonify_signed_int_value( 1893 PyObject* argument, char* descr, 1894 long long* out, long long min, long long max) 1895{ 1896 PyObjC_Assert(argument != NULL, -1); 1897 PyObjC_Assert(descr != NULL, -1); 1898 PyObjC_Assert(out != NULL, -1); 1899 1900 if (PyInt_Check (argument)) { 1901 *out = (long long)PyInt_AsLong(argument); 1902 if (PyErr_Occurred()) { 1903 return -1; 1904 } 1905 if (*out < min || *out > max) { 1906 PyErr_Format(PyExc_ValueError, 1907 "depythonifying '%s', got '%s' of " 1908 "wrong magnitude", descr, 1909 argument->ob_type->tp_name); 1910 return -1; 1911 } 1912 return 0; 1913 1914 } else if (PyLong_Check(argument)) { 1915 *out = PyLong_AsLongLong(argument); 1916 if (PyErr_Occurred()) { 1917 PyErr_Format(PyExc_ValueError, 1918 "depythonifying '%s', got '%s' of " 1919 "wrong magnitude", descr, 1920 argument->ob_type->tp_name); 1921 return -1; 1922 } 1923 1924 if (*out < min || *out > max) { 1925 PyErr_Format(PyExc_ValueError, 1926 "depythonifying '%s', got '%s' of " 1927 "wrong magnitude", descr, 1928 argument->ob_type->tp_name); 1929 return -1; 1930 } 1931 return 0; 1932 1933 } else { 1934 PyObject* tmp; 1935 1936 if (PyString_Check(argument) || PyUnicode_Check(argument)) { 1937 PyErr_Format(PyExc_ValueError, 1938 "depythonifying '%s', got '%s' of %"PY_FORMAT_SIZE_T"d", 1939 descr, 1940 argument->ob_type->tp_name, 1941 PyString_Size(argument)); 1942 return -1; 1943 } 1944 1945 1946 tmp = PyNumber_Long(argument); 1947 if (tmp != NULL) { 1948 *out = PyLong_AsLongLong(tmp); 1949 Py_DECREF(tmp); 1950 1951 if (PyErr_Occurred()) { 1952 return -1; 1953 } 1954 1955 if (*out >= min && *out <= max) { 1956 return 0; 1957 } 1958 } 1959 1960 PyErr_Format(PyExc_ValueError, 1961 "depythonifying '%s', got '%s'", 1962 descr, 1963 argument->ob_type->tp_name); 1964 return -1; 1965 } 1966} 1967 1968int depythonify_c_return_value( 1969const char* type, PyObject* argument, void* datum) 1970{ 1971 PyObjC_Assert(type != NULL, -1); 1972 PyObjC_Assert(argument != NULL, -1); 1973 PyObjC_Assert(datum != NULL, -1); 1974 1975#ifdef __ppc__ 1976 long long temp; 1977 unsigned long long utemp; 1978 int r; 1979 1980 /* Small integers are promoted to integers when returning them */ 1981 switch (*type) { 1982#ifdef _C_BOOL 1983 case _C_BOOL: 1984 case _C_NSBOOL: 1985 if (PyObject_IsTrue(argument)) { 1986 *(int*) datum = YES; 1987 } else { 1988 *(int*) datum = NO; 1989 } 1990 return 0; 1991 1992#endif 1993 case _C_CHAR_AS_INT: 1994 r = depythonify_signed_int_value(argument, "char", 1995 &temp, CHAR_MIN, CHAR_MAX); 1996 if (r == 0) { 1997 *(int*)datum = temp; 1998 } 1999 return r; 2000 2001 case _C_CHAR_AS_TEXT: 2002 if (PyString_Check(argument) && PyString_Size(argument) == 1) { 2003 *(int*) datum = PyString_AsString (argument)[0]; 2004 return 0; 2005 } else { 2006 PyErr_Format(PyExc_ValueError, 2007 "Expecting string of length 1"); 2008 return -1; 2009 } 2010 break; 2011 2012 case _C_CHR: 2013 if (PyString_Check(argument) && PyString_Size(argument) == 1) { 2014 *(int*) datum = PyString_AsString (argument)[0]; 2015 return 0; 2016 } 2017 2018 r = depythonify_signed_int_value(argument, "char", 2019 &temp, CHAR_MIN, CHAR_MAX); 2020 if (r == 0) { 2021 *(int*)datum = temp; 2022 } 2023 return r; 2024 2025 case _C_UNICHAR: 2026 if (PyUnicode_Check(argument) && PyUnicode_GetSize(argument) == 1) { 2027 *(int*)datum = (int)(*PyUnicode_AsUnicode(argument)); 2028 return 0; 2029 2030 } else if (PyString_Check(argument)) { 2031 PyObject* u = PyUnicode_FromObject(argument); 2032 if (u == NULL) { 2033 return -1; 2034 } 2035 if (PyUnicode_Check(u) && PyUnicode_GetSize(u) == 1) { 2036 *(int*)datum = (int)(*PyUnicode_AsUnicode(u)); 2037 Py_DECREF(u); 2038 return 0; 2039 } 2040 Py_DECREF(u); 2041 } 2042 PyErr_SetString(PyExc_ValueError, "Expecting unicode string of length 1"); 2043 return -1; 2044 2045 case _C_UCHR: 2046 if (PyString_Check(argument) && PyString_Size(argument) == 1) { 2047 *(unsigned int*) datum = 2048 PyString_AsString (argument)[0]; 2049 return 0; 2050 } 2051 r = depythonify_unsigned_int_value(argument, "unsigned char", 2052 &utemp, UCHAR_MAX); 2053 if (r == 0) { 2054 *(unsigned int*)datum = utemp; 2055 } 2056 return r; 2057 2058 case _C_SHT: 2059 r = depythonify_signed_int_value(argument, "short", 2060 &temp, SHRT_MIN, SHRT_MAX); 2061 if (r == 0) { 2062 *(int*)datum = temp; 2063 } 2064 return r; 2065 2066 case _C_USHT: 2067 r = depythonify_unsigned_int_value(argument, "unsigned short", 2068 &utemp, USHRT_MAX); 2069 if (r == 0) { 2070 *(unsigned int*)datum = utemp; 2071 } 2072 return r; 2073 2074 default: 2075 return depythonify_c_value(type, argument, datum); 2076 } 2077 2078#else 2079 return depythonify_c_value(type, argument, datum); 2080#endif 2081} 2082 2083PyObject * 2084pythonify_c_return_value (const char *type, void *datum) 2085{ 2086 PyObjC_Assert(type != NULL, NULL); 2087 PyObjC_Assert(datum != NULL, NULL); 2088 2089#ifdef __ppc__ 2090 /* 2091 * On PowerPC short and char return values are returned 2092 * as full-size ints. 2093 */ 2094 static const char intType[] = { _C_INT, 0 }; 2095 static const char uintType[] = { _C_UINT, 0 }; 2096 2097 switch(*type) { 2098 case _C_BOOL: 2099 case _C_NSBOOL: 2100 return PyBool_FromLong(*(int*)datum); 2101 2102 case _C_CHR: 2103 case _C_CHAR_AS_INT: 2104 case _C_SHT: 2105 return pythonify_c_value(intType, datum); 2106 case _C_UCHR: case _C_USHT: 2107 return pythonify_c_value(uintType, datum); 2108 2109 case _C_CHAR_AS_TEXT: 2110 { 2111 char ch = *(int*)datum; 2112 return PyString_FromStringAndSize(&ch, 1); 2113 } 2114 2115 case _C_UNICHAR: 2116 { 2117 Py_UNICODE ch = *(int*)datum; 2118 return PyUnicode_FromUnicode(&ch, 1); 2119 } 2120 2121 default: 2122 return pythonify_c_value(type, datum); 2123 } 2124 2125#else 2126 return pythonify_c_value(type, datum); 2127 2128#endif 2129} 2130 2131 2132int 2133depythonify_c_value (const char *type, PyObject *argument, void *datum) 2134{ 2135 PyObjC_Assert(type != NULL, -1); 2136 PyObjC_Assert(argument != NULL, -1); 2137 PyObjC_Assert(datum != NULL, -1); 2138 2139 if (argument == NULL) abort(); 2140 2141 /* Pass by reference output arguments are sometimes passed a NULL 2142 * pointer, this surpresses a core dump. 2143 */ 2144 long long temp; 2145 unsigned long long utemp; 2146 int r; 2147 2148 if (!datum) return 0; 2149 2150 type = PyObjCRT_SkipTypeQualifiers (type); 2151 2152 switch (*type) { 2153#ifdef _C_ATOM 2154 case _C_ATOM: 2155#endif 2156 case _C_CHARPTR: 2157 if (!PyString_Check (argument) && argument != Py_None) { 2158 PyErr_Format(PyExc_ValueError, 2159 "depythonifying 'charptr', got '%s'", 2160 argument->ob_type->tp_name); 2161 return -1; 2162 } else if (argument == Py_None) { 2163 *(char **) datum = NULL; 2164 } else { 2165 *(char **) datum = PyString_AS_STRING( 2166 (PyStringObject*)argument); 2167 } 2168 break; 2169 2170 case _C_CHR: 2171 if (PyString_Check(argument) && PyString_Size(argument) == 1) { 2172 *(char*) datum = PyString_AsString (argument)[0]; 2173 return 0; 2174 } 2175 2176 r = depythonify_signed_int_value(argument, "char", 2177 &temp, CHAR_MIN, CHAR_MAX); 2178 if (r == 0) { 2179 *(char*)datum = temp; 2180 } 2181 return r; 2182 2183 case _C_CHAR_AS_INT: 2184 r = depythonify_signed_int_value(argument, "char", 2185 &temp, CHAR_MIN, CHAR_MAX); 2186 if (r == 0) { 2187 *(char*)datum = temp; 2188 } 2189 return r; 2190 2191 case _C_CHAR_AS_TEXT: 2192 if (PyString_Check(argument) && PyString_Size(argument) == 1) { 2193 *(char*) datum = PyString_AsString (argument)[0]; 2194 return 0; 2195 } else { 2196 PyErr_SetString(PyExc_ValueError, 2197 "Expecting string of length 1"); 2198 return -1; 2199 } 2200 2201 case _C_UCHR: 2202 if (PyString_Check(argument) && PyString_Size(argument) == 1) { 2203 *(unsigned char*) datum = 2204 PyString_AsString (argument)[0]; 2205 return 0; 2206 } 2207 r = depythonify_unsigned_int_value(argument, "unsigned char", 2208 &utemp, UCHAR_MAX); 2209 if (r == 0) { 2210 *(unsigned char*)datum = utemp; 2211 } 2212 return r; 2213 2214 case _C_SHT: 2215 r = depythonify_signed_int_value(argument, "short", 2216 &temp, SHRT_MIN, SHRT_MAX); 2217 if (r == 0) { 2218 *(short*)datum = temp; 2219 } 2220 return r; 2221 2222 case _C_USHT: 2223 r = depythonify_unsigned_int_value(argument, "unsigned short", 2224 &utemp, USHRT_MAX); 2225 if (r == 0) { 2226 *(unsigned short*)datum = utemp; 2227 } 2228 return r; 2229 2230#ifdef _C_BOOL 2231 case _C_BOOL: 2232 *(bool*)datum = PyObject_IsTrue(argument); 2233 return 0; 2234#endif 2235 2236 case _C_NSBOOL: 2237 *(BOOL*)datum = PyObject_IsTrue(argument); 2238 return 0; 2239 2240 case _C_UNICHAR: 2241 if (PyUnicode_Check(argument) && PyUnicode_GetSize(argument) == 1) { 2242 *(UniChar*)datum = (UniChar)(*PyUnicode_AsUnicode(argument)); 2243 return 0; 2244 2245 } else if (PyString_Check(argument)) { 2246 PyObject* u = PyUnicode_FromObject(argument); 2247 if (u == NULL) { 2248 return -1; 2249 } 2250 if (PyUnicode_Check(u) && PyUnicode_GetSize(u) == 1) { 2251 *(UniChar*)datum = (UniChar)(*PyUnicode_AsUnicode(u)); 2252 Py_DECREF(u); 2253 return 0; 2254 } 2255 Py_DECREF(u); 2256 } 2257 PyErr_SetString(PyExc_ValueError, "Expecting unicode string of length 1"); 2258 return -1; 2259 2260 case _C_INT: 2261 r = depythonify_signed_int_value(argument, "int", 2262 &temp, INT_MIN, INT_MAX); 2263 if (r == 0) { 2264 *(int*)datum = temp; 2265 } 2266 return r; 2267 2268 case _C_UINT: 2269 r = depythonify_unsigned_int_value(argument, "unsigned int", 2270 &utemp, UINT_MAX); 2271 if (r == 0) { 2272 *(unsigned int*)datum = utemp; 2273 } 2274 return r; 2275 2276 case _C_LNG: 2277 r = depythonify_signed_int_value(argument, "long", 2278 &temp, LONG_MIN, LONG_MAX); 2279 if (r == 0) { 2280 *(long*)datum = temp; 2281 } 2282 return r; 2283 2284 case _C_ULNG: 2285 r = depythonify_unsigned_int_value(argument, "unsigned long", 2286 &utemp, ULONG_MAX); 2287 if (r == 0) { 2288 *(unsigned long*)datum = utemp; 2289 } 2290 return r; 2291 2292 case _C_LNG_LNG: 2293 r = depythonify_signed_int_value(argument, "long long", 2294 &temp, LLONG_MIN, LLONG_MAX); 2295 if (r == 0) { 2296 *(long long*)datum = temp; 2297 } 2298 return r; 2299 2300 case _C_ULNG_LNG: 2301 r = depythonify_unsigned_int_value(argument, 2302 "unsigned long long", &utemp, ULLONG_MAX); 2303 if (r == 0) { 2304 *(unsigned long long*)datum = utemp; 2305 } 2306 return r; 2307 2308 case _C_ID: 2309 /* 2310 XXX 2311 2312 This should, for values other than Py_None, always return the same id 2313 for the same PyObject for as long as that id lives. I think that the 2314 implementation of this should be moved to OC_PythonObject, 2315 which would itself have a map of PyObject->id. The dealloc 2316 of each of these custom objects should notify OC_PythonObject 2317 to remove map entry. We need to significantly change how immutable types 2318 are bridged, and create OC_PythonString, OC_PythonBool, etc. which are 2319 subclasses of what they should be from the the Objective C side. 2320 2321 If we don't do this, we break binary plist serialization, and likely 2322 other things, which assume that foo[bar] is foo[bar] for the duration of 2323 the serialization process. I would imagine that other things also 2324 assume this kind of invariant, so we should do it here rather than in every 2325 container object. 2326 */ 2327 2328 2329 return [OC_PythonObject wrapPyObject:argument toId:(id *)datum]; 2330 2331 case _C_CLASS: 2332 if (PyObjCClass_Check(argument)) { 2333 *(Class*) datum = PyObjCClass_GetClass(argument); 2334 2335 } else if (argument == Py_None) { 2336 *(Class*) datum = nil; 2337 2338 } else if (PyType_Check(argument) && PyType_IsSubtype((PyTypeObject*)argument, &PyObjCClass_Type)) { 2339 *(Class*) datum = PyObjCClass_GetClass(PyObjCClass_ClassForMetaClass(argument)); 2340 2341 } else { 2342 PyErr_Format(PyExc_ValueError, 2343 "depythonifying 'Class', got '%s'", 2344 argument->ob_type->tp_name); 2345 return -1; 2346 } 2347 break; 2348 2349 case _C_SEL: 2350 if (argument == Py_None) { 2351 *(SEL*)datum = NULL; 2352 } else if (PyObjCSelector_Check (argument)) { 2353 *(SEL *) datum = PyObjCSelector_GetSelector(argument); 2354 } else if (PyString_Check(argument)) { 2355 char *selname = PyString_AsString (argument); 2356 SEL sel; 2357 2358 if (*selname == '\0') { 2359 *(SEL*)datum = NULL; 2360 } else { 2361 sel = sel_getUid (selname); 2362 2363 if (sel) { 2364 *(SEL*) datum = sel; 2365 } else { 2366 PyErr_Format(PyExc_ValueError, 2367 "depythonifying 'SEL', cannot " 2368 "register string with runtime"); 2369 return -1; 2370 } 2371 } 2372 } else { 2373 PyErr_Format(PyExc_ValueError, 2374 "depythonifying 'SEL', got '%s'", 2375 argument->ob_type->tp_name); 2376 return -1; 2377 } 2378 break; 2379 2380 2381 case _C_PTR: 2382 if (argument == Py_None) { 2383 *(void**)datum = NULL; 2384 return 0; 2385 } 2386 if (type[1] == _C_VOID) { 2387 r = depythonify_unsigned_int_value(argument, 2388 "unsigned long", 2389 &utemp, ULONG_MAX); 2390 if (r == 0) { 2391 *(void**)datum = (void*)(unsigned long)utemp; 2392 } 2393 return r; 2394 2395 } 2396 r = PyObjCPointerWrapper_FromPython(type, argument, datum); 2397 if (r == -1) { 2398 if (PyErr_Occurred()) { 2399 return -1; 2400 } else if (PyObjCPointer_Check (argument)) { 2401 *(void **) datum = PyObjCPointer_Ptr(argument); 2402 } else { 2403 PyErr_Format(PyExc_ValueError, 2404 "depythonifying 'pointer', got '%s'", 2405 argument->ob_type->tp_name); 2406 return -1; 2407 } 2408 } 2409 break; 2410 2411 case _C_FLT: 2412 if (PyFloat_Check (argument)) { 2413 *(float *) datum = (float)PyFloat_AsDouble (argument); 2414 } else if (PyInt_Check (argument)) { 2415 *(float *) datum = (float) PyInt_AsLong (argument); 2416 } else if (PyString_Check(argument) || PyUnicode_Check(argument)) { 2417 PyErr_Format(PyExc_ValueError, 2418 "depythonifying 'float', got '%s'", 2419 argument->ob_type->tp_name); 2420 return -1; 2421 } else { 2422 PyObject* tmp = PyNumber_Float(argument); 2423 if (tmp != NULL) { 2424 double dblval = PyFloat_AsDouble(tmp); 2425 Py_DECREF(tmp); 2426 *(float*) datum = dblval; 2427 return 0; 2428 } 2429 2430 PyErr_Format(PyExc_ValueError, 2431 "depythonifying 'float', got '%s'", 2432 argument->ob_type->tp_name); 2433 return -1; 2434 } 2435 break; 2436 2437 case _C_DBL: 2438 if (PyFloat_Check (argument)) { 2439 *(double *) datum = PyFloat_AsDouble (argument); 2440 } else if (PyInt_Check (argument)) { 2441 *(double *) datum = (double) PyInt_AsLong (argument); 2442 } else if (PyString_Check(argument) || PyUnicode_Check(argument)) { 2443 PyErr_Format(PyExc_ValueError, 2444 "depythonifying 'float', got '%s'", 2445 argument->ob_type->tp_name); 2446 return -1; 2447 } else { 2448 PyObject* tmp = PyNumber_Float(argument); 2449 if (tmp != NULL) { 2450 double dblval = PyFloat_AsDouble(tmp); 2451 Py_DECREF(tmp); 2452 *(double*) datum = dblval; 2453 return 0; 2454 } 2455 2456 PyErr_Format(PyExc_ValueError, 2457 "depythonifying 'double', got '%s'", 2458 argument->ob_type->tp_name); 2459 return -1; 2460 } 2461 break; 2462 2463 case _C_UNION_B: 2464 if (PyString_Check (argument)) { 2465 Py_ssize_t expected_size = PyObjCRT_SizeOfType (type); 2466 2467 if (expected_size == -1) { 2468 PyErr_Format(PyExc_ValueError, 2469 "depythonifying 'union' of " 2470 "unknown size"); 2471 return -1; 2472 } else if (expected_size != PyString_Size (argument)) { 2473 PyErr_Format(PyExc_ValueError, 2474 "depythonifying 'union' of size %"PY_FORMAT_SIZE_T"d, " 2475 "got string of %"PY_FORMAT_SIZE_T"d", 2476 expected_size, 2477 PyString_Size (argument)); 2478 return -1; 2479 } else { 2480 memcpy ((void *) datum, 2481 PyString_AS_STRING (argument), 2482 expected_size); 2483 } 2484 } else { 2485 PyErr_Format(PyExc_ValueError, 2486 "depythonifying 'union', got '%s'", 2487 argument->ob_type->tp_name); 2488 return -1; 2489 } 2490 break; 2491 2492 case _C_STRUCT_B: 2493 return depythonify_c_struct (type, argument, datum); 2494 2495 case _C_ARY_B: 2496 return depythonify_c_array (type, argument, datum); 2497 2498 default: 2499 PyErr_Format(PyExc_ValueError, 2500 "depythonifying unknown typespec %#x", *type); 2501 return -1; 2502 } 2503 return 0; 2504} 2505 2506const char* 2507PyObjCRT_RemoveFieldNames(char* buf, const char* type) 2508{ 2509 PyObjC_Assert(buf != NULL, NULL); 2510 PyObjC_Assert(type != NULL, NULL); 2511 2512 const char* end; 2513 if (*type == '"') { 2514 type++; 2515 while (*type++ != '"') {} 2516 } 2517 end = PyObjCRT_SkipTypeQualifiers(type); 2518 if (end == NULL) { 2519 return NULL; 2520 } 2521 switch (*end) { 2522 case _C_STRUCT_B: 2523 /* copy struct header */ 2524 while (*end && *end != '=' && *end != _C_STRUCT_E) { 2525 end++; 2526 } 2527 if (*end == '\0') { 2528 PyErr_SetString(PyExc_ValueError, "Bad type string"); 2529 return NULL; 2530 } 2531 if (*end == _C_STRUCT_E) { 2532 end ++; 2533 memcpy(buf, type, end-type); 2534 buf[end-type] = '\0'; 2535 return end; 2536 } 2537 end++; 2538 memcpy(buf, type, end-type); 2539 buf += end - type; 2540 type = end; 2541 2542 /* RemoveFieldNames until reaching end of struct */ 2543 while (*type != _C_STRUCT_E) { 2544 end = PyObjCRT_RemoveFieldNames(buf, type); 2545 if (end == NULL) return NULL; 2546 buf += strlen(buf); 2547 type = end; 2548 } 2549 buf[0] = _C_STRUCT_E; 2550 buf[1] = '\0'; 2551 return type+1; 2552 2553 case _C_ARY_B: 2554 /* copy array header */ 2555 end ++; 2556 while(isdigit(*end)) { end++; } 2557 2558 memcpy(buf, type, end-type); 2559 buf += end - type; 2560 type = end; 2561 if (*type == _C_ARY_E) { 2562 buf[0] = _C_ARY_E; 2563 buf[1] = '\0'; 2564 return type; 2565 } 2566 2567 /* RemoveFieldName until reaching end of array */ 2568 end = PyObjCRT_RemoveFieldNames(buf, type); 2569 if (end == NULL) return NULL; 2570 2571 if (*end != _C_ARY_E) { 2572 PyErr_SetString(PyExc_ValueError, "bad type string"); 2573 return NULL; 2574 } 2575 2576 buf += strlen(buf); 2577 type += end - type; 2578 buf[0] = _C_ARY_E; 2579 buf[1] = '\0'; 2580 return end + 1; 2581 break; 2582 2583 default: 2584 end = PyObjCRT_SkipTypeSpec(end); 2585 if (end == NULL) return NULL; 2586 2587 memcpy(buf, type, end-type); 2588 buf[end-type] = '\0'; 2589 return end; 2590 } 2591} 2592 2593 2594PyObject* PyObjCObject_NewTransient(id objc_object, int* cookie) 2595{ 2596 return [(NSObject*)objc_object __pyobjc_PythonTransient__:cookie]; 2597} 2598 2599void PyObjCObject_ReleaseTransient(PyObject* proxy, int cookie) 2600{ 2601 if (cookie && proxy->ob_refcnt != 1) { 2602 CFRetain(PyObjCObject_GetObject(proxy)); 2603 ((PyObjCObject*)proxy)-> flags &= ~PyObjCObject_kSHOULD_NOT_RELEASE; 2604 } 2605 Py_DECREF(proxy); 2606} 2607