From e55beefed89f21985b3791f4a2a253ba7da508e9 Mon Sep 17 00:00:00 2001
From: Jack Jansen <jack.jansen@cwi.nl>
Date: Tue, 17 Dec 2002 22:10:46 +0000
Subject: - Added as_pathname and as_tuple methods - Added access to the "data"
 attribute - Fixed the FSRef tp_init routine to accept pathnames on OSX -
 Changed the FSSpec tp_repr to return something resembling what   macfs
 returns.

---
 Mac/Modules/file/_Filemodule.c  | 122 ++++++++++++++++++++++++++++++++++++----
 Mac/Modules/file/filesupport.py | 102 ++++++++++++++++++++++++++++++---
 2 files changed, 205 insertions(+), 19 deletions(-)

diff --git a/Mac/Modules/file/_Filemodule.c b/Mac/Modules/file/_Filemodule.c
index e76939f..eaaa547 100644
--- a/Mac/Modules/file/_Filemodule.c
+++ b/Mac/Modules/file/_Filemodule.c
@@ -291,7 +291,25 @@ static PyMethodDef Alias_methods[] = {
 	{NULL, NULL, 0}
 };
 
-#define Alias_getsetlist NULL
+static PyObject *Alias_get_data(AliasObject *self, void *closure)
+{
+	int size;
+				PyObject *rv;
+				
+				size = GetHandleSize((Handle)self->ob_itself);
+				HLock((Handle)self->ob_itself);
+				rv = PyString_FromStringAndSize(*(Handle)self->ob_itself, size);
+				HUnlock((Handle)self->ob_itself);
+				return rv;
+			
+}
+
+#define Alias_set_data NULL
+
+static PyGetSetDef Alias_getsetlist[] = {
+	{"data", (getter)Alias_get_data, (setter)Alias_set_data, "Raw data of the alias object"},
+	{NULL, NULL, NULL, NULL},
+};
 
 
 #define Alias_compare NULL
@@ -329,7 +347,7 @@ static PyObject *Alias_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds
 PyTypeObject Alias_Type = {
 	PyObject_HEAD_INIT(NULL)
 	0, /*ob_size*/
-	"_File.Alias", /*tp_name*/
+	"Carbon.File.Alias", /*tp_name*/
 	sizeof(AliasObject), /*tp_basicsize*/
 	0, /*tp_itemsize*/
 	/* methods */
@@ -691,6 +709,37 @@ static PyObject *FSSpec_UpdateAlias(FSSpecObject *_self, PyObject *_args)
 	return _res;
 }
 
+static PyObject *FSSpec_as_pathname(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	char strbuf[1024];
+	OSErr err;
+
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	err = PyMac_GetFullPathname(&_self->ob_itself, strbuf, sizeof(strbuf));
+	if ( err ) {
+		PyMac_Error(err);
+		return NULL;
+	}
+	_res = PyString_FromString(strbuf);
+	return _res;
+
+}
+
+static PyObject *FSSpec_as_tuple(FSSpecObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
+	_res = Py_BuildValue("(iis#)", _self->ob_itself.vRefNum, _self->ob_itself.parID, 
+						&_self->ob_itself.name[1], _self->ob_itself.name[0]);
+	return _res;
+
+}
+
 static PyMethodDef FSSpec_methods[] = {
 	{"FSpOpenDF", (PyCFunction)FSSpec_FSpOpenDF, 1,
 	 PyDoc_STR("(SInt8 permission) -> (short refNum)")},
@@ -726,15 +775,38 @@ static PyMethodDef FSSpec_methods[] = {
 	 PyDoc_STR("() -> (Boolean aliasFileFlag, Boolean folderFlag)")},
 	{"UpdateAlias", (PyCFunction)FSSpec_UpdateAlias, 1,
 	 PyDoc_STR("(FSSpec target, AliasHandle alias) -> (Boolean wasChanged)")},
+	{"as_pathname", (PyCFunction)FSSpec_as_pathname, 1,
+	 PyDoc_STR("() -> string")},
+	{"as_tuple", (PyCFunction)FSSpec_as_tuple, 1,
+	 PyDoc_STR("() -> (vRefNum, dirID, name)")},
 	{NULL, NULL, 0}
 };
 
