Back to index

enigmail  1.4.3
Public Member Functions | Static Public Member Functions | Public Attributes | Private Member Functions | Static Private Attributes
xpt.Typelib Class Reference

List of all members.

Public Member Functions

def __init__
def __repr__
def writefd
def write
def merge
def dump

Static Public Member Functions

def iid_to_string
def string_to_iid
def read_string
def read

Public Attributes

 version
 interfaces
 annotations
 filename

Private Member Functions

def _sanityCheck

Static Private Attributes

tuple _header = struct.Struct(">16sBBHIII")

Detailed Description

A typelib represents one entire typelib file and all the interfaces
referenced within, whether defined entirely within the typelib or
merely referenced by name or IID.

Typelib objects may be instantiated directly and populated with data,
or the static Typelib.read method may be called to read one from a file.

Definition at line 1000 of file xpt.py.


Constructor & Destructor Documentation

def xpt.Typelib.__init__ (   self,
  version = TYPELIB_VERSION,
  interfaces = [],
  annotations = [] 
)
Instantiate a new Typelib.

Definition at line 1012 of file xpt.py.

01012 
01013     def __init__(self, version=TYPELIB_VERSION, interfaces=[], annotations=[]):
01014         """
01015         Instantiate a new Typelib.
01016 
01017         """
01018         self.version = version
01019         self.interfaces = list(interfaces)
01020         self.annotations = list(annotations)
01021         self.filename = None


Member Function Documentation

def xpt.Typelib.__repr__ (   self)

Definition at line 1105 of file xpt.py.

01105 
01106     def __repr__(self):
01107         return "<Typelib with %d interfaces>" % len(self.interfaces)

def xpt.Typelib._sanityCheck (   self) [private]
Check certain assumptions about data contained in this typelib.
Sort the interfaces array by IID, check that all interfaces
referenced by methods exist in the array.

Definition at line 1108 of file xpt.py.

01108 
01109     def _sanityCheck(self):
01110         """
01111         Check certain assumptions about data contained in this typelib.
01112         Sort the interfaces array by IID, check that all interfaces
01113         referenced by methods exist in the array.
01114 
01115         """
01116         self.interfaces.sort()
01117         for i in self.interfaces:
01118             if i.parent and i.parent not in self.interfaces:
01119                 raise DataError, "Interface %s has parent %s not present in typelib!" % (i.name, i.parent.name)
01120             for m in i.methods:
01121                 for n, p in enumerate(m.params):
01122                     if isinstance(p, InterfaceType) and \
01123                         p.iface not in self.interfaces:
01124                         raise DataError, "Interface method %s::%s, parameter %d references interface %s not present in typelib!" % (i.name, m.name, n, p.iface.name)
01125                 if isinstance(m.result, InterfaceType) and m.result.iface not in self.interfaces:
01126                     raise DataError, "Interface method %s::%s, result references interface %s not present in typelib!" % (i.name, m.name, m.result.iface.name)

Here is the call graph for this function:

Here is the caller graph for this function:

def xpt.Typelib.dump (   self,
  out 
)
Print a human-readable listing of the contents of this typelib
to |out|, in the format of xpt_dump.

Definition at line 1260 of file xpt.py.

