1"""Mac-only module to find the home file of a resource.""" 2 3from __future__ import print_function, division, absolute_import 4from fontTools.misc.py23 import * 5from fontTools.misc import sstruct 6import array 7import calldll 8import macfs, Res 9 10 11def HomeResFile(res): 12 """Return a path to the file in which resource 'res' lives.""" 13 return GetFileLocation(res.HomeResFile()) 14 15 16def 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") 26GetVRefNum = 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 54class 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 94if __name__ == "__main__": 95 fond = Res.GetNamedResource("FOND", "Helvetica") 96 print(HomeResFile(fond)) 97