183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com/* 2a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * Copyright (C) 2007 The Android Open Source Project 383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 4a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * Licensed under the Apache License, Version 2.0 (the "License"); 5a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * you may not use this file except in compliance with the License. 6a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * You may obtain a copy of the License at 783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * 8a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * http://www.apache.org/licenses/LICENSE-2.0 9a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * 10a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * Unless required by applicable law or agreed to in writing, software 11a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * distributed under the License is distributed on an "AS IS" BASIS, 12a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * See the License for the specific language governing permissions and 14a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * limitations under the License. 1583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 1683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 17128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com/* 18128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * As per the Apache license requirements, this file has been modified 19128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * from its original state. 20128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * 21128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * Such modifications are Copyright (C) 2010 Ben Gruver, and are released 22128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * under the original license 23128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com */ 24128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com 2583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.compackage org.jf.dexlib.Util; 2683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 2783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.comimport java.io.IOException; 2883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.comimport java.io.Writer; 2983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.comimport java.util.ArrayList; 3083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 3183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com/** 3283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Implementation of {@link AnnotatedOutput} which stores the written data 3383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * into a <code>byte[]</code>. 349ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 3583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * <p><b>Note:</b> As per the {@link Output} interface, multi-byte 3683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * writes all use little-endian order.</p> 3783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 3883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.compublic final class ByteArrayAnnotatedOutput 3983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com implements AnnotatedOutput { 4083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** default size for stretchy instances */ 4183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private static final int DEFAULT_SIZE = 1000; 429ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com 4383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 4483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * whether the instance is stretchy, that is, whether its array 4583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * may be resized to increase capacity 4683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 4783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private final boolean stretchy; 4883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 4983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** non-null; the data itself */ 5083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private byte[] data; 5183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 5283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** >= 0; current output cursor */ 5383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private int cursor; 5483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 5583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** whether annotations are to be verbose */ 5683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private boolean verbose; 5783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 5883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 5983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * null-ok; list of annotations, or <code>null</code> if this instance 609ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * isn't keeping them 6183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 6283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private ArrayList<Annotation> annotations; 6383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 6483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** >= 40 (if used); the desired maximum annotation width */ 6583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private int annotationWidth; 6683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 6783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 6883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * >= 8 (if used); the number of bytes of hex output to use 699ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * in annotations 7083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 7183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private int hexCols; 7283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 7383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private int currentIndent = 0; 7483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private int indentAmount = 2; 7583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 7683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 7783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Constructs an instance with a fixed maximum size. Note that the 7883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * given array is the only one that will be used to store data. In 7983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * particular, no reallocation will occur in order to expand the 8083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * capacity of the resulting instance. Also, the constructed 8183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * instance does not keep annotations by default. 829ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 8383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param data non-null; data array to use for output 8483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 8583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public ByteArrayAnnotatedOutput(byte[] data) { 8683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this(data, false); 8783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 8883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 8983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 9083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Constructs a "stretchy" instance. The underlying array may be 9183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * reallocated. The constructed instance does not keep annotations 9283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * by default. 9383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 9483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public ByteArrayAnnotatedOutput() { 9583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this(new byte[DEFAULT_SIZE], true); 9683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 9783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 9883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 9983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Internal constructor. 1009ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 10183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param data non-null; data array to use for output 10283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param stretchy whether the instance is to be stretchy 10383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 10483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private ByteArrayAnnotatedOutput(byte[] data, boolean stretchy) { 10583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (data == null) { 10683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throw new NullPointerException("data == null"); 10783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 10883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 10983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.stretchy = stretchy; 11083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.data = data; 11183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.cursor = 0; 11283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.verbose = false; 11383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.annotations = null; 11483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.annotationWidth = 0; 11583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.hexCols = 0; 11683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 11783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 11883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 11983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Gets the underlying <code>byte[]</code> of this instance, which 12083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * may be larger than the number of bytes written 1219ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 12283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @see #toByteArray 1239ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 12483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @return non-null; the <code>byte[]</code> 12583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 12683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public byte[] getArray() { 12783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return data; 12883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 12983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 13083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 13183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Constructs and returns a new <code>byte[]</code> that contains 13283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * the written contents exactly (that is, with no extra unwritten 13383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * bytes at the end). 1349ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 13583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @see #getArray 1369ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 13783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @return non-null; an appropriately-constructed array 13883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 13983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public byte[] toByteArray() { 14083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com byte[] result = new byte[cursor]; 14183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com System.arraycopy(data, 0, result, 0, cursor); 14283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return result; 14383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 14483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 14583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 14683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public int getCursor() { 14783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return cursor; 14883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 14983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 15083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 15183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void assertCursor(int expectedCursor) { 15283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (cursor != expectedCursor) { 15383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throw new ExceptionWithContext("expected cursor " + 15483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com expectedCursor + "; actual value: " + cursor); 15583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 15683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 15783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 15883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 15983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void writeByte(int value) { 16083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int writeAt = cursor; 16183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int end = writeAt + 1; 16283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 16383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (stretchy) { 16483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com ensureCapacity(end); 16583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else if (end > data.length) { 16683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throwBounds(); 16783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return; 16883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 16983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 17083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt] = (byte) value; 17183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com cursor = end; 17283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 17383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 17483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 17583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void writeShort(int value) { 17683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int writeAt = cursor; 17783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int end = writeAt + 2; 17883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 17983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (stretchy) { 18083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com ensureCapacity(end); 18183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else if (end > data.length) { 18283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throwBounds(); 18383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return; 18483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 18583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 18683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt] = (byte) value; 18783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt + 1] = (byte) (value >> 8); 18883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com cursor = end; 18983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 19083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 19183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 19283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void writeInt(int value) { 19383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int writeAt = cursor; 19483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int end = writeAt + 4; 19583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 19683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (stretchy) { 19783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com ensureCapacity(end); 19883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else if (end > data.length) { 19983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throwBounds(); 20083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return; 20183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 20283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 20383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt] = (byte) value; 20483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt + 1] = (byte) (value >> 8); 20583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt + 2] = (byte) (value >> 16); 20683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt + 3] = (byte) (value >> 24); 20783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com cursor = end; 20883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 20983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 21083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 21183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void writeLong(long value) { 21283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int writeAt = cursor; 21383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int end = writeAt + 8; 21483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 21583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (stretchy) { 21683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com ensureCapacity(end); 21783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else if (end > data.length) { 21883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throwBounds(); 21983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return; 22083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 22183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 22283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int half = (int) value; 22383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt] = (byte) half; 22483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt + 1] = (byte) (half >> 8); 22583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt + 2] = (byte) (half >> 16); 22683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt + 3] = (byte) (half >> 24); 22783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 22883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com half = (int) (value >> 32); 22983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt + 4] = (byte) half; 23083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt + 5] = (byte) (half >> 8); 23183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt + 6] = (byte) (half >> 16); 23283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data[writeAt + 7] = (byte) (half >> 24); 23383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 23483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com cursor = end; 23583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 23683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 23783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 23883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public int writeUnsignedLeb128(int value) { 23983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com long remaining = (value & 0xFFFFFFFFL) >> 7; 24083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com long lValue = value; 24183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int count = 0; 24283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 24383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com while (remaining != 0) { 24483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com writeByte((int)(lValue & 0x7f) | 0x80); 24583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com lValue = remaining; 24683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com remaining >>= 7; 24783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com count++; 24883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 24983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 25083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com writeByte((int)(lValue & 0x7f)); 25183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return count + 1; 25283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 25383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 25483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 25583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public int writeSignedLeb128(int value) { 25683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int remaining = value >> 7; 25783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int count = 0; 25883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com boolean hasMore = true; 25983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1; 26083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 26183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com while (hasMore) { 26283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com hasMore = (remaining != end) 26383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com || ((remaining & 1) != ((value >> 6) & 1)); 26483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 26583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com writeByte((value & 0x7f) | (hasMore ? 0x80 : 0)); 26683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com value = remaining; 26783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com remaining >>= 7; 26883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com count++; 26983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 27083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 27183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return count; 27283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 2739ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com 27483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 27583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void write(ByteArray bytes) { 27683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int blen = bytes.size(); 27783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int writeAt = cursor; 27883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int end = writeAt + blen; 27983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 28083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (stretchy) { 28183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com ensureCapacity(end); 28283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else if (end > data.length) { 28383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throwBounds(); 28483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return; 28583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 28683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 28783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com bytes.getBytes(data, writeAt); 28883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com cursor = end; 28983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 29083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 29183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 29283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void write(byte[] bytes, int offset, int length) { 29383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int writeAt = cursor; 29483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int end = writeAt + length; 29583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int bytesEnd = offset + length; 29683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 29783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com // twos-complement math trick: ((x < 0) || (y < 0)) <=> ((x|y) < 0) 29883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (((offset | length | end) < 0) || (bytesEnd > bytes.length)) { 29983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throw new IndexOutOfBoundsException("bytes.length " + 3009ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com bytes.length + "; " + 30183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com offset + "..!" + end); 30283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 30383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 30483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (stretchy) { 30583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com ensureCapacity(end); 30683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else if (end > data.length) { 30783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throwBounds(); 30883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return; 30983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 31083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 31183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com System.arraycopy(bytes, offset, data, writeAt, length); 31283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com cursor = end; 31383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 31483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 31583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 31683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void write(byte[] bytes) { 31783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com write(bytes, 0, bytes.length); 31883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 31983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 32083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 32183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void writeZeroes(int count) { 32283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (count < 0) { 32383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throw new IllegalArgumentException("count < 0"); 32483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 32583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 32683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int end = cursor + count; 32783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 32883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (stretchy) { 32983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com ensureCapacity(end); 33083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else if (end > data.length) { 33183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throwBounds(); 33283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return; 33383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 33483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 33583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /* 33683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * There is no need to actually write zeroes, since the array is 33783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * already preinitialized with zeroes. 33883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 33983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 34083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com cursor = end; 34183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 34283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 34383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 34483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void alignTo(int alignment) { 34583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int mask = alignment - 1; 34683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 34783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if ((alignment < 0) || ((mask & alignment) != 0)) { 34883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throw new IllegalArgumentException("bogus alignment"); 34983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 35083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 35183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int end = (cursor + mask) & ~mask; 35283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 35383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (stretchy) { 35483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com ensureCapacity(end); 35583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else if (end > data.length) { 35683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throwBounds(); 35783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return; 35883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 35983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 36083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /* 36183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * There is no need to actually write zeroes, since the array is 36283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * already preinitialized with zeroes. 36383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 36483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 36583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com cursor = end; 36683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 36783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 36883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 36983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public boolean annotates() { 37083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return (annotations != null); 37183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 37283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 37383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 37483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public boolean isVerbose() { 37583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return verbose; 37683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 37783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 37883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 37983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void annotate(String msg) { 38083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (annotations == null) { 38183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return; 38283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 38383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 38483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com endAnnotation(); 38583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com annotations.add(new Annotation(cursor, msg, currentIndent)); 38683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 38783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 38883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void indent() { 38983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com currentIndent++; 39083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 39183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 39283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void deindent() { 39383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com currentIndent--; 39483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (currentIndent < 0) { 39583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com currentIndent = 0; 39683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 39783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 39883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 39983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void setIndentAmount(int indentAmount) { 40083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.indentAmount = indentAmount; 40183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 40283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 40383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 40483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void annotate(int amt, String msg) { 40583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (annotations == null) { 40683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return; 40783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 40883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 40983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com endAnnotation(); 41083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 41183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int asz = annotations.size(); 41283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int lastEnd = (asz == 0) ? 0 : annotations.get(asz - 1).getEnd(); 41383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int startAt; 41483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 41583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (lastEnd <= cursor) { 41683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com startAt = cursor; 41783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else { 41883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com startAt = lastEnd; 41983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 42083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 42183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com annotations.add(new Annotation(startAt, startAt + amt, msg, currentIndent)); 42283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 42383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 42483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 42583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void endAnnotation() { 42683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (annotations == null) { 42783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return; 42883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 42983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 43083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int sz = annotations.size(); 43183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 43283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (sz != 0) { 43383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com annotations.get(sz - 1).setEndIfUnset(cursor); 43483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 43583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 43683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 43783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** {@inheritDoc} */ 43883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public int getAnnotationWidth() { 43983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int leftWidth = 8 + (hexCols * 2) + (hexCols / 2); 44083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 44183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return annotationWidth - leftWidth; 44283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 44383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 44483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 44583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Indicates that this instance should keep annotations. This method may 44683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * be called only once per instance, and only before any data has been 44783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * written to the it. 4489ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 44983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param annotationWidth >= 40; the desired maximum annotation width 45083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param verbose whether or not to indicate verbose annotations 45183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 45283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void enableAnnotations(int annotationWidth, boolean verbose) { 45383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if ((annotations != null) || (cursor != 0)) { 45483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throw new RuntimeException("cannot enable annotations"); 45583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 45683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 45783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (annotationWidth < 40) { 45883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throw new IllegalArgumentException("annotationWidth < 40"); 45983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 46083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 46183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int hexCols = (((annotationWidth - 7) / 15) + 1) & ~1; 46283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (hexCols < 6) { 46383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com hexCols = 6; 46483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else if (hexCols > 10) { 46583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com hexCols = 10; 46683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 46783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 46883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.annotations = new ArrayList<Annotation>(1000); 46983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.annotationWidth = annotationWidth; 47083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.hexCols = hexCols; 47183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.verbose = verbose; 47283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 47383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 47483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 47583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Finishes up annotation processing. This closes off any open 47683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * annotations and removes annotations that don't refer to written 47783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * data. 47883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 47983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void finishAnnotating() { 48083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com // Close off the final annotation, if any. 48183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com endAnnotation(); 48283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 48383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com // Remove annotations that refer to unwritten data. 48483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (annotations != null) { 48583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int asz = annotations.size(); 48683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com while (asz > 0) { 48783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com Annotation last = annotations.get(asz - 1); 48883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (last.getStart() > cursor) { 48983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com annotations.remove(asz - 1); 49083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com asz--; 49183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else if (last.getEnd() > cursor) { 49283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com last.setEnd(cursor); 49383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com break; 49483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else { 49583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com break; 49683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 49783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 49883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 49983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 50083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 50183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 50283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Writes the annotated content of this instance to the given writer. 5039ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 50483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param out non-null; where to write to 50583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 50683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void writeAnnotationsTo(Writer out) throws IOException { 50783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int width2 = getAnnotationWidth(); 50883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int width1 = annotationWidth - width2 - 1; 50983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 51083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com StringBuilder padding = new StringBuilder(); 51183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com for (int i=0; i<1000; i++) { 51283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com padding.append(' '); 51383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 51483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 51583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com TwoColumnOutput twoc = new TwoColumnOutput(out, width1, width2, "|"); 51683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com Writer left = twoc.getLeft(); 51783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com Writer right = twoc.getRight(); 51883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int leftAt = 0; // left-hand byte output cursor 51983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int rightAt = 0; // right-hand annotation index 52083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int rightSz = annotations.size(); 52183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 52283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com while ((leftAt < cursor) && (rightAt < rightSz)) { 52383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com Annotation a = annotations.get(rightAt); 52483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int start = a.getStart(); 52583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com int end; 52683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com String text; 52783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 52883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (leftAt < start) { 52983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com // This is an area with no annotation. 53083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com end = start; 53183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com start = leftAt; 53283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com text = ""; 53383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } else { 53483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com // This is an area with an annotation. 53583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com end = a.getEnd(); 53683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com text = padding.substring(0, a.getIndent() * this.indentAmount) + a.getText(); 53783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com rightAt++; 53883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 53983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 54083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com left.write(Hex.dump(data, start, end - start, start, hexCols, 6)); 54183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com right.write(text); 54283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com twoc.flush(); 54383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com leftAt = end; 54483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 54583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 54683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (leftAt < cursor) { 54783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com // There is unannotated output at the end. 54883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com left.write(Hex.dump(data, leftAt, cursor - leftAt, leftAt, 54983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com hexCols, 6)); 55083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 55183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 55283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com while (rightAt < rightSz) { 55383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com // There are zero-byte annotations at the end. 55483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com right.write(annotations.get(rightAt).getText()); 55583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com rightAt++; 55683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 55783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 55883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com twoc.flush(); 55983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 56083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 56183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 56283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Throws the excpetion for when an attempt is made to write past the 56383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * end of the instance. 56483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 56583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private static void throwBounds() { 56683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com throw new IndexOutOfBoundsException("attempt to write past the end"); 56783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 56883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 56983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 57083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Reallocates the underlying array if necessary. Calls to this method 57183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * should be guarded by a test of {@link #stretchy}. 5729ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 57383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param desiredSize >= 0; the desired minimum total size of the array 57483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 57583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private void ensureCapacity(int desiredSize) { 57683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (data.length < desiredSize) { 57783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com byte[] newData = new byte[desiredSize * 2 + 1000]; 57883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com System.arraycopy(data, 0, newData, 0, cursor); 57983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com data = newData; 58083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 58183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 58283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 58383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 58483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Annotation on output. 58583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 58683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private static class Annotation { 58783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** >= 0; start of annotated range (inclusive) */ 58883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private final int start; 58983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 59083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 59183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * >= 0; end of annotated range (exclusive); 5929ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * <code>Integer.MAX_VALUE</code> if unclosed 59383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 59483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private int end; 59583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 59683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** non-null; annotation text */ 59783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private final String text; 59883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 59983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com private int indent; 60083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 60183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 60283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Constructs an instance. 6039ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 60483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param start >= 0; start of annotated range 60583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param end >= start; end of annotated range (exclusive) or 60683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * <code>Integer.MAX_VALUE</code> if unclosed 60783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param text non-null; annotation text 60883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 60983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public Annotation(int start, int end, String text, int indent) { 61083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.start = start; 61183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.end = end; 61283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.text = text; 61383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.indent = indent; 61483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 61583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 61683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 61783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Constructs an instance. It is initally unclosed. 6189ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 61983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param start >= 0; start of annotated range 62083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param text non-null; annotation text 62183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 62283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public Annotation(int start, String text, int indent) { 62383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this(start, Integer.MAX_VALUE, text, indent); 62483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 62583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 62683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 62783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Sets the end as given, but only if the instance is unclosed; 62883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * otherwise, do nothing. 6299ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 63083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param end >= start; the end 63183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 63283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void setEndIfUnset(int end) { 63383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com if (this.end == Integer.MAX_VALUE) { 63483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.end = end; 63583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 63683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 63783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 63883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 63983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Sets the end as given. 6409ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 64183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @param end >= start; the end 64283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 64383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public void setEnd(int end) { 64483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com this.end = end; 64583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 64683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 64783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 64883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Gets the start. 6499ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 65083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @return the start 65183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 65283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public int getStart() { 65383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return start; 65483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 65583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 65683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 65783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Gets the end. 6589ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 65983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @return the end 66083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 66183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public int getEnd() { 66283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return end; 66383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 66483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 66583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com /** 66683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Gets the text. 6679ab2b45ec8531658e3acf0b96b11a214ce8d3b60JesusFreke@JesusFreke.com * 66883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * @return non-null; the text 66983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */ 67083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public String getText() { 67183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return text; 67283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 67383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com 67483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com public int getIndent() { 67583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com return indent; 67683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 67783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com } 67883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com} 679