01260 
01261     def dump(self, out):
01262         """
01263         Print a human-readable listing of the contents of this typelib
01264         to |out|, in the format of xpt_dump.
01265         
01266         """
01267         out.write("""Header:
01268    Major version:         %d
01269    Minor version:         %d
01270    Number of interfaces:  %d
01271    Annotations:\n""" % (self.version[0], self.version[1], len(self.interfaces)))
01272         for i, a in enumerate(self.annotations):
01273             if a is None:
01274                 out.write("      Annotation #%d is empty.\n" % i)
01275         out.write("\nInterface Directory:\n")
01276         for i in self.interfaces:
01277             out.write("   - %s::%s (%s):\n" % (i.namespace, i.name, i.iid))
01278             if not i.resolved:
01279                 out.write("      [Unresolved]\n")
01280             else:
01281                 if i.parent:
01282                     out.write("      Parent: %s::%s\n" % (i.parent.namespace,
01283                                                     i.parent.name))
01284                 out.write("""      Flags:
01285          Scriptable: %s
01286          BuiltinClass: %s
01287          Function: %s\n""" % (i.scriptable and "TRUE" or "FALSE",
01288                               i.builtinclass and "TRUE" or "FALSE",
01289                               i.function and "TRUE" or "FALSE"))
01290                 out.write("      Methods:\n")
01291                 if len(i.methods) == 0:
01292                     out.write("         No Methods\n")
01293                 else:
01294                     for m in i.methods:
01295                         out.write("   %s%s%s%s%s%s%s %s %s(%s);\n" % (
01296                             m.getter and "G" or " ",
01297                             m.setter and "S" or " ",
01298                             m.hidden and "H" or " ",
01299                             m.notxpcom and "N" or " ",
01300                             m.constructor and "C" or " ",
01301                             m.optargc and "O" or " ",
01302                             m.implicit_jscontext and "J" or " ",
01303                             str(m.result.type),
01304                             m.name,
01305                             m.params and ", ".join(str(p) for p in m.params) or ""
01306                             ))
01307                 out.write("      Constants:\n")
01308                 if len(i.constants) == 0:
01309                     out.write("         No Constants\n")
01310                 else:
01311                     for c in i.constants:
01312                         out.write("         %s %s = %d;\n" % (c.type, c.name, c.value))

Here is the call graph for this function:

def xpt.Typelib.iid_to_string (   iid) [static]
Convert a 16-byte IID into a UUID string.

Definition at line 1023 of file xpt.py.

01023 
01024     def iid_to_string(iid):
01025         """
01026         Convert a 16-byte IID into a UUID string.
01027 
01028         """
01029         def hexify(s):
01030             return ''.join(["%02x" % ord(x) for x in s])
01031 
01032         return "%s-%s-%s-%s-%s" % (hexify(iid[:4]), hexify(iid[4:6]),
01033                                    hexify(iid[6:8]), hexify(iid[8:10]),
01034                                    hexify(iid[10:]))

Here is the caller graph for this function:

def xpt.Typelib.merge (   self,
  other,
  sanitycheck = True 
)
Merge the contents of Typelib |other| into this typelib.
If |sanitycheck| is False, don't sort the interface table
after merging.

Definition at line 1172 of file xpt.py.

