~ubuntu-branches/ubuntu/quantal/gcc-defaults/quantal-proposed

« back to all changes in this revision

Viewing changes to .svn/text-base/classfile.py.svn-base

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2012-09-21 17:35:36 UTC
  • mfrom: (1.1.39 sid)
  • Revision ID: package-import@ubuntu.com-20120921173536-rjpjgfdab0oljrpr
Tags: 1.117ubuntu2
Bump versions to 4.7.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
## Copyright (C) 2004, 2005 Red Hat, Inc.
3
 
## Written by Gary Benson <gbenson@redhat.com>
4
 
##
5
 
## This program is free software; you can redistribute it and/or modify
6
 
## it under the terms of the GNU General Public License as published by
7
 
## the Free Software Foundation; either version 2 of the License, or
8
 
## (at your option) any later version.
9
 
##
10
 
## This program is distributed in the hope that it will be useful,
11
 
## but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
## GNU General Public License for more details.
14
 
 
15
 
"""Read Java(TM) class files."""
16
 
 
17
 
import cStringIO as StringIO
18
 
import struct
19
 
 
20
 
class Class:
21
 
    def __init__(self, arg):
22
 
        if hasattr(arg, "read"):
23
 
            self.fp = arg
24
 
        elif type(arg) == type(""):
25
 
            if arg.startswith("\xca\xfe\xba\xbe"):
26
 
                self.fp = StringIO.StringIO(arg)
27
 
            else:
28
 
                self.fp = open(arg, "r")
29
 
        else:
30
 
            raise TypeError, type(arg)
31
 
 
32
 
        magic = self._read_int()
33
 
        assert magic == 0xcafebabeL
34
 
        minor, major = self._read(">HH")        
35
 
        self.version = (major, minor)
36
 
 
37
 
        self.pool_integrity_checks = None
38
 
        try:
39
 
            assert False
40
 
        except AssertionError:
41
 
            self.pool_integrity_checks = []
42
 
 
43
 
        self._read_constants_pool()
44
 
 
45
 
        self.access_flags = self._read_short()
46
 
        self.name = self._read_reference_Class()
47
 
        self.super = self._read_reference_Class()
48
 
 
49
 
        self.interfaces = self._read_interfaces()
50
 
        self.fields = self._read_fieldsormethods()
51
 
        self.methods = self._read_fieldsormethods()
52
 
        self.attributes = self._read_attributes()
53
 
 
54
 
        if self.pool_integrity_checks is not None:
55
 
            for index, tag in self.pool_integrity_checks:
56
 
                assert self.constants[index][0] == tag
57
 
 
58
 
        del self.fp, self.pool_integrity_checks
59
 
 
60
 
    def __repr__(self):
61
 
        result = []
62
 
        attrs = [attr for attr in dir(self)
63
 
                 if not attr.startswith("_") and attr != "Member"]
64
 
        attrs.sort()
65
 
        for attr in attrs:
66
 
            result.append("%-13s %s" % (
67
 
                attr + ":", attr == "constants" and
68
 
                "<ELIDED>" or repr(getattr(self, attr))))
69
 
        return "\n".join(result)
70
 
 
71
 
    def _read_constants_pool(self):
72
 
        self.constants = {}
73
 
        skip = False
74
 
        for i in xrange(1, self._read_short()):
75
 
            if skip:
76
 
                skip = False
77
 
                continue
78
 
            tag = {
79
 
                1: "Utf8", 3: "Integer", 4: "Float", 5: "Long",
80
 
                6: "Double", 7: "Class", 8: "String", 9: "Fieldref",
81
 
                10: "Methodref", 11: "InterfaceMethodref",
82
 
                12: "NameAndType"}[self._read_byte()]
83
 
            skip = tag in ("Long", "Double") # crack crack crack!
84
 
            self.constants[i] = (tag, getattr(self, "_read_constant_" + tag)())
85
 
 
86
 
    def _read_interfaces(self):
87
 
        result = []
88
 
        for i in xrange(self._read_short()):
89
 
            result.append(self._read_reference_Class())
90
 
        return result
91
 
 
92
 
    def _read_fieldsormethods(self):
93
 
        result = []
94
 
        for i in xrange(self._read_short()):
95
 
            result.append(self.Member(self))
96
 
        return result
97
 
 
98
 
    class Member:
99
 
        def __init__(self, source):
100
 
            self.access_flags = source._read_short()
101
 
            self.name = source._read_reference_Utf8()
102
 
            self.descriptor = source._read_reference_Utf8()
103
 
            self.attributes = source._read_attributes()
104
 
 
105
 
        def __repr__(self):
106
 
            result = []
107
 
            attrs = [attr for attr in dir(self) if not attr.startswith("_")]
108
 
            attrs.sort()
