Prechádzať zdrojové kódy

Add JNI double getter method support

Patrick-Christopher Mattulat 1 rok pred
rodič
commit
c964d9ee2a

+ 1 - 0
include/ls-std/core/interface/IJniApi.hpp

@@ -26,6 +26,7 @@ namespace ls::std::core::experimental::interface_type
       virtual jboolean callBooleanMethod(jobject _javaObject, jmethodID _methodId) = 0;
       virtual jbyte callByteMethod(jobject _javaObject, jmethodID _methodId) = 0;
       virtual jchar callCharMethod(jobject _javaObject, jmethodID _methodId) = 0;
+      virtual jdouble callDoubleMethod(jobject _javaObject, jmethodID _methodId) = 0;
       virtual jfloat callFloatMethod(jobject _javaObject, jmethodID _methodId) = 0;
       virtual jint callIntMethod(jobject _javaObject, jmethodID _methodId) = 0;
       virtual jlong callLongMethod(jobject _javaObject, jmethodID _methodId) = 0;

+ 1 - 0
include/ls-std/core/jni/JniApi.hpp

@@ -25,6 +25,7 @@ namespace ls::std::core::experimental
       jboolean callBooleanMethod(jobject _javaObject, jmethodID _methodId) override;
       jbyte callByteMethod(jobject _javaObject, jmethodID _methodId) override;
       jchar callCharMethod(jobject _javaObject, jmethodID _methodId) override;
+      jdouble callDoubleMethod(jobject _javaObject, jmethodID _methodId) override;
       jfloat callFloatMethod(jobject _javaObject, jmethodID _methodId) override;
       jint callIntMethod(jobject _javaObject, jmethodID _methodId) override;
       jlong callLongMethod(jobject _javaObject, jmethodID _methodId) override;

+ 1 - 0
include/ls-std/core/jni/JniClass.hpp

@@ -44,6 +44,7 @@ namespace ls::std::core::experimental
       void _callBooleanMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
       void _callByteMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
       void _callCharMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
+      void _callDoubleMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
       void _callFloatMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
       void _callIntMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);
       void _callLongMethod(const ::std::string &_methodIdentifier, ls::std::core::experimental::JniReturnValue &_returnValue);

+ 3 - 0
include/ls-std/core/jni/JniReturnValue.hpp

@@ -25,6 +25,7 @@ namespace ls::std::core::experimental
       [[nodiscard]] jboolean getBooleanValue() const;
       [[nodiscard]] jbyte getByteValue() const;
       [[nodiscard]] jchar getCharValue() const;
+      [[nodiscard]] jdouble getDoubleValue() const;
       [[nodiscard]] jfloat getFloatValue() const;
       [[nodiscard]] jint getIntegerValue() const;
       [[nodiscard]] jlong getLongValue() const;
@@ -32,6 +33,7 @@ namespace ls::std::core::experimental
       void setBooleanValue(jboolean _booleanValue);
       void setByteValue(jbyte _byteValue);
       void setCharValue(jchar _charValue);
+      void setDoubleValue(jdouble _doubleValue);
       void setFloatValue(jfloat _floatValue);
       void setIntegerValue(jint _integerValue);
       void setLongValue(jlong _longValue);
@@ -42,6 +44,7 @@ namespace ls::std::core::experimental
       jboolean booleanValue{};
       jbyte byteValue{};
       jchar charValue{};
+      jdouble doubleValue{};
       jfloat floatValue{};
       jint integerValue{};
       jlong longValue{};

+ 5 - 0
source/ls-std/core/jni/JniApi.cpp

@@ -37,6 +37,11 @@ jchar JniApi::callCharMethod(jobject _javaObject, jmethodID _methodId)
   return this->environment->CallCharMethod(_javaObject, _methodId);
 }
 
+jdouble JniApi::callDoubleMethod(jobject _javaObject, jmethodID _methodId)
+{
+  return this->environment->CallDoubleMethod(_javaObject, _methodId);
+}
+
 jfloat JniApi::callFloatMethod(jobject _javaObject, jmethodID _methodId)
 {
   return this->environment->CallFloatMethod(_javaObject, _methodId);

+ 14 - 0
source/ls-std/core/jni/JniClass.cpp

@@ -51,6 +51,7 @@ JniReturnValue JniClass::callMethod(const string &_methodIdentifier)
     this->_callBooleanMethod(_methodIdentifier, returnValue);
     this->_callByteMethod(_methodIdentifier, returnValue);
     this->_callCharMethod(_methodIdentifier, returnValue);
+    this->_callDoubleMethod(_methodIdentifier, returnValue);
     this->_callFloatMethod(_methodIdentifier, returnValue);
     this->_callIntMethod(_methodIdentifier, returnValue);
     this->_callLongMethod(_methodIdentifier, returnValue);
@@ -126,6 +127,19 @@ void JniClass::_callCharMethod(const string &_methodIdentifier, JniReturnValue &
   }
 }
 
