1579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/* 2579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Copyright (C) 2008 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 Wilsonimport com.android.dx.util.Hex; 21579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 22579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonimport java.util.ArrayList; 23579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 24579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson/** 25579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Class that represents a map item. 26579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 27579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilsonpublic final class MapItem extends OffsettedItem { 28579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** file alignment of this class, in bytes */ 29579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static final int ALIGNMENT = 4; 30579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 31579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** write size of this class, in bytes: three {@code uint}s */ 32579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private static final int WRITE_SIZE = (4 * 3); 33579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 34579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} item type this instance covers */ 35579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final ItemType type; 36579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 37579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@code non-null;} section this instance covers */ 38579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final Section section; 39579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 40579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 41579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code null-ok;} first item covered or {@code null} if this is 42579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * a self-reference 43579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 44579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final Item firstItem; 45579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 46579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 47579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code null-ok;} last item covered or {@code null} if this is 48579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * a self-reference 49579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 50579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final Item lastItem; 51579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 52579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 53579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * {@code > 0;} count of items covered; {@code 1} if this 54579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * is a self-reference 55579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 56579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private final int itemCount; 57579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 58579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 59579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs a list item with instances of this class representing 60579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * the contents of the given array of sections, adding it to the 61579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * given map section. 62579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 63579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param sections {@code non-null;} the sections 64579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param mapSection {@code non-null;} the section that the resulting map 65579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * should be added to; it should be empty on entry to this method 66579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 67579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public static void addMap(Section[] sections, 68579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson MixedItemSection mapSection) { 69579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (sections == null) { 70579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("sections == null"); 71579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 72579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 73579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (mapSection.items().size() != 0) { 74579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException( 75579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson "mapSection.items().size() != 0"); 76579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 77579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 78579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ArrayList<MapItem> items = new ArrayList<MapItem>(50); 79579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 80579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (Section section : sections) { 81579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ItemType currentType = null; 82579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Item firstItem = null; 83579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Item lastItem = null; 84579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int count = 0; 85579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 86579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson for (Item item : section.items()) { 87579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson ItemType type = item.itemType(); 88579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (type != currentType) { 89579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (count != 0) { 90579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson items.add(new MapItem(currentType, section, 91579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson firstItem, lastItem, count)); 92579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 93579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson currentType = type; 94579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson firstItem = item; 95579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson count = 0; 96579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 97579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson lastItem = item; 98579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson count++; 99579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 100579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 101579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (count != 0) { 102579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Add a MapItem for the final items in the section. 103579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson items.add(new MapItem(currentType, section, 104579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson firstItem, lastItem, count)); 105579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else if (section == mapSection) { 106579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // Add a MapItem for the self-referential section. 107579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson items.add(new MapItem(mapSection)); 108579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 109579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 110579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 111579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson mapSection.add( 112579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson new UniformListItem<MapItem>(ItemType.TYPE_MAP_LIST, items)); 113579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 114579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 115579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 116579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs an instance. 117579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 118579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param type {@code non-null;} item type this instance covers 119579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param section {@code non-null;} section this instance covers 120579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param firstItem {@code non-null;} first item covered 121579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param lastItem {@code non-null;} last item covered 122579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param itemCount {@code > 0;} count of items covered 123579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 124579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private MapItem(ItemType type, Section section, Item firstItem, 125579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson Item lastItem, int itemCount) { 126579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson super(ALIGNMENT, WRITE_SIZE); 127579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 128579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (type == null) { 129579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("type == null"); 130579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 131579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 132579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (section == null) { 133579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("section == null"); 134579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 135579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 136579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (firstItem == null) { 137579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("firstItem == null"); 138579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 139579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 140579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (lastItem == null) { 141579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("lastItem == null"); 142579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 143579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 144579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (itemCount <= 0) { 145579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new IllegalArgumentException("itemCount <= 0"); 146579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 147579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 148579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.type = type; 149579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.section = section; 150579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.firstItem = firstItem; 151579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.lastItem = lastItem; 152579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.itemCount = itemCount; 153579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 154579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 155579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** 156579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * Constructs a self-referential instance. This instance is meant to 157579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * represent the section containing the {@code map_list}. 158579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * 159579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson * @param section {@code non-null;} section this instance covers 160579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson */ 161579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson private MapItem(Section section) { 162579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson super(ALIGNMENT, WRITE_SIZE); 163579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 164579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (section == null) { 165579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson throw new NullPointerException("section == null"); 166579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 167579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 168579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.type = ItemType.TYPE_MAP_LIST; 169579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.section = section; 170579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.firstItem = null; 171579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.lastItem = null; 172579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson this.itemCount = 1; 173579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 174579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 175579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 176579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 177579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public ItemType itemType() { 178579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return ItemType.TYPE_MAP_ITEM; 179579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 180579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 181579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 182579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 183579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public String toString() { 184579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson StringBuffer sb = new StringBuffer(100); 185579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 186579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson sb.append(getClass().getName()); 187579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson sb.append('{'); 188579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson sb.append(section.toString()); 189579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson sb.append(' '); 190579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson sb.append(type.toHuman()); 191579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson sb.append('}'); 192579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 193579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return sb.toString(); 194579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 195579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 196579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 197579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 198579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public void addContents(DexFile file) { 199579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson // We have nothing to add. 200579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 201579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 202579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 203579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 204579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson public final String toHuman() { 205579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson return toString(); 206579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 207579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 208579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson /** {@inheritDoc} */ 209579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson @Override 210579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson protected void writeTo0(DexFile file, AnnotatedOutput out) { 211579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int value = type.getMapValue(); 212579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson int offset; 213579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 214579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (firstItem == null) { 215579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson offset = section.getFileOffset(); 216579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } else { 217579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson offset = section.getAbsoluteItemOffset(firstItem); 218579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 219579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 220579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson if (out.annotates()) { 221579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(0, offsetString() + ' ' + type.getTypeName() + 222579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson " map"); 223579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(2, " type: " + Hex.u2(value) + " // " + 224579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson type.toString()); 225579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(2, " unused: 0"); 226579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(4, " size: " + Hex.u4(itemCount)); 227579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.annotate(4, " offset: " + Hex.u4(offset)); 228579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 229579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson 230579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.writeShort(value); 231579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.writeShort(0); // unused 232579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.writeInt(itemCount); 233579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson out.writeInt(offset); 234579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson } 235579d7739c53a2707ad711a2d2cae46d7d782f06Jesse Wilson} 236