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 17 package com.android.dx.dex.file; 18 19 import com.android.dex.SizeOf; 20 import com.android.dx.rop.cst.CstMemberRef; 21 import com.android.dx.rop.cst.CstNat; 22 import com.android.dx.util.AnnotatedOutput; 23 import com.android.dx.util.Hex; 24 25 /** 26 * Representation of a member (field or method) reference inside a 27 * Dalvik file. 28 */ 29 public abstract class MemberIdItem extends IdItem { 30 /** {@code non-null;} the constant for the member */ 31 private final CstMemberRef cst; 32 33 /** 34 * Constructs an instance. 35 * 36 * @param cst {@code non-null;} the constant for the member 37 */ MemberIdItem(CstMemberRef cst)38 public MemberIdItem(CstMemberRef cst) { 39 super(cst.getDefiningClass()); 40 41 this.cst = cst; 42 } 43 44 /** {@inheritDoc} */ 45 @Override writeSize()46 public int writeSize() { 47 return SizeOf.MEMBER_ID_ITEM; 48 } 49 50 /** {@inheritDoc} */ 51 @Override addContents(DexFile file)52 public void addContents(DexFile file) { 53 super.addContents(file); 54 55 StringIdsSection stringIds = file.getStringIds(); 56 stringIds.intern(getRef().getNat().getName()); 57 } 58 59 /** {@inheritDoc} */ 60 @Override writeTo(DexFile file, AnnotatedOutput out)61 public final void writeTo(DexFile file, AnnotatedOutput out) { 62 TypeIdsSection typeIds = file.getTypeIds(); 63 StringIdsSection stringIds = file.getStringIds(); 64 CstNat nat = cst.getNat(); 65 int classIdx = typeIds.indexOf(getDefiningClass()); 66 int nameIdx = stringIds.indexOf(nat.getName()); 67 int typoidIdx = getTypoidIdx(file); 68 69 if (out.annotates()) { 70 out.annotate(0, indexString() + ' ' + cst.toHuman()); 71 out.annotate(2, " class_idx: " + Hex.u2(classIdx)); 72 out.annotate(2, String.format(" %-10s %s", getTypoidName() + ':', 73 Hex.u2(typoidIdx))); 74 out.annotate(4, " name_idx: " + Hex.u4(nameIdx)); 75 } 76 77 out.writeShort(classIdx); 78 out.writeShort(typoidIdx); 79 out.writeInt(nameIdx); 80 } 81 82 /** 83 * Returns the index of the type-like thing associated with 84 * this item, in order that it may be written out. Subclasses must 85 * override this to get whatever it is they need to store. 86 * 87 * @param file {@code non-null;} the file being written 88 * @return the index in question 89 */ getTypoidIdx(DexFile file)90 protected abstract int getTypoidIdx(DexFile file); 91 92 /** 93 * Returns the field name of the type-like thing associated with 94 * this item, for listing-generating purposes. Subclasses must override 95 * this. 96 * 97 * @return {@code non-null;} the name in question 98 */ getTypoidName()99 protected abstract String getTypoidName(); 100 101 /** 102 * Gets the member constant. 103 * 104 * @return {@code non-null;} the constant 105 */ getRef()106 public final CstMemberRef getRef() { 107 return cst; 108 } 109 } 110