You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2009/06/29 09:56:10 UTC

svn commit: r789248 - in /commons/sandbox/runtime/trunk/src: main/java/org/apache/commons/runtime/util/Ascii.java test/org/apache/commons/runtime/TestStrings.java

Author: mturk
Date: Mon Jun 29 07:56:10 2009
New Revision: 789248

URL: http://svn.apache.org/viewvc?rev=789248&view=rev
Log:
Add Ascii atoi/atol methods

Modified:
    commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Ascii.java
    commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStrings.java

Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Ascii.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Ascii.java?rev=789248&r1=789247&r2=789248&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Ascii.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/util/Ascii.java Mon Jun 29 07:56:10 2009
@@ -259,5 +259,183 @@
             arr[i] = (byte)ccs_cupper[(int)arr[i] & 0xff];
     }
 
+    public static int atoi(byte[] arr, int srcPos, int len, int base)
+    {
+        int  acc;
+        int  val;
+        int  neg;
+        int  any;
+        int  i = srcPos;
+        int  c;
+
+        // Skip leading spaces
+        if (len < 1)
+            return 0;
+        do {
+            c = arr[i++];
+        } while (isspace(c) && i < len);
+
+        if (c == '-') {
+            neg = 1;
+            if (i < len)
+                c = arr[i++];
+            else {
+                // EINVAL
+                return 0;
+            }
+        } else {
+            neg = 0;
+            if (c == '+') {
+                if (i < len)
+                    c = arr[i++];
+                else {
+                    // EINVAL
+                    return 0;
+                }
+            }
+        }
+        if ((base == 0 || base == 16) &&
+            c == '0' && i < len && (arr[i] == 'x' || arr[i] == 'X')) {
+            if ((i + 1) < len) {
+                c = arr[i + 1];
+                i += 2;
+                base = 16;
+            }
+            else {
+                // EINVAL
+                return 0;
+            }
+        }
+        if (base == 0)
+            base = c == '0' ? 8 : 10;
+            acc = any = 0;
+        if (base < 2 || base > 36) {
+            // EINVAL
+            return acc;
+        }
+        val = 0;
+        while (i <= len) {
+            if (c >= '0' && c <= '9')
+                c -= '0';
+            else if (c >= 'A' && c <= 'Z')
+                c -= 'A' - 10;
+            else if (c >= 'a' && c <= 'z')
+                c -= 'a' - 10;
+            else
+                break;
+            if (c >= base)
+                break;
+            val *= base;
+            if ((any < 0) || /* already noted an over/under flow - short circuit */
+                (neg != 0 && (val > acc || (val -= c) > acc)) ||    /* underflow */
+                (neg == 0 && (val < acc || (val += c) < acc))) {    /* overflow  */
+                any = -1;    /* once noted, over/underflows never go away */
+                break;
+            } else {
+                acc = val;
+                any = 1;
+            }
+            if (i < len)
+                c = arr[i];
+            i++;
+        }
+
+        if (any < 0) {
+            acc = neg == 0 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
+        } else if (any == 0) {
+            // EINVAL
+        }
+        return acc;
+    }
+
+    public static long atol(byte[] arr, int srcPos, int len, int base)
+    {
+        long acc;
+        long val;
+        int  neg;
+        int  any;
+        int  i = srcPos;
+        int  c;
+
+        // Skip leading spaces
+        if (len < 1)
+            return 0;
+        do {
+            c = arr[i++];
+        } while (isspace(c) && i < len);
+
+        if (c == '-') {
+            neg = 1;
+            if (i < len)
+                c = arr[i++];
+            else {
+                // EINVAL
+                return 0;
+            }
+        } else {
+            neg = 0;
+            if (c == '+') {
+                if (i < len)
+                    c = arr[i++];
+                else {
+                    // EINVAL
+                    return 0;
+                }
+            }
+        }
+        if ((base == 0 || base == 16) &&
+            c == '0' && i < len && (arr[i] == 'x' || arr[i] == 'X')) {
+            if ((i + 1) < len) {
+                c = arr[i + 1];
+                i += 2;
+                base = 16;
+            }
+            else {
+                // EINVAL
+                return 0;
+            }
+        }
+        if (base == 0)
+            base = c == '0' ? 8 : 10;
+            acc = any = 0;
+        if (base < 2 || base > 36) {
+            // EINVAL
+            return acc;
+        }
+        val = 0;
+        while (i <= len) {
+            if (c >= '0' && c <= '9')
+                c -= '0';
+            else if (c >= 'A' && c <= 'Z')
+                c -= 'A' - 10;
+            else if (c >= 'a' && c <= 'z')
+                c -= 'a' - 10;
+            else
+                break;
+            if (c >= base)
+                break;
+            val *= base;
+            if ((any < 0) || /* already noted an over/under flow - short circuit */
+                (neg != 0 && (val > acc || (val -= c) > acc)) ||    /* underflow */
+                (neg == 0 && (val < acc || (val += c) < acc))) {    /* overflow  */
+                any = -1;    /* once noted, over/underflows never go away */
+                break;
+            } else {
+                acc = val;
+                any = 1;
+            }
+            if (i < len)
+                c = arr[i];
+            i++;
+        }
+
+        if (any < 0) {
+            acc = neg == 0 ? Long.MAX_VALUE : Long.MIN_VALUE;
+        } else if (any == 0) {
+            // EINVAL
+        }
+        return acc;
+    }
+
 }
 

