srcanamdw/codescanner/pyinstaller/carchive.py
author noe\swadi
Thu, 18 Feb 2010 12:29:02 +0530
changeset 1 22878952f6e2
permissions -rw-r--r--
Committing the CodeScanner Core tool This component has been moved from the StaticAnaApps package. BUG : 5889 (http://developer.symbian.org/webbugs/show_bug.cgi?id=5889).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     1
# Subclass of Archive that can be understood by a C program (see launch.c).
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     2
# Copyright (C) 2005, Giovanni Bajo
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     3
# Based on previous work under copyright (c) 1999, 2002 McMillan Enterprises, Inc.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     4
#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     5
# This program is free software; you can redistribute it and/or
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     6
# modify it under the terms of the GNU General Public License
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     7
# as published by the Free Software Foundation; either version 2
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     8
# of the License, or (at your option) any later version.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
     9
#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    10
# This program is distributed in the hope that it will be useful,
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    13
# GNU General Public License for more details.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    14
#
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    15
# You should have received a copy of the GNU General Public License
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    16
# along with this program; if not, write to the Free Software
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    17
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    18
import archive
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    19
import struct
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    20
try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    21
  import zlib
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    22
except ImportError:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    23
  zlib = archive.DummyZlib()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    24
import sys
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    25
if sys.version[0] == '1':
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    26
    import strop
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    27
    find = strop.find
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    28
    split = strop.split
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    29
else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    30
    def find(s, sub):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    31
        return s.find(sub)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    32
    def split(s, delim, count):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    33
        return s.split(delim, count)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    34
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    35
class CTOC:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    36
  """A class encapsulating the table of contents of a CArchive.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    37
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    38
     When written to disk, it is easily read from C."""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    39
  ENTRYSTRUCT = '!iiiibc' #(structlen, dpos, dlen, ulen, flag, typcd) followed by name
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    40
  def __init__(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    41
    self.data = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    42
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    43
  def frombinary(self, s):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    44
    """Decode the binary string into an in memory list.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    45
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    46
        S is a binary string."""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    47
    entrylen = struct.calcsize(self.ENTRYSTRUCT)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    48
    p = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    49
    while p<len(s):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    50
      (slen, dpos, dlen, ulen, flag, typcd) = struct.unpack(self.ENTRYSTRUCT,
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    51
                                                  s[p:p+entrylen])
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    52
      nmlen = slen - entrylen
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    53
      p = p + entrylen
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    54
      (nm,) = struct.unpack(`nmlen`+'s', s[p:p+nmlen])
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    55
      p = p + nmlen
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    56
      # version 4
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    57
      # self.data.append((dpos, dlen, ulen, flag, typcd, nm[:-1]))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    58
      # version 5
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    59
      # nm may have up to 15 bytes of padding
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    60
      pos = find(nm, '\0')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    61
      if pos < 0:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    62
          self.data.append((dpos, dlen, ulen, flag, typcd, nm))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    63
      else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    64
          self.data.append((dpos, dlen, ulen, flag, typcd, nm[:pos]))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    65
      #end version 5
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    66
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    67
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    68
  def tobinary(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    69
    """Return self as a binary string."""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    70
    import string
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    71
    entrylen = struct.calcsize(self.ENTRYSTRUCT)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    72
    rslt = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    73
    for (dpos, dlen, ulen, flag, typcd, nm) in self.data:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    74
      nmlen = len(nm) + 1	# add 1 for a '\0'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    75
      # version 4
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    76
      # rslt.append(struct.pack(self.ENTRYSTRUCT+`nmlen`+'s',
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    77
      #   nmlen+entrylen, dpos, dlen, ulen, flag, typcd, nm+'\0'))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    78
      # version 5
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    79
      #   align to 16 byte boundary so xplatform C can read
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    80
      toclen = nmlen + entrylen
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    81
      if toclen % 16 == 0:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    82
          pad = '\0'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    83
      else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    84
          padlen = 16 - (toclen % 16)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    85
          pad = '\0'*padlen
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    86
          nmlen = nmlen + padlen
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    87
      rslt.append(struct.pack(self.ENTRYSTRUCT+`nmlen`+'s',
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    88
                      nmlen+entrylen, dpos, dlen, ulen, flag, typcd, nm+pad))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    89
      # end version 5
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    90
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    91
    return string.join(rslt, '')
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    92
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    93
  def add(self, dpos, dlen, ulen, flag, typcd, nm):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    94
    """Add an entry to the table of contents.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    95
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    96
       DPOS is data position.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    97
       DLEN is data length.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    98
       ULEN is the uncompressed data len.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
    99
       FLAG says if the data is compressed.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   100
       TYPCD is the "type" of the entry (used by the C code)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   101
       NM is the entry's name."""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   102
    self.data.append((dpos, dlen, ulen, flag, typcd, nm))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   103
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   104
  def get(self, ndx):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   105
    """return the toc entry (tuple) at index NDX"""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   106
    return self.data[ndx]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   107
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   108
  def __getitem__(self, ndx):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   109
    return self.data[ndx]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   110
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   111
  def find(self, name):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   112
    """Return the index of the toc entry with name NAME.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   113
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   114
       Return -1 for failure."""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   115
    for i in range(len(self.data)):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   116
      if self.data[i][-1] == name:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   117
        return i
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   118
    return -1
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   119
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   120
class CArchive(archive.Archive):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   121
  """An Archive subclass that an hold arbitrary data.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   122
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   123
     Easily handled from C or from Python."""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   124
  MAGIC = 'MEI\014\013\012\013\016'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   125
  HDRLEN = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   126
  TOCTMPLT = CTOC
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   127
  TRLSTRUCT = '!8siiii'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   128
  TRLLEN = 24
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   129
  LEVEL = 9
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   130
  def __init__(self, path=None, start=0, len=0):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   131
    """Constructor.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   132
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   133
       PATH is path name of file (create an empty CArchive if path is None).
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   134
       START is the seekposition within PATH.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   135
       LEN is the length of the CArchive (if 0, then read till EOF). """
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   136
    self.len = len
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   137
    archive.Archive.__init__(self, path, start)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   138
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   139
  def checkmagic(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   140
    """Verify that self is a valid CArchive.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   141
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   142
        Magic signature is at end of the archive."""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   143
    #magic is at EOF; if we're embedded, we need to figure where that is
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   144
    if self.len:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   145
      self.lib.seek(self.start+self.len, 0)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   146
    else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   147
      self.lib.seek(0, 2)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   148
    filelen = self.lib.tell()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   149
    if self.len:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   150
      self.lib.seek(self.start+self.len-self.TRLLEN, 0)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   151
    else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   152
      self.lib.seek(-self.TRLLEN, 2)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   153
    (magic, totallen, tocpos, toclen, pyvers) = struct.unpack(self.TRLSTRUCT,
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   154
                        self.lib.read(self.TRLLEN))
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   155
    if magic != self.MAGIC:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   156
      raise RuntimeError, "%s is not a valid %s archive file" \
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   157
        % (self.path, self.__class__.__name__)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   158
    self.pkgstart = filelen - totallen
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   159
    if self.len:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   160
      if totallen != self.len or self.pkgstart != self.start:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   161
        raise RuntimeError, "Problem with embedded archive in %s" % self.path
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   162
    self.tocpos, self.toclen = tocpos, toclen
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   163
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   164
  def loadtoc(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   165
    """Load the table of contents into memory."""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   166
    self.toc = self.TOCTMPLT()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   167
    self.lib.seek(self.pkgstart+self.tocpos)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   168
    tocstr = self.lib.read(self.toclen)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   169
    self.toc.frombinary(tocstr)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   170
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   171
  def extract(self, name):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   172
    """Get the contents of an entry.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   173
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   174
       NAME is an entry name.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   175
       Return the tuple (ispkg, contents).
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   176
       For non-Python resoures, ispkg is meaningless (and 0).
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   177
       Used by the import mechanism."""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   178
    if type(name) == type(''):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   179
      ndx = self.toc.find(name)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   180
      if ndx == -1:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   181
        return None
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   182
    else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   183
      ndx = name
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   184
    (dpos, dlen, ulen, flag, typcd, nm) = self.toc.get(ndx)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   185
    self.lib.seek(self.pkgstart+dpos)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   186
    rslt = self.lib.read(dlen)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   187
    if flag == 1:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   188
      rslt = zlib.decompress(rslt)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   189
    if typcd == 'M':
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   190
      return (1, rslt)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   191
    return (0, rslt)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   192
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   193
  def contents(self):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   194
    """Return the names of the entries"""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   195
    rslt = []
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   196
    for (dpos, dlen, ulen, flag, typcd, nm) in self.toc:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   197
      rslt.append(nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   198
    return rslt
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   199
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   200
  def add(self, entry):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   201
    """Add an ENTRY to the CArchive.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   202
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   203
       ENTRY must have:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   204
         entry[0] is name (under which it will be saved).
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   205
         entry[1] is fullpathname of the file.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   206
         entry[2] is a flag for it's storage format (0==uncompressed,
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   207
         1==compressed)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   208
         entry[3] is the entry's type code.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   209
         Version 5:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   210
           If the type code is 'o':
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   211
             entry[0] is the runtime option
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   212
             eg: v  (meaning verbose imports)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   213
                 u  (menaing unbuffered)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   214
                 W arg (warning option arg)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   215
                 s  (meaning do site.py processing."""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   216
    (nm, pathnm, flag, typcd) = entry[:4]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   217
    # version 5 - allow type 'o' = runtime option
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   218
    try:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   219
      if typcd == 'o':
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   220
          s = ''
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   221
          flag = 0
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   222
      elif typcd == 's':
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   223
          # If it's a source code file, add \0 terminator as it will be
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   224
          # executed as-is by the bootloader.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   225
          s = open(pathnm, 'r').read()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   226
          s = s + '\n\0'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   227
      else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   228
          s = open(pathnm, 'rb').read()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   229
    except IOError:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   230
      print "Cannot find ('%s', '%s', %s, '%s')" % (nm, pathnm, flag, typcd)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   231
      raise
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   232
    ulen = len(s)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   233
    if flag == 1:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   234
      s = zlib.compress(s, self.LEVEL)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   235
    dlen = len(s)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   236
    where = self.lib.tell()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   237
    if typcd == 'm':
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   238
      if find(pathnm, '.__init__.py') > -1:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   239
        typcd = 'M'
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   240
    self.toc.add(where, dlen, ulen, flag, typcd, nm)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   241
    self.lib.write(s)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   242
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   243
  def save_toc(self, tocpos):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   244
    """Save the table of contents to disk."""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   245
    self.tocpos = tocpos
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   246
    tocstr = self.toc.tobinary()
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   247
    self.toclen = len(tocstr)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   248
    self.lib.write(tocstr)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   249
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   250
  def save_trailer(self, tocpos):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   251
    """Save the trailer to disk.
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   252
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   253
       CArchives can be opened from the end - the trailer points
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   254
       back to the start. """
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   255
    totallen = tocpos + self.toclen + self.TRLLEN
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   256
    if hasattr(sys, "version_info"):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   257
        pyvers = sys.version_info[0]*10 + sys.version_info[1]
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   258
    else:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   259
        toks = split(sys.version, '.', 2)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   260
        pyvers = int(toks[0])*10 + int(toks[1])
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   261
    trl = struct.pack(self.TRLSTRUCT, self.MAGIC, totallen,
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   262
                      tocpos, self.toclen, pyvers)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   263
    self.lib.write(trl)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   264
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   265
  def openEmbedded(self, name):
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   266
    """Open a CArchive of name NAME embedded within this CArchive."""
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   267
    ndx = self.toc.find(name)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   268
    if ndx == -1:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   269
      raise KeyError, "Member '%s' not found in %s" % (name, self.path)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   270
    (dpos, dlen, ulen, flag, typcd, nm) = self.toc.get(ndx)
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   271
    if flag:
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   272
      raise ValueError, "Cannot open compressed archive %s in place"
22878952f6e2 Committing the CodeScanner Core tool
noe\swadi
parents:
diff changeset
   273
    return CArchive(self.path, self.pkgstart+dpos, dlen)