From 511905c894fdb6560048f7a9e6ab4e7773450839 Mon Sep 17 00:00:00 2001 From: Martin Vajnar Date: Wed, 24 Jul 2013 22:55:24 +0200 Subject: [PATCH] JORTE: add deserialize function to support endianness setting This adds implementation of deserialize function which sets proper byte order for Java's ByteBuffer based on the received data's endianness. Serialize function is not needed as long as the byte order of Java's ByteBuffer is not manually changed from native byte order. --- orte/include/jorte/org_ocera_orte_DomainApp.h | 2 +- orte/java/src/org/ocera/orte/DomainApp.java | 11 +- .../ocera/orte/examples/hello/HelloMsg.java | 2 +- .../ocera/orte/examples/robot/RoboMsg.java | 2 +- orte/libjorte/JORTETypeRegisterAdd.c | 105 +++++++++++++++++- orte/libjorte/onLoad.c | 3 + 6 files changed, 116 insertions(+), 9 deletions(-) diff --git a/orte/include/jorte/org_ocera_orte_DomainApp.h b/orte/include/jorte/org_ocera_orte_DomainApp.h index 9fbe1d4..194760d 100644 --- a/orte/include/jorte/org_ocera_orte_DomainApp.h +++ b/orte/include/jorte/org_ocera_orte_DomainApp.h @@ -37,7 +37,7 @@ JNIEXPORT jboolean JNICALL Java_org_ocera_orte_DomainApp_jORTEDomainAppDestroy * Signature: (JLjava/lang/String;J)I */ JNIEXPORT jint JNICALL Java_org_ocera_orte_DomainApp_jORTETypeRegisterAdd - (JNIEnv *, jobject, jlong, jstring, jlong); + (JNIEnv *, jobject, jlong, jstring, jlong, jobject); /* * Class: org_ocera_orte_DomainApp diff --git a/orte/java/src/org/ocera/orte/DomainApp.java b/orte/java/src/org/ocera/orte/DomainApp.java index 771f5fe..32d2a2c 100644 --- a/orte/java/src/org/ocera/orte/DomainApp.java +++ b/orte/java/src/org/ocera/orte/DomainApp.java @@ -22,6 +22,8 @@ */ package org.ocera.orte; +import java.nio.ByteBuffer; + import org.ocera.orte.types.*; @@ -83,11 +85,13 @@ public class DomainApp extends Domain */ public boolean regNewDataType(String name, - long maxlength) + long maxlength, + ByteBuffer buffer) { int b = jORTETypeRegisterAdd(this.handle, name, - maxlength); + maxlength, + buffer); if (b == ORTEConstant.ORTE_BAD_HANDLE) { System.out.println(":!j: regNewDataType() failed! [bad domain handle]"); @@ -219,7 +223,8 @@ public class DomainApp extends Domain private native int jORTETypeRegisterAdd(long dhandle, String typeName, - long maxlenght); + long maxlenght, + ByteBuffer buffer); /** diff --git a/orte/java/src/org/ocera/orte/examples/hello/HelloMsg.java b/orte/java/src/org/ocera/orte/examples/hello/HelloMsg.java index b87bf5d..a60ece7 100644 --- a/orte/java/src/org/ocera/orte/examples/hello/HelloMsg.java +++ b/orte/java/src/org/ocera/orte/examples/hello/HelloMsg.java @@ -37,7 +37,7 @@ public class HelloMsg extends org.ocera.orte.types.MessageData counter++; this.setTopic(newTopic); // set the topic of a publication // register new data typeName - b = domainApp.regNewDataType(this.getType(),getMaxDataLength()); + b = domainApp.regNewDataType(this.getType(),getMaxDataLength(),this.buffer); if (b == false) { System.out.println(":j!: cannot register data type!"); diff --git a/orte/java/src/org/ocera/orte/examples/robot/RoboMsg.java b/orte/java/src/org/ocera/orte/examples/robot/RoboMsg.java index fee3865..57e7a3d 100644 --- a/orte/java/src/org/ocera/orte/examples/robot/RoboMsg.java +++ b/orte/java/src/org/ocera/orte/examples/robot/RoboMsg.java @@ -40,7 +40,7 @@ public class RoboMsg extends org.ocera.orte.types.MessageData counter++; this.setTopic(newTopic); // set the topic of a publication // register new data typeName - b = domainApp.regNewDataType("motion_speed",getMaxDataLength()); + b = domainApp.regNewDataType("motion_speed",getMaxDataLength(),this.buffer); if (b == false) { System.out.println(":j!: cannot register data type!"); diff --git a/orte/libjorte/JORTETypeRegisterAdd.c b/orte/libjorte/JORTETypeRegisterAdd.c index 73e9c64..f5e6718 100644 --- a/orte/libjorte/JORTETypeRegisterAdd.c +++ b/orte/libjorte/JORTETypeRegisterAdd.c @@ -25,16 +25,112 @@ * */ - +#include +#include // library header file's path #include "orte.h" // pregenerated header #include "jorte/org_ocera_orte_DomainApp.h" +#include "jorte/jorte_protos_api.h" #include "jorte/4all.h" +extern JavaVM *javavm; +static jobject byte_buf; + +void deserialize(CDR_Codec *cdrCodec, void *instance) { + JNIEnv *env = 0; + jclass cls = 0; + jfieldID fid = 0; + jmethodID mid = 0; + jobject obj_bo = 0; + + //set byte order only once + if(byte_buf) { + // get environment + (*javavm)->AttachCurrentThread(javavm, (void **)&env, NULL); + if(env == 0) + { + #ifdef TEST_STAGE + printf(":!c: env = NULL \n"); + #endif + } + + //prepare ByteOrder + cls = (*env)->FindClass(env, "java/nio/ByteOrder"); + if (cls == 0) { + #ifdef TEST_STAGE + printf(":!c: cls = NULL \n"); + #endif + } + if(cdrCodec->data_endian == BigEndian) { + fid = (*env)->GetStaticFieldID(env, + cls, + "BIG_ENDIAN", + "Ljava/nio/ByteOrder;"); + } + else { + fid = (*env)->GetStaticFieldID(env, + cls, + "LITTLE_ENDIAN", + "Ljava/nio/ByteOrder;"); + } + if(fid == 0) { + #ifdef TEST_STAGE + printf(":!c: fid = NULL \n"); + #endif + } + obj_bo = (*env)->GetStaticObjectField(env, cls, fid); + if(obj_bo == 0) { + #ifdef TEST_STAGE + printf(":!c: cls = NULL \n"); + #endif + } + + // set byte order to ByteBuffer + // get BB class + cls = (*env)->GetObjectClass(env, byte_buf); + if(cls == 0) + { + #ifdef TEST_STAGE + printf(":!c: cls = NULL \n"); + #endif + } + // get methodID - order(ByteOrder) + mid = (*env)->GetMethodID(env, + cls, + "order", + "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"); + if(mid == 0) + { + #ifdef TEST_STAGE + printf(":!c: mid = NULL \n"); + #endif + } + + // set ByteOrder + if((*env)->CallObjectMethod(env,byte_buf,mid,obj_bo) == 0) + { + #ifdef TEST_STAGE + printf(":!c: set byte order failed.. \n"); + #endif + } + + // delete global reference + (*env)->DeleteGlobalRef(env, byte_buf); + byte_buf = 0; + + (*javavm)->DetachCurrentThread(javavm); + } + + //copy over the message instance + memcpy(instance, + cdrCodec->buffer, + cdrCodec->buf_len); +} + JNIEXPORT jint JNICALL Java_org_ocera_orte_DomainApp_jORTETypeRegisterAdd -(JNIEnv *env, jclass cls, jlong handle, jstring jname, jlong jlength) +(JNIEnv *env, jclass cls, jlong handle, jstring jname, jlong jlength, jobject obj_bb) { const char *name; int b; @@ -45,11 +141,14 @@ Java_org_ocera_orte_DomainApp_jORTETypeRegisterAdd b = ORTETypeRegisterAdd((ORTEDomain *) handle, name, NULL, - NULL, + (ORTETypeDeserialize)deserialize, NULL, (unsigned int) jlength); // free memmory space (*env)->ReleaseStringUTFChars(env,jname,name); + + byte_buf = (*env)->NewGlobalRef(env, obj_bb); + #ifdef TEST_STAGE printf(":c: jORTETypeRegisterAdd vraci %d [%d = ORTE_OK, %d = ORTE_BAD_HANDLE] \n", b,ORTE_OK,ORTE_BAD_HANDLE); diff --git a/orte/libjorte/onLoad.c b/orte/libjorte/onLoad.c index f7b8e48..21d56b7 100644 --- a/orte/libjorte/onLoad.c +++ b/orte/libjorte/onLoad.c @@ -5,6 +5,8 @@ static jmethodID findClassM; static jmethodID findLoadedClassM; static jobject classLoader; +JavaVM *javavm; + JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { JNIEnv *env; jclass testCl; @@ -13,6 +15,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { jmethodID getClassLoader; (*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6); + javavm = vm; testCl = (*env)->FindClass(env, "org/ocera/orte/JOrte"); clClass = (*env)->FindClass(env, "java/lang/Class"); -- 2.39.2