8050114: Expose Integer/Long formatUnsigned methods internally

Reviewed-by: mduigou
This commit is contained in:
Claes Redestad 2014-07-18 22:32:24 +02:00
parent 1fa3b2ce7f
commit f697e160a1
5 changed files with 116 additions and 16 deletions

View File

@ -320,24 +320,27 @@ public final class Integer extends Number implements Comparable<Integer> {
}
/**
* Format a long (treated as unsigned) into a character buffer.
* Format an {@code int} (treated as unsigned) into a character buffer. If
* {@code len} exceeds the formatted ASCII representation of {@code val},
* {@code buf} will be padded with leading zeroes.
*
* @param val the unsigned int to format
* @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
* @param buf the character buffer to write to
* @param offset the offset in the destination buffer to start at
* @param len the number of characters to write
* @return the lowest character location used
*/
static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
int charPos = len;
static void formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
// assert offset >= 0 && offset < buf.length : "illegal offset";
// assert len > 0 && (offset + len) <= buf.length : "illegal length";
int charPos = offset + len;
int radix = 1 << shift;
int mask = radix - 1;
do {
buf[offset + --charPos] = Integer.digits[val & mask];
buf[--charPos] = Integer.digits[val & mask];
val >>>= shift;
} while (val != 0 && charPos > 0);
return charPos;
} while (charPos > offset);
}
final static char [] DigitTens = {

View File

@ -361,24 +361,27 @@ public final class Long extends Number implements Comparable<Long> {
}
/**
* Format a long (treated as unsigned) into a character buffer.
* Format a long (treated as unsigned) into a character buffer. If
* {@code len} exceeds the formatted ASCII representation of {@code val},
* {@code buf} will be padded with leading zeroes.
*
* @param val the unsigned long to format
* @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)
* @param buf the character buffer to write to
* @param offset the offset in the destination buffer to start at
* @param len the number of characters to write
* @return the lowest character location used
*/
static int formatUnsignedLong(long val, int shift, char[] buf, int offset, int len) {
int charPos = len;
static void formatUnsignedLong(long val, int shift, char[] buf, int offset, int len) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
// assert offset >= 0 && offset < buf.length : "illegal offset";
// assert len > 0 && (offset + len) <= buf.length : "illegal length";
int charPos = offset + len;
int radix = 1 << shift;
int mask = radix - 1;
do {
buf[offset + --charPos] = Integer.digits[((int) val) & mask];
buf[--charPos] = Integer.digits[((int) val) & mask];
val >>>= shift;
} while (val != 0 && charPos > 0);
return charPos;
} while (charPos > offset);
}
/**

View File

@ -1263,6 +1263,12 @@ public final class System {
public void invokeFinalize(Object o) throws Throwable {
o.finalize();
}
public void formatUnsignedLong(long val, int shift, char[] buf, int offset, int len) {
Long.formatUnsignedLong(val, shift, buf, offset, len);
}
public void formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
Integer.formatUnsignedInt(val, shift, buf, offset, len);
}
});
}
}

View File

@ -132,4 +132,14 @@ public interface JavaLangAccess {
* Invokes the finalize method of the given object.
*/
void invokeFinalize(Object o) throws Throwable;
/**
* Invokes Long.formatUnsignedLong(long val, int shift, char[] buf, int offset, int len)
*/
void formatUnsignedLong(long val, int shift, char[] buf, int offset, int len);
/**
* Invokes Integer.formatUnsignedInt(long val, int shift, char[] buf, int offset, int len)
*/
void formatUnsignedInt(int val, int shift, char[] buf, int offset, int len);
}

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import sun.misc.JavaLangAccess;
import sun.misc.SharedSecrets;
/*
* @test
* @summary Test JavaLangAccess.formatUnsignedInt/-Long
* @bug 8050114
*/
public class FormatUnsigned {
static final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
public static void testFormatUnsignedInt() {
testFormatUnsignedInt("7fffffff", Integer.MAX_VALUE, 8, 4, 0, 8);
testFormatUnsignedInt("80000000", Integer.MIN_VALUE, 8, 4, 0, 8);
testFormatUnsignedInt("4711", 04711, 4, 3, 0, 4);
testFormatUnsignedInt("4711", 0x4711, 4, 4, 0, 4);
testFormatUnsignedInt("1010", 0b1010, 4, 1, 0, 4);
testFormatUnsignedInt("00001010", 0b1010, 8, 1, 0, 8);
testFormatUnsignedInt("\u0000\u000000001010", 0b1010, 10, 1, 2, 8);
}
public static void testFormatUnsignedLong() {
testFormatUnsignedLong("7fffffffffffffff", Long.MAX_VALUE, 16, 4, 0, 16);
testFormatUnsignedLong("8000000000000000", Long.MIN_VALUE, 16, 4, 0, 16);
testFormatUnsignedLong("4711", 04711L, 4, 3, 0, 4);
testFormatUnsignedLong("4711", 0x4711L, 4, 4, 0, 4);
testFormatUnsignedLong("1010", 0b1010L, 4, 1, 0, 4);
testFormatUnsignedLong("00001010", 0b1010L, 8, 1, 0, 8);
testFormatUnsignedLong("\u0000\u000000001010", 0b1010L, 10, 1, 2, 8);
}
public static void testFormatUnsignedInt(String expected, int value, int arraySize, int shift, int offset, int length) {
char[] chars = new char[arraySize];
jla.formatUnsignedInt(value, shift, chars, offset, length);
String s = new String(chars);
if (!expected.equals(s)) {
throw new Error(s + " should be equal to expected " + expected);
}
}
public static void testFormatUnsignedLong(String expected, long value, int arraySize, int shift, int offset, int length) {
char[] chars = new char[arraySize];
jla.formatUnsignedLong(value, shift, chars, offset, length);
String s = new String(chars);
if (!expected.equals(s)) {
throw new Error(s + " should be equal to expected " + expected);
}
}
public static void main(String[] args) {
testFormatUnsignedInt();
testFormatUnsignedLong();
}
}