FileDocCategorySizeDatePackage
IntegralToString.javaAPI DocAndroid 5.1 API18596Thu Mar 12 22:22:44 GMT 2015com.android.tools.layoutlib.java

IntegralToString

public final class IntegralToString extends Object
Defines the same class as the java.lang.IntegralToString which was added in Dalvik VM. This hack, provides a replacement for that class which can't be loaded in the standard JVM since it's in the java package and standard JVM doesn't have it. Since it's no longer in java.lang, access to package private methods and classes has been replaced by the closes matching public implementation.

Extracted from API level 18, file: platform/libcore/luni/src/main/java/java/lang/IntegralToString.java

Fields Summary
private static final ThreadLocal
BUFFER
When appending to an AbstractStringBuilder, this thread-local char[] lets us avoid allocation of a temporary array. (We can't write straight into the AbstractStringBuilder because it's almost as expensive to work out the exact length of the result as it is to do the formatting. We could try being conservative and "delete"-ing the unused space afterwards, but then we'd need to duplicate convertInt and convertLong rather than share the code.)
private static final String[]
SMALL_NONNEGATIVE_VALUES
These tables are used to special-case toString computation for small values. This serves three purposes: it reduces memory usage; it increases performance for small values; and it decreases the number of comparisons required to do the length computation. Elements of this table are lazily initialized on first use. No locking is necessary, i.e., we use the non-volatile, racy single-check idiom.
private static final String[]
SMALL_NEGATIVE_VALUES
private static final char[]
TENS
TENS[i] contains the tens digit of the number i, 0 <= i <= 99.
private static final char[]
ONES
Ones [i] contains the tens digit of the number i, 0 <= i <= 99.
private static final char[]
MOD_10_TABLE
Table for MOD / DIV 10 computation described in Section 10-21 of Hank Warren's "Hacker's Delight" online addendum. http://www.hackersdelight.org/divcMore.pdf
private static final char[]
DIGITS
The digits for every supported radix.
private static final char[]
UPPER_CASE_DIGITS
Constructors Summary
private IntegralToString()


      
    
Methods Summary
public static java.lang.StringBuilderappendByteAsHex(java.lang.StringBuilder sb, byte b, boolean upperCase)

        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
        sb.append(digits[(b >> 4) & 0xf]);
        sb.append(digits[b & 0xf]);
        return sb;
    
public static voidappendInt(java.lang.StringBuilder sb, int i)
Equivalent to sb.append(Integer.toString(i)).

        convertInt(sb, i);
    
public static voidappendLong(java.lang.StringBuilder sb, long l)
Equivalent to sb.append(Long.toString(l)).

        convertLong(sb, l);
    
public static java.lang.StringbyteToHexString(byte b, boolean upperCase)

        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
        char[] buf = new char[2]; // We always want two digits.
        buf[0] = digits[(b >> 4) & 0xf];
        buf[1] = digits[b & 0xf];
        return new String(buf, 0, 2);
    
public static java.lang.StringbytesToHexString(byte[] bytes, boolean upperCase)

        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
        char[] buf = new char[bytes.length * 2];
        int c = 0;
        for (byte b : bytes) {
            buf[c++] = digits[(b >> 4) & 0xf];
            buf[c++] = digits[b & 0xf];
        }
        return new String(buf);
    
private static java.lang.StringconvertInt(java.lang.StringBuilder sb, int i)
Returns the string representation of i and leaves sb alone if sb is null. Returns null and appends the string representation of i to sb if sb is non-null.

        boolean negative = false;
        String quickResult = null;
        if (i < 0) {
            negative = true;
            i = -i;
            if (i < 100) {
                if (i < 0) {
                    // If -n is still negative, n is Integer.MIN_VALUE
                    quickResult = "-2147483648";
                } else {
                    quickResult = SMALL_NEGATIVE_VALUES[i];
                    if (quickResult == null) {
                        SMALL_NEGATIVE_VALUES[i] = quickResult =
                                i < 10 ? stringOf('-", ONES[i]) : stringOf('-", TENS[i], ONES[i]);
                    }
                }
            }
        } else {
            if (i < 100) {
                quickResult = SMALL_NONNEGATIVE_VALUES[i];
                if (quickResult == null) {
                    SMALL_NONNEGATIVE_VALUES[i] = quickResult =
                            i < 10 ? stringOf(ONES[i]) : stringOf(TENS[i], ONES[i]);
                }
            }
        }
        if (quickResult != null) {
            if (sb != null) {
                sb.append(quickResult);
                return null;
            }
            return quickResult;
        }

        int bufLen = 11; // Max number of chars in result
        char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];
        int cursor = bufLen;

        // Calculate digits two-at-a-time till remaining digits fit in 16 bits
        while (i >= (1 << 16)) {
            // Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8
            int q = (int) ((0x51EB851FL * i) >>> 37);
            int r = i - 100*q;
            buf[--cursor] = ONES[r];
            buf[--cursor] = TENS[r];
            i = q;
        }

        // Calculate remaining digits one-at-a-time for performance
        while (i != 0) {
            // Compute q = n/10 and r = n % 10 as per "Hacker's Delight" 10-8
            int q = (0xCCCD * i) >>> 19;
            int r = i - 10*q;
            buf[--cursor] = DIGITS[r];
            i = q;
        }

        if (negative) {
            buf[--cursor] = '-";
        }

        if (sb != null) {
            sb.append(buf, cursor, bufLen - cursor);
            return null;
        } else {
            return new String(buf, cursor, bufLen - cursor);
        }
    
private static java.lang.StringconvertLong(java.lang.StringBuilder sb, long n)
Returns the string representation of n and leaves sb alone if sb is null. Returns null and appends the string representation of n to sb if sb is non-null.

        int i = (int) n;
        if (i == n) {
            return convertInt(sb, i);
        }

        boolean negative = (n < 0);
        if (negative) {
            n = -n;
            if (n < 0) {
                // If -n is still negative, n is Long.MIN_VALUE
                String quickResult = "-9223372036854775808";
                if (sb != null) {
                    sb.append(quickResult);
                    return null;
                }
                return quickResult;
            }
        }

        int bufLen = 20; // Maximum number of chars in result
        char[] buf = (sb != null) ? BUFFER.get() : new char[bufLen];

        int low = (int) (n % 1000000000); // Extract low-order 9 digits
        int cursor = intIntoCharArray(buf, bufLen, low);

        // Zero-pad Low order part to 9 digits
        while (cursor != (bufLen - 9)) {
            buf[--cursor] = '0";
        }

        /*
         * The remaining digits are (n - low) / 1,000,000,000.  This
         * "exact division" is done as per the online addendum to Hank Warren's
         * "Hacker's Delight" 10-20, http://www.hackersdelight.org/divcMore.pdf
         */
        n = ((n - low) >>> 9) * 0x8E47CE423A2E9C6DL;

        /*
         * If the remaining digits fit in an int, emit them using a
         * single call to intIntoCharArray. Otherwise, strip off the
         * low-order digit, put it in buf, and then call intIntoCharArray
         * on the remaining digits (which now fit in an int).
         */
        if ((n & (-1L << 32)) == 0) {
            cursor = intIntoCharArray(buf, cursor, (int) n);
        } else {
            /*
             * Set midDigit to n % 10
             */
            int lo32 = (int) n;
            int hi32 = (int) (n >>> 32);

            // midDigit = ((unsigned) low32) % 10, per "Hacker's Delight" 10-21
            int midDigit = MOD_10_TABLE[(0x19999999 * lo32 + (lo32 >>> 1) + (lo32 >>> 3)) >>> 28];

            // Adjust midDigit for hi32. (assert hi32 == 1 || hi32 == 2)
            midDigit -= hi32 << 2;  // 1L << 32 == -4 MOD 10
            if (midDigit < 0) {
                midDigit += 10;
            }
            buf[--cursor] = DIGITS[midDigit];

            // Exact division as per Warren 10-20
            int rest = ((int) ((n - midDigit) >>> 1)) * 0xCCCCCCCD;
            cursor = intIntoCharArray(buf, cursor, rest);
        }

        if (negative) {
            buf[--cursor] = '-";
        }
        if (sb != null) {
            sb.append(buf, cursor, bufLen - cursor);
            return null;
        } else {
            return new String(buf, cursor, bufLen - cursor);
        }
    
private static intintIntoCharArray(char[] buf, int cursor, int n)
Inserts the unsigned decimal integer represented by n into the specified character array starting at position cursor. Returns the index after the last character inserted (i.e., the value to pass in as cursor the next time this method is called). Note that n is interpreted as a large positive integer (not a negative integer) if its sign bit is set.

        // Calculate digits two-at-a-time till remaining digits fit in 16 bits
        while ((n & 0xffff0000) != 0) {
            /*
             * Compute q = n/100 and r = n % 100 as per "Hacker's Delight" 10-8.
             * This computation is slightly different from the corresponding
             * computation in intToString: the shifts before and after
             * multiply can't be combined, as that would yield the wrong result
             * if n's sign bit were set.
             */
            int q = (int) ((0x51EB851FL * (n >>> 2)) >>> 35);
            int r = n - 100*q;
            buf[--cursor] = ONES[r];
            buf[--cursor] = TENS[r];
            n = q;
        }

        // Calculate remaining digits one-at-a-time for performance
        while (n != 0) {
            // Compute q = n / 10 and r = n % 10 as per "Hacker's Delight" 10-8
            int q = (0xCCCD * n) >>> 19;
            int r = n - 10*q;
            buf[--cursor] = DIGITS[r];
            n = q;
        }
        return cursor;
    
public static java.lang.StringintToBinaryString(int i)

        int bufLen = 32;  // Max number of binary digits in an int
        char[] buf = new char[bufLen];
        int cursor = bufLen;

        do {
            buf[--cursor] = DIGITS[i & 1];
        }  while ((i >>>= 1) != 0);

        return new String(buf, cursor, bufLen - cursor);
    
public static java.lang.StringintToHexString(int i, boolean upperCase, int minWidth)

        int bufLen = 8;  // Max number of hex digits in an int
        char[] buf = new char[bufLen];
        int cursor = bufLen;

        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
        do {
            buf[--cursor] = digits[i & 0xf];
        } while ((i >>>= 4) != 0 || (bufLen - cursor < minWidth));

        return new String(buf, cursor, bufLen - cursor);
    
public static java.lang.StringintToOctalString(int i)

        int bufLen = 11;  // Max number of octal digits in an int
        char[] buf = new char[bufLen];
        int cursor = bufLen;

        do {
            buf[--cursor] = DIGITS[i & 7];
        } while ((i >>>= 3) != 0);

        return new String(buf, cursor, bufLen - cursor);
    
public static java.lang.StringintToString(int i, int radix)
Equivalent to Integer.toString(i, radix).

        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
            radix = 10;
        }
        if (radix == 10) {
            return intToString(i);
        }

        /*
         * If i is positive, negate it. This is the opposite of what one might
         * expect. It is necessary because the range of the negative values is
         * strictly larger than that of the positive values: there is no
         * positive value corresponding to Integer.MIN_VALUE.
         */
        boolean negative = false;
        if (i < 0) {
            negative = true;
        } else {
            i = -i;
        }

        int bufLen = radix < 8 ? 33 : 12;  // Max chars in result (conservative)
        char[] buf = new char[bufLen];
        int cursor = bufLen;

        do {
            int q = i / radix;
            buf[--cursor] = DIGITS[radix * q - i];
            i = q;
        } while (i != 0);

        if (negative) {
            buf[--cursor] = '-";
        }

        return new String(buf, cursor, bufLen - cursor);
    
