1.1 --- a/javaclass/classfile.py Thu Mar 24 01:00:49 2011 +0100
1.2 +++ b/javaclass/classfile.py Sun Sep 18 20:25:18 2011 +0100
1.3 @@ -6,6 +6,7 @@
1.4
1.5 Copyright (C) 2004, 2005, 2006, 2011 Paul Boddie <paul@boddie.org.uk>
1.6 Copyright (C) 2010 Braden Thomas <bradenthomas@me.com>
1.7 +Copyright (C) 2011 David Drysdale <dmd@lurklurk.org>
1.8
1.9 This program is free software; you can redistribute it and/or modify it under
1.10 the terms of the GNU Lesser General Public License as published by the Free
1.11 @@ -537,9 +538,415 @@
1.12 od += lv.serialize()
1.13 return od
1.14
1.15 +class LocalVariableTypeAttributeInfo(AttributeInfo):
1.16 + def init(self, data, class_file):
1.17 + self.class_file = class_file
1.18 + self.attribute_length = u4(data[0:4])
1.19 + local_variable_type_table_length = u2(data[4:6])
1.20 + data = data[6:]
1.21 + self.local_variable_type_table = []
1.22 + for i in range(0, local_variable_type_table_length):
1.23 + local_variable = LocalVariableInfo()
1.24 + data = local_variable.init(data, self.class_file)
1.25 + self.local_variable_type_table.append(local_variable)
1.26 + return data
1.27 +
1.28 + def serialize(self):
1.29 + od = su4(self.attribute_length)+su2(len(self.local_variable_type_table))
1.30 + od += "".join([lv.serialize() for lv in self.local_variable_type_table])
1.31 + return od
1.32 +
1.33 class DeprecatedAttributeInfo(AttributeInfo):
1.34 pass
1.35
1.36 +class VerificationTypeInfo(object):
1.37 + def __init__(self, tag):
1.38 + self.tag = tag
1.39 + def init(self, data, class_file):
1.40 + self.class_file = class_file
1.41 + tag = u1(data[0:1])
1.42 + assert(tag == self.tag)
1.43 + return data[1:]
1.44 + def serialize(self):
1.45 + return su1(self.tag)
1.46 +class TopVariableInfo(VerificationTypeInfo):
1.47 + TAG = 0
1.48 +class IntegerVariableInfo(VerificationTypeInfo):
1.49 + TAG = 1
1.50 +class FloatVariableInfo(VerificationTypeInfo):
1.51 + TAG = 2
1.52 +class DoubleVariableInfo(VerificationTypeInfo):
1.53 + TAG = 3
1.54 +class LongVariableInfo(VerificationTypeInfo):
1.55 + TAG = 4
1.56 +class NullVariableInfo(VerificationTypeInfo):
1.57 + TAG = 5
1.58 +class UninitializedThisVariableInfo(VerificationTypeInfo):
1.59 + TAG = 6
1.60 +class ObjectVariableInfo(VerificationTypeInfo):
1.61 + TAG = 7
1.62 + def init(self, data, class_file):
1.63 + data = super(ObjectVariableInfo, self).init(data, class_file)
1.64 + self.cpool_index = u2(data)
1.65 + return data[2:]
1.66 + def serialize(self):
1.67 + return super(ObjectVariableInfo, self).serialize() + su2(self.cpool_index)
1.68 +class UninitializedVariableInfo(VerificationTypeInfo):
1.69 + TAG = 8
1.70 + def init(self, data, class_file):
1.71 + data = super(UninitializedVariableInfo, self).init(data, class_file)
1.72 + self.offset = u2(data)
1.73 + return data[2:]
1.74 + def serialize(self):
1.75 + return super(UninitializedVariableInfo, self).serialize() + su2(self.offset)
1.76 +
1.77 +VARIABLE_INFO_CLASSES = (TopVariableInfo, IntegerVariableInfo, FloatVariableInfo, DoubleVariableInfo,
1.78 + LongVariableInfo, NullVariableInfo, UninitializedThisVariableInfo,
1.79 + ObjectVariableInfo, UninitializedVariableInfo)
1.80 +VARIABLE_INFO_TAG_MAP = dict([(cls.TAG, cls) for cls in VARIABLE_INFO_CLASSES])
1.81 +
1.82 +# Exception
1.83 +class UnknownVariableInfo:
1.84 + def __init__(self, tag):
1.85 + self.tag = tag
1.86 + def __str__(self):
1.87 + return repr(self.tag)
1.88 +
1.89 +def create_verification_type_info(data):
1.90 + # Does not consume data, just does lookahead
1.91 + tag = u1(data[0:1])
1.92 + if tag in VARIABLE_INFO_TAG_MAP:
1.93 + return VARIABLE_INFO_TAG_MAP[tag](tag)
1.94 + else:
1.95 + raise UnknownVariableInfo, tag
1.96 +
1.97 +
1.98 +class StackMapFrame(object):
1.99 + def __init__(self, frame_type):
1.100 + self.frame_type = frame_type
1.101 + def init(self, data, class_file):
1.102 + self.class_file = class_file
1.103 + frame_type = u1(data[0:1])
1.104 + assert(frame_type == self.frame_type)
1.105 + return data[1:]
1.106 + def serialize(self):
1.107 + return su1(self.frame_type)
1.108 +class SameFrame(StackMapFrame):
1.109 + TYPE_LOWER = 0
1.110 + TYPE_UPPER = 63
1.111 +class SameLocals1StackItemFrame(StackMapFrame):
1.112 + TYPE_LOWER = 64
1.113 + TYPE_UPPER = 127
1.114 + def init(self, data, class_file):
1.115 + data = super(SameLocals1StackItemFrame, self).init(data, class_file)
1.116 + self.offset_delta = self.frame_type - 64
1.117 + self.stack = [create_verification_type_info(data)]
1.118 + return self.stack[0].init(data, class_file)
1.119 + def serialize(self):
1.120 + return super(SameLocals1StackItemFrame, self).serialize()+self.stack[0].serialize()
1.121 +class SameLocals1StackItemFrameExtended(StackMapFrame):
1.122 + TYPE_LOWER = 247
1.123 + TYPE_UPPER = 247
1.124 + def init(self, data, class_file):
1.125 + data = super(SameLocals1StackItemFrameExtended, self).init(data, class_file)
1.126 + self.offset_delta = u2(data[0:2])
1.127 + data = data[2:]
1.128 + self.stack = [create_verification_type_info(data)]
1.129 + return self.stack[0].init(data, class_file)
1.130 + def serialize(self):
1.131 + return super(SameLocals1StackItemFrameExtended, self).serialize()+su2(self.offset_delta)+self.stack[0].serialize()
1.132 +class ChopFrame(StackMapFrame):
1.133 + TYPE_LOWER = 248
1.134 + TYPE_UPPER = 250
1.135 + def init(self, data, class_file):
1.136 + data = super(ChopFrame, self).init(data, class_file)
1.137 + self.offset_delta = u2(data[0:2])
1.138 + return data[2:]
1.139 + def serialize(self):
1.140 + return super(ChopFrame, self).serialize()+su2(self.offset_delta)
1.141 +class SameFrameExtended(StackMapFrame):
1.142 + TYPE_LOWER = 251
1.143 + TYPE_UPPER = 251
1.144 + def init(self, data, class_file):
1.145 + data = super(SameFrameExtended, self).init(data, class_file)
1.146 + self.offset_delta = u2(data[0:2])
1.147 + return data[2:]
1.148 + def serialize(self):
1.149 + return super(SameFrameExtended, self).serialize()+su2(self.offset_delta)
1.150 +class AppendFrame(StackMapFrame):
1.151 + TYPE_LOWER = 252
1.152 + TYPE_UPPER = 254
1.153 + def init(self, data, class_file):
1.154 + data = super(AppendFrame, self).init(data, class_file)
1.155 + self.offset_delta = u2(data[0:2])
1.156 + data = data[2:]
1.157 + num_locals = self.frame_type - 251
1.158 + self.locals = []
1.159 + for ii in xrange(num_locals):
1.160 + info = create_verification_type_info(data)
1.161 + data = info.init(data, class_file)
1.162 + self.locals.append(info)
1.163 + return data
1.164 + def serialize(self):
1.165 + od = super(AppendFrame, self).serialize()+su2(self.offset_delta)
1.166 + od += "".join([l.serialize() for l in self.locals])
1.167 + return od
1.168 +class FullFrame(StackMapFrame):
1.169 + TYPE_LOWER = 255
1.170 + TYPE_UPPER = 255
1.171 + def init(self, data, class_file):
1.172 + data = super(FullFrame, self).init(data, class_file)
1.173 + self.offset_delta = u2(data[0:2])
1.174 + num_locals = u2(data[2:4])
1.175 + data = data[4:]
1.176 + self.locals = []
1.177 + for ii in xrange(num_locals):
1.178 + info = create_verification_type_info(data)
1.179 + data = info.init(data, class_file)
1.180 + self.locals.append(info)
1.181 + num_stack_items = u2(data[0:2])
1.182 + data = data[2:]
1.183 + self.stack = []
1.184 + for ii in xrange(num_stack_items):
1.185 + stack_item = create_verification_type_info(data)
1.186 + data = stack_item.init(data, class_file)
1.187 + self.stack.append(stack_item)
1.188 + return data
1.189 + def serialize(self):
1.190 + od = super(FullFrame, self).serialize()+su2(self.offset_delta)+su2(len(self.locals))
1.191 + od += "".join([l.serialize() for l in self.locals])
1.192 + od += su2(len(self.stack))
1.193 + od += "".join([s.serialize() for s in self.stack])
1.194 + return od
1.195 +
1.196 +FRAME_CLASSES = (SameFrame, SameLocals1StackItemFrame, SameLocals1StackItemFrameExtended,
1.197 + ChopFrame, SameFrameExtended, AppendFrame, FullFrame)
1.198 +
1.199 +# Exception
1.200 +class UnknownStackFrame:
1.201 + def __init__(self, frame_type):
1.202 + self.frame_type = frame_type
1.203 + def __str__(self):
1.204 + return repr(self.frame_type)
1.205 +
1.206 +def create_stack_frame(data):
1.207 + # Does not consume data, just does lookahead
1.208 + frame_type = u1(data[0:1])
1.209 + for cls in FRAME_CLASSES:
1.210 + if frame_type >= cls.TYPE_LOWER and frame_type <= cls.TYPE_UPPER:
1.211 + return cls(frame_type)
1.212 + raise UnknownStackFrame, frame_type
1.213 +
1.214 +class StackMapTableAttributeInfo(AttributeInfo):
1.215 + def init(self, data, class_file):
1.216 + self.class_file = class_file
1.217 + self.attribute_length = u4(data[0:4])
1.218 + num_entries = u2(data[4:6])
1.219 + self.entries = []
1.220 + data = data[6:]
1.221 + for i in range(0, num_entries):
1.222 + frame = create_stack_frame(data)
1.223 + data = frame.init(data, class_file)
1.224 + self.entries.append(frame)
1.225 + return data
1.226 + def serialize(self):
1.227 + od = su4(self.attribute_length)+su2(len(self.entries))
1.228 + od += "".join([e.serialize() for e in self.entries])
1.229 + return od
1.230 +
1.231 +
1.232 +class EnclosingMethodAttributeInfo(AttributeInfo):
1.233 + def init(self, data, class_file):
1.234 + self.class_file = class_file
1.235 + self.attribute_length = u4(data[0:4])
1.236 + self.class_index = u2(data[4:6])
1.237 + self.method_index = u2(data[6:8])
1.238 + return data[8:]
1.239 + def serialize(self):
1.240 + return su4(self.attribute_length)+su2(self.class_index)+su2(self.method_index)
1.241 +
1.242 +
1.243 +class SignatureAttributeInfo(AttributeInfo):
1.244 + def init(self, data, class_file):
1.245 + self.class_file = class_file
1.246 + self.attribute_length = u4(data[0:4])
1.247 + self.signature_index = u2(data[4:6])
1.248 + return data[6:]
1.249 + def serialize(self):
1.250 + return su4(self.attribute_length)+su2(self.signature_index)
1.251 +
1.252 +
1.253 +class SourceDebugExtensionAttributeInfo(AttributeInfo):
1.254 + def init(self, data, class_file):
1.255 + self.class_file = class_file
1.256 + self.attribute_length = u4(data[0:4])
1.257 + self.debug_extension = data[4:(4 + self.attribute_length)]
1.258 + return data[(4+ self.attribute_length):]
1.259 + def serialize(self):
1.260 + return su4(self.attribute_length)+self.debug_extension
1.261 +
1.262 +
1.263 +class ElementValue(object):
1.264 + def __init__(self, tag):
1.265 + self.tag = tag
1.266 + def init(self, data, class_file):
1.267 + self.class_file = class_file
1.268 + tag = chr(u1(data[0:1]))
1.269 + assert(tag == self.tag)
1.270 + return data[1:]
1.271 + def serialize(self):
1.272 + return su1(ord(self.tag))
1.273 +class ConstValue(ElementValue):
1.274 + def init(self, data, class_file):
1.275 + data = super(ConstValue, self).init(data, class_file)
1.276 + self.const_value_index = u2(data[0:2])
1.277 + return data[2:]
1.278 + def serialize(self):
1.279 + return super(ConstValue, self).serialize()+su2(self.const_value_index)
1.280 +class EnumConstValue(ElementValue):
1.281 + def init(self, data, class_file):
1.282 + data = super(EnumConstValue, self).init(data, class_file)
1.283 + self.type_name_index = u2(data[0:2])
1.284 + self.const_name_index = u2(data[2:4])
1.285 + return data[4:]
1.286 + def serialize(self):
1.287 + return super(EnumConstValue, self).serialize()+su2(self.type_name_index)+su2(self.const_name_index)
1.288 +class ClassInfoValue(ElementValue):
1.289 + def init(self, data, class_file):
1.290 + data = super(ClassInfoValue, self).init(data, class_file)
1.291 + self.class_info_index = u2(data[0:2])
1.292 + return data[2:]
1.293 + def serialize(self):
1.294 + return super(ClassInfoValue, self).serialize()+su2(self.class_info_index)
1.295 +class AnnotationValue(ElementValue):
1.296 + def init(self, data, class_file):
1.297 + data = super(AnnotationValue, self).init(data, class_file)
1.298 + self.annotation_value = Annotation()
1.299 + return self.annotation_value.init(data, class_file)
1.300 + def serialize(self):
1.301 + return super(AnnotationValue, self).serialize()+self.annotation_value.serialize()
1.302 +class ArrayValue(ElementValue):
1.303 + def init(self, data, class_file):
1.304 + data = super(ArrayValue, self).init(data, class_file)
1.305 + num_values = u2(data[0:2])
1.306 + data = data[2:]
1.307 + self.values = []
1.308 + for ii in xrange(num_values):
1.309 + element_value = create_element_value(data)
1.310 + data = element_value.init(data, class_file)
1.311 + self.values.append(element_value)
1.312 + return data
1.313 + def serialize(self):
1.314 + od = super(ArrayValue, self).serialize()+su2(len(self.values))
1.315 + od += "".join([v.serialize() for v in self.values])
1.316 + return od
1.317 +# Exception
1.318 +class UnknownElementValue:
1.319 + def __init__(self, tag):
1.320 + self.tag = tag
1.321 + def __str__(self):
1.322 + return repr(self.tag)
1.323 +
1.324 +def create_element_value(data):
1.325 + tag = chr(u1(data[0:1]))
1.326 + if tag in ('B', 'C', 'D', 'F', 'I', 'J', 'S', 'Z', 's'):
1.327 + return ConstValue(tag)
1.328 + elif tag == 'e':
1.329 + return EnumConstValue(tag)
1.330 + elif tag == 'c':
1.331 + return ClassInfoValue(tag)
1.332 + elif tag == '@':
1.333 + return AnnotationValue(tag)
1.334 + elif tag == '[':
1.335 + return ArrayValue(tag)
1.336 + else:
1.337 + raise UnknownElementValue, tag
1.338 +
1.339 +
1.340 +class Annotation(object):
1.341 + def init(self, data, class_file):
1.342 + self.class_file = class_file
1.343 + self.type_index = u2(data[0:2])
1.344 + num_element_value_pairs = u2(data[2:4])
1.345 + data = data[4:]
1.346 + self.element_value_pairs = []
1.347 + for ii in xrange(num_element_value_pairs):
1.348 + element_name_index = u2(data[0:2])
1.349 + data = data[2:]
1.350 + element_value = create_element_value(data)
1.351 + data = element_value.init(data, class_file)
1.352 + self.element_value_pairs.append((element_name_index, element_value))
1.353 + return data
1.354 + def serialize(self):
1.355 + od = su2(self.type_index)+su2(len(self.element_value_pairs))
1.356 + od += "".join([su2(evp[0])+evp[1].serialize() for evp in self.element_value_pairs])
1.357 + return od
1.358 +
1.359 +
1.360 +class RuntimeAnnotationsAttributeInfo(AttributeInfo):
1.361 + def init(self, data, class_file):
1.362 + self.class_file = class_file
1.363 + self.attribute_length = u4(data[0:4])
1.364 + num_annotations = u2(data[4:6])
1.365 + data = data[6:]
1.366 + self.annotations = []
1.367 + for ii in xrange(num_annotations):
1.368 + annotation = Annotation()
1.369 + data = annotation.init(data, class_file)
1.370 + self.annotations.append(annotation)
1.371 + return data
1.372 + def serialize(self):
1.373 + od = su4(self.attribute_length)+su2(len(self.annotations))
1.374 + od += "".join([a.serialize() for a in self.annotations])
1.375 + return od
1.376 +
1.377 +class RuntimeVisibleAnnotationsAttributeInfo(RuntimeAnnotationsAttributeInfo):
1.378 + pass
1.379 +
1.380 +class RuntimeInvisibleAnnotationsAttributeInfo(RuntimeAnnotationsAttributeInfo):
1.381 + pass
1.382 +
1.383 +class RuntimeParameterAnnotationsAttributeInfo(AttributeInfo):
1.384 + def init(self, data, class_file):
1.385 + self.class_file = class_file
1.386 + self.attribute_length = u4(data[0:4])
1.387 + num_parameters = u1(data[4:5])
1.388 + data = data[5:]
1.389 + self.parameter_annotations = []
1.390 + for ii in xrange(num_parameters):
1.391 + num_annotations = u2(data[0:2])
1.392 + data = data[2:]
1.393 + annotations = []
1.394 + for jj in xrange(num_annotations):
1.395 + annotation = Annotation()
1.396 + data = annotation.init(data, class_file)
1.397 + annotations.append(annotation)
1.398 + self.parameter_annotations.append(annotations)
1.399 + return data
1.400 + def serialize(self):
1.401 + od = su4(self.attribute_length)+su1(len(self.parameter_annotations))
1.402 + for pa in self.parameter_annotations:
1.403 + od += su2(len(pa))
1.404 + od += "".join([a.serialize() for a in pa])
1.405 + return od
1.406 +
1.407 +class RuntimeVisibleParameterAnnotationsAttributeInfo(RuntimeParameterAnnotationsAttributeInfo):
1.408 + pass
1.409 +
1.410 +class RuntimeInvisibleParameterAnnotationsAttributeInfo(RuntimeParameterAnnotationsAttributeInfo):
1.411 + pass
1.412 +
1.413 +class AnnotationDefaultAttributeInfo(AttributeInfo):
1.414 + def init(self, data, class_file):
1.415 + self.class_file = class_file
1.416 + self.attribute_length = u4(data[0:4])
1.417 + data = data[4:]
1.418 + self.default_value = create_element_value(data)
1.419 + return self.default_value.init(data, class_file)
1.420 + def serialize(self):
1.421 + return su4(self.attribute_length)+self.default_value.serialize()
1.422 +
1.423 +
1.424 # Child classes of the attribute information classes.
1.425
1.426 class ExceptionInfo:
1.427 @@ -592,11 +999,45 @@
1.428 # Exceptions.
1.429
1.430 class UnknownTag(Exception):
1.431 - pass
1.432 + def __init__(self, tag):
1.433 + self.tag = tag
1.434 + def __str__(self):
1.435 + return repr(self.tag)
1.436
1.437 class UnknownAttribute(Exception):
1.438 - pass
1.439 + def __init__(self, name):
1.440 + self.name = name
1.441
1.442 +ATTR_NAMES_TO_CLASS = {"SourceFile": SourceFileAttributeInfo,
1.443 + "ConstantValue": ConstantValueAttributeInfo,
1.444 + "Code": CodeAttributeInfo,
1.445 + "Exceptions": ExceptionsAttributeInfo,
1.446 + "InnerClasses": InnerClassesAttributeInfo,
1.447 + "Synthetic": SyntheticAttributeInfo,
1.448 + "LineNumberTable": LineNumberAttributeInfo,
1.449 + "LocalVariableTable": LocalVariableAttributeInfo,
1.450 + "Deprecated": DeprecatedAttributeInfo,
1.451 + # Java SE 1.6, class file >= 50.0, VMSpec v3 s4.7.4
1.452 + "StackMapTable": StackMapTableAttributeInfo,
1.453 + # Java SE 1.5, class file >= 49.0, VMSpec v3 s4.7.7
1.454 + "EnclosingMethod": EnclosingMethodAttributeInfo,
1.455 + # Java SE 1.5, class file >= 49.0, VMSpec v3 s4.7.9
1.456 + "Signature": SignatureAttributeInfo,
1.457 + # Java SE 1.5, class file >= 49.0, VMSpec v3 s4.7.11
1.458 + "SourceDebugExtension": SourceDebugExtensionAttributeInfo,
1.459 + # Java SE 1.5, class file >= 49.0, VMSpec v3 s4.7.14
1.460 + "LocalVariableTypeTable": LocalVariableTypeAttributeInfo,
1.461 + # Java SE 1.5, class file >= 49.0, VMSpec v3 s4.7.16
1.462 + "RuntimeVisibleAnnotations": RuntimeVisibleAnnotationsAttributeInfo,
1.463 + # Java SE 1.5, class file >= 49.0, VMSpec v3 s4.7.17
1.464 + "RuntimeInvisibleAnnotations": RuntimeInvisibleAnnotationsAttributeInfo,
1.465 + # Java SE 1.5, class file >= 49.0, VMSpec v3 s4.7.18
1.466 + "RuntimeVisibleParameterAnnotations": RuntimeVisibleParameterAnnotationsAttributeInfo,
1.467 + # Java SE 1.5, class file >= 49.0, VMSpec v3 s4.7.19
1.468 + "RuntimeInvisibleParameterAnnotations": RuntimeInvisibleParameterAnnotationsAttributeInfo,
1.469 + # Java SE 1.5, class file >= 49.0, VMSpec v3 s4.7.20
1.470 + "AnnotationDefault": AnnotationDefaultAttributeInfo,}
1.471 +
1.472 # Abstractions for the main structures.
1.473
1.474 class ClassFile:
1.475 @@ -611,6 +1052,9 @@
1.476 """
1.477
1.478 self.attribute_class_to_index = None
1.479 + magic = u4(s[0:])
1.480 + if magic != 0xCAFEBABE:
1.481 + raise UnknownAttribute, magic
1.482 self.minorv,self.majorv = u2(s[4:]),u2(s[6:])
1.483 self.constants, s = self._get_constants(s[8:])
1.484 self.access_flags, s = self._get_access_flags(s)
1.485 @@ -651,10 +1095,10 @@
1.486 od += su1(8)
1.487 elif isinstance(c, FieldRefInfo):
1.488 od += su1(9)
1.489 + elif isinstance(c, InterfaceMethodRefInfo): # check subclass first
1.490 + od += su1(11)
1.491 elif isinstance(c, MethodRefInfo):
1.492 od += su1(10)
1.493 - elif isinstance(c, InterfaceMethodRefInfo):
1.494 - od += su1(11)
1.495 elif isinstance(c, NameAndTypeInfo):
1.496 od += su1(12)
1.497 else:
1.498 @@ -725,24 +1169,8 @@
1.499 def _get_attribute_from_table(self, s):
1.500 attribute_name_index = u2(s[0:2])
1.501 constant_name = self.constants[attribute_name_index - 1].bytes
1.502 - if constant_name == "SourceFile":
1.503 - attribute = SourceFileAttributeInfo()
1.504 - elif constant_name == "ConstantValue":
1.505 - attribute = ConstantValueAttributeInfo()
1.506 - elif constant_name == "Code":
1.507 - attribute = CodeAttributeInfo()
1.508 - elif constant_name == "Exceptions":
1.509 - attribute = ExceptionsAttributeInfo()
1.510 - elif constant_name == "InnerClasses":
1.511 - attribute = InnerClassesAttributeInfo()
1.512 - elif constant_name == "Synthetic":
1.513 - attribute = SyntheticAttributeInfo()
1.514 - elif constant_name == "LineNumberTable":
1.515 - attribute = LineNumberAttributeInfo()
1.516 - elif constant_name == "LocalVariableTable":
1.517 - attribute = LocalVariableAttributeInfo()
1.518 - elif constant_name == "Deprecated":
1.519 - attribute = DeprecatedAttributeInfo()
1.520 + if constant_name in ATTR_NAMES_TO_CLASS:
1.521 + attribute = ATTR_NAMES_TO_CLASS[constant_name]()
1.522 else:
1.523 raise UnknownAttribute, constant_name
1.524 s = attribute.init(s[2:], self)
1.525 @@ -796,7 +1224,7 @@
1.526 return interfaces, s
1.527
1.528 def _serialize_interfaces(self):
1.529 - return su2(len(self.interfaces))+"".join([su2(self.interfaces.index(interf)+1) for interf in self.interfaces])
1.530 + return su2(len(self.interfaces))+"".join([su2(self.constants.index(interf)+1) for interf in self.interfaces])
1.531
1.532 def _get_fields(self, s):
1.533 number = u2(s[0:2])
1.534 @@ -816,16 +1244,11 @@
1.535 if len(attrs) == 0: return od
1.536 if self.attribute_class_to_index == None:
1.537 self.attribute_class_to_index = {}
1.538 - attr_names_to_class = {"SourceFile":SourceFileAttributeInfo, "ConstantValue":ConstantValueAttributeInfo,
1.539 - "Code":CodeAttributeInfo, "Exceptions":ExceptionsAttributeInfo,
1.540 - "InnerClasses":InnerClassesAttributeInfo, "Synthetic":SyntheticAttributeInfo,
1.541 - "LineNumberTable":LineNumberAttributeInfo, "LocalVariableTable":LocalVariableAttributeInfo,
1.542 - "Deprecated":DeprecatedAttributeInfo}
1.543 index = 0
1.544 for c in self.constants:
1.545 index += 1
1.546 - if isinstance(c, Utf8Info) and str(c) in attr_names_to_class.keys():
1.547 - self.attribute_class_to_index[attr_names_to_class[str(c)]]=index
1.548 + if isinstance(c, Utf8Info) and str(c) in ATTR_NAMES_TO_CLASS.keys():
1.549 + self.attribute_class_to_index[ATTR_NAMES_TO_CLASS[str(c)]]=index
1.550 for attribute in attrs:
1.551 for (classtype,name_index) in self.attribute_class_to_index.iteritems():
1.552 if isinstance(attribute, classtype):
1.553 @@ -847,7 +1270,10 @@
1.554 if __name__ == "__main__":
1.555 import sys
1.556 f = open(sys.argv[1], "rb")
1.557 - c = ClassFile(f.read())
1.558 + in_data = f.read()
1.559 + c = ClassFile(in_data)
1.560 f.close()
1.561 + out_data = c.serialize()
1.562 + assert(in_data == out_data)
1.563
1.564 # vim: tabstop=4 expandtab shiftwidth=4