PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/lib-python/2.7/plat-mac/cfmfile.py

https://bitbucket.org/dac_io/pypy
Python | 187 lines | 174 code | 8 blank | 5 comment | 0 complexity | 82491dc941387dbe550072e3556e2152 MD5 | raw file
  1. """codefragments.py -- wrapper to modify code fragments."""
  2. # (c) 1998, Just van Rossum, Letterror
  3. __version__ = "0.8b3"
  4. __author__ = "jvr"
  5. import warnings
  6. warnings.warnpy3k("the cfmfile module is deprecated and is removed in 3,0",
  7. stacklevel=2)
  8. import Carbon.File
  9. import struct
  10. from Carbon import Res
  11. import os
  12. import sys
  13. DEBUG = 0
  14. error = "cfm.error"
  15. BUFSIZE = 0x80000
  16. def mergecfmfiles(srclist, dst, architecture = 'fat'):
  17. """Merge all files in srclist into a new file dst.
  18. If architecture is given, only code fragments of that type will be used:
  19. "pwpc" for PPC, "m68k" for cfm68k. This does not work for "classic"
  20. 68k code, since it does not use code fragments to begin with.
  21. If architecture is None, all fragments will be used, enabling FAT binaries.
  22. """
  23. srclist = list(srclist)
  24. for i in range(len(srclist)):
  25. srclist[i] = Carbon.File.pathname(srclist[i])
  26. dst = Carbon.File.pathname(dst)
  27. dstfile = open(dst, "wb")
  28. rf = Res.FSpOpenResFile(dst, 3)
  29. try:
  30. dstcfrg = CfrgResource()
  31. for src in srclist:
  32. srccfrg = CfrgResource(src)
  33. for frag in srccfrg.fragments:
  34. if frag.architecture == 'pwpc' and architecture == 'm68k':
  35. continue
  36. if frag.architecture == 'm68k' and architecture == 'pwpc':
  37. continue
  38. dstcfrg.append(frag)
  39. frag.copydata(dstfile)
  40. cfrgres = Res.Resource(dstcfrg.build())
  41. Res.UseResFile(rf)
  42. cfrgres.AddResource('cfrg', 0, "")
  43. finally:
  44. dstfile.close()
  45. rf = Res.CloseResFile(rf)
  46. class CfrgResource:
  47. def __init__(self, path = None):
  48. self.version = 1
  49. self.fragments = []
  50. self.path = path
  51. if path is not None and os.path.exists(path):
  52. currentresref = Res.CurResFile()
  53. resref = Res.FSpOpenResFile(path, 1)
  54. Res.UseResFile(resref)
  55. try:
  56. try:
  57. data = Res.Get1Resource('cfrg', 0).data
  58. except Res.Error:
  59. raise Res.Error, "no 'cfrg' resource found", sys.exc_traceback
  60. finally:
  61. Res.CloseResFile(resref)
  62. Res.UseResFile(currentresref)
  63. self.parse(data)
  64. if self.version != 1:
  65. raise error, "unknown 'cfrg' resource format"
  66. def parse(self, data):
  67. (res1, res2, self.version,
  68. res3, res4, res5, res6,
  69. self.memberCount) = struct.unpack("8l", data[:32])
  70. data = data[32:]
  71. while data:
  72. frag = FragmentDescriptor(self.path, data)
  73. data = data[frag.memberSize:]
  74. self.fragments.append(frag)
  75. def build(self):
  76. self.memberCount = len(self.fragments)
  77. data = struct.pack("8l", 0, 0, self.version, 0, 0, 0, 0, self.memberCount)
  78. for frag in self.fragments:
  79. data = data + frag.build()
  80. return data
  81. def append(self, frag):
  82. self.fragments.append(frag)
  83. class FragmentDescriptor:
  84. def __init__(self, path, data = None):
  85. self.path = path
  86. if data is not None:
  87. self.parse(data)
  88. def parse(self, data):
  89. self.architecture = data[:4]
  90. ( self.updatelevel,
  91. self.currentVersion,
  92. self.oldDefVersion,
  93. self.stacksize,
  94. self.applibdir,
  95. self.fragtype,
  96. self.where,
  97. self.offset,
  98. self.length,
  99. self.res1, self.res2,
  100. self.memberSize,) = struct.unpack("4lhBB4lh", data[4:42])
  101. pname = data[42:self.memberSize]
  102. self.name = pname[1:1+ord(pname[0])]
  103. def build(self):
  104. data = self.architecture
  105. data = data + struct.pack("4lhBB4l",
  106. self.updatelevel,
  107. self.currentVersion,
  108. self.oldDefVersion,
  109. self.stacksize,
  110. self.applibdir,
  111. self.fragtype,
  112. self.where,
  113. self.offset,
  114. self.length,
  115. self.res1, self.res2)
  116. self.memberSize = len(data) + 2 + 1 + len(self.name)
  117. # pad to 4 byte boundaries
  118. if self.memberSize % 4:
  119. self.memberSize = self.memberSize + 4 - (self.memberSize % 4)
  120. data = data + struct.pack("hb", self.memberSize, len(self.name))
  121. data = data + self.name
  122. data = data + '\000' * (self.memberSize - len(data))
  123. return data
  124. def getfragment(self):
  125. if self.where != 1:
  126. raise error, "can't read fragment, unsupported location"
  127. f = open(self.path, "rb")
  128. f.seek(self.offset)
  129. if self.length:
  130. frag = f.read(self.length)
  131. else:
  132. frag = f.read()
  133. f.close()
  134. return frag
  135. def copydata(self, outfile):
  136. if self.where != 1:
  137. raise error, "can't read fragment, unsupported location"
  138. infile = open(self.path, "rb")
  139. if self.length == 0:
  140. infile.seek(0, 2)
  141. self.length = infile.tell()
  142. # Position input file and record new offset from output file
  143. infile.seek(self.offset)
  144. # pad to 16 byte boundaries
  145. offset = outfile.tell()
  146. if offset % 16:
  147. offset = offset + 16 - (offset % 16)
  148. outfile.seek(offset)
  149. self.offset = offset
  150. l = self.length
  151. while l:
  152. if l > BUFSIZE:
  153. outfile.write(infile.read(BUFSIZE))
  154. l = l - BUFSIZE
  155. else:
  156. outfile.write(infile.read(l))
  157. l = 0
  158. infile.close()