1.1 --- a/classfile.py Sat Oct 23 21:31:59 2004 +0200
1.2 +++ b/classfile.py Sat Oct 23 21:34:47 2004 +0200
1.3 @@ -7,17 +7,29 @@
1.4
1.5 import struct
1.6
1.7 +# Utility functions.
1.8 +
1.9 +def u1(data):
1.10 + return struct.unpack(">B", data[0:1])[0]
1.11 +
1.12 +def u2(data):
1.13 + return struct.unpack(">H", data[0:2])[0]
1.14 +
1.15 +def u4(data):
1.16 + return struct.unpack(">L", data[0:4])[0]
1.17 +
1.18 # Constant information.
1.19 +# Objects of these classes are not directly aware of the class they reside in.
1.20
1.21 class ClassInfo:
1.22 def init(self, data):
1.23 - self.name_index = struct.unpack(">H", data[0:2])[0]
1.24 + self.name_index = u2(data[0:2])
1.25 return data[2:]
1.26
1.27 class RefInfo:
1.28 def init(self, data):
1.29 - self.class_index = struct.unpack(">H", data[0:2])[0]
1.30 - self.name_and_type_index = struct.unpack(">H", data[2:4])[0]
1.31 + self.class_index = u2(data[0:2])
1.32 + self.name_and_type_index = u2(data[2:4])
1.33 return data[4:]
1.34
1.35 class FieldRefInfo(RefInfo):
1.36 @@ -31,13 +43,13 @@
1.37
1.38 class NameAndTypeInfo:
1.39 def init(self, data):
1.40 - self.name_index = struct.unpack(">H", data[0:2])[0]
1.41 - self.descriptor_index = struct.unpack(">H", data[2:4])[0]
1.42 + self.name_index = u2(data[0:2])
1.43 + self.descriptor_index = u2(data[2:4])
1.44 return data[4:]
1.45
1.46 class Utf8Info:
1.47 def init(self, data):
1.48 - self.length = struct.unpack(">H", data[0:2])[0]
1.49 + self.length = u2(data[0:2])
1.50 self.bytes = data[2:2+self.length]
1.51 return data[2+self.length:]
1.52
1.53 @@ -49,12 +61,12 @@
1.54
1.55 class StringInfo:
1.56 def init(self, data):
1.57 - self.string_index = struct.unpack(">H", data[0:2])[0]
1.58 + self.string_index = u2(data[0:2])
1.59 return data[2:]
1.60
1.61 class SmallNumInfo:
1.62 def init(self, data):
1.63 - self.bytes = struct.unpack(">L", data[0:4])[0]
1.64 + self.bytes = u4(data[0:4])
1.65 return data[4:]
1.66
1.67 class IntegerInfo(SmallNumInfo):
1.68 @@ -65,8 +77,8 @@
1.69
1.70 class LargeNumInfo:
1.71 def init(self, data):
1.72 - self.high_bytes = struct.unpack(">L", data[0:4])[0]
1.73 - self.low_bytes = struct.unpack(">L", data[4:8])[0]
1.74 + self.high_bytes = u4(data[0:4])
1.75 + self.low_bytes = u4(data[4:8])
1.76 return data[8:]
1.77
1.78 class LongInfo(LargeNumInfo):
1.79 @@ -76,13 +88,14 @@
1.80 pass
1.81
1.82 # Other information.
1.83 +# Objects of these classes are generally aware of the class they reside in.
1.84
1.85 class ItemInfo:
1.86 def init(self, data, class_file):
1.87 self.class_file = class_file
1.88 - self.access_flags = struct.unpack(">H", data[0:2])[0]
1.89 - self.name_index = struct.unpack(">H", data[2:4])[0]
1.90 - self.descriptor_index = struct.unpack(">H", data[4:6])[0]
1.91 + self.access_flags = u2(data[0:2])
1.92 + self.name_index = u2(data[2:4])
1.93 + self.descriptor_index = u2(data[4:6])
1.94 self.attributes, data = self.class_file._get_attributes(data[6:])
1.95 return data
1.96
1.97 @@ -155,7 +168,7 @@
1.98
1.99 class AttributeInfo:
1.100 def init(self, data, class_file):
1.101 - self.attribute_length = struct.unpack(">L", data[0:4])[0]
1.102 + self.attribute_length = u4(data[0:4])
1.103 self.info = data[4:4+self.attribute_length]
1.104 return data[4+self.attribute_length:]
1.105
1.106 @@ -166,21 +179,21 @@
1.107
1.108 class ConstantValueAttributeInfo(AttributeInfo):
1.109 def init(self, data, class_file):
1.110 - self.attribute_length = struct.unpack(">L", data[0:4])[0]
1.111 - self.constant_value_index = struct.unpack(">H", data[4:6])[0]
1.112 + self.attribute_length = u4(data[0:4])
1.113 + self.constant_value_index = u2(data[4:6])
1.114 assert 4+self.attribute_length == 6
1.115 return data[4+self.attribute_length:]
1.116
1.117 class CodeAttributeInfo(AttributeInfo):
1.118 def init(self, data, class_file):
1.119 self.class_file = class_file
1.120 - self.attribute_length = struct.unpack(">L", data[0:4])[0]
1.121 - self.max_stack = struct.unpack(">H", data[4:6])[0]
1.122 - self.max_locals = struct.unpack(">H", data[6:8])[0]
1.123 - self.code_length = struct.unpack(">L", data[8:12])[0]
1.124 + self.attribute_length = u4(data[0:4])
1.125 + self.max_stack = u2(data[4:6])
1.126 + self.max_locals = u2(data[6:8])
1.127 + self.code_length = u4(data[8:12])
1.128 end_of_code = 12+self.code_length
1.129 self.code = data[12:end_of_code]
1.130 - self.exception_table_length = struct.unpack(">H", data[end_of_code:end_of_code+2])[0]
1.131 + self.exception_table_length = u2(data[end_of_code:end_of_code+2])
1.132 self.exception_table = []
1.133 data = data[end_of_code + 2:]
1.134 for i in range(0, self.exception_table_length):
1.135 @@ -190,7 +203,20 @@
1.136 return data
1.137
1.138 class ExceptionsAttributeInfo(AttributeInfo):
1.139 - pass
1.140 + def init(self, data, class_file):
1.141 + self.class_file = class_file
1.142 + self.attribute_length = u4(data[0:4])
1.143 + self.number_of_exceptions = u2(data[4:6])
1.144 + self.exception_index_table = []
1.145 + index = 6
1.146 + for i in range(0, self.number_of_exceptions):
1.147 + self.exception_index_table.append(u2(data[index:index+2]))
1.148 + index += 2
1.149 + return data[index:]
1.150 +
1.151 + def get_exception(self, i):
1.152 + exception_index = self.exception_index_table[i]
1.153 + return self.class_file.constants[exception_index - 1]
1.154
1.155 class InnerClassesAttributeInfo(AttributeInfo):
1.156 pass
1.157 @@ -212,10 +238,10 @@
1.158 self.start_pc, self.end_pc, self.handler_pc, self.catch_type = None, None, None, None
1.159
1.160 def init(self, data):
1.161 - self.start_pc = struct.unpack(">H", data[0:2])[0]
1.162 - self.end_pc = struct.unpack(">H", data[2:4])[0]
1.163 - self.handler_pc = struct.unpack(">H", data[4:6])[0]
1.164 - self.catch_type = struct.unpack(">H", data[6:8])[0]
1.165 + self.start_pc = u2(data[0:2])
1.166 + self.end_pc = u2(data[2:4])
1.167 + self.handler_pc = u2(data[4:6])
1.168 + self.catch_type = u2(data[6:8])
1.169 return data[8:]
1.170
1.171 class UnknownTag(Exception):
1.172 @@ -247,7 +273,7 @@
1.173 self.attributes, s = self._get_attributes(s)
1.174
1.175 def _decode_const(self, s):
1.176 - tag = struct.unpack(">B", s[0:1])[0]
1.177 + tag = u1(s[0:1])
1.178 if tag == 1:
1.179 const = Utf8Info()
1.180 elif tag == 3:
1.181 @@ -304,7 +330,7 @@
1.182 return self._get_items_from_table(FieldInfo, number, s)
1.183
1.184 def _get_attribute_from_table(self, s):
1.185 - attribute_name_index = struct.unpack(">H", s[0:2])[0]
1.186 + attribute_name_index = u2(s[0:2])
1.187 constant_name = self.constants[attribute_name_index - 1].bytes
1.188 if constant_name == "SourceFile":
1.189 attribute = SourceFileAttributeInfo()
1.190 @@ -337,38 +363,38 @@
1.191 return attributes, s
1.192
1.193 def _get_constants(self, s):
1.194 - count = struct.unpack(">H", s[0:2])[0]
1.195 + count = u2(s[0:2])
1.196 return self._get_constants_from_table(count, s[2:])
1.197
1.198 def _get_access_flags(self, s):
1.199 - return struct.unpack(">H", s[0:2])[0], s[2:]
1.200 + return u2(s[0:2]), s[2:]
1.201
1.202 def _get_this_class(self, s):
1.203 - index = struct.unpack(">H", s[0:2])[0]
1.204 + index = u2(s[0:2])
1.205 return self.constants[index - 1], s[2:]
1.206
1.207 _get_super_class = _get_this_class
1.208
1.209 def _get_interfaces(self, s):
1.210 interfaces = []
1.211 - number = struct.unpack(">H", s[0:2])[0]
1.212 + number = u2(s[0:2])
1.213 s = s[2:]
1.214 for i in range(0, number):
1.215 - index = struct.unpack(">H", s[0:2])[0]
1.216 + index = u2(s[0:2])
1.217 interfaces.append(self.constants[index - 1])
1.218 s = s[2:]
1.219 return interfaces, s
1.220
1.221 def _get_fields(self, s):
1.222 - number = struct.unpack(">H", s[0:2])[0]
1.223 + number = u2(s[0:2])
1.224 return self._get_fields_from_table(number, s[2:])
1.225
1.226 def _get_attributes(self, s):
1.227 - number = struct.unpack(">H", s[0:2])[0]
1.228 + number = u2(s[0:2])
1.229 return self._get_attributes_from_table(number, s[2:])
1.230
1.231 def _get_methods(self, s):
1.232 - number = struct.unpack(">H", s[0:2])[0]
1.233 + number = u2(s[0:2])
1.234 return self._get_methods_from_table(number, s[2:])
1.235
1.236 if __name__ == "__main__":