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);
+ }
+
}