Modified: commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStrings.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStrings.java?rev=789248&r1=789247&r2=789248&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStrings.java (original)
+++ commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestStrings.java Mon Jun 29 07:56:10 2009
@@ -159,5 +159,105 @@
         assertEquals("Lower Ascii",  (byte)0xF4, b[0]);
     }
 
+    public void testAsciiAtoii()
+        throws Exception
+    {
+        byte [] b = " +1234".getBytes();
+        int  i = Ascii.atoi(b, 0, b.length, 0);
+        assertEquals("Atoi",  1234, i);
+    }
+
+    public void testAsciiAtoix()
+        throws Exception
+    {
+        byte [] b = " +0x1234".getBytes();
+        int  i = Ascii.atoi(b, 0, b.length, 0);
+        assertEquals("Atol",  0x1234, i);
+    }
+
+    public void testAsciiAtoiErr()
+        throws Exception
+    {
+        byte [] b = "".getBytes();
+        int  i = Ascii.atoi(b, 0, b.length, 0);
+        assertEquals("Empty",  0, i);
+        b = " ".getBytes();
+        i = Ascii.atoi(b, 0, b.length, 0);
+        assertEquals("Space",  0, i);
+        b = " -".getBytes();
+        i = Ascii.atoi(b, 0, b.length, 0);
+        assertEquals("Sign",  0, i);
+        b = " +".getBytes();
+        i = Ascii.atoi(b, 0, b.length, 0);
+        assertEquals("Plus",  0, i);
+        b = " 0x".getBytes();
+        i = Ascii.atoi(b, 0, b.length, 0);
+        assertEquals("EmptyHex",  0, i);
+        b = " 0xm".getBytes();
+        i = Ascii.atoi(b, 0, b.length, 0);
+        assertEquals("NonHex",  0, i);
+    }
+
+    public void testAsciiAtoiOverflow()
+        throws Exception
+    {
+        byte [] b = "9223372036854775810".getBytes();
+        int  i = Ascii.atoi(b, 0, b.length, 0);
+        assertEquals("MaxOverflow",  Integer.MAX_VALUE, i);
+        b = "-9223372036854775810".getBytes();
+        i = Ascii.atoi(b, 0, b.length, 0);
+        assertEquals("MinOverflow",  Integer.MIN_VALUE, i);
+    }
+
+    public void testAsciiAtoll()
+        throws Exception
+    {
+        byte [] b = " +1234".getBytes();
+        long l = Ascii.atol(b, 0, b.length, 0);
+        assertEquals("Atol",  1234L, l);
+    }
+
+    public void testAsciiAtolx()
+        throws Exception
+    {
+        byte [] b = " +0x1234".getBytes();
+        long l = Ascii.atol(b, 0, b.length, 0);
+        assertEquals("Atol",  0x1234L, l);
+    }
+
+    public void testAsciiAtolErr()
+        throws Exception
+    {
+        byte [] b = "".getBytes();
+        long l = Ascii.atol(b, 0, b.length, 0);
+        assertEquals("Empty",  0, l);
+        b = " ".getBytes();
+        l = Ascii.atol(b, 0, b.length, 0);
+        assertEquals("Space",  0, l);
+        b = " -".getBytes();
+        l = Ascii.atol(b, 0, b.length, 0);
+        assertEquals("Sign",  0, l);
+        b = " +".getBytes();
+        l = Ascii.atol(b, 0, b.length, 0);
+        assertEquals("Plus",  0, l);
+        b = " 0x".getBytes();
+        l = Ascii.atol(b, 0, b.length, 0);
+        assertEquals("EmptyHex",  0, l);
+        b = " 0xm".getBytes();
+        l = Ascii.atol(b, 0, b.length, 0);
+        assertEquals("NonHex",  0, l);
+    }
+
+    public void testAsciiAtolOverflow()
+        throws Exception
+    {
+        byte [] b = "9223372036854775810".getBytes();
+        long l = Ascii.atol(b, 0, b.length, 0);
+        assertEquals("MaxOverflow",  Long.MAX_VALUE, l);
+        b = "-9223372036854775810".getBytes();
+        l = Ascii.atol(b, 0, b.length, 0);
+        assertEquals("MinOverflow",  Long.MIN_VALUE, l);
+    }
+
 }