1/* 2 * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.tools.javap; 27 28import java.io.PrintWriter; 29 30import com.sun.tools.classfile.AttributeException; 31import com.sun.tools.classfile.ConstantPoolException; 32import com.sun.tools.classfile.DescriptorException; 33 34/* 35 * A writer similar to a PrintWriter but which does not hide exceptions. 36 * The standard print calls are line-buffered; report calls write messages directly. 37 * 38 * <p><b>This is NOT part of any supported API. 39 * If you write code that depends on this, you do so at your own risk. 40 * This code and its internal interfaces are subject to change or 41 * deletion without notice.</b> 42 */ 43public class BasicWriter { 44 protected BasicWriter(Context context) { 45 lineWriter = LineWriter.instance(context); 46 out = context.get(PrintWriter.class); 47 messages = context.get(Messages.class); 48 if (messages == null) 49 throw new AssertionError(); 50 } 51 52 protected void print(String s) { 53 lineWriter.print(s); 54 } 55 56 protected void print(Object o) { 57 lineWriter.print(o == null ? null : o.toString()); 58 } 59 60 protected void println() { 61 lineWriter.println(); 62 } 63 64 protected void println(String s) { 65 lineWriter.print(s); 66 lineWriter.println(); 67 } 68 69 protected void println(Object o) { 70 lineWriter.print(o == null ? null : o.toString()); 71 lineWriter.println(); 72 } 73 74 protected void indent(int delta) { 75 lineWriter.indent(delta); 76 } 77 78 protected void tab() { 79 lineWriter.tab(); 80 } 81 82 protected void setPendingNewline(boolean b) { 83 lineWriter.pendingNewline = b; 84 } 85 86 protected String report(AttributeException e) { 87 out.println("Error: " + e.getMessage()); // i18n? 88 return "???"; 89 } 90 91 protected String report(ConstantPoolException e) { 92 out.println("Error: " + e.getMessage()); // i18n? 93 return "???"; 94 } 95 96 protected String report(DescriptorException e) { 97 out.println("Error: " + e.getMessage()); // i18n? 98 return "???"; 99 } 100 101 protected String report(String msg) { 102 out.println("Error: " + msg); // i18n? 103 return "???"; 104 } 105 106 protected String space(int w) { 107 if (w < spaces.length && spaces[w] != null) 108 return spaces[w]; 109 110 StringBuilder sb = new StringBuilder(); 111 for (int i = 0; i < w; i++) 112 sb.append(" "); 113 114 String s = sb.toString(); 115 if (w < spaces.length) 116 spaces[w] = s; 117 118 return s; 119 } 120 121 private String[] spaces = new String[80]; 122 123 private LineWriter lineWriter; 124 private PrintWriter out; 125 protected Messages messages; 126 127 private static class LineWriter { 128 static LineWriter instance(Context context) { 129 LineWriter instance = context.get(LineWriter.class); 130 if (instance == null) 131 instance = new LineWriter(context); 132 return instance; 133 } 134 135 protected LineWriter(Context context) { 136 context.put(LineWriter.class, this); 137 Options options = Options.instance(context); 138 indentWidth = options.indentWidth; 139 tabColumn = options.tabColumn; 140 out = context.get(PrintWriter.class); 141 buffer = new StringBuilder(); 142 } 143 144 protected void print(String s) { 145 if (pendingNewline) { 146 println(); 147 pendingNewline = false; 148 } 149 if (s == null) 150 s = "null"; 151 for (int i = 0; i < s.length(); i++) { 152 char c = s.charAt(i); 153 switch (c) { 154 case ' ': 155 pendingSpaces++; 156 break; 157 158 case '\n': 159 println(); 160 break; 161 162 default: 163 if (buffer.length() == 0) 164 indent(); 165 if (pendingSpaces > 0) { 166 for (int sp = 0; sp < pendingSpaces; sp++) 167 buffer.append(' '); 168 pendingSpaces = 0; 169 } 170 buffer.append(c); 171 } 172 } 173 174 } 175 176 protected void println() { 177 // ignore/discard pending spaces 178 pendingSpaces = 0; 179 out.println(buffer); 180 buffer.setLength(0); 181 } 182 183 protected void indent(int delta) { 184 indentCount += delta; 185 } 186 187 protected void tab() { 188 int col = indentCount * indentWidth + tabColumn; 189 pendingSpaces += (col <= buffer.length() ? 1 : col - buffer.length()); 190 } 191 192 private void indent() { 193 pendingSpaces += (indentCount * indentWidth); 194 } 195 196 private final PrintWriter out; 197 private final StringBuilder buffer; 198 private int indentCount; 199 private final int indentWidth; 200 private final int tabColumn; 201 private boolean pendingNewline; 202 private int pendingSpaces; 203 } 204} 205 206