Java - unsigned long long marshalling improvements for negative numbers

Affects marshalling of negative numbers from Java to C only.
A cast to signed long long in the C layer will now result in the expected value.

Closes #623.
This commit is contained in:
William S Fulton 2016-03-31 18:42:08 +01:00
parent 8322686e84
commit a15bbbaee5
5 changed files with 90 additions and 14 deletions

View File

@ -5,6 +5,12 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.9 (in progress)
===========================
2016-03-31: wsfulton
[Java] unsigned long long marshalling improvements when a negative number
is passed from Java to C. A cast to signed long long in the C layer will now
result in the expected value. No change for positive numbers passed to C.
Fixes #623.
2016-03-22: alexwarg
[Lua] #398 Fix lua __getitem + inheritance
The new handling of classes in Lua (not merging methods into the derived classes)

View File

@ -3,7 +3,8 @@
// unsigned long long types map correctly to long and BigInteger respectively.
import long_long.*;
import java.math.*;
import java.math.BigInteger;
import java.util.ArrayList;
public class long_long_runme {
@ -54,12 +55,57 @@ public class long_long_runme {
check_ull(testNumber);
testNumber = testNumber.add(BigInteger.ONE);
}
try {
long_long.setUll(null);
throw new RuntimeException("null check failed");
} catch (NullPointerException e) {
}
// UnsignedToSigned - checks that a cast from unsigned long long to long long in C
// gives expected value (including -ve numbers)
long[] nums = {
0x00,
0xFF, 0x80, 0x7F, 0x01,
-0xFF, -0x80, -0x7F, -0x01,
0x100, 0x10000,
-0x100, -0x10000,
0xFFFF, 0xFF80, 0xFF7F, 0xFF01, 0xFF00,
-0xFFFF, -0xFF80, -0xFF7F, -0xFF01, -0xFF00,
0x7FFF, 0x7F80, 0x7F7F, 0x7F01, 0x7F00,
-0x7FFF, -0x7F80, -0x7F7F, -0x7F01, -0x7F00,
0x80FF, 0x8080, 0x807F, 0x8001, 0x8000,
-0x80FF, -0x8080, -0x807F, -0x8001, -0x8000,
Integer.MAX_VALUE, Integer.MIN_VALUE,
Integer.MAX_VALUE+1, Integer.MIN_VALUE-1,
Long.MAX_VALUE, Long.MIN_VALUE,
};
ArrayList<BigInteger> bigIntegers = new ArrayList<BigInteger>();
for (int i=0; i<nums.length; ++i) {
BigInteger bi = new BigInteger(new Long(nums[i]).toString());
bigIntegers.add(bi);
}
{
BigInteger bi = new BigInteger(new Long(Long.MAX_VALUE).toString());
bigIntegers.add(bi.add(BigInteger.ONE));
bi = new BigInteger(new Long(Long.MIN_VALUE).toString());
bigIntegers.add(bi.subtract(BigInteger.ONE));
}
boolean failed = false;
for (int i=0; i<bigIntegers.size(); ++i) {
BigInteger bi = (BigInteger)bigIntegers.get(i);
long longReturn = long_long.UnsignedToSigned(bi);
if (bi.longValue() != longReturn) {
System.err.println("Conversion to long failed, in:" + bi + " out:" + longReturn);
failed = true;
}
}
if (failed)
throw new RuntimeException("There were UnsignedToSigned failures");
}
public static void check_ll(long ll) {

View File

@ -38,3 +38,9 @@ unsigned long long ull;
#define lconst5 987654321LL
#define lconst6 987654321ULL
%inline %{
long long UnsignedToSigned(unsigned long long ull) {
return (long long)ull;
}
%}

View File

@ -310,8 +310,11 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
sz = JCALL1(GetArrayLength, jenv, ba);
$1 = 0;
for(i=0; i<sz; i++) {
$1 = ($1 << 8) | ($1_type)(unsigned char)bae[i];
if (sz > 0) {
$1 = ($1_type)(signed char)bae[0];
for(i=1; i<sz; i++) {
$1 = ($1 << 8) | ($1_type)(unsigned char)bae[i];
}
}
JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
}
@ -334,8 +337,11 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
sz = JCALL1(GetArrayLength, jenv, ba);
$result = 0;
for(i=0; i<sz; i++) {
$result = ($result << 8) | ($1_type)(unsigned char)bae[i];
if (sz > 0) {
$result = ($1_type)(signed char)bae[0];
for(i=1; i<sz; i++) {
$result = ($result << 8) | ($1_type)(unsigned char)bae[i];
}
}
JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
}
@ -552,8 +558,11 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
sz = JCALL1(GetArrayLength, jenv, ba);
$1 = &temp;
temp = 0;
for(i=0; i<sz; i++) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
if (sz > 0) {
temp = ($*1_ltype)(signed char)bae[0];
for(i=1; i<sz; i++) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
}
}
JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
}
@ -578,8 +587,11 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
sz = JCALL1(GetArrayLength, jenv, ba);
$result = &temp;
temp = 0;
for(i=0; i<sz; i++) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
if (sz > 0) {
temp = ($*1_ltype)(signed char)bae[0];
for(i=1; i<sz; i++) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
}
}
JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
}

View File

@ -109,8 +109,11 @@ INPUT_TYPEMAP(double, jdouble, double, "D");
bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
sz = JCALL1(GetArrayLength, jenv, ba);
temp = 0;
for(i=0; i<sz; i++) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
if (sz > 0) {
temp = ($*1_ltype)(signed char)bae[0];
for(i=1; i<sz; i++) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
}
}
JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
$1 = &temp;
@ -416,8 +419,11 @@ INOUT_TYPEMAP(double, jdouble, double, Double, "[Ljava/lang/Double;", jdoubleArr
bae = JCALL2(GetByteArrayElements, jenv, ba, 0);
sz = JCALL1(GetArrayLength, jenv, ba);
temp = 0;
for(i=0; i<sz; i++) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
if (sz > 0) {
temp = ($*1_ltype)(signed char)bae[0];
for(i=1; i<sz; i++) {
temp = (temp << 8) | ($*1_ltype)(unsigned char)bae[i];
}
}
JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0);
$1 = &temp;