1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/* 2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project 3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License"); 5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License. 6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at 7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * http://www.apache.org/licenses/LICENSE-2.0 9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software 11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS, 12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and 14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License. 15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.dex.file; 18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.AnnotatedOutput; 20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.util.Collection; 22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/** 24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * A section of a {@code .dex} file. Each section consists of a list 25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * of items of some sort or other. 26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic abstract class Section { 28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code null-ok;} name of this part, for annotation purposes */ 29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final String name; 30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} file that this instance is part of */ 32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final DexFile file; 33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code > 0;} alignment requirement for the final output; 35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * must be a power of 2 */ 36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final int alignment; 37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code >= -1;} offset from the start of the file to this part, or 39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code -1} if not yet known */ 40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private int fileOffset; 41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** whether {@link #prepare} has been called successfully on this 43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * instance */ 44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private boolean prepared; 45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Validates an alignment. 48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param alignment the alignment 50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @throws IllegalArgumentException thrown if {@code alignment} 51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * isn't a positive power of 2 52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static void validateAlignment(int alignment) { 54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if ((alignment <= 0) || 55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul (alignment & (alignment - 1)) != 0) { 56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("invalid alignment"); 57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an instance. The file offset is initially unknown. 62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param name {@code null-ok;} the name of this instance, for annotation 64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * purposes 65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param file {@code non-null;} file that this instance is part of 66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param alignment {@code > 0;} alignment requirement for the final output; 67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * must be a power of 2 68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Section(String name, DexFile file, int alignment) { 70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (file == null) { 71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("file == null"); 72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul validateAlignment(alignment); 75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.name = name; 77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.file = file; 78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.alignment = alignment; 79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.fileOffset = -1; 80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.prepared = false; 81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the file that this instance is part of. 85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the file 87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public final DexFile getFile() { 89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return file; 90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the alignment for this instance's final output. 94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code > 0;} the alignment 96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public final int getAlignment() { 98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return alignment; 99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the offset from the start of the file to this part. This 103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * throws an exception if the offset has not yet been set. 104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= 0;} the file offset 106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public final int getFileOffset() { 108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (fileOffset < 0) { 109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new RuntimeException("fileOffset not set"); 110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return fileOffset; 113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Sets the file offset. It is only valid to call this method once 117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * once per instance. 118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param fileOffset {@code >= 0;} the desired offset from the start of the 120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * file where this for this instance 121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= 0;} the offset that this instance should be placed at 122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * in order to meet its alignment constraint 123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public final int setFileOffset(int fileOffset) { 125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (fileOffset < 0) { 126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("fileOffset < 0"); 127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (this.fileOffset >= 0) { 130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new RuntimeException("fileOffset already set"); 131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int mask = alignment - 1; 134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul fileOffset = (fileOffset + mask) & ~mask; 135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul this.fileOffset = fileOffset; 137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return fileOffset; 139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Writes this instance to the given raw data object. 143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param out {@code non-null;} where to write to 145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public final void writeTo(AnnotatedOutput out) { 147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throwIfNotPrepared(); 148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul align(out); 149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int cursor = out.getCursor(); 151917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 152917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (fileOffset < 0) { 153917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul fileOffset = cursor; 154917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } else if (fileOffset != cursor) { 155917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new RuntimeException("alignment mismatch: for " + this + 156917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul ", at " + cursor + 157917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul ", but expected " + fileOffset); 158917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 159917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 160917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (out.annotates()) { 161917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (name != null) { 162917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul out.annotate(0, "\n" + name + ":"); 163917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } else if (cursor != 0) { 164917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul out.annotate(0, "\n"); 165917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 166917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 167917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 168917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul writeTo0(out); 169917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 170917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 171917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 172917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns the absolute file offset, given an offset from the 173917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * start of this instance's output. This is only valid to call 174917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * once this instance has been assigned a file offset (via {@link 175917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * #setFileOffset}). 176917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 177917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param relative {@code >= 0;} the relative offset 178917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= 0;} the corresponding absolute file offset 179917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 180917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public final int getAbsoluteOffset(int relative) { 181917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (relative < 0) { 182917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("relative < 0"); 183917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 184917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 185917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (fileOffset < 0) { 186917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new RuntimeException("fileOffset not yet set"); 187917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 188917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 189917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return fileOffset + relative; 190917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 191917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 192917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 193917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns the absolute file offset of the given item which must 194917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * be contained in this section. This is only valid to call 195917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * once this instance has been assigned a file offset (via {@link 196917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * #setFileOffset}). 197917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 198917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * <p><b>Note:</b> Subclasses must implement this as appropriate for 199917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * their contents.</p> 200917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 201917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param item {@code non-null;} the item in question 202917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= 0;} the item's absolute file offset 203917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 204917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public abstract int getAbsoluteItemOffset(Item item); 205917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 206917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 207917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Prepares this instance for writing. This performs any necessary 208917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * prerequisites, including particularly adding stuff to other 209917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * sections. This method may only be called once per instance; 210917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * subsequent calls will throw an exception. 211917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 212917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public final void prepare() { 213917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throwIfPrepared(); 214917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul prepare0(); 215917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul prepared = true; 216917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 217917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 218917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 219917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the collection of all the items in this section. 220917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * It is not valid to attempt to change the returned list. 221917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 222917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the items 223917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 224917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public abstract Collection<? extends Item> items(); 225917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 226917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 227917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Does the main work of {@link #prepare}. 228917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 229917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul protected abstract void prepare0(); 230917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 231917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 232917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the size of this instance when output, in bytes. 233917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 234917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= 0;} the size of this instance, in bytes 235917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 236917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public abstract int writeSize(); 237917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 238917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 239917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Throws an exception if {@link #prepare} has not been 240917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * called on this instance. 241917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 242917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul protected final void throwIfNotPrepared() { 243917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (!prepared) { 244917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new RuntimeException("not prepared"); 245917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 246917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 247917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 248917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 249917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Throws an exception if {@link #prepare} has already been called 250917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * on this instance. 251917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 252917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul protected final void throwIfPrepared() { 253917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (prepared) { 254917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new RuntimeException("already prepared"); 255917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 256917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 257917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 258917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 259917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Aligns the output of the given data to the alignment of this instance. 260917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 261917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param out {@code non-null;} the output to align 262917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 263917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul protected final void align(AnnotatedOutput out) { 264917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul out.alignTo(alignment); 265917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 266917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 267917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 268917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Writes this instance to the given raw data object. This gets 269917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * called by {@link #writeTo} after aligning the cursor of 270917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * {@code out} and verifying that either the assigned file 271917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * offset matches the actual cursor {@code out} or that the 272917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * file offset was not previously assigned, in which case it gets 273917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * assigned to {@code out}'s cursor. 274917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 275917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param out {@code non-null;} where to write to 276917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 277917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul protected abstract void writeTo0(AnnotatedOutput out); 278917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 279917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 280917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Returns the name of this section, for annotation purposes. 281917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 282917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code null-ok;} name of this part, for annotation purposes 283917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 284917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul protected final String getName() { 285917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return name; 286917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 287917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul} 288