1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2007 The Android Open Source Project 3579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 4579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * you may not use this file except in compliance with the License. 6579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * You may obtain a copy of the License at 7579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 8579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 10579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * See the License for the specific language governing permissions and 14579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * limitations under the License. 15579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 16579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 17579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpackage com.android.dx.dex.file; 18579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 19579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport com.android.dx.util.AnnotatedOutput; 20579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.Collection; 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * A section of a {@code .dex} file. Each section consists of a list 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * of items of some sort or other. 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic abstract class Section { 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code null-ok;} name of this part, for annotation purposes */ 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final String name; 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} file that this instance is part of */ 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final DexFile file; 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code > 0;} alignment requirement for the final output; 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * must be a power of 2 */ 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final int alignment; 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code >= -1;} offset from the start of the file to this part, or 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code -1} if not yet known */ 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private int fileOffset; 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** whether {@link #prepare} has been called successfully on this 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * instance */ 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private boolean prepared; 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Validates an alignment. 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param alignment the alignment 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @throws IllegalArgumentException thrown if {@code alignment} 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * isn't a positive power of 2 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static void validateAlignment(int alignment) { 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if ((alignment <= 0) || 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson (alignment & (alignment - 1)) != 0) { 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("invalid alignment"); 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an instance. The file offset is initially unknown. 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param name {@code null-ok;} the name of this instance, for annotation 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * purposes 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param file {@code non-null;} file that this instance is part of 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param alignment {@code > 0;} alignment requirement for the final output; 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * must be a power of 2 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public Section(String name, DexFile file, int alignment) { 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (file == null) { 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("file == null"); 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson validateAlignment(alignment); 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.name = name; 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.file = file; 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.alignment = alignment; 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.fileOffset = -1; 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.prepared = false; 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the file that this instance is part of. 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the file 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public final DexFile getFile() { 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return file; 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the alignment for this instance's final output. 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code > 0;} the alignment 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public final int getAlignment() { 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return alignment; 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the offset from the start of the file to this part. This 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * throws an exception if the offset has not yet been set. 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= 0;} the file offset 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public final int getFileOffset() { 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (fileOffset < 0) { 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new RuntimeException("fileOffset not set"); 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return fileOffset; 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Sets the file offset. It is only valid to call this method once 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * once per instance. 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param fileOffset {@code >= 0;} the desired offset from the start of the 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * file where this for this instance 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= 0;} the offset that this instance should be placed at 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * in order to meet its alignment constraint 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public final int setFileOffset(int fileOffset) { 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (fileOffset < 0) { 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("fileOffset < 0"); 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (this.fileOffset >= 0) { 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new RuntimeException("fileOffset already set"); 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int mask = alignment - 1; 134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fileOffset = (fileOffset + mask) & ~mask; 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.fileOffset = fileOffset; 137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return fileOffset; 139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Writes this instance to the given raw data object. 143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param out {@code non-null;} where to write to 145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public final void writeTo(AnnotatedOutput out) { 147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throwIfNotPrepared(); 148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson align(out); 149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int cursor = out.getCursor(); 151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (fileOffset < 0) { 153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson fileOffset = cursor; 154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else if (fileOffset != cursor) { 155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new RuntimeException("alignment mismatch: for " + this + 156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ", at " + cursor + 157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ", but expected " + fileOffset); 158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (out.annotates()) { 161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (name != null) { 162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(0, "\n" + name + ":"); 163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else if (cursor != 0) { 164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(0, "\n"); 165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson writeTo0(out); 169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns the absolute file offset, given an offset from the 173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * start of this instance's output. This is only valid to call 174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * once this instance has been assigned a file offset (via {@link 175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * #setFileOffset}). 176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param relative {@code >= 0;} the relative offset 178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= 0;} the corresponding absolute file offset 179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public final int getAbsoluteOffset(int relative) { 181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (relative < 0) { 182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("relative < 0"); 183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (fileOffset < 0) { 186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new RuntimeException("fileOffset not yet set"); 187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return fileOffset + relative; 190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns the absolute file offset of the given item which must 194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * be contained in this section. This is only valid to call 195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * once this instance has been assigned a file offset (via {@link 196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * #setFileOffset}). 197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * <p><b>Note:</b> Subclasses must implement this as appropriate for 199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * their contents.</p> 200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param item {@code non-null;} the item in question 202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= 0;} the item's absolute file offset 203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public abstract int getAbsoluteItemOffset(Item item); 205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Prepares this instance for writing. This performs any necessary 208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * prerequisites, including particularly adding stuff to other 209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * sections. This method may only be called once per instance; 210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * subsequent calls will throw an exception. 211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public final void prepare() { 213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throwIfPrepared(); 214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson prepare0(); 215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson prepared = true; 216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the collection of all the items in this section. 220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * It is not valid to attempt to change the returned list. 221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code non-null;} the items 223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public abstract Collection<? extends Item> items(); 225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Does the main work of {@link #prepare}. 228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected abstract void prepare0(); 230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Gets the size of this instance when output, in bytes. 233579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 234579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code >= 0;} the size of this instance, in bytes 235579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 236579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public abstract int writeSize(); 237579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 238579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 239579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Throws an exception if {@link #prepare} has not been 240579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * called on this instance. 241579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 242579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected final void throwIfNotPrepared() { 243579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (!prepared) { 244579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new RuntimeException("not prepared"); 245579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 246579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 247579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 248579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 249579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Throws an exception if {@link #prepare} has already been called 250579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * on this instance. 251579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 252579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected final void throwIfPrepared() { 253579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (prepared) { 254579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new RuntimeException("already prepared"); 255579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 256579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 257579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 258579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 259579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Aligns the output of the given data to the alignment of this instance. 260579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 261579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param out {@code non-null;} the output to align 262579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 263579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected final void align(AnnotatedOutput out) { 264579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.alignTo(alignment); 265579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 266579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 267579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 268579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Writes this instance to the given raw data object. This gets 269579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * called by {@link #writeTo} after aligning the cursor of 270579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code out} and verifying that either the assigned file 271579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * offset matches the actual cursor {@code out} or that the 272579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * file offset was not previously assigned, in which case it gets 273579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * assigned to {@code out}'s cursor. 274579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 275579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param out {@code non-null;} where to write to 276579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 277579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected abstract void writeTo0(AnnotatedOutput out); 278579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 279579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 280579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Returns the name of this section, for annotation purposes. 281579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 282579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @return {@code null-ok;} name of this part, for annotation purposes 283579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 284579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected final String getName() { 285579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return name; 286579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 287579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 288