01172 
01173     def merge(self, other, sanitycheck=True):
01174         """
01175         Merge the contents of Typelib |other| into this typelib.
01176         If |sanitycheck| is False, don't sort the interface table
01177         after merging.
01178 
01179         """
01180         # This will be a list of (replaced interface, replaced with)
01181         # containing interfaces that were replaced with interfaces from
01182         # another typelib, and the interface that replaced them.
01183         merged_interfaces = []
01184         for i in other.interfaces:
01185             if i in self.interfaces:
01186                 continue
01187             # See if there's a copy of this interface with different
01188             # resolved status or IID value.
01189             merged = False
01190             for j in self.interfaces:
01191                 if i.name == j.name:
01192                     if i.resolved != j.resolved:
01193                         # prefer resolved interfaces over unresolved
01194                         if j.resolved:
01195                             # keep j
01196                             merged_interfaces.append((i, j))
01197                             merged = True
01198                             # Fixup will happen after processing all interfaces.
01199                         else:
01200                             # replace j with i
01201                             merged_interfaces.append((j, i))
01202                             merged = True
01203                             self.interfaces[self.interfaces.index(j)] = i
01204                     elif i.iid != j.iid:
01205                         # Prefer unresolved interfaces with valid IIDs
01206                         if j.iid == Interface.UNRESOLVED_IID:
01207                             # replace j with i
01208                             merged_interfaces.append((j, i))
01209                             merged = True
01210                             self.interfaces[self.interfaces.index(j)] = i
01211                         elif i.iid == Interface.UNRESOLVED_IID:
01212                             # keep j
01213                             merged_interfaces.append((i, j))
01214                             merged = True
01215                             # Fixup will happen after processing all interfaces.
01216                         else:
01217                             # Same name but different IIDs: raise an exception.
01218                             # self.* is the (target) Typelib being merged into,
01219                             #   not the one which j.iid was from.
01220                             raise DataError, \
01221                                   "Typelibs contain definitions of interface %s" \
01222                                     " with different IIDs (%s (%s) vs %s (%s))!" % \
01223                                     (i.name, i.iid, i.xpt_filename or other.filename, \
01224                                              j.iid, j.xpt_filename or self.filename)
01225                 elif i.iid == j.iid and i.iid != Interface.UNRESOLVED_IID:
01226                     # Same IID but different names: raise an exception.
01227                     # self.* is the (target) Typelib being merged into,
01228                     #   not the one which j.name was from.
01229                     raise DataError, \
01230                           "Typelibs contain definitions of interface %s" \
01231                             " with different names (%s (%s) vs %s (%s))!" % \
01232                             (i.iid, i.name, i.xpt_filename or other.filename, \
01233                                     j.name, j.xpt_filename or self.filename)
01234             if not merged:
01235                 # No partially matching interfaces, so just take this interface
01236                 self.interfaces.append(i)
01237 
01238         # Now fixup any merged interfaces
01239         def checkType(t, replaced_from, replaced_to):
01240             if isinstance(t, InterfaceType) and t.iface == replaced_from:
01241                 t.iface = replaced_to
01242             elif isinstance(t, ArrayType) and \
01243                  isinstance(t.element_type, InterfaceType) and \
01244                  t.element_type.iface == replaced_from:
01245                 t.element_type.iface = replaced_to
01246 
01247         for replaced_from, replaced_to in merged_interfaces:
01248             for i in self.interfaces:
01249                 # Replace parent references
01250                 if i.parent is not None and i.parent == replaced_from:
01251                     i.parent = replaced_to
01252                 for m in i.methods:
01253                     # Replace InterfaceType params and return values
01254                     checkType(m.result.type, replaced_from, replaced_to)
01255                     for p in m.params:
01256                         checkType(p.type, replaced_from, replaced_to)
01257         if sanitycheck:
01258             self._sanityCheck()
01259         #TODO: do we care about annotations? probably not

Here is the call graph for this function:

def xpt.Typelib.read (   filename) [static]
Read a typelib from the file named |filename| and return
the constructed Typelib object.

Definition at line 1054 of file xpt.py.

01054 
01055     def read(filename):
01056         """
01057         Read a typelib from the file named |filename| and return
01058         the constructed Typelib object.
01059 
01060         """
01061         with open(filename, "r+b") as f:
01062             st = os.fstat(f.fileno())
01063             map = f.read(st.st_size)
01064             data = Typelib._header.unpack(map[:Typelib._header.size])
01065             if data[0] != XPT_MAGIC:
01066                 raise FileFormatError, "Bad magic: %s" % data[0]
01067             xpt = Typelib((data[1], data[2]))
01068             xpt.filename = filename
01069             num_interfaces = data[3]
01070             file_length = data[4]
01071             if file_length != st.st_size:
01072                 raise FileFormatError, "File is of wrong length, got %d bytes, expected %d" % (st.st_size, file_length)
01073             #XXX: by spec this is a zero-based file offset. however,
01074             # the xpt_xdr code always subtracts 1 from data offsets
01075             # (because that's what you do in the data pool) so it
01076             # winds up accidentally treating this as 1-based.
01077             # Filed as: https://bugzilla.mozilla.org/show_bug.cgi?id=575343
01078             interface_directory_offset = data[5] - 1
01079             data_pool_offset = data[6]
01080             # make a half-hearted attempt to read Annotations,
01081             # since XPIDL doesn't produce any anyway.
01082             start = Typelib._header.size
01083             (anno, ) = struct.unpack(">B", map[start:start + struct.calcsize(">B")])
01084             islast = anno & 0x80
01085             tag = anno & 0x7F
01086             if tag == 0: # EmptyAnnotation
01087                 xpt.annotations.append(None)
01088             # We don't bother handling PrivateAnnotations or anything
01089             
01090             for i in range(num_interfaces):
01091                 # iid, name, namespace, interface_descriptor
01092                 start = interface_directory_offset + i * Interface._direntry.size
01093                 end = interface_directory_offset + (i+1) * Interface._direntry.size
01094                 ide = Interface._direntry.unpack(map[start:end])
01095                 iid = Typelib.iid_to_string(ide[0])
01096                 name = Typelib.read_string(map, data_pool_offset, ide[1])
01097                 namespace = Typelib.read_string(map, data_pool_offset, ide[2])
01098                 iface = Interface(name, iid, namespace)
01099                 iface._descriptor_offset = ide[3]
01100                 iface.xpt_filename = xpt.filename
01101                 xpt.interfaces.append(iface)
01102             for iface in xpt.interfaces:
01103                 iface.read_descriptor(xpt, map, data_pool_offset)
01104         return xpt