public static java.lang.StringintToString(int i)
Equivalent to Integer.toString(i).

        return convertInt(null, i);
    
public static java.lang.StringlongToBinaryString(long v)

        int i = (int) v;
        if (v >= 0 && i == v) {
            return intToBinaryString(i);
        }

        int bufLen = 64;  // Max number of binary digits in a long
        char[] buf = new char[bufLen];
        int cursor = bufLen;

        do {
            buf[--cursor] = DIGITS[((int) v) & 1];
        }  while ((v >>>= 1) != 0);

        return new String(buf, cursor, bufLen - cursor);
    
public static java.lang.StringlongToHexString(long v)

        int i = (int) v;
        if (v >= 0 && i == v) {
            return intToHexString(i, false, 0);
        }

        int bufLen = 16;  // Max number of hex digits in a long
        char[] buf = new char[bufLen];
        int cursor = bufLen;

        do {
            buf[--cursor] = DIGITS[((int) v) & 0xF];
        } while ((v >>>= 4) != 0);

        return new String(buf, cursor, bufLen - cursor);
    
public static java.lang.StringlongToOctalString(long v)

        int i = (int) v;
        if (v >= 0 && i == v) {
            return intToOctalString(i);
        }
        int bufLen = 22;  // Max number of octal digits in a long
        char[] buf = new char[bufLen];
        int cursor = bufLen;

        do {
            buf[--cursor] = DIGITS[((int) v) & 7];
        } while ((v >>>= 3) != 0);

        return new String(buf, cursor, bufLen - cursor);
    
public static java.lang.StringlongToString(long v, int radix)
Equivalent to Long.toString(v, radix).

        int i = (int) v;
        if (i == v) {
            return intToString(i, radix);
        }

        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
            radix = 10;
        }
        if (radix == 10) {
            return longToString(v);
        }

        /*
         * If v is positive, negate it. This is the opposite of what one might
         * expect. It is necessary because the range of the negative values is
         * strictly larger than that of the positive values: there is no
         * positive value corresponding to Integer.MIN_VALUE.
         */
        boolean negative = false;
        if (v < 0) {
            negative = true;
        } else {
            v = -v;
        }

        int bufLen = radix < 8 ? 65 : 23;  // Max chars in result (conservative)
        char[] buf = new char[bufLen];
        int cursor = bufLen;

        do {
            long q = v / radix;
            buf[--cursor] = DIGITS[(int) (radix * q - v)];
            v = q;
        } while (v != 0);

        if (negative) {
            buf[--cursor] = '-";
        }

        return new String(buf, cursor, bufLen - cursor);
    
public static java.lang.StringlongToString(long l)
Equivalent to Long.toString(l).

        return convertLong(null, l);
    
private static java.lang.StringstringOf(char args)

        return new String(args, 0, args.length);