1 /*
2  * Copyright (c) 2008-2019 Emmanuel Dupuy.
3  * This project is distributed under the GPLv3 license.
4  * This is a Copyleft license that gives the user the right to use,
5  * copy and modify the code freely for non-commercial purposes.
6  */
7 
8 package org.jd.gui.util.decompiler;
9 
10 import org.jd.core.v1.api.printer.Printer;
11 
12 public class StringBuilderPrinter implements Printer {
13     protected static final String TAB = "  ";
14     protected static final String NEWLINE = "\n";
15 
16     protected StringBuilder stringBuffer = new StringBuilder(10*1024);
17 
18     protected boolean unicodeEscape = true;
19     protected boolean realignmentLineNumber = false;
20 
21     protected int majorVersion = 0;
22     protected int minorVersion = 0;
23     protected int indentationCount;
24 
setUnicodeEscape(boolean unicodeEscape)25     public void setUnicodeEscape(boolean unicodeEscape) { this.unicodeEscape = unicodeEscape; }
setRealignmentLineNumber(boolean realignmentLineNumber)26     public void setRealignmentLineNumber(boolean realignmentLineNumber) { this.realignmentLineNumber = realignmentLineNumber; }
27 
getMajorVersion()28     public int getMajorVersion() { return majorVersion; }
getMinorVersion()29     public int getMinorVersion() { return minorVersion; }
getStringBuffer()30     public StringBuilder getStringBuffer() { return stringBuffer; }
31 
escape(String s)32     protected void escape(String s) {
33         if (unicodeEscape && (s != null)) {
34             int length = s.length();
35 
36             for (int i=0; i<length; i++) {
37                 char c = s.charAt(i);
38 
39                 if (c == '\t') {
40                     stringBuffer.append(c);
41                 } else if (c < 32) {
42                     // Write octal format
43                     stringBuffer.append("\\0");
44                     stringBuffer.append((char) ('0' + (c >> 3)));
45                     stringBuffer.append((char) ('0' + (c & 0x7)));
46                 } else if (c > 127) {
47                     // Write octal format
48                     stringBuffer.append("\\u");
49 
50                     int z = (c >> 12);
51                     stringBuffer.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z)));
52                     z = ((c >> 8) & 0xF);
53                     stringBuffer.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z)));
54                     z = ((c >> 4) & 0xF);
55                     stringBuffer.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z)));
56                     z = (c & 0xF);
57                     stringBuffer.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z)));
58                 } else {
59                     stringBuffer.append(c);
60                 }
61             }
62         } else {
63             stringBuffer.append(s);
64         }
65     }
66 
67     // --- Printer --- //
68     @Override
start(int maxLineNumber, int majorVersion, int minorVersion)69     public void start(int maxLineNumber, int majorVersion, int minorVersion) {
70         this.stringBuffer.setLength(0);
71         this.majorVersion = majorVersion;
72         this.minorVersion = minorVersion;
73         this.indentationCount = 0;
74     }
75 
end()76     @Override public void end() {}
77 
printText(String text)78     @Override public void printText(String text) { escape(text); }
printNumericConstant(String constant)79     @Override public void printNumericConstant(String constant) { escape(constant); }
printStringConstant(String constant, String ownerInternalName)80     @Override public void printStringConstant(String constant, String ownerInternalName) { escape(constant); }
printKeyword(String keyword)81     @Override public void printKeyword(String keyword) { stringBuffer.append(keyword); }
82 
printDeclaration(int type, String internalTypeName, String name, String descriptor)83     @Override public void printDeclaration(int type, String internalTypeName, String name, String descriptor) { escape(name); }
printReference(int type, String internalTypeName, String name, String descriptor, String ownerInternalName)84     @Override public void printReference(int type, String internalTypeName, String name, String descriptor, String ownerInternalName) { escape(name); }
85 
indent()86     @Override public void indent() { indentationCount++; }
unindent()87     @Override public void unindent() { if (indentationCount > 0) indentationCount--; }
88 
startLine(int lineNumber)89     @Override public void startLine(int lineNumber) { for (int i=0; i<indentationCount; i++) stringBuffer.append(TAB); }
endLine()90     @Override public void endLine() { stringBuffer.append(NEWLINE); }
extraLine(int count)91     @Override public void extraLine(int count) { if (realignmentLineNumber) while (count-- > 0) stringBuffer.append(NEWLINE); }
92 
startMarker(int type)93     @Override public void startMarker(int type) {}
endMarker(int type)94     @Override public void endMarker(int type) {}
95 }
96