# Subclass of Archive that can be understood by a C program (see launch.c). # Copyright (C) 2005, Giovanni Bajo # Based on previous work under copyright (c) 1999, 2002 McMillan Enterprises, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA import archive import struct try: import zlib except ImportError: zlib = archive.DummyZlib() import sys if sys.version[0] == '1': import strop find = strop.find split = strop.split else: def find(s, sub): return s.find(sub) def split(s, delim, count): return s.split(delim, count) class CTOC: """A class encapsulating the table of contents of a CArchive. When written to disk, it is easily read from C.""" ENTRYSTRUCT = '!iiiibc' #(structlen, dpos, dlen, ulen, flag, typcd) followed by name def __init__(self): self.data = [] def frombinary(self, s): """Decode the binary string into an in memory list. S is a binary string.""" entrylen = struct.calcsize(self.ENTRYSTRUCT) p = 0 while p -1: typcd = 'M' self.toc.add(where, dlen, ulen, flag, typcd, nm) self.lib.write(s) def save_toc(self, tocpos): """Save the table of contents to disk.""" self.tocpos = tocpos tocstr = self.toc.tobinary() self.toclen = len(tocstr) self.lib.write(tocstr) def save_trailer(self, tocpos): """Save the trailer to disk. CArchives can be opened from the end - the trailer points back to the start. """ totallen = tocpos + self.toclen + self.TRLLEN if hasattr(sys, "version_info"): pyvers = sys.version_info[0]*10 + sys.version_info[1] else: toks = split(sys.version, '.', 2) pyvers = int(toks[0])*10 + int(toks[1]) trl = struct.pack(self.TRLSTRUCT, self.MAGIC, totallen, tocpos, self.toclen, pyvers) self.lib.write(trl) def openEmbedded(self, name): """Open a CArchive of name NAME embedded within this CArchive.""" ndx = self.toc.find(name) if ndx == -1: raise KeyError, "Member '%s' not found in %s" % (name, self.path) (dpos, dlen, ulen, flag, typcd, nm) = self.toc.get(ndx) if flag: raise ValueError, "Cannot open compressed archive %s in place" return CArchive(self.path, self.pkgstart+dpos, dlen)