@@ -38,8 +38,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3838
3939#include "getapplbycreator.h"
4040
41- /* Should this be in macglue.h? */
42- extern FSSpec * mfs_GetFSSpecFSSpec (PyObject * );
4341
4442static PyObject * ErrorObject ;
4543
@@ -67,6 +65,18 @@ staticforward PyTypeObject Mfsstype;
6765
6866#define is_mfssobject (v ) ((v)->ob_type == &Mfsstype)
6967
68+ /* ---------------------------------------------------------------- */
69+ /* Declarations for objects of type FSRef */
70+
71+ typedef struct {
72+ PyObject_HEAD
73+ FSRef fsref ;
74+ } mfsrobject ;
75+
76+ staticforward PyTypeObject Mfsrtype ;
77+
78+ #define is_mfsrobject (v ) ((v)->ob_type == &Mfsrtype)
79+
7080
7181/* ---------------------------------------------------------------- */
7282/* Declarations for objects of type FInfo */
@@ -81,7 +91,8 @@ staticforward PyTypeObject Mfsitype;
8191#define is_mfsiobject (v ) ((v)->ob_type == &Mfsitype)
8292
8393
84- mfssobject * newmfssobject (FSSpec * fss ); /* Forward */
94+ staticforward mfssobject * newmfssobject (FSSpec * fss ); /* Forward */
95+ staticforward mfsrobject * newmfsrobject (FSRef * fsr ); /* Forward */
8596
8697/* ---------------------------------------------------------------- */
8798
@@ -336,15 +347,56 @@ static PyTypeObject Mfsitype = {
336347
337348
338349/*
339- ** Helper routine for other modules: return an FSSpec * if the
340- ** object is a python fsspec object, else NULL
350+ ** Helper routines for the FSRef and FSSpec creators in macglue.c
351+ ** They return an FSSpec/FSRef if the Python object encapsulating
352+ ** either is passed. They return a boolean success indicator.
353+ ** Note that they do not set an exception on failure, they're only
354+ ** helper routines.
341355*/
342- FSSpec *
343- mfs_GetFSSpecFSSpec (PyObject * self )
356+ static int
357+ _mfs_GetFSSpecFromFSSpec (PyObject * self , FSSpec * fssp )
358+ {
359+ if ( is_mfssobject (self ) ) {
360+ * fssp = ((mfssobject * )self )-> fsspec ;
361+ return 1 ;
362+ }
363+ return 0 ;
364+ }
365+
366+ /* Return an FSSpec if this is an FSref */
367+ static int
368+ _mfs_GetFSSpecFromFSRef (PyObject * self , FSSpec * fssp )
344369{
345- if ( is_mfssobject (self ) )
346- return & ((mfssobject * )self )-> fsspec ;
347- return NULL ;
370+ static FSRef * fsrp ;
371+
372+ if ( is_mfsrobject (self ) ) {
373+ fsrp = & ((mfsrobject * )self )-> fsref ;
374+ if ( FSGetCatalogInfo (& ((mfsrobject * )self )-> fsref , kFSCatInfoNone , NULL , NULL , fssp , NULL ) == noErr )
375+ return 1 ;
376+ }
377+ return 0 ;
378+ }
379+
380+ /* Return an FSRef if this is an FSRef */
381+ static int
382+ _mfs_GetFSRefFromFSRef (PyObject * self , FSRef * fsrp )
383+ {
384+ if ( is_mfsrobject (self ) ) {
385+ * fsrp = ((mfsrobject * )self )-> fsref ;
386+ return 1 ;
387+ }
388+ return 0 ;
389+ }
390+
391+ /* Return an FSRef if this is an FSSpec */
392+ static int
393+ _mfs_GetFSRefFromFSSpec (PyObject * self , FSRef * fsrp )
394+ {
395+ if ( is_mfssobject (self ) ) {
396+ if ( FSpMakeFSRef (& ((mfssobject * )self )-> fsspec , fsrp ) == noErr )
397+ return 1 ;
398+ }
399+ return 0 ;
348400}
349401
350402/*
@@ -467,6 +519,24 @@ mfss_NewAliasMinimal(self, args)
467519 return (PyObject * )newmfsaobject (alias );
468520}
469521
522+ static PyObject *
523+ mfss_FSpMakeFSRef (self , args )
524+ mfssobject * self ;
525+ PyObject * args ;
526+ {
527+ OSErr err ;
528+ FSRef fsref ;
529+
530+ if (!PyArg_ParseTuple (args , "" ))
531+ return NULL ;
532+ err = FSpMakeFSRef (& self -> fsspec , & fsref );
533+ if ( err ) {
534+ PyErr_Mac (ErrorObject , err );
535+ return NULL ;
536+ }
537+ return (PyObject * )newmfsrobject (& fsref );
538+ }
539+
470540/* XXXX These routines should be replaced by a wrapper to the *FInfo routines */
471541static PyObject *
472542mfss_GetCreatorType (self , args )
@@ -596,6 +666,8 @@ mfss_SetDates(self, args)
596666static struct PyMethodDef mfss_methods [] = {
597667 {"as_pathname" , (PyCFunction )mfss_as_pathname , 1 },
598668 {"as_tuple" , (PyCFunction )mfss_as_tuple , 1 },
669+ {"as_fsref" , (PyCFunction )mfss_FSpMakeFSRef , 1 },
670+ {"FSpMakeFSRef" , (PyCFunction )mfss_FSpMakeFSRef , 1 },
599671 {"NewAlias" , (PyCFunction )mfss_NewAlias , 1 },
600672 {"NewAliasMinimal" , (PyCFunction )mfss_NewAliasMinimal , 1 },
601673 {"GetCreatorType" , (PyCFunction )mfss_GetCreatorType , 1 },
@@ -695,6 +767,112 @@ statichere PyTypeObject Mfsstype = {
695767/* End of code for FSSpec objects */
696768/* -------------------------------------------------------- */
697769
770+ static PyObject *
771+ mfsr_as_fsspec (self , args )
772+ mfsrobject * self ;
773+ PyObject * args ;
774+ {
775+ OSErr err ;
776+ FSSpec fss ;
777+
778+ if (!PyArg_ParseTuple (args , "" ))
779+ return NULL ;
780+ err = FSGetCatalogInfo (& self -> fsref , kFSCatInfoNone , NULL , NULL , & fss , NULL );
781+ if ( err ) {
782+ PyErr_Mac (ErrorObject , err );
783+ return NULL ;
784+ }
785+ Py_INCREF (Py_None );
786+ return (PyObject * )newmfssobject (& fss );
787+ }
788+
789+ static struct PyMethodDef mfsr_methods [] = {
790+ {"as_fsspec" , (PyCFunction )mfsr_as_fsspec , 1 },
791+ #if 0
792+ {"as_pathname" , (PyCFunction )mfss_as_pathname , 1 },
793+ {"as_tuple" , (PyCFunction )mfss_as_tuple , 1 },
794+ {"NewAlias" , (PyCFunction )mfss_NewAlias , 1 },
795+ {"NewAliasMinimal" , (PyCFunction )mfss_NewAliasMinimal , 1 },
796+ {"GetCreatorType" , (PyCFunction )mfss_GetCreatorType , 1 },
797+ {"SetCreatorType" , (PyCFunction )mfss_SetCreatorType , 1 },
798+ {"GetFInfo" , (PyCFunction )mfss_GetFInfo , 1 },
799+ {"SetFInfo" , (PyCFunction )mfss_SetFInfo , 1 },
800+ {"GetDates" , (PyCFunction )mfss_GetDates , 1 },
801+ {"SetDates" , (PyCFunction )mfss_SetDates , 1 },
802+ #endif
803+
804+ {NULL , NULL } /* sentinel */
805+ };
806+
807+ /* ---------- */
808+
809+ static PyObject *
810+ mfsr_getattr (self , name )
811+ mfsrobject * self ;
812+ char * name ;
813+ {
814+ if ( strcmp (name , "data" ) == 0 )
815+ return PyString_FromStringAndSize ((char * )& self -> fsref , sizeof (FSRef ));
816+ return Py_FindMethod (mfsr_methods , (PyObject * )self , name );
817+ }
818+
819+ mfsrobject *
820+ newmfsrobject (fsr )
821+ FSRef * fsr ;
822+ {
823+ mfsrobject * self ;
824+
825+ self = PyObject_NEW (mfsrobject , & Mfsrtype );
826+ if (self == NULL )
827+ return NULL ;
828+ self -> fsref = * fsr ;
829+ return self ;
830+ }
831+
832+ static int
833+ mfsr_compare (v , w )
834+ mfsrobject * v , * w ;
835+ {
836+ OSErr err ;
837+
838+ if ( v == w ) return 0 ;
839+ err = FSCompareFSRefs (& v -> fsref , & w -> fsref );
840+ if ( err == 0 )
841+ return 0 ;
842+ if (v < w )
843+ return -1 ;
844+ return 1 ;
845+ }
846+
847+ static void
848+ mfsr_dealloc (self )
849+ mfsrobject * self ;
850+ {
851+ PyMem_DEL (self );
852+ }
853+
854+ statichere PyTypeObject Mfsrtype = {
855+ PyObject_HEAD_INIT (& PyType_Type )
856+ 0 , /*ob_size*/
857+ "FSRef" , /*tp_name*/
858+ sizeof (mfsrobject ), /*tp_basicsize*/
859+ 0 , /*tp_itemsize*/
860+ /* methods */
861+ (destructor )mfsr_dealloc , /*tp_dealloc*/
862+ (printfunc )0 , /*tp_print*/
863+ (getattrfunc )mfsr_getattr , /*tp_getattr*/
864+ (setattrfunc )0 , /*tp_setattr*/
865+ (cmpfunc )mfsr_compare , /*tp_compare*/
866+ (reprfunc )0 , /*tp_repr*/
867+ 0 , /*tp_as_number*/
868+ 0 , /*tp_as_sequence*/
869+ 0 , /*tp_as_mapping*/
870+ (hashfunc )0 , /*tp_hash*/
871+ };
872+
873+ /* End of code for FSRef objects */
874+ /* -------------------------------------------------------- */
875+
698876static PyObject *
699877mfs_ResolveAliasFile (self , args )
700878 PyObject * self ; /* Not used */
@@ -819,6 +997,18 @@ mfs_FSSpec(self, args)
819997 return (PyObject * )newmfssobject (& fss );
820998}
821999
1000+ static PyObject *
1001+ mfs_FSRef (self , args )
1002+ PyObject * self ; /* Not used */
1003+ PyObject * args ;
1004+ {
1005+ FSRef fsr ;
1006+
1007+ if (!PyArg_ParseTuple (args , "O&" , PyMac_GetFSRef , & fsr ))
1008+ return NULL ;
1009+ return (PyObject * )newmfsrobject (& fsr );
1010+ }
1011+
8221012static PyObject *
8231013mfs_RawFSSpec (self , args )
8241014 PyObject * self ; /* Not used */
@@ -963,6 +1153,7 @@ static struct PyMethodDef mfs_methods[] = {
9631153 {"SetFolder" , mfs_SetFolder , 1 },
9641154#endif
9651155 {"FSSpec" , mfs_FSSpec , 1 },
1156+ {"FSRef" , mfs_FSRef , 1 },
9661157 {"RawFSSpec" , mfs_RawFSSpec , 1 },
9671158 {"RawAlias" , mfs_RawAlias , 1 },
9681159 {"FindFolder" , mfs_FindFolder , 1 },
@@ -973,6 +1164,79 @@ static struct PyMethodDef mfs_methods[] = {
9731164 {NULL , NULL } /* sentinel */
9741165};
9751166
1167+ /*
1168+ ** Convert a Python object to an FSSpec.
1169+ ** The object may either be a full pathname, an FSSpec, an FSRef or a triple
1170+ ** (vrefnum, dirid, path).
1171+ */
1172+ int
1173+ PyMac_GetFSRef (PyObject * v , FSRef * fsr )
1174+ {
1175+ OSErr err ;
1176+
1177+ /* If it's an FSRef we're also okay. */
1178+ if (_mfs_GetFSRefFromFSRef (v , fsr ))
1179+ return 1 ;
1180+ /* first check whether it already is an FSSpec */
1181+ if ( _mfs_GetFSRefFromFSSpec (v , fsr ) )
1182+ return 1 ;
1183+ if ( PyString_Check (v ) ) {
1184+ PyErr_SetString (PyExc_NotImplementedError , "Cannot create an FSRef from a pathname on this platform" );
1185+ return 0 ;
1186+ }
1187+ PyErr_SetString (PyExc_TypeError , "FSRef argument should be existing FSRef, FSSpec or (OSX only) pathname" );
1188+ return 0 ;
1189+ }
1190+
1191+ /* Convert FSSpec to PyObject */
1192+ PyObject * PyMac_BuildFSRef (FSRef * v )
1193+ {
1194+ return (PyObject * )newmfsrobject (v );
1195+ }
1196+
1197+ /*
1198+ ** Convert a Python object to an FSRef.
1199+ ** The object may either be a full pathname (OSX only), an FSSpec or an FSRef.
1200+ */
1201+ int
1202+ PyMac_GetFSSpec (PyObject * v , FSSpec * fs )
1203+ {
1204+ Str255 path ;
1205+ short refnum ;
1206+ long parid ;
1207+ OSErr err ;
1208+
1209+ /* first check whether it already is an FSSpec */
1210+ if ( _mfs_GetFSSpecFromFSSpec (v , fs ) )
1211+ return 1 ;
1212+ /* If it's an FSRef we're also okay. */
1213+ if (_mfs_GetFSSpecFromFSRef (v , fs ))
1214+ return 1 ;
1215+ if ( PyString_Check (v ) ) {
1216+ /* It's a pathname */
1217+ if ( !PyArg_Parse (v , "O&" , PyMac_GetStr255 , & path ) )
1218+ return 0 ;
1219+ refnum = 0 ; /* XXXX Should get CurWD here?? */
1220+ parid = 0 ;
1221+ } else {
1222+ if ( !PyArg_Parse (v , "(hlO&); FSSpec should be FSSpec, FSRef, fullpath or (vrefnum,dirid,path)" ,
1223+ & refnum , & parid , PyMac_GetStr255 , & path )) {
1224+ return 0 ;
1225+ }
1226+ }
1227+ err = FSMakeFSSpec (refnum , parid , path , fs );
1228+ if ( err && err != fnfErr ) {
1229+ PyMac_Error (err );
1230+ return 0 ;
1231+ }
1232+ return 1 ;
1233+ }
1234+
1235+ /* Convert FSSpec to PyObject */
1236+ PyObject * PyMac_BuildFSSpec (FSSpec * v )
1237+ {
1238+ return (PyObject * )newmfssobject (v );
1239+ }
9761240
9771241/* Initialization function for the module (*must* be called initmacfs) */
9781242
0 commit comments