/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.taobao.dex;
import com.taobao.dex.util.CompareUtils;
public final class ClassData extends TableOfContents.Section.Item<ClassData> {
public Field[] staticFields;
public Field[] instanceFields;
public Method[] directMethods;
public Method[] virtualMethods;
public ClassData(int off, Field[] staticFields, Field[] instanceFields,
Method[] directMethods, Method[] virtualMethods) {
super(off);
this.staticFields = staticFields;
this.instanceFields = instanceFields;
this.directMethods = directMethods;
this.virtualMethods = virtualMethods;
}
@Override
public int compareTo(ClassData other) {
int res = CompareUtils.aArrCompare(staticFields, other.staticFields);
if (res != 0) {
return res;
}
res = CompareUtils.aArrCompare(instanceFields, other.instanceFields);
if (res != 0) {
return res;
}
res = CompareUtils.aArrCompare(directMethods, other.directMethods);
if (res != 0) {
return res;
}
return CompareUtils.aArrCompare(virtualMethods, other.virtualMethods);
}
@Override
public int byteCountInDex() {
int res = Leb128.unsignedLeb128Size(staticFields.length);
res += Leb128.unsignedLeb128Size(instanceFields.length);
res += Leb128.unsignedLeb128Size(directMethods.length);
res += Leb128.unsignedLeb128Size(virtualMethods.length);
res += calcFieldsSize(staticFields);
res += calcFieldsSize(instanceFields);
res += calcMethodsSize(directMethods);
res += calcMethodsSize(virtualMethods);
return res;
}
private int calcFieldsSize(Field[] fields) {
int res = 0;
int prevFieldIndex = 0;
for (Field field : fields) {
int fieldIndexDelta = field.fieldIndex - prevFieldIndex;
prevFieldIndex = field.fieldIndex;
res += Leb128.unsignedLeb128Size(fieldIndexDelta) + Leb128.unsignedLeb128Size(field.accessFlags);
}
return res;
}
private int calcMethodsSize(Method[] methods) {
int res = 0;
int prevMethodIndex = 0;
for (Method method : methods) {
int methodIndexDelta = method.methodIndex - prevMethodIndex;
prevMethodIndex = method.methodIndex;
res += Leb128.unsignedLeb128Size(methodIndexDelta)
+ Leb128.unsignedLeb128Size(method.accessFlags)
+ Leb128.unsignedLeb128Size(method.codeOffset);
}
return res;
}
public static class Field implements Comparable<Field> {
public int fieldIndex;
public int accessFlags;
public Field(int fieldIndex, int accessFlags) {
this.fieldIndex = fieldIndex;
this.accessFlags = accessFlags;
}
@Override
public int compareTo(Field other) {
int res = CompareUtils.uCompare(fieldIndex, other.fieldIndex);
if (res != 0) {
return res;
}
return CompareUtils.sCompare(accessFlags, other.accessFlags);
}
}
public static class Method implements Comparable<Method> {
public int methodIndex;
public int accessFlags;
public int codeOffset;
public Method(int methodIndex, int accessFlags, int codeOffset) {
this.methodIndex = methodIndex;
this.accessFlags = accessFlags;
this.codeOffset = codeOffset;
}
@Override
public int compareTo(Method other) {
int res = CompareUtils.uCompare(methodIndex, other.methodIndex);
if (res != 0) {
return res;
}
res = CompareUtils.sCompare(accessFlags, other.accessFlags);
if (res != 0) {
return res;
}
return CompareUtils.sCompare(codeOffset, other.codeOffset);
}
}
}