+void JniClass::_callDoubleMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
+{
+  JniMethod method = this->methods.at(_methodIdentifier);
+  string searchString = ")D";
+  string methodSignature = method.getMethodSignature();
+  bool hasDoubleReturnType = methodSignature.rfind(searchString) == (methodSignature.size() - searchString.size());
+
+  if (hasDoubleReturnType)
+  {
+    _returnValue.setDoubleValue(this->parameter->getJniApi()->callDoubleMethod(this->parameter->getJavaObject(), method.getMethodId()));
+  }
+}
+
 void JniClass::_callFloatMethod(const string &_methodIdentifier, JniReturnValue &_returnValue)
 {
   JniMethod method = this->methods.at(_methodIdentifier);

+ 10 - 0
source/ls-std/core/jni/JniReturnValue.cpp

@@ -30,6 +30,11 @@ jchar JniReturnValue::getCharValue() const
   return this->charValue;
 }
 
+jdouble JniReturnValue::getDoubleValue() const
+{
+  return this->doubleValue;
+}
+
 jfloat JniReturnValue::getFloatValue() const
 {
   return this->floatValue;
@@ -65,6 +70,11 @@ void JniReturnValue::setCharValue(jchar _charValue)
   this->charValue = _charValue;
 }
 
+void JniReturnValue::setDoubleValue(jdouble _doubleValue)
+{
+  this->doubleValue = _doubleValue;
+}
+
 void JniReturnValue::setFloatValue(jfloat _floatValue)
 {
   this->floatValue = _floatValue;

+ 22 - 0
test/cases/core/jni/JniClassTest.cpp

@@ -175,6 +175,28 @@ namespace
     ASSERT_EQ('P', javaClass.callMethod(methodIdentifier).getCharValue());
   }
 
+  TEST_F(JniClassTest, callMethod_double_return_value)
+  {
+    string classPath = "java.utils.String";
+    JniClass javaClass = this->createJniClass(classPath);
+
+    EXPECT_CALL(*this->jniApi, findClass(classPath)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, findClass(classPath)).WillByDefault(Return(make_shared<_jclass>().get()));
+
+    string methodIdentifier = "getPi";
+    string methodSignature = "()D";
+    EXPECT_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).Times(AtLeast(1));
+    jmethodID methodId = (jmethodID) make_shared<int>().get();
+    ON_CALL(*this->jniApi, getMethodId(testing::_, methodIdentifier.c_str(), methodSignature.c_str())).WillByDefault(Return(methodId));
+
+    EXPECT_CALL(*this->jniApi, callDoubleMethod(testing::_, methodId)).Times(AtLeast(1));
+    ON_CALL(*this->jniApi, callDoubleMethod(testing::_, methodId)).WillByDefault(Return(3.14159265l));
+
+    ASSERT_TRUE(javaClass.load());
+    ASSERT_TRUE(javaClass.loadMethod(methodIdentifier, methodSignature));
+    ASSERT_DOUBLE_EQ(3.14159265l, javaClass.callMethod(methodIdentifier).getDoubleValue());
+  }
+
   TEST_F(JniClassTest, callMethod_float_return_value)
   {
     string classPath = "java.utils.String";

+ 14 - 0
test/cases/core/jni/JniReturnValueTest.cpp

@@ -41,6 +41,12 @@ namespace
     ASSERT_EQ(0, (int) returnValue.getCharValue());
   }
 
+  TEST_F(JniReturnValueTest, getDoubleValue)
+  {
+    JniReturnValue returnValue{};
+    ASSERT_FLOAT_EQ(0.0l, returnValue.getDoubleValue());
+  }
+
   TEST_F(JniReturnValueTest, getFloatValue)
   {
     JniReturnValue returnValue{};
@@ -89,6 +95,14 @@ namespace
     ASSERT_EQ('P', returnValue.getCharValue());
   }
 
+  TEST_F(JniReturnValueTest, setDoubleValue)
+  {
+    JniReturnValue returnValue{};
+    returnValue.setDoubleValue(3.14159265l);
+
+    ASSERT_FLOAT_EQ(3.14159265l, returnValue.getDoubleValue());
+  }
+
   TEST_F(JniReturnValueTest, setFloatValue)
   {
     JniReturnValue returnValue{};

+ 2 - 1
test/classes/core/jni/MockJniApi.hpp

@@ -23,8 +23,9 @@ namespace test::core::jni
       ~MockJniApi() noexcept override;
 
       MOCK_METHOD(jboolean, callBooleanMethod, (jobject _javaObject, jmethodID _methodId), (override));
-      MOCK_METHOD(jbyte, callByteMethod, (jobject _javaObject, jmethodID _methodId), (override));
+      MOCK_METHOD(jbyte, callByteMethod, (jobject _javaObject, jmethodID _methodINd), (override));
       MOCK_METHOD(jchar, callCharMethod, (jobject _javaObject, jmethodID _methodId), (override));
+      MOCK_METHOD(jdouble, callDoubleMethod, (jobject _javaObject, jmethodID _methodId), (override));
       MOCK_METHOD(jfloat, callFloatMethod, (jobject _javaObject, jmethodID _methodId), (override));
       MOCK_METHOD(jint, callIntMethod, (jobject _javaObject, jmethodID _methodId), (override));
       MOCK_METHOD(jlong, callLongMethod, (jobject _javaObject, jmethodID _methodId), (override));