1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.dex.file;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.AnnotatedOutput;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.ExceptionWithContext;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * An item in a Dalvik file which is referenced by absolute offset.
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic abstract class OffsettedItem extends Item
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        implements Comparable<OffsettedItem> {
2799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code > 0;} alignment requirement */
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final int alignment;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code >= -1;} the size of this instance when written, in bytes, or
3199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code -1} if not yet known */
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int writeSize;
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
3599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null-ok;} section the item was added to, or {@code null} if
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * not yet added
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private Section addedTo;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
4199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code >= -1;} assigned offset of the item from the start of its section,
4299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * or {@code -1} if not yet assigned
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int offset;
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
4799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Gets the absolute offset of the given item, returning {@code 0}
4899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * if handed {@code null}.
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
5099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param item {@code null-ok;} the item in question
5199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the item's absolute offset, or {@code 0}
5299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * if {@code item == null}
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static int getAbsoluteOffsetOr0(OffsettedItem item) {
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (item == null) {
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return 0;
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return item.getAbsoluteOffset();
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance. The offset is initially unassigned.
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
6599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param alignment {@code > 0;} output alignment requirement; must be a
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * power of 2
6799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param writeSize {@code >= -1;} the size of this instance when written,
6899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * in bytes, or {@code -1} if not immediately known
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public OffsettedItem(int alignment, int writeSize) {
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Section.validateAlignment(alignment);
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (writeSize < -1) {
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("writeSize < -1");
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.alignment = alignment;
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.writeSize = writeSize;
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.addedTo = null;
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.offset = -1;
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@inheritDoc}
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Comparisons for this class are defined to be type-major (if the
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * types don't match then the objects are not equal), with
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@link #compareTo0} deciding same-type comparisons.
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final boolean equals(Object other) {
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (this == other) {
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return true;
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        OffsettedItem otherItem = (OffsettedItem) other;
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ItemType thisType = itemType();
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ItemType otherType = otherItem.itemType();
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (thisType != otherType) {
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (compareTo0(otherItem) == 0);
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@inheritDoc}
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Comparisons for this class are defined to be class-major (if the
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * classes don't match then the objects are not equal), with
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@link #compareTo0} deciding same-class comparisons.
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int compareTo(OffsettedItem other) {
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (this == other) {
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return 0;
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ItemType thisType = itemType();
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ItemType otherType = other.itemType();
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (thisType != otherType) {
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return thisType.compareTo(otherType);
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return compareTo0(other);
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the write size of this item. This may only be called once
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * per instance, and only if the size was unknown upon instance
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * creation.
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
13499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param writeSize {@code > 0;} the write size, in bytes
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void setWriteSize(int writeSize) {
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (writeSize < 0) {
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("writeSize < 0");
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (this.writeSize >= 0) {
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new UnsupportedOperationException("writeSize already set");
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.writeSize = writeSize;
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc}
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws UnsupportedOperationException thrown if the write size
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is not yet known
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int writeSize() {
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (writeSize < 0) {
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new UnsupportedOperationException("writeSize is unknown");
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return writeSize;
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void writeTo(DexFile file, AnnotatedOutput out) {
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out.alignTo(alignment);
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (writeSize < 0) {
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new UnsupportedOperationException(
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        "writeSize is unknown");
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.assertCursor(getAbsoluteOffset());
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (RuntimeException ex) {
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw ExceptionWithContext.withContext(ex,
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "...while writing " + this);
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        writeTo0(file, out);
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the relative item offset. The offset is from the start of
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the section which the instance was written to.
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
18599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the offset
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws RuntimeException thrown if the offset is not yet known
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int getRelativeOffset() {
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (offset < 0) {
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new RuntimeException("offset not yet known");
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return offset;
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the absolute item offset. The offset is from the start of
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the file which the instance was written to.
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
20099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the offset
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws RuntimeException thrown if the offset is not yet known
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int getAbsoluteOffset() {
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (offset < 0) {
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new RuntimeException("offset not yet known");
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return addedTo.getAbsoluteOffset(offset);
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Indicates that this item has been added to the given section at
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the given offset. It is only valid to call this method once per
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * instance.
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
21655423dcd081e30c4fc27b997f127db7b00f1b981Dan Bornstein     * @param addedTo {@code non-null;} the section this instance has
21755423dcd081e30c4fc27b997f127db7b00f1b981Dan Bornstein     * been added to
21899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param offset {@code >= 0;} the desired offset from the start of the
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * section where this instance was placed
22099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the offset that this instance should be placed at
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * in order to meet its alignment constraint
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int place(Section addedTo, int offset) {
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (addedTo == null) {
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("addedTo == null");
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (offset < 0) {
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("offset < 0");
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (this.addedTo != null) {
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new RuntimeException("already written");
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int mask = alignment - 1;
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        offset = (offset + mask) & ~mask;
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.addedTo = addedTo;
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.offset = offset;
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        place0(addedTo, offset);
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return offset;
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the alignment requirement of this instance. An instance should
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * only be written when so aligned.
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
25199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code > 0;} the alignment requirement; must be a power of 2
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int getAlignment() {
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return alignment;
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the absolute offset of this item as a string, suitable for
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * including in annotations.
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
26199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the offset string
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final String offsetString() {
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return '[' + Integer.toHexString(getAbsoluteOffset()) + ']';
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets a short human-readable string representing this instance.
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
27099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the human form
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public abstract String toHuman();
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Compares this instance to another which is guaranteed to be of
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the same class. The default implementation of this method is to
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * throw an exception (unsupported operation). If a particular
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * class needs to actually sort, then it should override this
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * method.
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
28199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param other {@code non-null;} instance to compare to
28299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code -1}, {@code 0}, or {@code 1}, depending
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * on the sort order of this instance and the other
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected int compareTo0(OffsettedItem other) {
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throw new UnsupportedOperationException("unsupported");
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Does additional work required when placing an instance. The
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * default implementation of this method is a no-op. If a
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * particular class needs to do something special, then it should
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * override this method. In particular, if this instance did not
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * know its write size up-front, then this method is responsible
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * for setting it.
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
29799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param addedTo {@code non-null;} the section this instance has been added to
29899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param offset {@code >= 0;} the offset from the start of the
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * section where this instance was placed
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected void place0(Section addedTo, int offset) {
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // This space intentionally left blank.
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Performs the actual write of the contents of this instance to
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the given data section. This is called by {@link #writeTo},
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * which will have taken care of ensuring alignment.
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
31099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param file {@code non-null;} the file to use for reference
31199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param out {@code non-null;} where to write to
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected abstract void writeTo0(DexFile file, AnnotatedOutput out);
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
315