1/* 2 * A custom wrapper for the (opaque) FSSpec structure. 3 */ 4#include "pyobjc.h" 5#import <CoreServices/CoreServices.h> 6 7 8#if USE_TOOLBOX_OBJECT_GLUE 9#include "pymactoolbox.h" 10#endif 11 12/* 13 * Interface of the FSSpec type: 14 * 15 * FSSpec.from_pathname(value) 16 * # -> returns new FSSpec instance for posix path 'value' 17 * 18 * aspec.as_pathname() 19 * # -> returns a Unicode string with the posix path 20 * 21 * aspec.as_carbon() 22 * # -> return a Carbon.File.FSSpec instance (only 23 * # available when Carbon support is enabled in Python) 24 * 25 * aspec.data 26 * # -> read-only property with the bytes in the FSSpec 27 * 28 * This is more or less the same interface as Carbon.File.FSSpec, but 29 * excluding API wrappers. 30 */ 31 32typedef struct { 33 PyObject_HEAD 34 35 FSSpec ref; 36} PyObjC_FSSpecObject; 37 38static PyObject* fsspec_as_bytes(PyObject* ref, void* closure __attribute__((__unused__))) 39{ 40 if (!PyObjC_FSSpecCheck(ref)) { 41 PyErr_SetString(PyExc_TypeError, "self is not a FSSpec"); 42 } 43 44 return PyBytes_FromStringAndSize( 45 (char*)&((PyObjC_FSSpecObject*)ref)->ref, 46 sizeof(FSSpec)); 47} 48 49#if defined(USE_TOOLBOX_OBJECT_GLUE) && !defined(__LP64__) 50static PyObject* fsspec_as_carbon(PyObject* ref) 51{ 52 if (!PyObjC_FSSpecCheck(ref)) { 53 PyErr_SetString(PyExc_TypeError, "self is not a FSSpec"); 54 } 55 56 return PyMac_BuildFSSpec((&((PyObjC_FSSpecObject*)ref)->ref)); 57} 58#endif 59 60static PyGetSetDef fsspec_getset[] = { 61 { 62 "data", 63 fsspec_as_bytes, 64 0, 65 "bytes in the FSSpec", 66 0 67 }, 68 { 0, 0, 0, 0, 0} 69}; 70 71 72static PyMethodDef fsspec_methods[] = { 73#if defined(USE_TOOLBOX_OBJECT_GLUE) && !defined(__LP64__) 74 { 75 "as_carbon", 76 (PyCFunction)fsspec_as_carbon, 77 METH_NOARGS, 78 "return Carbon.File.FSSpec instance for this object" 79 }, 80#endif 81 82 { 0, 0, 0, 0 } 83}; 84 85 86PyTypeObject PyObjC_FSSpecType = { 87 PyVarObject_HEAD_INIT(&PyType_Type, 0) 88 "objc.FSSpec", /* tp_name */ 89 sizeof(PyObjC_FSSpecObject), /* tp_basicsize */ 90 0, /* tp_itemsize */ 91 /* methods */ 92 0, /* tp_dealloc */ 93 0, /* tp_print */ 94 0, /* tp_getattr */ 95 0, /* tp_setattr */ 96 0, /* tp_compare */ 97 0, /* tp_repr */ 98 0, /* tp_as_number */ 99 0, /* tp_as_sequence */ 100 0, /* tp_as_mapping */ 101 0, /* tp_hash */ 102 0, /* tp_call */ 103 0, /* tp_str */ 104 PyObject_GenericGetAttr, /* tp_getattro */ 105 PyObject_GenericSetAttr, /* tp_setattro */ 106 0, /* tp_as_buffer */ 107 Py_TPFLAGS_DEFAULT, /* tp_flags */ 108 0, /* tp_doc */ 109 0, /* tp_traverse */ 110 0, /* tp_clear */ 111 0, /* tp_richcompare */ 112 0, /* tp_weaklistoffset */ 113 0, /* tp_iter */ 114 0, /* tp_iternext */ 115 fsspec_methods, /* tp_methods */ 116 0, /* tp_members */ 117 fsspec_getset, /* tp_getset */ 118 0, /* tp_base */ 119 0, /* tp_dict */ 120 0, /* tp_descr_get */ 121 0, /* tp_descr_set */ 122 0, /* tp_dictoffset */ 123 0, /* tp_init */ 124 0, /* tp_alloc */ 125 0, /* tp_new */ 126 0, /* tp_free */ 127 0, /* tp_is_gc */ 128 0, /* tp_bases */ 129 0, /* tp_mro */ 130 0, /* tp_cache */ 131 0, /* tp_subclasses */ 132 0, /* tp_weaklist */ 133 0 /* tp_del */ 134#if PY_VERSION_HEX >= 0x02060000 135 , 0 /* tp_version_tag */ 136#endif 137 138}; 139 140 141int PyObjC_encode_fsspec(PyObject* value, void* buffer) 142{ 143#if defined(USE_TOOLBOX_OBJECT_GLUE) && !defined(__LP64__) 144 /* We cannot test if 'arg' is an instance of Carbon.File.FSSpec... */ 145 if (PyMac_GetFSSpec(value, (FSSpec*)buffer) == 1) { 146 return 0; 147 } 148 PyErr_Clear(); 149#endif 150 151 if (PyObjC_FSSpecCheck(value)) { 152 *(FSSpec*)buffer = ((PyObjC_FSSpecObject*)value)->ref; 153 return 0; 154 } 155 156 PyErr_SetString(PyExc_ValueError, "Cannot convert value to FSSpec"); 157 return -1; 158} 159 160 161PyObject* PyObjC_decode_fsspec(void* buffer) 162{ 163 PyObjC_FSSpecObject* result = PyObject_New( 164 PyObjC_FSSpecObject, &PyObjC_FSSpecType); 165 if (result == NULL) { 166 return NULL; 167 } 168 result->ref = *(FSSpec*)buffer; 169 return (PyObject*)result; 170} 171