private static long parseInteger(final String text,
            final boolean isSigned,
            final boolean isLong)
            throws NumberFormatException
    {
        int pos = 0;

        boolean negative = false;
        if (text.startsWith("-", pos))
        {
            if (!isSigned)
            {
                throw new NumberFormatException("Number must be positive: " + text);
            }
            ++pos;
            negative = true;
        }

        int radix = 10;
        if (text.startsWith("0x", pos))
        {
            pos += 2;
            radix = 16;
        }
        else if (text.startsWith("0", pos))
        {
            radix = 8;
        }

        final String numberText = text.substring(pos);

        long result = 0;
        if (numberText.length() < 16)
        {
            // Can safely assume no overflow.
            result = Long.parseLong(numberText, radix);
            if (negative)
            {
                result = -result;
            }

            // Check bounds.
            // No need to check for 64-bit numbers since they'd have to be 16 chars
            // or longer to overflow.
            if (!isLong)
            {
                if (isSigned)
                {
                    if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE)
                    {
                        throw new NumberFormatException(
                                "Number out of range for 32-bit signed integer: " + text);
                    }
                }
                else
                {
                    if (result >= (1L << 32) || result < 0)
                    {
                        throw new NumberFormatException(
                                "Number out of range for 32-bit unsigned integer: " + text);
                    }
                }
            }
        }
        else
        {
            BigInteger bigValue = new BigInteger(numberText, radix);
            if (negative)
            {
                bigValue = bigValue.negate();
            }

            // Check bounds.
            if (!isLong)
            {
                if (isSigned)
                {
                    if (bigValue.bitLength() > 31)
                    {
                        throw new NumberFormatException(
                                "Number out of range for 32-bit signed integer: " + text);
                    }
                }
                else
                {
                    if (bigValue.bitLength() > 32)
                    {
                        throw new NumberFormatException(
                                "Number out of range for 32-bit unsigned integer: " + text);
                    }
                }
            }
            else
            {
                if (isSigned)
                {
                    if (bigValue.bitLength() > 63)
                    {
                        throw new NumberFormatException(
                                "Number out of range for 64-bit signed integer: " + text);
                    }
                }
                else
                {
                    if (bigValue.bitLength() > 64)
                    {
                        throw new NumberFormatException(
                                "Number out of range for 64-bit unsigned integer: " + text);
                    }
                }
            }

            result = bigValue.longValue();
        }

        return result;
    }
Parse a 64-bit unsigned integer from the text. Unlike the Java standard {@code Integer.parseInt()}, this function
recognizes the prefixes "0x" and "0" to signify hexidecimal and octal numbers, respectively. The result is
coerced to a (signed) {@code long} when returned since Java has no unsigned long type.
protostuff-parser/src/main/java/io/protostuff/parser/TextFormat.java