-#define FSSpec_getsetlist NULL
+static PyObject *FSSpec_get_data(FSSpecObject *self, void *closure)
+{
+	return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));
+}
+
+#define FSSpec_set_data NULL
+
+static PyGetSetDef FSSpec_getsetlist[] = {
+	{"data", (getter)FSSpec_get_data, (setter)FSSpec_set_data, "Raw data of the FSSpec object"},
+	{NULL, NULL, NULL, NULL},
+};
 
 
 #define FSSpec_compare NULL
 
-#define FSSpec_repr NULL
+static PyObject * FSSpec_repr(FSSpecObject *self)
+{
+	char buf[512];
+	PyOS_snprintf(buf, sizeof(buf), "%s((%d, %ld, '%.*s'))",
+			self->ob_type->tp_name,
+			self->ob_itself.vRefNum, 
+			self->ob_itself.parID,
+			self->ob_itself.name[0], self->ob_itself.name+1);
+	return PyString_FromString(buf);
+}
 
 #define FSSpec_hash NULL
 static int FSSpec_tp_init(PyObject *self, PyObject *args, PyObject *kwds)
@@ -765,7 +837,7 @@ static PyObject *FSSpec_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwd
 PyTypeObject FSSpec_Type = {
 	PyObject_HEAD_INIT(NULL)
 	0, /*ob_size*/
-	"_File.FSSpec", /*tp_name*/
+	"Carbon.File.FSSpec", /*tp_name*/
 	sizeof(FSSpecObject), /*tp_basicsize*/
 	0, /*tp_itemsize*/
 	/* methods */
@@ -1122,6 +1194,8 @@ static PyObject *FSRef_FSRefMakePath(FSRefObject *_self, PyObject *_args)
 	UInt8 path[MAXPATHNAME];
 	UInt32 maxPathSize = MAXPATHNAME;
 
+	if (!PyArg_ParseTuple(_args, ""))
+		return NULL;
 	_err = FSRefMakePath(&_self->ob_itself,
 						 path,
 						 maxPathSize);
@@ -1131,6 +1205,15 @@ static PyObject *FSRef_FSRefMakePath(FSRefObject *_self, PyObject *_args)
 
 }
 
+static PyObject *FSRef_as_pathname(FSRefObject *_self, PyObject *_args)
+{
+	PyObject *_res = NULL;
+
+	_res = FSRef_FSRefMakePath(_self, _args);
+	return _res;
+
+}
+
 static PyMethodDef FSRef_methods[] = {
 	{"FSMakeFSRefUnicode", (PyCFunction)FSRef_FSMakeFSRefUnicode, 1,
 	 PyDoc_STR("(Buffer nameLength, TextEncoding textEncodingHint) -> (FSRef newRef)")},
@@ -1165,10 +1248,22 @@ static PyMethodDef FSRef_methods[] = {
 	 PyDoc_STR("(FSRef target, AliasHandle alias) -> (Boolean wasChanged)")},
 	{"FSRefMakePath", (PyCFunction)FSRef_FSRefMakePath, 1,
 	 PyDoc_STR("() -> string")},
+	{"as_pathname", (PyCFunction)FSRef_as_pathname, 1,
+	 PyDoc_STR("() -> string")},
 	{NULL, NULL, 0}
 };
 
-#define FSRef_getsetlist NULL
+static PyObject *FSRef_get_data(FSRefObject *self, void *closure)
+{
+	return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));
+}
+
+#define FSRef_set_data NULL
+
+static PyGetSetDef FSRef_getsetlist[] = {
+	{"data", (getter)FSRef_get_data, (setter)FSRef_set_data, "Raw data of the FSRef object"},
+	{NULL, NULL, NULL, NULL},
+};
 
 
 #define FSRef_compare NULL
