Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNumberFormat.java')
-rw-r--r--plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNumberFormat.java230
1 files changed, 230 insertions, 0 deletions
diff --git a/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNumberFormat.java b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNumberFormat.java
new file mode 100644
index 000000000..d0ebef67c
--- /dev/null
+++ b/plugins/org.eclipse.tcf.debug.ui/src/org/eclipse/tcf/internal/debug/ui/model/TCFNumberFormat.java
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tm.internal.tcf.debug.ui.model;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+
+public class TCFNumberFormat {
+
+ public static String isValidHexNumber(String s) {
+ int l = s.length();
+ if (l == 0) return "Need at least one digit";
+ for (int i = 0; i < l; i++) {
+ char ch = s.charAt(i);
+ if (ch >= '0' && ch <= '9') continue;
+ if (ch >= 'A' && ch <= 'F') continue;
+ if (ch >= 'a' && ch <= 'f') continue;
+ return "Hex digit expected";
+ }
+ return null;
+ }
+
+ public static String isValidDecNumber(boolean fp, String s) {
+ int i = 0;
+ int l = s.length();
+ if (l == 0) return "Need at least one digit";
+ char ch = s.charAt(i++);
+ if (ch == '-' || ch == '+') {
+ if (i >= l) return "Need at least one digit";
+ ch = s.charAt(i++);
+ }
+ if (fp) {
+ String n = s.substring(i - 1);
+ if (n.equals("NaN")) return null;
+ if (n.equals("Infinity")) return null;
+ }
+ while (ch >= '0' && ch <= '9') {
+ if (i >= l) return null;
+ ch = s.charAt(i++);
+ }
+ if (fp) {
+ if (ch == '.') {
+ if (i >= l) return null;
+ ch = s.charAt(i++);
+ while (ch >= '0' && ch <= '9') {
+ if (i >= l) return null;
+ ch = s.charAt(i++);
+ }
+ }
+ if (ch == 'e' || ch == 'E') {
+ if (i >= l) return "Invalid exponent: need at least one digit";
+ ch = s.charAt(i++);
+ if (ch == '-' || ch == '+') {
+ if (i >= l) return "Invalid exponent: need at least one digit";
+ ch = s.charAt(i++);
+ }
+ while (ch >= '0' && ch <= '9') {
+ if (i >= l) return null;
+ ch = s.charAt(i++);
+ }
+ return "Invalid exponent: decimal digit expected";
+ }
+ }
+ return "Decimal digit expected";
+ }
+
+ public static byte[] toByteArray(String s, int radix, boolean fp, int size, boolean signed, boolean big_endian) throws Exception {
+ byte[] bf = null;
+ if (!fp) {
+ bf = new BigInteger(s, radix).toByteArray();
+ }
+ else if (size == 4) {
+ int n = Float.floatToIntBits(Float.parseFloat(s));
+ bf = new byte[size];
+ for (int i = 0; i < size; i++) {
+ bf[i] = (byte)((n >> ((size - 1 - i) * 8)) & 0xff);
+ }
+ }
+ else if (size == 8) {
+ long n = Double.doubleToLongBits(Double.parseDouble(s));
+ bf = new byte[size];
+ for (int i = 0; i < size; i++) {
+ bf[i] = (byte)((n >> ((size - 1 - i) * 8)) & 0xff);
+ }
+ }
+ else {
+ throw new Exception("Unsupported floating point format");
+ }
+ byte[] rs = new byte[size];
+ if (signed && rs.length > bf.length && (bf[0] & 0x80) != 0) {
+ // Sign extension
+ for (int i = 0; i < rs.length; i++) rs[i] = (byte)0xff;
+ }
+ for (int i = 0; i < bf.length; i++) {
+ // i == 0 -> least significant byte
+ byte b = bf[bf.length - i - 1];
+ int j = big_endian ? rs.length - i - 1 : i;
+ if (j >= 0 && j < rs.length) rs[j] = b;
+ }
+ return rs;
+ }
+
+ public static String toFPString(byte[] data, int offs, int size, boolean big_endian) {
+ assert offs + size <= data.length;
+ byte[] arr = new byte[size];
+ if (big_endian) {
+ System.arraycopy(data, offs, arr, 0, size);
+ }
+ else {
+ for (int i = 0; i < size; i++) {
+ arr[arr.length - i - 1] = data[offs + i];
+ }
+ }
+
+ boolean neg = (arr[0] & 0x80) != 0;
+ arr[0] &= 0x7f;
+
+ int precision = 0;
+ int exponent = 0;
+ boolean nan = false;
+ switch (size) {
+ case 2:
+ precision = 3;
+ exponent = (arr[0] & 0x7c) >> 2;
+ nan = exponent == 0x1f;
+ arr[0] &= 0x03;
+ if (exponent == 0) exponent = 1;
+ else arr[0] |= 0x04;
+ exponent -= 10; // Significand
+ exponent -= 15; // Exponent bias
+ break;
+ case 4:
+ precision = 7;
+ exponent = ((arr[0] & 0x7f) << 1) | ((arr[1] & 0x80) >> 7);
+ nan = exponent == 0xff;
+ arr[0] = 0;
+ arr[1] &= 0x7f;
+ if (exponent == 0) exponent = 1;
+ else arr[1] |= 0x80;
+ exponent -= 23; // Significand
+ exponent -= 127; // Exponent bias
+ break;
+ case 8:
+ precision = 16;
+ exponent = ((arr[0] & 0x7f) << 4) | ((arr[1] & 0xf0) >> 4);
+ nan = exponent == 0x7ff;
+ arr[0] = 0;
+ arr[1] &= 0x0f;
+ if (exponent == 0) exponent = 1;
+ else arr[1] |= 0x10;
+ exponent -= 52; // Significand
+ exponent -= 1023; // Exponent bias
+ break;
+ case 10:
+ case 16:
+ precision = 34;
+ exponent = ((arr[0] & 0x7f) << 8) | (arr[1] & 0xff);
+ nan = exponent == 0x7fff;
+ arr[0] = arr[1] = 0;
+ if (size == 10) {
+ exponent -= 63; // Significand
+ }
+ else {
+ if (exponent == 0) exponent = 1;
+ else arr[1] = 1;
+ exponent -= 112; // Significand
+ }
+ exponent -= 16383; // Exponent bias
+ break;
+ default:
+ return null;
+ }
+ if (nan) {
+ for (int i = 0; i < arr.length; i++) {
+ int n = arr[i] & 0xff;
+ if (size == 10 && i == 2) n &= 0x7f;
+ if (n != 0) return neg ? "-NaN" : "+NaN";
+ }
+ return neg ? "-Infinity" : "+Infinity";
+ }
+ BigDecimal a = new BigDecimal(new BigInteger(arr), 0);
+ if (a.signum() != 0 && exponent != 0) {
+ BigDecimal p = new BigDecimal(BigInteger.valueOf(2), 0);
+ if (exponent > 0) {
+ a = a.multiply(p.pow(exponent));
+ }
+ else {
+ BigDecimal b = p.pow(-exponent);
+ a = a.divide(b, b.precision(), RoundingMode.HALF_DOWN);
+ }
+ if (precision != 0 && a.precision() > precision) {
+ int scale = a.scale() - a.precision() + precision;
+ a = a.setScale(scale, RoundingMode.HALF_DOWN);
+ }
+ }
+ String s = a.toString();
+ if (neg) s = "-" + s;
+ return s;
+ }
+
+ public static BigInteger toBigInteger(byte[] data, int offs, int size, boolean big_endian, boolean sign_extension) {
+ assert offs + size <= data.length;
+ byte[] temp = null;
+ if (sign_extension) {
+ temp = new byte[size];
+ }
+ else {
+ temp = new byte[size + 1];
+ temp[0] = 0; // Extra byte to avoid sign extension by BigInteger
+ }
+ if (big_endian) {
+ System.arraycopy(data, offs, temp, sign_extension ? 0 : 1, size);
+ }
+ else {
+ for (int i = 0; i < size; i++) {
+ temp[temp.length - i - 1] = data[i + offs];
+ }
+ }
+ return new BigInteger(temp);
+ }
+}

Back to the top