1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.dexgen.dex.file; 18 19import com.android.dexgen.rop.cst.CstMemberRef; 20import com.android.dexgen.rop.cst.CstNat; 21import com.android.dexgen.util.AnnotatedOutput; 22import com.android.dexgen.util.Hex; 23 24/** 25 * Representation of a member (field or method) reference inside a 26 * Dalvik file. 27 */ 28public abstract class MemberIdItem extends IdItem { 29 /** size of instances when written out to a file, in bytes */ 30 public static final int WRITE_SIZE = 8; 31 32 /** {@code non-null;} the constant for the member */ 33 private final CstMemberRef cst; 34 35 /** 36 * Constructs an instance. 37 * 38 * @param cst {@code non-null;} the constant for the member 39 */ 40 public MemberIdItem(CstMemberRef cst) { 41 super(cst.getDefiningClass()); 42 43 this.cst = cst; 44 } 45 46 /** {@inheritDoc} */ 47 @Override 48 public int writeSize() { 49 return WRITE_SIZE; 50 } 51 52 /** {@inheritDoc} */ 53 @Override 54 public void addContents(DexFile file) { 55 super.addContents(file); 56 57 StringIdsSection stringIds = file.getStringIds(); 58 stringIds.intern(getRef().getNat().getName()); 59 } 60 61 /** {@inheritDoc} */ 62 @Override 63 public final void writeTo(DexFile file, AnnotatedOutput out) { 64 TypeIdsSection typeIds = file.getTypeIds(); 65 StringIdsSection stringIds = file.getStringIds(); 66 CstNat nat = cst.getNat(); 67 int classIdx = typeIds.indexOf(getDefiningClass()); 68 int nameIdx = stringIds.indexOf(nat.getName()); 69 int typoidIdx = getTypoidIdx(file); 70 71 if (out.annotates()) { 72 out.annotate(0, indexString() + ' ' + cst.toHuman()); 73 out.annotate(2, " class_idx: " + Hex.u2(classIdx)); 74 out.annotate(2, String.format(" %-10s %s", getTypoidName() + ':', 75 Hex.u2(typoidIdx))); 76 out.annotate(4, " name_idx: " + Hex.u4(nameIdx)); 77 } 78 79 out.writeShort(classIdx); 80 out.writeShort(typoidIdx); 81 out.writeInt(nameIdx); 82 } 83 84 /** 85 * Returns the index of the type-like thing associated with 86 * this item, in order that it may be written out. Subclasses must 87 * override this to get whatever it is they need to store. 88 * 89 * @param file {@code non-null;} the file being written 90 * @return the index in question 91 */ 92 protected abstract int getTypoidIdx(DexFile file); 93 94 /** 95 * Returns the field name of the type-like thing associated with 96 * this item, for listing-generating purposes. Subclasses must override 97 * this. 98 * 99 * @return {@code non-null;} the name in question 100 */ 101 protected abstract String getTypoidName(); 102 103 /** 104 * Gets the member constant. 105 * 106 * @return {@code non-null;} the constant 107 */ 108 public final CstMemberRef getRef() { 109 return cst; 110 } 111} 112