0da1c5dcca
First commit of the 4.5 version (latest version available)
668 lines
26 KiB
Java
668 lines
26 KiB
Java
package mars.util;
|
|
import mars.Globals;
|
|
import java.util.*;
|
|
|
|
/*
|
|
Copyright (c) 2003-2006, Pete Sanderson and Kenneth Vollmar
|
|
|
|
Developed by Pete Sanderson (psanderson@otterbein.edu)
|
|
and Kenneth Vollmar (kenvollmar@missouristate.edu)
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
a copy of this software and associated documentation files (the
|
|
"Software"), to deal in the Software without restriction, including
|
|
without limitation the rights to use, copy, modify, merge, publish,
|
|
distribute, sublicense, and/or sell copies of the Software, and to
|
|
permit persons to whom the Software is furnished to do so, subject
|
|
to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be
|
|
included in all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
|
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
(MIT license, http://www.opensource.org/licenses/mit-license.html)
|
|
*/
|
|
|
|
/**
|
|
* Some utility methods for working with binary representations.
|
|
*
|
|
* @author Pete Sanderson, Ken Vollmar, and Jason Bumgarner
|
|
* @version July 2005
|
|
*/
|
|
public class Binary {
|
|
|
|
// Using int value 0-15 as index, yields equivalent hex digit as char.
|
|
private static char[] chars =
|
|
{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
|
// Use this to produce String equivalent of unsigned int value (add it to int value, result is long)
|
|
private static final long UNSIGNED_BASE = (long)0x7FFFFFFF + (long)0x7FFFFFFF +(long)2; //0xFFFFFFFF+1
|
|
|
|
/**
|
|
* Translate int value into a String consisting of '1's and '0's.
|
|
*
|
|
* @param value The int value to convert.
|
|
* @param length The number of bit positions, starting at least significant, to process.
|
|
* @return String consisting of '1' and '0' characters corresponding to the requested binary sequence.
|
|
**/
|
|
|
|
public static String intToBinaryString(int value, int length) {
|
|
char[] result = new char[length];
|
|
int index = length-1;
|
|
for (int i=0; i<length; i++) {
|
|
result[index] = (bitValue(value,i)==1) ? '1' : '0';
|
|
index--;
|
|
}
|
|
return new String(result);
|
|
}
|
|
|
|
/**
|
|
* Translate int value into a String consisting of '1's and '0's. Assumes all 32 bits are
|
|
* to be translated.
|
|
*
|
|
* @param value The int value to convert.
|
|
* @return String consisting of '1' and '0' characters corresponding to the requested binary sequence.
|
|
**/
|
|
|
|
public static String intToBinaryString(int value) {
|
|
return intToBinaryString(value,32);
|
|
}
|
|
|
|
|
|
/**
|
|
* Translate long value into a String consisting of '1's and '0's.
|
|
*
|
|
* @param value The long value to convert.
|
|
* @param length The number of bit positions, starting at least significant, to process.
|
|
* @return String consisting of '1' and '0' characters corresponding to the requested binary sequence.
|
|
**/
|
|
|
|
public static String longToBinaryString(long value, int length) {
|
|
char[] result = new char[length];
|
|
int index = length-1;
|
|
for (int i=0; i<length; i++) {
|
|
result[index] = (bitValue(value,i)==1) ? '1' : '0';
|
|
index--;
|
|
}
|
|
return new String(result);
|
|
}
|
|
|
|
/**
|
|
* Translate long value into a String consisting of '1's and '0's. Assumes all 64 bits are
|
|
* to be translated.
|
|
*
|
|
* @param value The long value to convert.
|
|
* @return String consisting of '1' and '0' characters corresponding to the requested binary sequence.
|
|
**/
|
|
|
|
public static String longToBinaryString(long value) {
|
|
return longToBinaryString(value,64);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Translate String consisting of '1's and '0's into an int value having that binary representation.
|
|
* The String is assumed to be at most 32 characters long. No error checking is performed.
|
|
* String position 0 has most-significant bit, position length-1 has least-significant.
|
|
*
|
|
* @param value The String value to convert.
|
|
* @return int whose binary value corresponds to decoded String.
|
|
**/
|
|
|
|
public static int binaryStringToInt(String value) {
|
|
int result = value.charAt(0) - 48;
|
|
for (int i=1; i<value.length(); i++) {
|
|
result = (result << 1) | (value.charAt(i)-48);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Translate String consisting of '1's and '0's into a long value having that binary representation.
|
|
* The String is assumed to be at most 64 characters long. No error checking is performed.
|
|
* String position 0 has most-significant bit, position length-1 has least-significant.
|
|
*
|
|
* @param value The String value to convert.
|
|
* @return long whose binary value corresponds to decoded String.
|
|
**/
|
|
|
|
public static long binaryStringToLong(String value) {
|
|
long result = value.charAt(0) - 48;
|
|
for (int i=1; i<value.length(); i++) {
|
|
result = (result << 1) | (value.charAt(i)-48);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Translate String consisting of '1's and '0's into String equivalent of the corresponding
|
|
* hexadecimal value. No length limit.
|
|
* String position 0 has most-significant bit, position length-1 has least-significant.
|
|
*
|
|
* @param value The String value to convert.
|
|
* @return String containing '0', '1', ...'F' characters which form hexadecimal
|
|
* equivalent of decoded String.
|
|
**/
|
|
public static String binaryStringToHexString(String value) {
|
|
int digits = (value.length()+3) / 4;
|
|
char[] hexChars = new char[digits+2];
|
|
int position, result, pow, rep;
|
|
hexChars[0] = '0';
|
|
hexChars[1] = 'x';
|
|
position = value.length()-1;
|
|
for (int digs = 0; digs<digits; digs++) {
|
|
result = 0;
|
|
pow = 1;
|
|
rep = 0;
|
|
while (rep < 4 && position >= 0) {
|
|
if (value.charAt(position) == '1')
|
|
result = result + pow;
|
|
pow *= 2;
|
|
position--;
|
|
rep++;
|
|
}
|
|
hexChars[digits-digs+1] = chars[result];
|
|
}
|
|
return new String(hexChars);
|
|
}
|
|
|
|
/**
|
|
* Translate String consisting of hexadecimal digits into String consisting of
|
|
* corresponding binary digits ('1's and '0's). No length limit.
|
|
* String position 0 will have most-significant bit, position length-1 has least-significant.
|
|
*
|
|
* @param value String containing '0', '1', ...'f'
|
|
* characters which form hexadecimal. Letters may be either upper or lower case.
|
|
* Works either with or without leading "Ox".
|
|
* @return String with equivalent value in binary.
|
|
**/
|
|
public static String hexStringToBinaryString(String value) {
|
|
String result = "";
|
|
// slice off leading Ox or 0X
|
|
if (value.indexOf("0x")==0 || value.indexOf("0X")==0) {
|
|
value = value.substring(2);
|
|
}
|
|
for (int digs = 0; digs < value.length(); digs++) {
|
|
switch (value.charAt(digs)) {
|
|
case '0' : result += "0000";
|
|
break;
|
|
case '1' : result += "0001";
|
|
break;
|
|
case '2' : result += "0010";
|
|
break;
|
|
case '3' : result += "0011";
|
|
break;
|
|
case '4' : result += "0100";
|
|
break;
|
|
case '5' : result += "0101";
|
|
break;
|
|
case '6' : result += "0110";
|
|
break;
|
|
case '7' : result += "0111";
|
|
break;
|
|
case '8' : result += "1000";
|
|
break;
|
|
case '9' : result += "1001";
|
|
break;
|
|
case 'a' : case 'A' : result += "1010";
|
|
break;
|
|
case 'b' : case 'B' : result += "1011";
|
|
break;
|
|
case 'c' : case 'C' : result += "1100";
|
|
break;
|
|
case 'd' : case 'D' : result += "1101";
|
|
break;
|
|
case 'e' : case 'E' : result += "1110";
|
|
break;
|
|
case 'f' : case 'F' : result += "1111";
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Translate String consisting of '1's and '0's into char equivalent of the corresponding
|
|
* hexadecimal digit. String limited to length 4.
|
|
* String position 0 has most-significant bit, position length-1 has least-significant.
|
|
*
|
|
* @param value The String value to convert.
|
|
* @return char '0', '1', ...'F' which form hexadecimal equivalent of decoded String.
|
|
* If string length > 4, returns '0'.
|
|
**/
|
|
|
|
public static char binaryStringToHexDigit(String value) {
|
|
if (value.length() > 4)
|
|
return '0';
|
|
int result = 0;
|
|
int pow = 1;
|
|
for (int i=value.length()-1; i>=0; i--) {
|
|
if (value.charAt(i) == '1')
|
|
result = result + pow;
|
|
pow *= 2;
|
|
}
|
|
return chars[result];
|
|
}
|
|
|
|
/**
|
|
* Prefix a hexadecimal-indicating string "0x" to the string which is
|
|
* returned by the method "Integer.toHexString". Prepend leading zeroes
|
|
* to that string as necessary to make it always eight hexadecimal digits.
|
|
*
|
|
* @param d The int value to convert.
|
|
* @return String containing '0', '1', ...'F' which form hexadecimal equivalent of int.
|
|
*/
|
|
public static String intToHexString(int d)
|
|
{
|
|
String leadingZero = new String("0");
|
|
String leadingX = new String("0x");
|
|
String t = Integer.toHexString(d);
|
|
while (t.length() < 8)
|
|
t = leadingZero.concat(t);
|
|
|
|
t = leadingX.concat(t);
|
|
return t;
|
|
}
|
|
|
|
/**
|
|
* Returns a 6 character string representing the 16-bit hexadecimal equivalent of the
|
|
* given integer value. First two characters are "0x". It assumes value will "fit"
|
|
* in 16 bits. If non-negative, prepend leading zeroes to that string as necessary
|
|
* to make it always four hexadecimal digits. If negative, chop off the first
|
|
* four 'f' digits so result is always four hexadecimal digits
|
|
*
|
|
* @param d The int value to convert.
|
|
* @return String containing '0', '1', ...'F' which form hexadecimal equivalent of int.
|
|
*/
|
|
public static String intToHalfHexString(int d)
|
|
{
|
|
String leadingZero = new String("0");
|
|
String leadingX = new String("0x");
|
|
String t = Integer.toHexString(d);
|
|
if (t.length() > 4) {
|
|
t = t.substring(t.length()-4, t.length());
|
|
}
|
|
while (t.length() < 4)
|
|
t = leadingZero.concat(t);
|
|
|
|
t = leadingX.concat(t);
|
|
return t;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Prefix a hexadecimal-indicating string "0x" to the string equivalent to the
|
|
* hexadecimal value in the long parameter. Prepend leading zeroes
|
|
* to that string as necessary to make it always sixteen hexadecimal digits.
|
|
*
|
|
* @param value The long value to convert.
|
|
* @return String containing '0', '1', ...'F' which form hexadecimal equivalent of long.
|
|
*/
|
|
|
|
public static String longToHexString(long value) {
|
|
return binaryStringToHexString(longToBinaryString(value));
|
|
}
|
|
|
|
|
|
/**
|
|
* Produce String equivalent of integer value interpreting it as an unsigned integer.
|
|
* For instance, -1 (0xffffffff) produces "4294967295" instead of "-1".
|
|
* @param d The int value to interpret.
|
|
* @return String which forms unsigned 32 bit equivalent of int.
|
|
*/
|
|
public static String unsignedIntToIntString(int d) {
|
|
return (d >= 0) ? Integer.toString(d) : Long.toString(UNSIGNED_BASE+d);
|
|
}
|
|
|
|
/**
|
|
* Produce ASCII string equivalent of integer value, interpreting it as 4 one-byte
|
|
* characters. If the value in a given byte does not correspond to a printable
|
|
* character, it will be assigned a default character (defined in config.properties)
|
|
* for a placeholder.
|
|
*
|
|
* @param d The int value to interpret
|
|
* @return String that represents ASCII equivalent
|
|
*/
|
|
public static String intToAscii(int d) {
|
|
StringBuilder result = new StringBuilder(8);
|
|
for (int i=3; i>=0; i--) {
|
|
int byteValue = getByte(d, i);
|
|
result.append( (byteValue < Globals.ASCII_TABLE.length) ? Globals.ASCII_TABLE[byteValue] : Globals.ASCII_NON_PRINT );
|
|
}
|
|
return result.toString();
|
|
}
|
|
|
|
/**
|
|
* Attempt to validate given string whose characters represent a 32 bit integer.
|
|
* Integer.decode() is insufficient because it will not allow incorporation of
|
|
* hex two's complement (i.e. 0x80...0 through 0xff...f). Allows
|
|
* optional negative (-) sign but no embedded spaces.
|
|
*
|
|
* @param s candidate string
|
|
* @return returns int value represented by given string
|
|
* @throws NumberFormatException if string cannot be translated into an int
|
|
*/
|
|
|
|
public static int stringToInt(String s) throws NumberFormatException {
|
|
String work = new String(s);
|
|
int result = 0;
|
|
// First, use Integer.decode(). This will validate most, but it flags
|
|
// valid hex two's complement values as exceptions. We'll catch those and
|
|
// do our own validation.
|
|
try {
|
|
result = Integer.decode(s).intValue();
|
|
}
|
|
catch (NumberFormatException nfe) {
|
|
// Multistep process toward validation of hex two's complement. 3-step test:
|
|
// (1) exactly 10 characters long,
|
|
// (2) starts with Ox or 0X,
|
|
// (3) last 8 characters are valid hex digits.
|
|
work = work.toLowerCase();
|
|
if (work.length() == 10 && work.startsWith("0x")) {
|
|
String bitString = "";
|
|
int index;
|
|
// while testing characters, build bit string to set up for binaryStringToInt
|
|
for (int i=2; i<10; i++) {
|
|
index = Arrays.binarySearch(chars, work.charAt(i));
|
|
if (index < 0) {
|
|
throw new NumberFormatException();
|
|
}
|
|
bitString = bitString + intToBinaryString(index,4);
|
|
}
|
|
result = binaryStringToInt(bitString);
|
|
}
|
|
/* The following "else" composed by Jose Baiocchi Paredes, Oct 2009. This new code
|
|
will correctly translate a string representing an unsigned decimal (not hex)
|
|
value whose signed value is negative. This is the decimal equivalent of the
|
|
"then" case just above. The method was not used in this context until Release 3.6
|
|
when background highlighting of the Data Segment was added. Caused exceptions
|
|
under certain conditions.
|
|
*/
|
|
else if (!work.startsWith("0x")) {
|
|
result = 0;
|
|
for (int i=0; i<work.length(); i++) {
|
|
char c = work.charAt(i);
|
|
if ('0' <= c && c <='9') {
|
|
result *= 10;
|
|
result += c - '0';
|
|
}
|
|
else {
|
|
throw new NumberFormatException();
|
|
}
|
|
}
|
|
}
|
|
/* End of the Jose Paredes code */
|
|
else {
|
|
throw new NumberFormatException();
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* Attempt to validate given string whose characters represent a 64 bit long.
|
|
* Long.decode() is insufficient because it will not allow incorporation of
|
|
* hex two's complement (i.e. 0x80...0 through 0xff...f). Allows
|
|
* optional negative (-) sign but no embedded spaces.
|
|
*
|
|
* @param s candidate string
|
|
* @return returns long value represented by given string
|
|
* @throws NumberFormatException if string cannot be translated into a long
|
|
*/
|
|
|
|
public static long stringToLong(String s) throws NumberFormatException {
|
|
String work = new String(s);
|
|
long result = 0;
|
|
// First, use Long.decode(). This will validate most, but it flags
|
|
// valid hex two's complement values as exceptions. We'll catch those and
|
|
// do our own validation.
|
|
try {
|
|
result = Long.decode(s).longValue();
|
|
}
|
|
catch (NumberFormatException nfe) {
|
|
// Multistep process toward validation of hex two's complement. 3-step test:
|
|
// (1) exactly 18 characters long,
|
|
// (2) starts with Ox or 0X,
|
|
// (3) last 16 characters are valid hex digits.
|
|
work = work.toLowerCase();
|
|
if (work.length() == 18 && work.startsWith("0x")) {
|
|
String bitString = "";
|
|
int index;
|
|
// while testing characters, build bit string to set up for binaryStringToInt
|
|
for (int i=2; i<18; i++) {
|
|
index = Arrays.binarySearch(chars, work.charAt(i));
|
|
if (index < 0) {
|
|
throw new NumberFormatException();
|
|
}
|
|
bitString = bitString + intToBinaryString(index,4);
|
|
}
|
|
result = binaryStringToLong(bitString);
|
|
}
|
|
else {
|
|
throw new NumberFormatException();
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns int representing the bit values of the high order 32 bits of given
|
|
* 64 bit long value.
|
|
* @param longValue The long value from which to extract bits.
|
|
* @return int containing high order 32 bits of argument
|
|
**/
|
|
|
|
public static int highOrderLongToInt(long longValue) {
|
|
return (int) (longValue >> 32); // high order 32 bits
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns int representing the bit values of the low order 32 bits of given
|
|
* 64 bit long value.
|
|
* @param longValue The long value from which to extract bits.
|
|
* @return int containing low order 32 bits of argument
|
|
**/
|
|
public static int lowOrderLongToInt(long longValue) {
|
|
return (int) (longValue << 32 >> 32); // low order 32 bits
|
|
}
|
|
|
|
/**
|
|
* Returns long (64 bit integer) combining the bit values of two given 32 bit
|
|
* integer values.
|
|
* @param highOrder Integer to form the high-order 32 bits of result.
|
|
* @param lowOrder Integer to form the high-order 32 bits of result.
|
|
* @return long containing concatenated 32 bit int values.
|
|
**/
|
|
public static long twoIntsToLong(int highOrder, int lowOrder) {
|
|
return (((long)highOrder) << 32) | (((long)lowOrder) & 0xFFFFFFFFL);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Returns the bit value of the given bit position of the given int value.
|
|
* @param value The value to read the bit from.
|
|
* @param bit bit position in range 0 (least significant) to 31 (most)
|
|
* @return 0 if the bit position contains 0, and 1 otherwise.
|
|
**/
|
|
|
|
public static int bitValue(int value, int bit) {
|
|
return 1 & (value >> bit);
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the bit value of the given bit position of the given long value.
|
|
* @param value The value to read the bit from.
|
|
* @param bit bit position in range 0 (least significant) to 63 (most)
|
|
* @return 0 if the bit position contains 0, and 1 otherwise.
|
|
**/
|
|
|
|
public static int bitValue(long value, int bit) {
|
|
|
|
return (int) (1L & (value >> bit));
|
|
}
|
|
|
|
/**
|
|
* Sets the specified bit of the specified value to 1, and returns the result.
|
|
* @param value The value in which the bit is to be set.
|
|
* @param bit bit position in range 0 (least significant) to 31 (most)
|
|
* @return value possibly modified with given bit set to 1.
|
|
**/
|
|
|
|
public static int setBit(int value, int bit) {
|
|
return value | ( 1 << bit) ;
|
|
}
|
|
|
|
|
|
/**
|
|
* Sets the specified bit of the specified value to 0, and returns the result.
|
|
* @param value The value in which the bit is to be set.
|
|
* @param bit bit position in range 0 (least significant) to 31 (most)
|
|
* @return value possibly modified with given bit set to 0.
|
|
**/
|
|
|
|
public static int clearBit(int value, int bit) {
|
|
return value & ~(1 << bit);
|
|
}
|
|
|
|
// setByte and getByte added by DPS on 12 July 2006
|
|
|
|
/**
|
|
* Sets the specified byte of the specified value to the low order 8 bits of
|
|
* specified replacement value, and returns the result.
|
|
* @param value The value in which the byte is to be set.
|
|
* @param bite byte position in range 0 (least significant) to 3 (most)
|
|
* @param replace value to place into that byte position - use low order 8 bits
|
|
* @return value modified value.
|
|
**/
|
|
|
|
public static int setByte(int value, int bite, int replace) {
|
|
return value & ~(0xFF << (bite<<3)) | ((replace & 0xFF) << (bite<<3)) ;
|
|
}
|
|
|
|
|
|
/**
|
|
* Gets the specified byte of the specified value.
|
|
* @param value The value in which the byte is to be retrieved.
|
|
* @param bite byte position in range 0 (least significant) to 3 (most)
|
|
* @return zero-extended byte value in low order byte.
|
|
**/
|
|
|
|
public static int getByte(int value, int bite) {
|
|
return value << ((3-bite)<<3) >>> 24;
|
|
}
|
|
|
|
// KENV 1/4/05
|
|
/**
|
|
* Parsing method to see if a string represents a hex number.
|
|
* As per http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Integer.html#decode(java.lang.String),
|
|
* a string represents a hex number if the string is in the forms:
|
|
* Signopt 0x HexDigits
|
|
* Signopt 0X HexDigits
|
|
* Signopt # HexDigits <---- Disallow this form since # is MIPS comment
|
|
*
|
|
*
|
|
* @param v String containing numeric digits (could be decimal, octal, or hex)
|
|
*
|
|
* @return Returns <tt>true</tt> if string represents a hex number, else returns <tt>false</tt>.
|
|
**/
|
|
public static boolean isHex(String v)
|
|
{
|
|
try
|
|
{
|
|
// don't care about return value, just whether it threw exception.
|
|
// If value is EITHER a valid int OR a valid long, continue.
|
|
try {
|
|
Binary.stringToInt(v);
|
|
}
|
|
catch (NumberFormatException nfe) {
|
|
try {
|
|
Binary.stringToLong(v);
|
|
}
|
|
catch (NumberFormatException e) {
|
|
return false; // both failed; it is neither valid int nor long
|
|
}
|
|
}
|
|
|
|
if ((v.charAt(0) == '-') && // sign is optional but if present can only be -
|
|
(v.charAt(1) == '0') &&
|
|
(Character.toUpperCase( v.charAt(1) ) == 'X') )
|
|
return true; // Form is Sign 0x.... and the entire string is parseable as a number
|
|
|
|
else if ((v.charAt(0) == '0') &&
|
|
(Character.toUpperCase( v.charAt(1) ) == 'X') )
|
|
return true; // Form is 0x.... and the entire string is parseable as a number
|
|
|
|
}
|
|
catch (StringIndexOutOfBoundsException e)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return false; // default
|
|
}
|
|
|
|
|
|
|
|
// KENV 1/4/05
|
|
/**
|
|
* Parsing method to see if a string represents an octal number.
|
|
* As per http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Integer.html#decode(java.lang.String),
|
|
* a string represents an octal number if the string is in the forms:
|
|
* Signopt 0 OctalDigits
|
|
*
|
|
* @param v String containing numeric digits (could be decimal, octal, or hex)
|
|
*
|
|
* @return Returns <tt>true</tt> if string represents an octal number, else returns <tt>false</tt>.
|
|
**/
|
|
public static boolean isOctal(String v)
|
|
{
|
|
// Don't mistake "0" or a string that starts "0x" for an octal string
|
|
try
|
|
{
|
|
// we don't care what value Binary.stringToInt(v) returns, just whether it threw exception
|
|
int dontCare = Binary.stringToInt(v);
|
|
|
|
if (isHex(v))
|
|
return false; // String starts with "0" but continues "0x", so not octal
|
|
|
|
if ((v.charAt(0) == '-') && // sign is optional but if present can only be -
|
|
(v.charAt(1) == '0') &&
|
|
(v.length() > 1) ) // Has to have more digits than the leading zero
|
|
return true; // Form is Sign 0.... and the entire string is parseable as a number
|
|
|
|
else if ((v.charAt(0) == '0') &&
|
|
(v.length() > 1) ) // Has to have more digits than the leading zero
|
|
return true; // Form is 0.... and the entire string is parseable as a number
|
|
|
|
}
|
|
catch (StringIndexOutOfBoundsException e)
|
|
{
|
|
return false;
|
|
}
|
|
catch (NumberFormatException e)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return false; // default
|
|
}
|
|
|
|
|
|
|
|
}
|