@@ -1204,7 +1299,7 @@ static PyObject *FSRef_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds
 PyTypeObject FSRef_Type = {
 	PyObject_HEAD_INIT(NULL)
 	0, /*ob_size*/
-	"_File.FSRef", /*tp_name*/
+	"Carbon.File.FSRef", /*tp_name*/
 	sizeof(FSRefObject), /*tp_basicsize*/
 	0, /*tp_itemsize*/
 	/* methods */
@@ -2318,17 +2413,18 @@ myPyMac_GetFSSpec(PyObject *v, FSSpec *spec)
 static int
 myPyMac_GetFSRef(PyObject *v, FSRef *fsr)
 {
+	OSStatus err;
+	
 	if (FSRef_Check(v)) {
 		*fsr = ((FSRefObject *)v)->ob_itself;
 		return 1;
 	}
 
-#if !TARGET_API_MAC_OSX
+#if TARGET_API_MAC_OSX
 	/* On OSX we now try a pathname */
-	if ( PyString_Check(args) ) {
-		OSStatus err;
+	if ( PyString_Check(v) ) {
 		if ( (err=FSPathMakeRef(PyString_AsString(v), fsr, NULL)) ) {
-			PyErr_Mac(ErrorObject, err);
+			PyMac_Error(err);
 			return 0;
 		}
 		return 1;
@@ -2337,8 +2433,9 @@ myPyMac_GetFSRef(PyObject *v, FSRef *fsr)
 #endif
 	/* Otherwise we try to go via an FSSpec */
 	if (FSSpec_Check(v)) {
-		if (FSpMakeFSRef(&((FSSpecObject *)v)->ob_itself, fsr))
+		if ((err=FSpMakeFSRef(&((FSSpecObject *)v)->ob_itself, fsr)) == 0)
 			return 1;
+		PyMac_Error(err);
 		return 0;
 	}
 	PyErr_SetString(PyExc_TypeError, "FSRef, FSSpec or pathname required");
@@ -2346,6 +2443,7 @@ myPyMac_GetFSRef(PyObject *v, FSRef *fsr)
 }
 
 
+
 void init_File(void)
 {
 	PyObject *m;
diff --git a/Mac/Modules/file/filesupport.py b/Mac/Modules/file/filesupport.py
index c431d42..4a215be 100644
--- a/Mac/Modules/file/filesupport.py
+++ b/Mac/Modules/file/filesupport.py
@@ -8,6 +8,7 @@ import string
 # Declarations that change for each manager
 #MACHEADERFILE = 'Files.h'		# The Apple header file
 MODNAME = '_File'				# The name of the module
+LONGMODNAME = 'Carbon.File'		# The "normal" external name of the module
 
 # The following is *usually* unchanged but may still require tuning
 MODPREFIX = 'File'			# The prefix for module-wide routines
@@ -175,17 +176,18 @@ myPyMac_GetFSSpec(PyObject *v, FSSpec *spec)
 static int
 myPyMac_GetFSRef(PyObject *v, FSRef *fsr)
 {
+	OSStatus err;
+	
 	if (FSRef_Check(v)) {
 		*fsr = ((FSRefObject *)v)->ob_itself;
 		return 1;
 	}
 
-#if !TARGET_API_MAC_OSX
+#if TARGET_API_MAC_OSX
 	/* On OSX we now try a pathname */
-	if ( PyString_Check(args) ) {
-		OSStatus err;
+	if ( PyString_Check(v) ) {
 		if ( (err=FSPathMakeRef(PyString_AsString(v), fsr, NULL)) ) {
-			PyErr_Mac(ErrorObject, err);
+			PyMac_Error(err);
 			return 0;
 		}
 		return 1;
@@ -194,19 +196,29 @@ myPyMac_GetFSRef(PyObject *v, FSRef *fsr)
 #endif
 	/* Otherwise we try to go via an FSSpec */
 	if (FSSpec_Check(v)) {
-		if (FSpMakeFSRef(&((FSSpecObject *)v)->ob_itself, fsr))
+		if ((err=FSpMakeFSRef(&((FSSpecObject *)v)->ob_itself, fsr)) == 0)
 			return 1;
+		PyMac_Error(err);
 		return 0;
 	}
 	PyErr_SetString(PyExc_TypeError, "FSRef, FSSpec or pathname required");
 	return 0;
 }
+
 """
 
 execfile(string.lower(MODPREFIX) + 'typetest.py')
 
 # Our object types:
 class FSSpecDefinition(PEP253Mixin, GlobalObjectDefinition):
+	getsetlist = [
+		("data",
+		 "return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));",
+		 None,
+		 "Raw data of the FSSpec object"
+		)
+	]
+		 
 	def __init__(self, name, prefix, itselftype):
 		GlobalObjectDefinition.__init__(self, name, prefix, itselftype)
 		self.argref = "*"	# Store FSSpecs, but pass them by address
@@ -231,7 +243,28 @@ class FSSpecDefinition(PEP253Mixin, GlobalObjectDefinition):
 		Output("if (myPyMac_GetFSSpec(v, &((%s *)self)->ob_itself)) return 0;", self.objecttype)
 		Output("return -1;")
 	
+	def outputRepr(self):
+		Output()
+		Output("static PyObject * %s_repr(%s *self)", self.prefix, self.objecttype)
+		OutLbrace()
+		Output("char buf[512];")
+		Output("""PyOS_snprintf(buf, sizeof(buf), \"%%s((%%d, %%ld, '%%.*s'))\",
+		self->ob_type->tp_name,
+		self->ob_itself.vRefNum, 
+		self->ob_itself.parID,
+		self->ob_itself.name[0], self->ob_itself.name+1);""")
+		Output("return PyString_FromString(buf);")
+		OutRbrace()
+		
 class FSRefDefinition(PEP253Mixin, GlobalObjectDefinition):
+	getsetlist = [
+		("data",
+		 "return PyString_FromStringAndSize((char *)&self->ob_itself, sizeof(self->ob_itself));",
+		 None,
+		 "Raw data of the FSRef object"
+		)
+	]
+		 
 	def __init__(self, name, prefix, itselftype):
 		GlobalObjectDefinition.__init__(self, name, prefix, itselftype)
 		self.argref = "*"	# Store FSRefs, but pass them by address
@@ -258,7 +291,22 @@ class FSRefDefinition(PEP253Mixin, GlobalObjectDefinition):
 	
 class AliasDefinition(PEP253Mixin, GlobalObjectDefinition):
 	# XXXX Should inherit from resource?
-
+	getsetlist = [
+		("data",
+		 """int size;
+			PyObject *rv;
+			
+			size = GetHandleSize((Handle)self->ob_itself);
+			HLock((Handle)self->ob_itself);
+			rv = PyString_FromStringAndSize(*(Handle)self->ob_itself, size);
+			HUnlock((Handle)self->ob_itself);
+			return rv;
+		""",
+		 None,
+		 "Raw data of the alias object"
+		)
+	]
+		 
 	def outputCheckNewArg(self):
 		Output("if (itself == NULL) return PyMac_Error(resNotFound);")
 		
@@ -314,7 +362,8 @@ class Arg2MethodGenerator(MethodGenerator):
 # From here on it's basically all boiler plate...
 
 # Create the generator groups and link them
-module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
+module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff,
+	longname=LONGMODNAME)
 
 aliasobject = AliasDefinition('Alias', 'Alias', 'AliasHandle')
 fsspecobject = FSSpecDefinition('FSSpec', 'FSSpec', 'FSSpec')
@@ -342,6 +391,8 @@ OSStatus _err;
 UInt8 path[MAXPATHNAME];
 UInt32 maxPathSize = MAXPATHNAME;
 
+if (!PyArg_ParseTuple(_args, ""))
+	return NULL;
 _err = FSRefMakePath(&_self->ob_itself,
 					 path,
 					 maxPathSize);
@@ -353,6 +404,43 @@ f = ManualGenerator("FSRefMakePath", FSRefMakePath_body)
 f.docstring = lambda: "() -> string"
 fsref_methods.append(f)
 
+FSRef_as_pathname_body = """
+_res = FSRef_FSRefMakePath(_self, _args);
+return _res;
+"""
+f = ManualGenerator("as_pathname", FSRef_as_pathname_body)
+f.docstring = lambda: "() -> string"
+fsref_methods.append(f)
+
+FSSpec_as_pathname_body = """
+char strbuf[1024];
+OSErr err;
+
+if (!PyArg_ParseTuple(_args, ""))
+	return NULL;
+err = PyMac_GetFullPathname(&_self->ob_itself, strbuf, sizeof(strbuf));
+if ( err ) {
+	PyMac_Error(err);
+	return NULL;
+}
+_res = PyString_FromString(strbuf);
+return _res;
+"""
+f = ManualGenerator("as_pathname", FSSpec_as_pathname_body)
+f.docstring = lambda: "() -> string"
+fsspec_methods.append(f)
+
+FSSpec_as_tuple_body = """
+if (!PyArg_ParseTuple(_args, ""))
+	return NULL;
+_res = Py_BuildValue("(iis#)", _self->ob_itself.vRefNum, _self->ob_itself.parID, 
+					&_self->ob_itself.name[1], _self->ob_itself.name[0]);
+return _res;
+"""
+f = ManualGenerator("as_tuple", FSSpec_as_tuple_body)
+f.docstring = lambda: "() -> (vRefNum, dirID, name)"
+fsspec_methods.append(f)
+
 
 # add the populated lists to the generator groups
 # (in a different wordl the scan program would generate this)
-- 
cgit v0.12

