[Python-checkins] CVS: python/dist/src/Mac/Modules macfsmodule.c,1.36,1.37

Jack Jansen jackjansen@users.sourceforge.net
Sun, 08 Jul 2001 15:07:15 -0700


Update of /cvsroot/python/python/dist/src/Mac/Modules
In directory usw-pr-cvs1:/tmp/cvs-serv17020/Python/Mac/Modules

Modified Files:
	macfsmodule.c 
Log Message:
Implemented minimal FSRef support, plus conversion between FSRefs, FSSpecs and pathnames where applicable.

PyMac_GetFSSpec and PyMac_BuildFSSpec have moved to macfsmodule from macglue.

These mods are untested on OSX.

Index: macfsmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Mac/Modules/macfsmodule.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -C2 -r1.36 -r1.37
*** macfsmodule.c	2001/05/19 12:34:59	1.36
--- macfsmodule.c	2001/07/08 22:07:13	1.37
***************
*** 39,44 ****
  #include "getapplbycreator.h"
  
- /* Should this be in macglue.h? */
- extern FSSpec *mfs_GetFSSpecFSSpec(PyObject *);
  
  static PyObject *ErrorObject;
--- 39,42 ----
***************
*** 68,72 ****
--- 66,82 ----
  #define is_mfssobject(v)		((v)->ob_type == &Mfsstype)
  
+ /* ---------------------------------------------------------------- */
+ /* Declarations for objects of type FSRef */
+ 
+ typedef struct {
+ 	PyObject_HEAD
+ 	FSRef fsref;
+ } mfsrobject;
+ 
+ staticforward PyTypeObject Mfsrtype;
  
+ #define is_mfsrobject(v)		((v)->ob_type == &Mfsrtype)
+ 
+ 
  /* ---------------------------------------------------------------- */
  /* Declarations for objects of type FInfo */
***************
*** 82,86 ****
  
  
! mfssobject *newmfssobject(FSSpec *fss); /* Forward */
  
  /* ---------------------------------------------------------------- */
--- 92,97 ----
  
  
! staticforward mfssobject *newmfssobject(FSSpec *fss); /* Forward */
! staticforward mfsrobject *newmfsrobject(FSRef *fsr); /* Forward */
  
  /* ---------------------------------------------------------------- */
***************
*** 337,351 ****
  
  /*
! ** Helper routine for other modules: return an FSSpec * if the
! ** object is a python fsspec object, else NULL
  */
! FSSpec *
! mfs_GetFSSpecFSSpec(PyObject *self)
  {
! 	if ( is_mfssobject(self) )
! 		return &((mfssobject *)self)->fsspec;
! 	return NULL;
  }
  
  /*
  ** Two generally useful routines
--- 348,403 ----
  
  /*
! ** Helper routines for the FSRef and FSSpec creators in macglue.c
! ** They return an FSSpec/FSRef if the Python object encapsulating
! ** either is passed. They return a boolean success indicator.
! ** Note that they do not set an exception on failure, they're only
! ** helper routines.
  */
! static int
! _mfs_GetFSSpecFromFSSpec(PyObject *self, FSSpec *fssp)
! {
! 	if ( is_mfssobject(self) ) {
! 		*fssp = ((mfssobject *)self)->fsspec;
! 		return 1;
! 	}
! 	return 0;
! }
! 
! /* Return an FSSpec if this is an FSref */
! static int
! _mfs_GetFSSpecFromFSRef(PyObject *self, FSSpec *fssp)
  {
! 	static FSRef *fsrp;
! 	
! 	if ( is_mfsrobject(self) ) {
! 		fsrp = &((mfsrobject *)self)->fsref;
! 		if ( FSGetCatalogInfo(&((mfsrobject *)self)->fsref, kFSCatInfoNone, NULL, NULL, fssp, NULL) == noErr )
! 			return 1;
! 	}
! 	return 0;
  }
  
+ /* Return an FSRef if this is an FSRef */
+ static int
+ _mfs_GetFSRefFromFSRef(PyObject *self, FSRef *fsrp)
+ {
+ 	if ( is_mfsrobject(self) ) {
+ 		*fsrp = ((mfsrobject *)self)->fsref;
+ 		return 1;
+ 	}
+ 	return 0;
+ }
+ 
+ /* Return an FSRef if this is an FSSpec */
+ static int
+ _mfs_GetFSRefFromFSSpec(PyObject *self, FSRef *fsrp)
+ {
+ 	if ( is_mfssobject(self) ) {
+ 		if ( FSpMakeFSRef(&((mfssobject *)self)->fsspec, fsrp) == noErr )
+ 			return 1;
+ 	}
+ 	return 0;
+ }
+ 
  /*
  ** Two generally useful routines
***************
*** 468,471 ****
--- 520,541 ----
  }
  
+ static PyObject *
+ mfss_FSpMakeFSRef(self, args)
+ 	mfssobject *self;
+ 	PyObject *args;
+ {
+ 	OSErr err;
+ 	FSRef fsref;
+ 	
+ 	if (!PyArg_ParseTuple(args, ""))
+ 		return NULL;
+ 	err = FSpMakeFSRef(&self->fsspec, &fsref);
+ 	if ( err ) {
+ 		PyErr_Mac(ErrorObject, err);
+ 		return NULL;
+ 	}
+ 	return (PyObject *)newmfsrobject(&fsref);
+ }
+ 
  /* XXXX These routines should be replaced by a wrapper to the *FInfo routines */
  static PyObject *
