com.googlecode.d2j.dex.writer.item.ClassDefItem Maven / Gradle / Ivy
The newest version!
/*
* dex2jar - Tools to work with android .dex and java .class files
* Copyright (c) 2009-2013 Panxiaobo
*
* 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.googlecode.d2j.dex.writer.item;
import com.googlecode.d2j.dex.writer.ann.Idx;
import com.googlecode.d2j.dex.writer.ann.Off;
import com.googlecode.d2j.dex.writer.ev.EncodedArray;
import com.googlecode.d2j.dex.writer.ev.EncodedValue;
import com.googlecode.d2j.dex.writer.io.DataOut;
import com.googlecode.d2j.dex.writer.item.ClassDataItem.EncodedField;
import com.googlecode.d2j.dex.writer.item.ClassDataItem.EncodedMethod;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class ClassDefItem extends BaseItem {
@Idx
public TypeIdItem clazz;
public int accessFlags;
@Idx
public TypeIdItem superclazz;
@Off
public TypeListItem interfaces;
@Idx
public StringIdItem sourceFile;
@Off
public ClassDataItem classData;
//
public AnnotationSetItem classAnnotations;
@Off
private AnnotationsDirectoryItem annotations;// Build later
@Off
private EncodedArrayItem staticValues; // Build later
@Override
public int place(int offset) {
return offset + 0x20;
}
public void prepare(ConstPool cp) {
if (classData != null) {
classData.prepare(cp);
}
preparteAnnotationsDirectoryItem(cp);
prepareEncodedArrayItem(cp);
}
private void prepareEncodedArrayItem(ConstPool cp) {
if (classData == null) {
return;
}
List fs = classData.staticFields;
int count = -1;
for (int i = 0; i < fs.size(); i++) {
EncodedField f = fs.get(i);
EncodedValue ev = f.staticValue;
if (ev != null) {
if (!ev.isDefaultValueForType()) {
count = i;
}
}
}
if (count >= 0) {
EncodedArrayItem encodedArrayItem = cp.putEnCodedArrayItem();
EncodedArray array = encodedArrayItem.value;
for (int i = 0; i <= count; i++) {
EncodedField f = fs.get(i);
EncodedValue ev = f.staticValue;
if (ev == null) {
array.values.add(EncodedValue.defaultValueForType(f.field.getTypeString()));
} else {
array.values.add(ev);
}
}
staticValues = encodedArrayItem;
}
}
private void preparteAnnotationsDirectoryItem(ConstPool cp) {
Map fieldAnnotations = new TreeMap<>();
Map methodAnnotations = new TreeMap<>();
Map parameterAnnotations = new TreeMap<>();
if (classData != null) {
collectField(fieldAnnotations, classData.staticFields, cp);
collectField(fieldAnnotations, classData.instanceFields, cp);
collectMethod(methodAnnotations, parameterAnnotations, classData.directMethods, cp);
collectMethod(methodAnnotations, parameterAnnotations, classData.virtualMethods, cp);
}
if (this.classAnnotations != null || fieldAnnotations.size() > 0 || methodAnnotations.size() > 0
|| parameterAnnotations.size() > 0) {
AnnotationsDirectoryItem annotationsDirectoryItem = cp.putAnnotationDirectoryItem();
this.annotations = annotationsDirectoryItem;
if (classAnnotations != null) {
annotationsDirectoryItem.classAnnotations = cp.uniqAnnotationSetItem(classAnnotations);
}
if (fieldAnnotations.size() > 0) {
annotationsDirectoryItem.fieldAnnotations = fieldAnnotations;
}
if (methodAnnotations.size() > 0) {
annotationsDirectoryItem.methodAnnotations = methodAnnotations;
}
if (parameterAnnotations.size() > 0) {
annotationsDirectoryItem.parameterAnnotations = parameterAnnotations;
}
}
}
private void collectMethod(Map methodAnnotations,
Map parameterAnnotations, List ms, ConstPool cp) {
for (EncodedMethod m : ms) {
if (m.annotationSetItem != null) {
methodAnnotations.put(m.method, cp.uniqAnnotationSetItem(m.annotationSetItem));
}
if (m.parameterAnnotation != null) {
parameterAnnotations.put(m.method, cp.uniqAnnotationSetRefListItem(m.parameterAnnotation));
}
}
}
private void collectField(Map fieldAnnotations, List fs, ConstPool cp) {
for (EncodedField f : fs) {
if (f.annotationSetItem != null) {
fieldAnnotations.put(f.field, cp.uniqAnnotationSetItem(f.annotationSetItem));
}
}
}
@Override
public void write(DataOut out) {
out.uint("class_idx", clazz.index);
out.uint("access_flags", this.accessFlags);
out.uint("superclass_idx", superclazz == null ? NO_INDEX : superclazz.index);
out.uint("interfaces_off", (interfaces == null || interfaces.items.size() == 0) ? 0 : interfaces.offset);
out.uint("source_file_idx", sourceFile == null ? NO_INDEX : sourceFile.index);
out.uint("annotations_off", annotations == null ? 0 : annotations.offset);
out.uint("class_data_off", classData == null ? 0 : classData.offset);
out.uint("static_values_off", staticValues == null ? 0 : staticValues.offset);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy