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 java.util.Collection;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
2399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * A section of a {@code .dex} file. Each section consists of a list
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of items of some sort or other.
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic abstract class Section {
2799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} name of this part, for annotation purposes */
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final String name;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code non-null;} file that this instance is part of */
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final DexFile file;
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code > 0;} alignment requirement for the final output;
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * must be a power of 2 */
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private final int alignment;
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code >= -1;} offset from the start of the file to this part, or
3899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code -1} if not yet known */
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int fileOffset;
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** whether {@link #prepare} has been called successfully on this
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * instance */
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private boolean prepared;
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Validates an alignment.
47de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param alignment the alignment
4999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @throws IllegalArgumentException thrown if {@code alignment}
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * isn't a positive power of 2
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static void validateAlignment(int alignment) {
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((alignment <= 0) ||
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (alignment & (alignment - 1)) != 0) {
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("invalid alignment");
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an instance. The file offset is initially unknown.
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
6299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param name {@code null-ok;} the name of this instance, for annotation
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * purposes
6499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param file {@code non-null;} file that this instance is part of
6599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param alignment {@code > 0;} alignment requirement for the final output;
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * must be a power of 2
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Section(String name, DexFile file, int alignment) {
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (file == null) {
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("file == null");
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        validateAlignment(alignment);
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.name = name;
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.file = file;
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.alignment = alignment;
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.fileOffset = -1;
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.prepared = false;
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the file that this instance is part of.
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
8599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the file
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final DexFile getFile() {
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return file;
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
91de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro    /**
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the alignment for this instance's final output.
93de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
9499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code > 0;} the alignment
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int getAlignment() {
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return alignment;
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the offset from the start of the file to this part. This
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * throws an exception if the offset has not yet been set.
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
10499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the file offset
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int getFileOffset() {
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (fileOffset < 0) {
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new RuntimeException("fileOffset not set");
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return fileOffset;
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the file offset. It is only valid to call this method once
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * once per instance.
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
11899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param fileOffset {@code >= 0;} the desired offset from the start of the
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * file where this for this instance
12099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the offset that this instance should be placed at
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * in order to meet its alignment constraint
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int setFileOffset(int fileOffset) {
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (fileOffset < 0) {
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("fileOffset < 0");
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (this.fileOffset >= 0) {
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new RuntimeException("fileOffset already set");
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int mask = alignment - 1;
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fileOffset = (fileOffset + mask) & ~mask;
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.fileOffset = fileOffset;
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return fileOffset;
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Writes this instance to the given raw data object.
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
14399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param out {@code non-null;} where to write to
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void writeTo(AnnotatedOutput out) {
146de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        throwIfNotPrepared();
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        align(out);
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int cursor = out.getCursor();
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (fileOffset < 0) {
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            fileOffset = cursor;
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (fileOffset != cursor) {
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new RuntimeException("alignment mismatch: for " + this +
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                       ", at " + cursor +
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                       ", but expected " + fileOffset);
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (out.annotates()) {
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (name != null) {
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                out.annotate(0, "\n" + name + ":");
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else if (cursor != 0) {
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                out.annotate(0, "\n");
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        writeTo0(out);
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the absolute file offset, given an offset from the
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * start of this instance's output. This is only valid to call
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * once this instance has been assigned a file offset (via {@link
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * #setFileOffset}).
175de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
17699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param relative {@code >= 0;} the relative offset
17799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the corresponding absolute file offset
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final int getAbsoluteOffset(int relative) {
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (relative < 0) {
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException("relative < 0");
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (fileOffset < 0) {
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new RuntimeException("fileOffset not yet set");
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return fileOffset + relative;
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the absolute file offset of the given item which must
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * be contained in this section. This is only valid to call
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * once this instance has been assigned a file offset (via {@link
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * #setFileOffset}).
196de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p><b>Note:</b> Subclasses must implement this as appropriate for
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * their contents.</p>
199de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
20099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param item {@code non-null;} the item in question
20199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the item's absolute file offset
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public abstract int getAbsoluteItemOffset(Item item);
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Prepares this instance for writing. This performs any necessary
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * prerequisites, including particularly adding stuff to other
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * sections. This method may only be called once per instance;
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * subsequent calls will throw an exception.
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final void prepare() {
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throwIfPrepared();
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        prepare0();
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        prepared = true;
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the collection of all the items in this section.
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * It is not valid to attempt to change the returned list.
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
22199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code non-null;} the items
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public abstract Collection<? extends Item> items();
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Does the main work of {@link #prepare}.
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected abstract void prepare0();
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the size of this instance when output, in bytes.
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
23399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} the size of this instance, in bytes
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public abstract int writeSize();
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Throws an exception if {@link #prepare} has not been
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * called on this instance.
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final void throwIfNotPrepared() {
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!prepared) {
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new RuntimeException("not prepared");
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Throws an exception if {@link #prepare} has already been called
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * on this instance.
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final void throwIfPrepared() {
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (prepared) {
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new RuntimeException("already prepared");
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Aligns the output of the given data to the alignment of this instance.
259de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
26099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param out {@code non-null;} the output to align
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final void align(AnnotatedOutput out) {
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out.alignTo(alignment);
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Writes this instance to the given raw data object. This gets
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * called by {@link #writeTo} after aligning the cursor of
26999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code out} and verifying that either the assigned file
27099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * offset matches the actual cursor {@code out} or that the
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * file offset was not previously assigned, in which case it gets
27299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * assigned to {@code out}'s cursor.
273de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
27499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param out {@code non-null;} where to write to
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected abstract void writeTo0(AnnotatedOutput out);
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the name of this section, for annotation purposes.
280de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
28199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} name of this part, for annotation purposes
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected final String getName() {
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return name;
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
287