blob: 17ff81366e9759a0453b2850cfdd4293726df968 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 Nokia 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:
* Nokia - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.edc.internal;
import java.math.BigInteger;
import org.eclipse.cdt.debug.edc.internal.symbols.ICPPBasicType;
import org.eclipse.cdt.debug.edc.symbols.IType;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
public class NumberFormatUtils {
private static final String HEX_PREFIX = "0x"; //$NON-NLS-1$
private static final String OCTAL_PREFIX = "0"; //$NON-NLS-1$
private static final String BINARY_PREFIX = "0b"; //$NON-NLS-1$
private static final String SINGLE_QUOTE = "'"; //$NON-NLS-1$
private static final String DECIMAL_SUFFIX = " (Decimal)"; //$NON-NLS-1$
static public String toHexString(Number number) {
String str = null;
if (number instanceof Integer)
str = Integer.toHexString((Integer) number);
else if (number instanceof Long)
str = Long.toHexString((Long) number);
else if (number instanceof BigInteger)
str = ((BigInteger) number).toString(16);
else if (number instanceof Float)
str = Float.toHexString((Float) number);
else if (number instanceof Double)
str = Double.toHexString((Double) number);
if (str != null && !str.startsWith(HEX_PREFIX))
return HEX_PREFIX + str;
return str;
}
static public String toOctalString(Number number) {
String str = null;
if (number instanceof Integer)
str = Integer.toOctalString((Integer) number);
else if (number instanceof Long)
str = Long.toOctalString((Long) number);
else if (number instanceof BigInteger)
str = ((BigInteger) number).toString(8);
if (str != null && !str.startsWith(OCTAL_PREFIX))
str = OCTAL_PREFIX + str;
if (str == null && (number instanceof Float || number instanceof Double))
str = number.toString() + DECIMAL_SUFFIX;
return str;
}
static public String asBinary(Number number) {
String str = null;
if (number instanceof Integer)
str = Integer.toBinaryString((Integer) number);
else if (number instanceof Long)
str = Long.toBinaryString((Long) number);
else if (number instanceof BigInteger)
str = ((BigInteger) number).toString(2);
if (str != null && !str.startsWith(BINARY_PREFIX))
str = BINARY_PREFIX + str;
if (str == null && (number instanceof Float || number instanceof Double))
str = number.toString() + DECIMAL_SUFFIX;
return str;
}
static public String toCharString(Number number, IType valueType) {
int intValue = number.intValue();
String charVal = null;
if (intValue < 128) {
switch ((char) intValue) {
case 0:
charVal = ("\\0"); //$NON-NLS-1$
break;
case '\b':
charVal = ("\\b"); //$NON-NLS-1$
break;
case '\f':
charVal = ("\\f"); //$NON-NLS-1$
break;
case '\n':
charVal = ("\\n"); //$NON-NLS-1$
break;
case '\r':
charVal = ("\\r"); //$NON-NLS-1$
break;
case '\t':
charVal = ("\\t"); //$NON-NLS-1$
break;
case '\'':
charVal = ("\\'"); //$NON-NLS-1$
break;
case '\"':
charVal = ("\\\""); //$NON-NLS-1$
break;
case '\\':
charVal = ("\\\\"); //$NON-NLS-1$
break;
case 0xb:
charVal = ("\\v"); //$NON-NLS-1$
break;
}
}
// Show the numeric value (decimal for char, since it's short, and hex for wchar_t)
// then the character value. Note that at the system font may not be able to show
// all characters in the variables/expressions view, which is why we show the
// more meaningful numeric value before the possibly "boxy" character representation.
//
// Also, we assume wchar_t == Unicode.
boolean isWchart = (valueType instanceof ICPPBasicType
&& ((ICPPBasicType) valueType).getBaseType() == ICPPBasicType.t_wchar_t)
|| valueType.getName().equals("wchar_t"); //$NON-NLS-1$
StringBuilder info = new StringBuilder();
if (isWchart) {
info.append(HEX_PREFIX);
if (valueType.getByteSize() == 2)
info.append(String.format("%04X", intValue)); //$NON-NLS-1$
else
info.append(String.format("%08X", intValue)); //$NON-NLS-1$
info.append(" (L"); //$NON-NLS-1$
} else {
info.append("" + intValue); //$NON-NLS-1$
info.append(" ("); //$NON-NLS-1$
}
if (charVal == null) {
// treat chars as unsigned for getting the char representation
String fmt = "\\U%08X"; //$NON-NLS-1$
switch (valueType.getByteSize()) {
case 1:
fmt = "\\%03o"; //$NON-NLS-1$
intValue &= 0xff; break;
case 2:
fmt = "\\u%04X"; //$NON-NLS-1$
intValue &= 0xffff; break;
case 4:
// note: may still be too large to be legal
fmt = "\\U%08X"; //$NON-NLS-1$
intValue &= 0xffffffff; break;
}
boolean gotRepr = false;
try {
if (!Character.isISOControl(intValue)) {
char[] chars = Character.toChars(intValue);
info.append(asStringQuoted(new String(chars)));
gotRepr = true;
}
} catch (IllegalArgumentException e) {
// some character values are negative or outside the UCS range;
// these throw exceptions
}
if (!gotRepr) {
info.append(asStringQuoted(String.format(fmt, intValue)));
}
} else {
info.append(asStringQuoted(charVal));
}
info.append(')');
return info.toString();
}
static public String asStringQuoted(String val) {
StringBuilder sb = new StringBuilder(SINGLE_QUOTE);
sb.append(val);
sb.append(SINGLE_QUOTE);
return sb.toString();
}
static public BigInteger parseIntegerByFormat(String expressionValue, String formatId) {
int radix = 10;
if (IFormattedValues.HEX_FORMAT.equals(formatId)) {
if (expressionValue.startsWith(HEX_PREFIX))
expressionValue = expressionValue.substring(HEX_PREFIX.length());
radix = 16;
} else if (IFormattedValues.OCTAL_FORMAT.equals(formatId)) {
if (expressionValue.startsWith(OCTAL_PREFIX))
expressionValue = expressionValue.substring(OCTAL_PREFIX.length());
radix = 8;
} else if (IFormattedValues.BINARY_FORMAT.equals(formatId)) {
if (expressionValue.startsWith(BINARY_PREFIX))
expressionValue = expressionValue.substring(BINARY_PREFIX.length());
radix = 2;
} else if (IFormattedValues.NATURAL_FORMAT.equals(formatId)) {
if (expressionValue.startsWith(BINARY_PREFIX)) {
expressionValue = expressionValue.substring(BINARY_PREFIX.length());
radix = 2;
} else if (expressionValue.startsWith(OCTAL_PREFIX)) {
expressionValue = expressionValue.substring(OCTAL_PREFIX.length());
radix = 8;
} else if (expressionValue.startsWith(HEX_PREFIX)) {
expressionValue = expressionValue.substring(HEX_PREFIX.length());
radix = 16;
}
// else, decimal
}
try {
return new BigInteger(expressionValue, radix);
} catch (NumberFormatException e) {
// just return null
}
return null;
}
}