***************
*** 597,600 ****
--- 667,672 ----
  	{"as_pathname",		(PyCFunction)mfss_as_pathname,			1},
  	{"as_tuple",		(PyCFunction)mfss_as_tuple,				1},
+ 	{"as_fsref",	(PyCFunction)mfss_FSpMakeFSRef,			1},
+ 	{"FSpMakeFSRef",	(PyCFunction)mfss_FSpMakeFSRef,			1},
  	{"NewAlias",		(PyCFunction)mfss_NewAlias,				1},
  	{"NewAliasMinimal",	(PyCFunction)mfss_NewAliasMinimal,		1},
***************
*** 697,700 ****
--- 769,878 ----
  
  static PyObject *
+ mfsr_as_fsspec(self, args)
+ 	mfsrobject *self;
+ 	PyObject *args;
+ {
+ 	OSErr err;
+ 	FSSpec fss;
+ 	
+ 	if (!PyArg_ParseTuple(args, ""))
+ 		return NULL;
+ 	err = FSGetCatalogInfo(&self->fsref, kFSCatInfoNone, NULL, NULL, &fss, NULL);
+ 	if ( err ) {
+ 		PyErr_Mac(ErrorObject, err);
+ 		return NULL;
+ 	}
+ 	Py_INCREF(Py_None);
+ 	return (PyObject *)newmfssobject(&fss);
+ }
+ 
+ static struct PyMethodDef mfsr_methods[] = {
+ 	{"as_fsspec",		(PyCFunction)mfsr_as_fsspec,	1},
+ #if 0
+ 	{"as_pathname",		(PyCFunction)mfss_as_pathname,			1},
+ 	{"as_tuple",		(PyCFunction)mfss_as_tuple,				1},
+ 	{"NewAlias",		(PyCFunction)mfss_NewAlias,				1},
+ 	{"NewAliasMinimal",	(PyCFunction)mfss_NewAliasMinimal,		1},
+ 	{"GetCreatorType",	(PyCFunction)mfss_GetCreatorType,		1},
+ 	{"SetCreatorType",	(PyCFunction)mfss_SetCreatorType,		1},
+ 	{"GetFInfo",		(PyCFunction)mfss_GetFInfo,				1},
+ 	{"SetFInfo",		(PyCFunction)mfss_SetFInfo,				1},
+ 	{"GetDates",		(PyCFunction)mfss_GetDates,				1},
+ 	{"SetDates",		(PyCFunction)mfss_SetDates,				1},
+ #endif
+  
+ 	{NULL,			NULL}		/* sentinel */
+ };
+ 
+ /* ---------- */
+ 
+ static PyObject *
+ mfsr_getattr(self, name)
+ 	mfsrobject *self;
+ 	char *name;
+ {
+ 	if ( strcmp(name, "data") == 0)
+ 		return PyString_FromStringAndSize((char *)&self->fsref, sizeof(FSRef));	
+ 	return Py_FindMethod(mfsr_methods, (PyObject *)self, name);
+ }
+ 
+ mfsrobject *
+ newmfsrobject(fsr)
+ 	FSRef *fsr;
+ {
+ 	mfsrobject *self;
+ 	
+ 	self = PyObject_NEW(mfsrobject, &Mfsrtype);
+ 	if (self == NULL)
+ 		return NULL;
+ 	self->fsref = *fsr;
+ 	return self;
+ }
+ 
+ static int
+ mfsr_compare(v, w)
+ 	mfsrobject *v, *w;
+ {
+ 	OSErr err;
+ 	
+ 	if ( v == w ) return 0;
+ 	err = FSCompareFSRefs(&v->fsref, &w->fsref);
+ 	if ( err == 0 )
+ 		return 0;
+ 	if (v < w )
+ 		return -1;
+ 	return 1;
+ }
+ 
+ static void
+ mfsr_dealloc(self)
+ 	mfsrobject *self;
+ {
+ 	PyMem_DEL(self);
+ }
+ 
+ statichere PyTypeObject Mfsrtype = {
+ 	PyObject_HEAD_INIT(&PyType_Type)
+ 	0,				/*ob_size*/
+ 	"FSRef",			/*tp_name*/
+ 	sizeof(mfsrobject),		/*tp_basicsize*/
+ 	0,				/*tp_itemsize*/
+ 	/* methods */
+ 	(destructor)mfsr_dealloc,	/*tp_dealloc*/
+ 	(printfunc)0,		/*tp_print*/
+ 	(getattrfunc)mfsr_getattr,	/*tp_getattr*/
+ 	(setattrfunc)0,	/*tp_setattr*/
+ 	(cmpfunc)mfsr_compare,		/*tp_compare*/
+ 	(reprfunc)0,		/*tp_repr*/
+ 	0,			/*tp_as_number*/
+ 	0,		/*tp_as_sequence*/
+ 	0,		/*tp_as_mapping*/
+ 	(hashfunc)0,		/*tp_hash*/
+ };
+ 
+ /* End of code for FSRef objects */
+ /* -------------------------------------------------------- */
+ 
+ static PyObject *
  mfs_ResolveAliasFile(self, args)
  	PyObject *self;	/* Not used */
