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