Here is the caller graph for this function:

def xpt.Typelib.read_string (   map,
  data_pool,
  offset 
) [static]

Definition at line 1045 of file xpt.py.

01045 
01046     def read_string(map, data_pool, offset):
01047         if offset == 0:
01048             return ""
01049         sz = map.find('\x00', data_pool + offset - 1)
01050         if sz == -1:
01051             return ""
01052         return map[data_pool + offset - 1:sz]

def xpt.Typelib.string_to_iid (   iid_str) [static]
Convert a UUID string into a 16-byte IID.

Definition at line 1036 of file xpt.py.

01036 
01037     def string_to_iid(iid_str):
01038         """
01039         Convert a UUID string into a 16-byte IID.
01040 
01041         """
01042         s = iid_str.replace('-','')
01043         return ''.join([chr(int(s[i:i+2], 16)) for i in range(0, len(s), 2)])

Here is the caller graph for this function:

def xpt.Typelib.write (   self,
  filename 
)
Write the contents of this typelib to the file named |filename|.

Definition at line 1163 of file xpt.py.

01163 
01164     def write(self, filename):
01165         """
01166         Write the contents of this typelib to the file named |filename|.
01167 
01168         """
01169         self._sanityCheck()
01170         with open(filename, "wb") as f:
01171             self.writefd(f)

Here is the call graph for this function:

def xpt.Typelib.writefd (   self,
  fd 
)

Definition at line 1127 of file xpt.py.

01127 
01128     def writefd(self, fd):
01129         # write out space for a header + one empty annotation,
01130         # padded to 4-byte alignment.
01131         headersize = (Typelib._header.size + 1)
01132         if headersize % 4:
01133             headersize += 4 - headersize % 4
01134         fd.write("\x00" * headersize)
01135         # save this offset, it's the interface directory offset.
01136         interface_directory_offset = fd.tell()
01137         # write out space for an interface directory
01138         fd.write("\x00" * Interface._direntry.size * len(self.interfaces))
01139         # save this offset, it's the data pool offset.
01140         data_pool_offset = fd.tell()
01141         # write out all the interface descriptors to the data pool
01142         for i in self.interfaces:
01143             i.write_names(fd, data_pool_offset)
01144             i.write(self, fd, data_pool_offset)
01145         # now, seek back and write the header
01146         file_len = fd.tell()
01147         fd.seek(0)
01148         fd.write(Typelib._header.pack(XPT_MAGIC,
01149                                       TYPELIB_VERSION[0],
01150                                       TYPELIB_VERSION[1],
01151                                       len(self.interfaces),
01152                                       file_len,
01153                                       interface_directory_offset,
01154                                       data_pool_offset))
01155         # write an empty annotation
01156         fd.write(struct.pack(">B", 0x80))
01157         # now write the interface directory
01158         #XXX: bug-compatible with existing xpt lib, put it one byte
01159         # ahead of where it's supposed to be.
01160         fd.seek(interface_directory_offset - 1)
01161         for i in self.interfaces:
01162             i.write_directory_entry(fd)

Here is the caller graph for this function:


Member Data Documentation

tuple xpt.Typelib._header = struct.Struct(">16sBBHIII") [static, private]

Definition at line 1010 of file xpt.py.

Definition at line 1019 of file xpt.py.

Definition at line 1020 of file xpt.py.

Definition at line 1018 of file xpt.py.

Definition at line 1017 of file xpt.py.


The documentation for this class was generated from the following file: