]> rtime.felk.cvut.cz Git - orte.git/commitdiff
JORTE: add deserialize function to support endianness setting
authorMartin Vajnar <martin.vajnar@gmail.com>
Wed, 24 Jul 2013 20:55:24 +0000 (22:55 +0200)
committerMartin Vajnar <martin.vajnar@gmail.com>
Wed, 24 Jul 2013 20:55:24 +0000 (22:55 +0200)
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
orte/java/src/org/ocera/orte/DomainApp.java
orte/java/src/org/ocera/orte/examples/hello/HelloMsg.java
orte/java/src/org/ocera/orte/examples/robot/RoboMsg.java
orte/libjorte/JORTETypeRegisterAdd.c
orte/libjorte/onLoad.c

index 9fbe1d43fd17e18babbf367cb93735e90f91e2d8..194760d954f513346349bc32103bf3c1fcbd984d 100644 (file)
@@ -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
index 771f5fe42cfebd89cde1cc632b5b6fb1effc15d2..32d2a2c189cbabf29ed6c7c8d92938d8b9b31ba3 100644 (file)
@@ -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);
 
 
  /**
index b87bf5d8066d91d6db906cb4537df776a1b00b8a..a60ece7281205d167d5cc27620b8fbb7f9f4ec8a 100644 (file)
@@ -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!");    
index fee386556c4f8d43192f23b2cf0baf0772ea0117..57e7a3dafc6b86ae115f97da8bc8ab808b6827eb 100644 (file)
@@ -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!");    
index 73e9c640ad6080bbe9424df5de4d4a4dae3d6c69..f5e6718c2e01c9335ae63e62d4bdf49caa8e258c 100644 (file)
   *
   */
 
-
+#include <jni.h>
+#include <string.h>
 // 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);
index f7b8e484e129802156fe0474b482b4f73485d4c5..21d56b7120ca82e9e9f79aca90e286cfa31f850b 100644 (file)
@@ -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");