***************
*** 821,824 ****
--- 999,1014 ----
  
  static PyObject *
+ mfs_FSRef(self, args)
+ 	PyObject *self;	/* Not used */
+ 	PyObject *args;
+ {
+ 	FSRef fsr;
+ 
+ 	if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSRef, &fsr))
+ 		return NULL;
+ 	return (PyObject *)newmfsrobject(&fsr);
+ }
+ 
+ static PyObject *
  mfs_RawFSSpec(self, args)
  	PyObject *self;	/* Not used */
***************
*** 964,967 ****
--- 1154,1158 ----
  #endif
  	{"FSSpec",				mfs_FSSpec,				1},
+ 	{"FSRef",				mfs_FSRef,				1},
  	{"RawFSSpec",			mfs_RawFSSpec,			1},
  	{"RawAlias",			mfs_RawAlias,			1},
***************
*** 974,977 ****
--- 1165,1241 ----
  };
  
+ /*
+ ** Convert a Python object to an FSSpec.
+ ** The object may either be a full pathname, an FSSpec, an FSRef or a triple
+ ** (vrefnum, dirid, path).
+ */
+ int
+ PyMac_GetFSRef(PyObject *v, FSRef *fsr)
+ {
+ 	OSErr err;
+ 
+ 	/* If it's an FSRef we're also okay. */
+ 	if (_mfs_GetFSRefFromFSRef(v, fsr))
+ 		return 1;
+ 	/* first check whether it already is an FSSpec */
+ 	if ( _mfs_GetFSRefFromFSSpec(v, fsr) )
+ 		return 1;
+ 	if ( PyString_Check(v) ) {
+ 		PyErr_SetString(PyExc_NotImplementedError, "Cannot create an FSRef from a pathname on this platform");
+ 		return 0;
+ 	}
+ 	PyErr_SetString(PyExc_TypeError, "FSRef argument should be existing FSRef, FSSpec or (OSX only) pathname");
+ 	return 0;
+ }
+ 
+ /* Convert FSSpec to PyObject */
+ PyObject *PyMac_BuildFSRef(FSRef *v)
+ {
+ 	return (PyObject *)newmfsrobject(v);
+ }
+ 
+ /*
+ ** Convert a Python object to an FSRef.
+ ** The object may either be a full pathname (OSX only), an FSSpec or an FSRef.
+ */
+ int
+ PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
+ {
+ 	Str255 path;
+ 	short refnum;
+ 	long parid;
+ 	OSErr err;
+ 
+ 	/* first check whether it already is an FSSpec */
+ 	if ( _mfs_GetFSSpecFromFSSpec(v, fs) )
+ 		return 1;
+ 	/* If it's an FSRef we're also okay. */
+ 	if (_mfs_GetFSSpecFromFSRef(v, fs))
+ 		return 1;
+ 	if ( PyString_Check(v) ) {
+ 		/* It's a pathname */
+ 		if( !PyArg_Parse(v, "O&", PyMac_GetStr255, &path) )
+ 			return 0;
+ 		refnum = 0; /* XXXX Should get CurWD here?? */
+ 		parid = 0;
+ 	} else {
+ 		if( !PyArg_Parse(v, "(hlO&); FSSpec should be FSSpec, FSRef, fullpath or (vrefnum,dirid,path)",
+ 							&refnum, &parid, PyMac_GetStr255, &path)) {
+ 			return 0;
+ 		}
+ 	}
+ 	err = FSMakeFSSpec(refnum, parid, path, fs);
+ 	if ( err && err != fnfErr ) {
+ 		PyMac_Error(err);
+ 		return 0;
+ 	}
+ 	return 1;
+ }
+ 
+ /* Convert FSSpec to PyObject */
+ PyObject *PyMac_BuildFSSpec(FSSpec *v)
+ {
+ 	return (PyObject *)newmfssobject(v);
+ }
  
  /* Initialization function for the module (*must* be called initmacfs) */