BaseDumper.java revision de75089fb7216d19e9c22cce4dc62a49513477d3
1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.command.dump; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.code.ConcreteMethod; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.Member; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.cf.iface.ParseObserver; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.code.AccessFlags; 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.ByteArray; 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.IndentingWriter; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.TwoColumnOutput; 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException; 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.PrintStream; 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.StringWriter; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/** 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Base class for the various human-friendly dumpers. 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic abstract class BaseDumper 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project implements ParseObserver { 3799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} array of data being dumped */ 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final byte[] bytes; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** whether or not to include the raw bytes (in a column on the left) */ 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final boolean rawBytes; 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 4399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} where to dump to */ 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final PrintStream out; 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** width of the output in columns */ 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int width; 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 5099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * {@code non-null;} the file path for the class, excluding any base 51de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * directory specification 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final String filePath; 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** whether to be strict about parsing */ 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final boolean strictParse; 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** number of bytes per line in hex dumps */ 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private final int hexCols; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** the current level of indentation */ 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int indent; 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project /** {@code non-null;} the current column separator string */ 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private String separator; 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** the offset of the next byte to dump */ 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int at; 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** commandline parsedArgs */ 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected Args args; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs an instance. 75de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param bytes {@code non-null;} bytes of the (alleged) class file 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * on the left) 7899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param out {@code non-null;} where to dump to 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param filePath the file path for the class, excluding any base 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * directory specification 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public BaseDumper(byte[] bytes, PrintStream out, 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String filePath, Args args) { 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.bytes = bytes; 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.rawBytes = args.rawBytes; 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.out = out; 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.width = (args.width <= 0) ? 79 : args.width; 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.filePath = filePath; 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.strictParse = args.strictParse; 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.indent = 0; 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.separator = rawBytes ? "|" : ""; 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.at = 0; 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.args = args; 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int hexCols = (((width - 5) / 15) + 1) & ~1; 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (hexCols < 6) { 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hexCols = 6; 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (hexCols > 10) { 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hexCols = 10; 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project this.hexCols = hexCols; 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Computes the total width, in register-units, of the parameters for 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this method. 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param meth method to process 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return width in register-units 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static int computeParamWidth(ConcreteMethod meth, boolean isStatic) { 11199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project return meth.getEffectiveDescriptor().getParameterTypes(). 11299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project getWordCount(); 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void changeIndent(int indentDelta) { 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project indent += indentDelta; 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project separator = rawBytes ? "|" : ""; 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < indent; i++) { 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project separator += " "; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void parsed(ByteArray bytes, int offset, int len, String human) { 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = bytes.underlyingOffset(offset, getBytes()); 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project boolean rawBytes = getRawBytes(); 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset < at) { 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project println("<dump skipped backwards to " + Hex.u4(offset) + ">"); 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at = offset; 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (offset > at) { 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String hex = rawBytes ? hexDump(at, offset - at) : ""; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project print(twoColumns(hex, "<skipped to " + Hex.u4(offset) + ">")); 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at = offset; 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String hex = rawBytes ? hexDump(offset, len) : ""; 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project print(twoColumns(hex, human)); 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at += len; 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void startParsingMember(ByteArray bytes, int offset, String name, 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String descriptor) { 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // This space intentionally left blank. 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** {@inheritDoc} */ 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public void endParsingMember(ByteArray bytes, int offset, String name, 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project String descriptor, Member member) { 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // This space intentionally left blank. 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the current dump cursor (that is, the offset of the expected 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * next byte to dump). 160de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 16199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the dump cursor 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final int getAt() { 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return at; 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sets the dump cursor to the indicated offset in the given array. 169de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 17099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param arr {@code non-null;} array in question 17199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param offset {@code >= 0;} offset into the array 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final void setAt(ByteArray arr, int offset) { 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project at = arr.underlyingOffset(offset, bytes); 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 17899409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the array of {@code byte}s to process. 179de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 18099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the bytes 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final byte[] getBytes() { 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return bytes; 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the filesystem/jar path of the file being dumped. 188de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 18999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the path 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final String getFilePath() { 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return filePath; 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets whether to be strict about parsing. 197de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return whether to be strict about parsing 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final boolean getStrictParse() { 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return strictParse; 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Prints the given string to this instance's output stream. 206de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 20799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param s {@code null-ok;} string to print 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final void print(String s) { 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.print(s); 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Prints the given string to this instance's output stream, followed 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * by a newline. 216de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 21799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param s {@code null-ok;} string to print 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final void println(String s) { 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project out.println(s); 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets whether this dump is to include raw bytes. 225de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return the raw bytes flag 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final boolean getRawBytes() { 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return rawBytes; 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 23399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * Gets the width of the first column of output. This is {@code 0} 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * unless raw bytes are being included in the output. 235de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 23699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the width of the first column 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final int getWidth1() { 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (rawBytes) { 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 5 + (hexCols * 2) + (hexCols / 2); 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Gets the width of the second column of output. 248de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 24999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code >= 0;} the width of the second column 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final int getWidth2() { 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int w1 = rawBytes ? (getWidth1() + 1) : 0; 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return width - w1 - (indent * 2); 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Constructs a hex data dump of the given portion of {@link #bytes}. 258de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param offset offset to start dumping at 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param len length to dump 26199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the dump 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final String hexDump(int offset, int len) { 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return Hex.dump(bytes, offset, len, offset, hexCols, 4); 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /** 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Combines a pair of strings as two columns, or if this is one-column 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * output, format the otherwise-second column. 270de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro * 27199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param s1 {@code non-null;} the first column's string 27299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @param s2 {@code non-null;} the second column's string 27399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project * @return {@code non-null;} the combined output 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project protected final String twoColumns(String s1, String s2) { 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int w1 = getWidth1(); 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int w2 = getWidth2(); 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (w1 == 0) { 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len2 = s2.length(); 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringWriter sw = new StringWriter(len2 * 2); 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project IndentingWriter iw = new IndentingWriter(sw, w2, separator); 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iw.write(s2); 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((len2 == 0) || (s2.charAt(len2 - 1) != '\n')) { 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iw.write('\n'); 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project iw.flush(); 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sw.toString(); 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return TwoColumnOutput.toString(s1, w1, separator, s2, w2); 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (IOException ex) { 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project throw new RuntimeException(ex); 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 300