Home | History | Annotate | Download | only in misc
      1 """Mac-only module to find the home file of a resource."""
      2 
      3 from __future__ import print_function, division, absolute_import
      4 from fontTools.misc.py23 import *
      5 from fontTools.misc import sstruct
      6 import array
      7 import calldll
      8 import macfs, Res
      9 
     10 
     11 def HomeResFile(res):
     12 	"""Return a path to the file in which resource 'res' lives."""
     13 	return GetFileLocation(res.HomeResFile())
     14 
     15 
     16 def GetFileLocation(refNum):
     17 	"""Return a path to the open file identified with refNum."""
     18 	pb = ParamBlock(refNum)
     19 	return pb.getPath()
     20 
     21 #
     22 # Internal cruft, adapted from MoreFiles
     23 #
     24 
     25 _InterfaceLib = calldll.getlibrary("InterfaceLib")
     26 GetVRefNum = calldll.newcall(_InterfaceLib.GetVRefNum, "None", "InShort", "OutShort")
     27 _getInfo = calldll.newcall(_InterfaceLib.PBGetFCBInfoSync, "Short", "InLong")
     28 
     29 
     30 _FCBPBFormat = """
     31 	qLink:        l
     32 	qType:        h
     33 	ioTrap:       h
     34 	ioCmdAddr:    l
     35 	ioCompletion: l
     36 	ioResult:     h
     37 	ioNamePtr:    l
     38 	ioVRefNum:    h
     39 	ioRefNum:     h
     40 	filler:       h
     41 	ioFCBIndx:    h
     42 	filler1:      h
     43 	ioFCBFINm:    l
     44 	ioFCBFlags:   h
     45 	ioFCBStBlk:   h
     46 	ioFCBEOF:     l
     47 	ioFCBPLen:    l
     48 	ioFCBCrPs:    l
     49 	ioFCBVRefNum: h
     50 	ioFCBClpSiz:  l
     51 	ioFCBParID:   l
     52 """
     53 
     54 class ParamBlock(object):
     55 	
     56 	"""Wrapper for the very low level FCBPB record."""
     57 	
     58 	def __init__(self, refNum):
     59 		self.__fileName = array.array("c", "\0" * 64)
     60 		sstruct.unpack(_FCBPBFormat, 
     61 				"\0" * sstruct.calcsize(_FCBPBFormat), self)
     62 		self.ioNamePtr = self.__fileName.buffer_info()[0]
     63 		self.ioRefNum = refNum
     64 		self.ioVRefNum = GetVRefNum(refNum)
     65 		self.__haveInfo = 0
     66 	
     67 	def getInfo(self):
     68 		if self.__haveInfo:
     69 			return
     70 		data = sstruct.pack(_FCBPBFormat, self)
     71 		buf = array.array("c", data)
     72 		ptr = buf.buffer_info()[0]
     73 		err = _getInfo(ptr)
     74 		if err:
     75 			raise Res.Error("can't get file info", err)
     76 		sstruct.unpack(_FCBPBFormat, buf.tostring(), self)
     77 		self.__haveInfo = 1
     78 	
     79 	def getFileName(self):
     80 		self.getInfo()
     81 		data = self.__fileName.tostring()
     82 		return data[1:byteord(data[0])+1]
     83 	
     84 	def getFSSpec(self):
     85 		self.getInfo()
     86 		vRefNum = self.ioVRefNum
     87 		parID = self.ioFCBParID
     88 		return macfs.FSSpec((vRefNum, parID, self.getFileName()))
     89 	
     90 	def getPath(self):
     91 		return self.getFSSpec().as_pathname()
     92 
     93 
     94 if __name__ == "__main__":
     95 	fond = Res.GetNamedResource("FOND", "Helvetica")
     96 	print(HomeResFile(fond))
     97