diff --git a/build.xml b/build.xml
index 9f4c208..33000ff 100644
--- a/build.xml
+++ b/build.xml
@@ -26,7 +26,7 @@
-
+
@@ -39,7 +39,7 @@
-
+
diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java
index afa2473..585ff5a 100644
--- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java
+++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java
@@ -459,6 +459,11 @@ public class ClassWriter {
}
else {
buffer.append(" = ");
+
+ if (initializer.type == Exprent.EXPRENT_CONST) {
+ ((ConstExprent) initializer).adjustConstType(fieldType);
+ }
+
// FIXME: special case field initializer. Can map to more than one method (constructor) and bytecode intruction.
buffer.append(initializer.toJava(indent, tracer));
}
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java
index 9296bb3..9b48600 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/ExprProcessor.java
@@ -896,23 +896,25 @@ public class ExprProcessor implements CodeConstants {
VarType rightType = exprent.getExprType();
- TextBuffer res = exprent.toJava(indent, tracer);
-
boolean cast =
castAlways ||
(!leftType.isSuperset(rightType) && (rightType.equals(VarType.VARTYPE_OBJECT) || leftType.type != CodeConstants.TYPE_OBJECT)) ||
(castNull && rightType.type == CodeConstants.TYPE_NULL && !UNDEFINED_TYPE_STRING.equals(getTypeName(leftType))) ||
(isIntConstant(exprent) && VarType.VARTYPE_INT.isStrictSuperset(leftType));
+
+ boolean quote = cast && exprent.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST);
- if (cast) {
- if (exprent.getPrecedence() >= FunctionExprent.getPrecedence(FunctionExprent.FUNCTION_CAST)) {
- res.enclose("(", ")");
- }
+ if (cast) buffer.append('(').append(getCastTypeName(leftType)).append(')');
- res.prepend("(" + getCastTypeName(leftType) + ")");
+ if (quote) buffer.append('(');
+
+ if (exprent.type == Exprent.EXPRENT_CONST) {
+ ((ConstExprent) exprent).adjustConstType(leftType);
}
- buffer.append(res);
+ buffer.append(exprent.toJava(indent, tracer));
+
+ if (quote) buffer.append(')');
return cast;
}
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java
index 95ebdc5..ef08e12 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/AssignmentExprent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -138,6 +138,10 @@ public class AssignmentExprent extends Exprent {
buffer.append(left.toJava(indent, tracer));
}
+ if (right.type == EXPRENT_CONST) {
+ ((ConstExprent) right).adjustConstType(leftType);
+ }
+
TextBuffer res = right.toJava(indent, tracer);
if (condType == CONDITION_NONE &&
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
index 4b9b687..31fe3cd 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java
@@ -28,12 +28,13 @@ import org.jetbrains.java.decompiler.struct.match.MatchNode;
import org.jetbrains.java.decompiler.struct.match.IMatchable.MatchProperties;
import org.jetbrains.java.decompiler.struct.match.MatchNode.RuleValue;
import org.jetbrains.java.decompiler.util.InterpreterUtil;
+import org.jetbrains.java.decompiler.util.TextUtil;
import java.util.*;
import java.util.Map.Entry;
public class ConstExprent extends Exprent {
- private static final Map ESCAPES = new HashMap() {{
+ private static final Map CHAR_ESCAPES = new HashMap() {{
put(new Integer(0x8), "\\b"); /* \u0008: backspace BS */
put(new Integer(0x9), "\\t"); /* \u0009: horizontal tab HT */
put(new Integer(0xA), "\\n"); /* \u000a: linefeed LF */
@@ -127,17 +128,17 @@ public class ConstExprent extends Exprent {
return new TextBuffer(Boolean.toString(((Integer)value).intValue() != 0));
case CodeConstants.TYPE_CHAR:
Integer val = (Integer)value;
- String ret = ESCAPES.get(val);
+ String ret = CHAR_ESCAPES.get(val);
if (ret == null) {
char c = (char)val.intValue();
- if (c >= 32 && c < 127 || !ascii && InterpreterUtil.isPrintableUnicode(c)) {
+ if (isPrintableAscii(c) || !ascii && TextUtil.isPrintableUnicode(c)) {
ret = String.valueOf(c);
}
else {
- ret = InterpreterUtil.charToUnicodeLiteral(c);
+ ret = TextUtil.charToUnicodeLiteral(c);
}
}
- return new TextBuffer(ret).enclose("\'", "\'");
+ return new TextBuffer(ret).enclose("'", "'");
case CodeConstants.TYPE_BYTE:
case CodeConstants.TYPE_BYTECHAR:
case CodeConstants.TYPE_SHORT:
@@ -306,7 +307,7 @@ public class ConstExprent extends Exprent {
buffer.append("\\\'");
break;
default:
- if (c >= 32 && c < 127 || !ascii && InterpreterUtil.isPrintableUnicode(c)) {
+ if (c >= 32 && c < 127 || !ascii && TextUtil.isPrintableUnicode(c)) {
buffer.append(c);
}
else {
@@ -389,6 +390,27 @@ public class ConstExprent extends Exprent {
this.constType = constType;
}
+ public void adjustConstType(VarType expectedType) {
+ // BYTECHAR and SHORTCHAR => CHAR in the CHAR context
+ if (expectedType.equals(VarType.VARTYPE_CHAR) &&
+ (constType.equals(VarType.VARTYPE_BYTECHAR) || constType.equals(VarType.VARTYPE_SHORTCHAR))) {
+ int intValue = getIntValue();
+ if (isPrintableAscii(intValue) || CHAR_ESCAPES.containsKey(intValue)) {
+ setConstType(VarType.VARTYPE_CHAR);
+ }
+ }
+ // CHAR => INT in the INT context
+ else if (expectedType.equals(VarType.VARTYPE_INT) &&
+ constType.equals(VarType.VARTYPE_CHAR)) {
+ setConstType(VarType.VARTYPE_INT);
+ }
+ }
+
+ private static boolean isPrintableAscii(int c) {
+ return c >= 32 && c < 127;
+ }
+
+
public Object getValue() {
return value;
}
diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java
index 48206a7..b8f212d 100644
--- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java
+++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/FunctionExprent.java
@@ -454,12 +454,35 @@ public class FunctionExprent extends Exprent {
tracer.addMapping(bytecode);
if (funcType <= FUNCTION_USHR) {
- return wrapOperandString(lstOperands.get(0), false, indent, tracer)
+ Exprent left = lstOperands.get(0);
+ Exprent right = lstOperands.get(1);
+
+ if (right.type == EXPRENT_CONST) {
+ ((ConstExprent) right).adjustConstType(left.getExprType());
+ }
+ else if (left.type == EXPRENT_CONST) {
+ ((ConstExprent) left).adjustConstType(right.getExprType());
+ }
+
+ return wrapOperandString(left, false, indent, tracer)
.append(OPERATORS[funcType])
- .append(wrapOperandString(lstOperands.get(1), true, indent, tracer));
+ .append(wrapOperandString(right, true, indent, tracer));
}
+ // try to determine more accurate type for 'char' literals
if (funcType >= FUNCTION_EQ) {
+ if (funcType <= FUNCTION_LE) {
+ Exprent left = lstOperands.get(0);
+ Exprent right = lstOperands.get(1);
+
+ if (right.type == EXPRENT_CONST) {
+ ((ConstExprent) right).adjustConstType(left.getExprType());
+ }
+ else if (left.type == EXPRENT_CONST) {
+ ((ConstExprent) left).adjustConstType(right.getExprType());
+ }
+ }
+
return wrapOperandString(lstOperands.get(0), false, indent, tracer)
.append(OPERATORS[funcType - FUNCTION_EQ + 11])
.append(wrapOperandString(lstOperands.get(1), true, indent, tracer));
@@ -484,11 +507,21 @@ public class FunctionExprent extends Exprent {
}
return res.append(".length");
case FUNCTION_IIF:
+ Exprent left = lstOperands.get(1);
+ Exprent right = lstOperands.get(2);
+
+ if (right.type == EXPRENT_CONST) {
+ ((ConstExprent) right).adjustConstType(left.getExprType());
+ }
+ else if (left.type == EXPRENT_CONST) {
+ ((ConstExprent) left).adjustConstType(right.getExprType());
+ }
+
return wrapOperandString(lstOperands.get(0), true, indent, tracer)
- .append("?")
- .append(wrapOperandString(lstOperands.get(1), true, indent, tracer))
- .append(":")
- .append(wrapOperandString(lstOperands.get(2), true, indent, tracer));
+ .append("?")
+ .append(wrapOperandString(left, true, indent, tracer))
+ .append(":")
+ .append(wrapOperandString(right, true, indent, tracer));
case FUNCTION_IPP:
return wrapOperandString(lstOperands.get(0), true, indent, tracer).append("++");
case FUNCTION_PPI:
diff --git a/src/org/jetbrains/java/decompiler/util/TextUtil.java b/src/org/jetbrains/java/decompiler/util/TextUtil.java
index 14e24f9..21f10e4 100644
--- a/src/org/jetbrains/java/decompiler/util/TextUtil.java
+++ b/src/org/jetbrains/java/decompiler/util/TextUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,12 +15,23 @@
*/
package org.jetbrains.java.decompiler.util;
+import org.jetbrains.java.decompiler.code.CodeConstants;
import org.jetbrains.java.decompiler.main.ClassesProcessor;
import org.jetbrains.java.decompiler.main.DecompilerContext;
import org.jetbrains.java.decompiler.main.TextBuffer;
+import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import org.jetbrains.java.decompiler.modules.decompiler.ExprProcessor;
+import java.util.Arrays;
+import java.util.HashSet;
+
public class TextUtil {
+ private static final HashSet KEYWORDS = new HashSet<>(Arrays.asList(
+ "abstract", "default", "if", "private", "this", "boolean", "do", "implements", "protected", "throw", "break", "double", "import",
+ "public", "throws", "byte", "else", "instanceof", "return", "transient", "case", "extends", "int", "short", "try", "catch", "final",
+ "interface", "static", "void", "char", "finally", "long", "strictfp", "volatile", "class", "float", "native", "super", "while",
+ "const", "for", "new", "switch", "continue", "goto", "package", "synchronized", "true", "false", "null", "assert"));
+
public static void writeQualifiedSuper(TextBuffer buf, String qualifier) {
ClassesProcessor.ClassNode classNode = (ClassesProcessor.ClassNode)DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE);
if (!qualifier.equals(classNode.classStruct.qualifiedName)) {
@@ -28,4 +39,48 @@ public class TextUtil {
}
buf.append("super");
}
-}
+
+ public static String getIndentString(int length) {
+ if (length == 0) return "";
+ StringBuilder buf = new StringBuilder();
+ String indent = (String)DecompilerContext.getProperty(IFernflowerPreferences.INDENT_STRING);
+ while (length-- > 0) {
+ buf.append(indent);
+ }
+ return buf.toString();
+ }
+
+ public static boolean isPrintableUnicode(char c) {
+ int t = Character.getType(c);
+ return t != Character.UNASSIGNED && t != Character.LINE_SEPARATOR && t != Character.PARAGRAPH_SEPARATOR &&
+ t != Character.CONTROL && t != Character.FORMAT && t != Character.PRIVATE_USE && t != Character.SURROGATE;
+ }
+
+ public static String charToUnicodeLiteral(int value) {
+ String sTemp = Integer.toHexString(value);
+ sTemp = ("0000" + sTemp).substring(sTemp.length());
+ return "\\u" + sTemp;
+ }
+
+ public static boolean isValidIdentifier(String id, int version) {
+ return isJavaIdentifier(id) && !isKeyword(id, version);
+ }
+
+ private static boolean isJavaIdentifier(String id) {
+ if (id.isEmpty() || !Character.isJavaIdentifierStart(id.charAt(0))) {
+ return false;
+ }
+
+ for (int i = 1; i < id.length(); i++) {
+ if (!Character.isJavaIdentifierPart(id.charAt(i))) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private static boolean isKeyword(String id, int version) {
+ return KEYWORDS.contains(id) || version > CodeConstants.BYTECODE_JAVA_5 && "enum".equals(id);
+ }
+}
\ No newline at end of file
diff --git a/testData/classes/pkg/TestConstType.class b/testData/classes/pkg/TestConstType.class
new file mode 100644
index 0000000..57d4fec
Binary files /dev/null and b/testData/classes/pkg/TestConstType.class differ
diff --git a/testData/results/TestClassLoop.dec b/testData/results/TestClassLoop.dec
index 0ea725e..5f386c2 100644
--- a/testData/results/TestClassLoop.dec
+++ b/testData/results/TestClassLoop.dec
@@ -51,10 +51,10 @@ public class TestClassLoop {
for(boolean var8 = false; var2 < var1; ++var2) {// 70 73 90
char var6 = var0.charAt(var2);// 74
- if(var6 == 48) {// 75
+ if (var6 == '0') {// 75
++var7;// 76
} else {
- if(var6 != 46) {// 77
+ if (var6 != '.') {// 77
break;
}
diff --git a/testData/results/TestConstType.dec b/testData/results/TestConstType.dec
new file mode 100644
index 0000000..9dd1b50
--- /dev/null
+++ b/testData/results/TestConstType.dec
@@ -0,0 +1,337 @@
+package pkg;
+
+public class TestConstType {
+ private char lineBreak = '\n';
+ private char zero = 0;
+
+ public void setLineBreak(char os) {
+ switch(os) {// 8
+ case 'u':
+ this.lineBreak = '\r';// 10
+ break;// 11
+ case 'w':
+ this.lineBreak = '\n';// 14
+ }
+
+ }// 17
+
+ public void init() {
+ this.setLineBreak('w');// 20
+ }// 21
+
+ public String convertIndentation(String text) {
+ if (text.charAt(0) == '\t') {// 24
+ text = text.replace('\t', ' ');// 25
+ }
+
+ return text;// 27
+ }
+
+ public void printalot() {
+ System.out.println('a');// 31
+ System.out.println('\t');// 32
+ System.out.println(0);// 34
+ System.out.println(65);// 35
+ System.out.println(120);// 36
+ System.out.println(32760);// 37
+ System.out.println(32761);// 38
+ System.out.println(35000);// 39
+ System.out.println(50000);// 40
+ System.out.println(128000);// 41
+ System.out.println(60793);// 42
+ System.out.println(60737);// 43
+ System.out.println(60777);// 44
+ System.out.println(60785);// 45
+ System.out.println(60835);// 46
+ System.out.println(60843);// 47
+ System.out.println(60851);// 48
+ System.out.println(60859);// 49
+ System.out.println(1048576);// 50
+ System.out.println(49152);// 51
+ System.out.println(44100);// 52
+ System.out.println(44101);// 53
+ System.out.println(44102);// 54
+ System.out.println(44103);// 55
+ System.out.println(60000);// 56
+ System.out.println(64000);// 57
+ System.out.println(65000);// 58
+ System.out.println(45000);// 59
+ }// 60
+
+ public char guessType(int val) {
+ if (0 <= val && val <= 127) {// 63
+ return 'X';// 64
+ } else if (-128 <= val && val <= 127) {// 66
+ return 'B';// 67
+ } else if (128 <= val && val <= 32767) {// 69
+ return 'Y';// 70
+ } else if (-32768 <= val && val <= 32767) {// 72
+ return 'S';// 73
+ } else {
+ return (char)(32768 <= val && val <= 65535 ? 'C' : 'I');// 75 76 79
+ }
+ }
+
+ public int getTypeMaxValue(char type) {
+ int maxValue;
+ switch(type) {// 85
+ case 'B':
+ maxValue = 127;// 90
+ break;// 91
+ case 'C':
+ maxValue = 65535;// 99
+ break;// 100
+ case 'S':
+ maxValue = 32767;// 96
+ break;// 97
+ case 'X':
+ maxValue = 128;// 87
+ break;// 88
+ case 'Y':
+ maxValue = 32768;// 93
+ break;// 94
+ default:
+ maxValue = 2147483647;// 102
+ }
+
+ return maxValue;// 104
+ }
+}
+
+class 'pkg/TestConstType' {
+ method 'setLineBreak (C)V' {
+ 1 7
+ 1d 9
+ 1f 9
+ 22 10
+ 26 12
+ 28 12
+ 2b 15
+ }
+
+ method 'init ()V' {
+ 1 18
+ 3 18
+ 6 19
+ }
+
+ method 'convertIndentation (Ljava/lang/String;)Ljava/lang/String;' {
+ 1 22
+ 2 22
+ 5 22
+ 7 22
+ b 23
+ d 23
+ f 23
+ 12 23
+ 14 26
+ }
+
+ method 'printalot ()V' {
+ 0 30
+ 3 30
+ 5 30
+ 8 31
+ b 31
+ d 31
+ 10 32
+ 13 32
+ 14 32
+ 17 33
+ 1a 33
+ 1c 33
+ 1f 34
+ 22 34
+ 24 34
+ 27 35
+ 2a 35
+ 2d 35
+ 30 36
+ 33 36
+ 36 36
+ 39 37
+ 3c 37
+ 3e 37
+ 41 38
+ 44 38
+ 46 38
+ 49 39
+ 4c 39
+ 4e 39
+ 51 40
+ 54 40
+ 56 40
+ 59 41
+ 5c 41
+ 5e 41
+ 61 42
+ 64 42
+ 66 42
+ 69 43
+ 6c 43
+ 6e 43
+ 71 44
+ 74 44
+ 76 44
+ 79 45
+ 7c 45
+ 7e 45
+ 81 46
+ 84 46
+ 86 46
+ 89 47
+ 8c 47
+ 8e 47
+ 91 48
+ 94 48
+ 96 48
+ 99 49
+ 9c 49
+ 9e 49
+ a1 50
+ a4 50
+ a6 50
+ a9 51
+ ac 51
+ ae 51
+ b1 52
+ b4 52
+ b6 52
+ b9 53
+ bc 53
+ be 53
+ c1 54
+ c4 54
+ c6 54
+ c9 55
+ cc 55
+ ce 55
+ d1 56
+ d4 56
+ d6 56
+ d9 57
+ dc 57
+ de 57
+ e1 58
+ }
+
+ method 'guessType (I)C' {
+ 0 61
+ 2 61
+ 6 61
+ 8 61
+ b 62
+ d 62
+ e 63
+ 11 63
+ 15 63
+ 17 63
+ 1a 64
+ 1c 64
+ 1d 65
+ 21 65
+ 25 65
+ 28 65
+ 2b 66
+ 2d 66
+ 2e 67
+ 32 67
+ 36 67
+ 39 67
+ 3c 68
+ 3e 68
+ 3f 70
+ 42 70
+ 46 70
+ 48 70
+ 4b 70
+ 4e 70
+ }
+
+ method 'getTypeMaxValue (C)I' {
+ 1 76
+ 34 87
+ 37 87
+ 38 88
+ 3b 78
+ 3d 78
+ 3e 79
+ 41 90
+ 43 90
+ 44 91
+ 47 84
+ 4a 84
+ 4b 85
+ 4e 81
+ 50 81
+ 51 82
+ 54 93
+ 56 93
+ 58 96
+ }
+}
+
+Lines mapping:
+8 <-> 8
+10 <-> 10
+11 <-> 11
+14 <-> 13
+17 <-> 16
+20 <-> 19
+21 <-> 20
+24 <-> 23
+25 <-> 24
+27 <-> 27
+31 <-> 31
+32 <-> 32
+34 <-> 33
+35 <-> 34
+36 <-> 35
+37 <-> 36
+38 <-> 37
+39 <-> 38
+40 <-> 39
+41 <-> 40
+42 <-> 41
+43 <-> 42
+44 <-> 43
+45 <-> 44
+46 <-> 45
+47 <-> 46
+48 <-> 47
+49 <-> 48
+50 <-> 49
+51 <-> 50
+52 <-> 51
+53 <-> 52
+54 <-> 53
+55 <-> 54
+56 <-> 55
+57 <-> 56
+58 <-> 57
+59 <-> 58
+60 <-> 59
+63 <-> 62
+64 <-> 63
+66 <-> 64
+67 <-> 65
+69 <-> 66
+70 <-> 67
+72 <-> 68
+73 <-> 69
+75 <-> 71
+76 <-> 71
+79 <-> 71
+85 <-> 77
+87 <-> 88
+88 <-> 89
+90 <-> 79
+91 <-> 80
+93 <-> 91
+94 <-> 92
+96 <-> 85
+97 <-> 86
+99 <-> 82
+100 <-> 83
+102 <-> 94
+104 <-> 97
diff --git a/testData/src/pkg/TestConstType.java b/testData/src/pkg/TestConstType.java
new file mode 100644
index 0000000..d4c0192
--- /dev/null
+++ b/testData/src/pkg/TestConstType.java
@@ -0,0 +1,106 @@
+package pkg;
+
+public class TestConstType {
+ private char lineBreak = '\n';
+ private char zero = 0;
+
+ public void setLineBreak(char os) {
+ switch (os) {
+ case 'u':
+ lineBreak = '\r';
+ break;
+
+ case 'w':
+ lineBreak = '\n';
+ break;
+ }
+ }
+
+ public void init() {
+ setLineBreak('w');
+ }
+
+ public String convertIndentation(String text) {
+ if (text.charAt(0) == '\t') {
+ text = text.replace('\t', ' ');
+ }
+ return text;
+ }
+
+ public void printalot() {
+ System.out.println('a');
+ System.out.println('\t');
+
+ System.out.println(0);
+ System.out.println(65);
+ System.out.println(120);
+ System.out.println(32760);
+ System.out.println(32761);
+ System.out.println(35000);
+ System.out.println(50000);
+ System.out.println(128000);
+ System.out.println(60793);
+ System.out.println(60737);
+ System.out.println(60777);
+ System.out.println(60785);
+ System.out.println(60835);
+ System.out.println(60843);
+ System.out.println(60851);
+ System.out.println(60859);
+ System.out.println(1048576);
+ System.out.println(49152);
+ System.out.println(44100);
+ System.out.println(44101);
+ System.out.println(44102);
+ System.out.println(44103);
+ System.out.println(60000);
+ System.out.println(64000);
+ System.out.println(65000);
+ System.out.println(45000);
+ }
+
+ public char guessType(int val) {
+ if (0 <= val && val <= 127) {
+ return 'X';
+ }
+ else if (-128 <= val && val <= 127) {
+ return 'B';
+ }
+ else if (128 <= val && val <= 32767) {
+ return 'Y';
+ }
+ else if (-32768 <= val && val <= 32767) {
+ return 'S';
+ }
+ else if (32768 <= val && val <= 0xFFFF) {
+ return 'C';
+ }
+ else {
+ return 'I';
+ }
+ }
+
+ public int getTypeMaxValue(char type) {
+ int maxValue;
+ switch (type) {
+ case 'X':
+ maxValue = 128;
+ break;
+ case 'B':
+ maxValue = 127;
+ break;
+ case 'Y':
+ maxValue = 32768;
+ break;
+ case 'S':
+ maxValue = 32767;
+ break;
+ case 'C':
+ maxValue = 0xFFFF;
+ break;
+ default:
+ maxValue = Integer.MAX_VALUE;
+ }
+ return maxValue;
+ }
+}