Merge pull request #150 from msmolens/set-fields

Enable setting primitive data type fields on Java classes
This commit is contained in:
Mathieu Virbel 2015-03-12 16:22:45 +01:00
commit 6208c609eb
3 changed files with 123 additions and 2 deletions

View File

@ -329,6 +329,61 @@ cdef class JavaField(object):
j_self = (<JavaClass?>obj).j_self.obj
return self.read_field(j_self)
def __set__(self, obj, value):
cdef jobject j_self
self.ensure_field()
if obj is None:
# set not implemented for static fields
raise NotImplementedError()
j_self = (<JavaClass?>obj).j_self.obj
self.write_field(j_self, value)
cdef write_field(self, jobject j_self, value):
cdef jboolean j_boolean
cdef jbyte j_byte
cdef jchar j_char
cdef jshort j_short
cdef jint j_int
cdef jlong j_long
cdef jfloat j_float
cdef jdouble j_double
cdef JNIEnv *j_env = get_jnienv()
# type of the java field
r = self.definition[0]
# set the java field; implemented only for primitive types
if r == 'Z':
j_boolean = <jboolean>value
j_env[0].SetBooleanField(j_env, j_self, self.j_field, j_boolean)
elif r == 'B':
j_byte = <jbyte>value
j_env[0].SetByteField(j_env, j_self, self.j_field, j_byte)
elif r == 'C':
j_char = <jchar>value
j_env[0].SetCharField(j_env, j_self, self.j_field, j_char)
elif r == 'S':
j_short = <jshort>value
j_env[0].SetShortField(j_env, j_self, self.j_field, j_short)
elif r == 'I':
j_int = <jint>value
j_env[0].SetIntField(j_env, j_self, self.j_field, j_int)
elif r == 'J':
j_long = <jlong>value
j_env[0].SetLongField(j_env, j_self, self.j_field, j_long)
elif r == 'F':
j_float = <jfloat>value
j_env[0].SetFloatField(j_env, j_self, self.j_field, j_float)
elif r == 'D':
j_double = <jdouble>value
j_env[0].SetDoubleField(j_env, j_self, self.j_field, j_double)
else:
raise Exception('Invalid field definition')
check_exception(j_env)
cdef read_field(self, jobject j_self):
cdef jboolean j_boolean
cdef jbyte j_byte

View File

@ -54,6 +54,19 @@ public class BasicsTest {
public double fieldD = 1.23456789;
public String fieldString = new String("helloworld");
public boolean fieldSetZ;
public byte fieldSetB;
public char fieldSetC;
public short fieldSetS;
public int fieldSetI;
public long fieldSetJ;
public float fieldSetF;
public double fieldSetD;
public String fieldSetString;
// Floating-point comparison epsilon
private final static double EPSILON = 1E-6;
public BasicsTest() {}
public BasicsTest(byte fieldBVal) {
fieldB = fieldBVal;
@ -108,9 +121,10 @@ public class BasicsTest {
public boolean methodParamsZBCSIJFD(boolean x1, byte x2, char x3, short x4,
int x5, long x6, float x7, double x8) {
// ADD float / double, but dunno how to do with approx
return (x1 == true && x2 == 127 && x3 == 'k' && x4 == 32767 &&
x5 == 2147483467 && x6 == 2147483467);
x5 == 2147483467 && x6 == 2147483467 &&
(Math.abs(x7 - 1.23456789f) < EPSILON) &&
(Math.abs(x8 - 1.23456789) < EPSILON));
}
public boolean methodParamsString(String s) {
@ -160,4 +174,36 @@ public class BasicsTest {
x[1] = 1;
x[2] = -127;
}
public boolean testFieldSetZ() {
return (fieldSetZ == true);
}
public boolean testFieldSetB() {
return (fieldSetB == 127);
}
public boolean testFieldSetC() {
return (fieldSetC == 'k');
}
public boolean testFieldSetS() {
return (fieldSetS == 32767);
}
public boolean testFieldSetI() {
return (fieldSetI == 2147483467);
}
public boolean testFieldSetJ() {
return (fieldSetJ == 2147483467);
}
public boolean testFieldSetF() {
return (Math.abs(fieldSetF - 1.23456789f) < EPSILON);
}
public boolean testFieldSetD() {
return (Math.abs(fieldSetD - 1.23456789) < EPSILON);
}
}

View File

@ -55,6 +55,26 @@ class BasicsTest(unittest.TestCase):
self.assertEquals(test.fieldB, 127)
self.assertEquals(test2.fieldB, 10)
def test_instance_set_fields(self):
test = autoclass('org.jnius.BasicsTest')()
test.fieldSetZ = True
test.fieldSetB = 127
test.fieldSetC = ord('k')
test.fieldSetS = 32767
test.fieldSetI = 2147483467
test.fieldSetJ = 2147483467
test.fieldSetF = 1.23456789
test.fieldSetD = 1.23456789
self.assertTrue(test.testFieldSetZ())
self.assertTrue(test.testFieldSetB())
self.assertTrue(test.testFieldSetC())
self.assertTrue(test.testFieldSetS())
self.assertTrue(test.testFieldSetI())
self.assertTrue(test.testFieldSetJ())
self.assertTrue(test.testFieldSetF())
self.assertTrue(test.testFieldSetD())
def test_instances_methods_array(self):
test = autoclass('org.jnius.BasicsTest')()
self.assertEquals(test.methodArrayZ(), [True] * 3)