109
 
            for attr in attrs:
110
 
                value = getattr(self, attr)
111
 
                if attr == "attributes" and value.has_key("Code"):
112
 
                    value = value.copy()
113
 
                    value.update({"Code": "<ELIDED>"})
114
 
                result.append("%-13s %s" % (
115
 
                    attr + ":", repr(value).replace(
116
 
                        "'Code': '<ELIDED>'", "'Code': <ELIDED>")))
117
 
            return ("\n%s" % (15 * " ")).join(result)
118
 
 
119
 
    def _read_attributes(self):
120
 
        result = {}
121
 
        for i in xrange(self._read_short()):
122
 
            name = self._read_reference_Utf8()
123
 
            data = self.fp.read(self._read_int())
124
 
            assert not result.has_key(name)
125
 
            result[name] = data
126
 
        return result
127
 
 
128
 
    # Constants pool reference reader convenience functions
129
 
 
130
 
    def _read_reference_Utf8(self):
131
 
        return self._read_references("Utf8")[0]
132
 
 
133
 
    def _read_reference_Class(self):
134
 
        return self._read_references("Class")[0]
135
 
 
136
 
    def _read_reference_Class_NameAndType(self):
137
 
        return self._read_references("Class", "NameAndType")
138
 
 
139
 
    def _read_references(self, *args):
140
 
        result = []
141
 
        for arg in args:
142
 
            index = self._read_short()
143
 
            if self.pool_integrity_checks is not None:
144
 
                self.pool_integrity_checks.append((index, arg))
145
 
            result.append(index)
146
 
        return result
147
 
 
148
 
    # Constants pool constant reader functions
149
 
 
150
 
    def _read_constant_Utf8(self):
151
 
        constant = self.fp.read(self._read_short())
152
 
        try:
153
 
            constant = constant.decode("utf-8")
154
 
        except UnicodeError:
155
 
            constant = _bork_utf8_decode(constant)
156
 
        try:
157
 
            constant = constant.encode("us-ascii")
158
 
        except UnicodeError:
159
 
            pass
160
 
        return constant
161
 
 
162
 
    def _read_constant_Integer(self):
163
 
        return self._read_int()
164
 
 
165
 
    def _read_constant_Float(self):
166
 
        return self._read(">f")[0]
167
 
 
168
 
    def _read_constant_Long(self):
169
 
        return self._read(">q")[0]
170
 
 
171
 
    def _read_constant_Double(self):
172
 
        return self._read(">d")[0]
173
 
 
174
 
    _read_constant_Class = _read_reference_Utf8
175
 
    _read_constant_String = _read_reference_Utf8
176
 
    _read_constant_Fieldref = _read_reference_Class_NameAndType
177
 
    _read_constant_Methodref = _read_reference_Class_NameAndType
178
 
    _read_constant_InterfaceMethodref = _read_reference_Class_NameAndType
179
 
 
180
 
    def _read_constant_NameAndType(self):
181
 
        return self._read_reference_Utf8(), self._read_reference_Utf8()
182
 
 
183
 
    # Generic reader functions
184
 
 
185
 
    def _read_int(self):
186
 
        # XXX how else to read 32 bits on a 64-bit box?
187
 
        h, l = map(long, self._read(">HH"))
188
 
        return (h << 16) + l
189
 
 
190
 
    def _read_short(self):
191
 
        return self._read(">H")[0]
192
 
 
193
 
    def _read_byte(self):
194
 
        return self._read("B")[0]
195
 
 
196
 
    def _read(self, fmt):
197
 
        return struct.unpack(fmt, self.fp.read(struct.calcsize(fmt)))
198
 
 
199
 
def _bork_utf8_decode(data):
200
 
    # more crack!
201
 
    bytes, unicode = map(ord, data), ""
202
 
    while bytes:
203
 
        b1 = bytes.pop(0)
204
 
        if b1 & 0x80:
205
 
            assert b1 & 0x40
206
 
            b2 = bytes.pop(0)
207
 
            assert b2 & 0xC0 == 0x80
208
 
            if b1 & 0x20:
209
 
                assert not b1 & 0x10
210
 
                b3 = bytes.pop(0)
211
 
                assert b3 & 0xC0 == 0x80
212
 
                unicode += unichr(
213
 
                    ((b1 & 0x0f) << 12) + ((b2 & 0x3f) << 6) + (b3 & 0x3f))
214
 
            else:
215
 
                unicode += unichr(((b1 & 0x1f) << 6) + (b2 & 0x3f))
216
 
        else:
217
 
            unicode += unichr(b1)
218
 
    return unicode
219
 
 
220
 
if __name__ == "__main__":
221
 
    print Class("/usr/share/katana/build/ListDependentClasses.class")
222