module to find the home file of a resource (handy for finding suitcase files when all you have is a resource)


git-svn-id: svn://svn.code.sf.net/p/fonttools/code/trunk@113 4cde692c-a291-49d1-8350-778aa11640f8
diff --git a/Lib/fontTools/misc/homeResFile.py b/Lib/fontTools/misc/homeResFile.py
new file mode 100644
index 0000000..3e3e92d
--- /dev/null
+++ b/Lib/fontTools/misc/homeResFile.py
@@ -0,0 +1,94 @@
+"""Mac-only module to find the home file of a resource."""
+
+import sstruct
+import array
+import calldll
+import macfs, Res
+
+
+def HomeResFile(res):
+	"""Return a path to the file in which resource 'res' lives."""
+	return GetFileLocation(res.HomeResFile())
+
+
+def GetFileLocation(refNum):
+	"""Return a path to the open file identified with refNum."""
+	pb = ParamBlock(refNum)
+	return pb.getPath()
+
+#
+# Internal cruft, adapted from MoreFiles
+#
+
+_InterfaceLib = calldll.getlibrary("InterfaceLib")
+GetVRefNum = calldll.newcall(_InterfaceLib.GetVRefNum, "None", "InShort", "OutShort")
+_getInfo = calldll.newcall(_InterfaceLib.PBGetFCBInfoSync, "Short", "InLong")
+
+
+_FCBPBFormat = """
+	qLink:        l
+	qType:        h
+	ioTrap:       h
+	ioCmdAddr:    l
+	ioCompletion: l
+	ioResult:     h
+	ioNamePtr:    l
+	ioVRefNum:    h
+	ioRefNum:     h
+	filler:       h
+	ioFCBIndx:    h
+	filler1:      h
+	ioFCBFINm:    l
+	ioFCBFlags:   h
+	ioFCBStBlk:   h
+	ioFCBEOF:     l
+	ioFCBPLen:    l
+	ioFCBCrPs:    l
+	ioFCBVRefNum: h
+	ioFCBClpSiz:  l
+	ioFCBParID:   l
+"""
+
+class ParamBlock:
+	
+	"""Wrapper for the very low level FCBPB record."""
+	
+	def __init__(self, refNum):
+		self.__fileName = array.array("c", "\0" * 64)
+		sstruct.unpack(_FCBPBFormat, 
+				"\0" * sstruct.calcsize(_FCBPBFormat), self)
+		self.ioNamePtr = self.__fileName.buffer_info()[0]
+		self.ioRefNum = refNum
+		self.ioVRefNum = GetVRefNum(refNum)
+		self.__haveInfo = 0
+	
+	def getInfo(self):
+		if self.__haveInfo:
+			return
+		data = sstruct.pack(_FCBPBFormat, self)
+		buf = array.array("c", data)
+		ptr = buf.buffer_info()[0]
+		err = _getInfo(ptr)
+		if err:
+			raise Res.Error, ("can't get file info", err)
+		sstruct.unpack(_FCBPBFormat, buf.tostring(), self)
+		self.__haveInfo = 1
+	
+	def getFileName(self):
+		self.getInfo()
+		data = self.__fileName.tostring()
+		return data[1:ord(data[0])+1]
+	
+	def getFSSpec(self):
+		self.getInfo()
+		vRefNum = self.ioVRefNum
+		parID = self.ioFCBParID
+		return macfs.FSSpec((vRefNum, parID, self.getFileName()))
+	
+	def getPath(self):
+		return self.getFSSpec().as_pathname()
+
+
+if __name__ == "__main__":
+	fond = Res.GetNamedResource("FOND", "Helvetica")
+	print HomeResFile(fond)