# ignite-496

Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/39f9760b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/39f9760b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/39f9760b

Branch: refs/heads/ignite-496
Commit: 39f9760bb591175d513144fc8288a14e9c65baba
Parents: 08cb065
Author: sboikov <semen.boi...@inria.fr>
Authored: Mon Mar 23 22:05:38 2015 +0300
Committer: sboikov <semen.boi...@inria.fr>
Committed: Mon Mar 23 23:35:21 2015 +0300

----------------------------------------------------------------------
 .../src/main/cpp/include/ignite-interop-api.h   | 180 ++++++++++++++++---
 .../src/main/cpp/src/ignite-interop-api.cpp     | 107 ++++++-----
 .../src/test/cpp/ingite-interop-api-test.cpp    |  39 +++-
 3 files changed, 256 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/39f9760b/modules/interop-api/src/main/cpp/include/ignite-interop-api.h
----------------------------------------------------------------------
diff --git a/modules/interop-api/src/main/cpp/include/ignite-interop-api.h 
b/modules/interop-api/src/main/cpp/include/ignite-interop-api.h
index 7049cd5..60e5907 100644
--- a/modules/interop-api/src/main/cpp/include/ignite-interop-api.h
+++ b/modules/interop-api/src/main/cpp/include/ignite-interop-api.h
@@ -18,7 +18,7 @@
 #ifndef IGNITE_INTEROP_API
 #define IGNITE_INTEROP_API
 
-#if defined(__CYGWIN__) || defined(_WINDLL)
+#if defined(__CYGWIN__) || defined(_WIN32)
 # ifdef IGNITE_API_EXPORT
 #    define IGNITE_API_IMPORT_EXPORT __declspec(dllexport)
 # else
@@ -28,37 +28,167 @@
 # define IGNITE_API_IMPORT_EXPORT
 #endif
 
+#include <stdint.h>
 #include <string>
 
 namespace ignite {
     /**
-     * Ignite exception.
-     */
-    class IGNITE_API_IMPORT_EXPORT IgniteException: public std::exception {
-    public:
-        /**
-         * Constructor of exception with message text.
-         *
-         * @param what Exception text.
-         */
-        IgniteException(const std::string& what) : what_(what) {
-            // No-op.
-        }
-
-        virtual const char* what() const throw() {
-            return what_.c_str();
-        }
+    * Callback to handle Java errors.
+    */
+    typedef void(*IgniteErrorCallback)(const std::string& errMsg, const 
std::string& errCls);
 
-    private:
-        std::string what_;
-    };
 
     /**
     * Callback for asynchronous operations.
     */
     typedef void(*IgniteAsyncCallback)(void* data, int resType, void* res);
 
-    class IgniteJvm;
+       class IgniteInputStream {
+       public:
+               IgniteInputStream(uint64_t dataPtr, int32_t size, int32_t 
allocSize) : 
+                       dataPtr(dataPtr), size(size), allocSize(allocSize), 
readPos(0) {
+                       assert(dataPtr);
+                       assert(size > 0);
+                       assert(allocSize > 0);
+               }
+
+               IgniteInputStream(void* dataPtr, int32_t size, int32_t 
allocSize) : 
+                       dataPtr(reinterpret_cast<uint64_t>(dataPtr)), 
size(size), allocSize(allocSize), readPos(0) {
+                       assert(dataPtr);
+                       assert(size > 0);
+                       assert(allocSize > 0);
+               }
+
+               int8_t readByte() {
+                       checkAvailable(1);
+
+                       int8_t res = *reinterpret_cast<int8_t*>(dataPtr + 
readPos);
+
+                       readPos++;
+
+                       return res;
+               }
+
+               int32_t readInt() {
+                       checkAvailable(4);
+
+                       int32_t res = *reinterpret_cast<int32_t*>(dataPtr + 
readPos);
+
+                       readPos += 4;
+
+                       return res;
+               }
+
+               int64_t readLong() {
+                       checkAvailable(8);
+
+                       int64_t res = *reinterpret_cast<int64_t*>(dataPtr + 
readPos);
+
+                       readPos += 8;
+
+                       return res;
+               }
+
+       private:
+               void checkAvailable(int32_t cnt) {
+                       assert(readPos + cnt <= size);
+               }
+
+               uint64_t dataPtr;
+
+               int32_t size;
+
+               int32_t allocSize;
+
+               int32_t readPos;
+       };
+
+       class IgniteOutputStream {
+       public:
+               /**
+               * @param initialSize Initially allocated size.
+               */
+               IgniteOutputStream(int initialSize) : allocSize(initialSize), 
pos(0) {
+                       assert(initialSize > 0);
+
+                       dataPtr = 
reinterpret_cast<uint64_t>(malloc(initialSize));
+               }
+
+               ~IgniteOutputStream() {
+                       free(reinterpret_cast<void*>(dataPtr));
+               }
+
+               /**
+               * @param val Value to write.
+               */
+               void writeBool(bool val) {
+                       writeByte(val ? 1 : 0);
+               }
+
+               /**
+               * @param val Value to write.
+               */
+               void writeByte(int8_t val) {
+                       resizeIfNeeded(1);
+
+                       *reinterpret_cast<int8_t*>(dataPtr + pos) = val;
+
+                       pos++;
+               }
+
+               void writeInt(int32_t val) {
+                       resizeIfNeeded(4);
+
+                       *reinterpret_cast<int32_t*>(dataPtr + pos) = val;
+
+                       pos += 4;
+               }
+
+               void writeLong(int64_t val) {
+                       resizeIfNeeded(8);
+
+                       *reinterpret_cast<int64_t*>(dataPtr + pos) = val;
+
+                       pos += 8;
+               }
+
+               uint64_t dataPointer() {
+                       return dataPtr;
+               }
+
+               int32_t position() {
+                       return pos;
+               }
+
+               int32_t allocatedSize() {
+                       return allocSize;
+               }
+
+       private:
+               /**
+               * @param cnt Resize byte count.
+               */
+               void resizeIfNeeded(int32_t cnt) {
+                       int32_t newSize = pos + cnt;
+
+                       if (newSize > allocSize) {
+                               allocSize *= 2;
+
+                               if (newSize > allocSize)
+                                       allocSize = newSize;
+
+                               dataPtr = 
reinterpret_cast<uint64_t>(realloc(reinterpret_cast<void*>(dataPtr), 
allocSize));
+                       }
+               }
+
+               uint64_t dataPtr;
+
+               int32_t pos;
+
+               int32_t allocSize;
+       };
+
+       class IgniteJvm;
     class IgniteCache;
 
     class IGNITE_API_IMPORT_EXPORT Ignite {
@@ -103,15 +233,15 @@ namespace ignite {
     public:
         ~IgniteJvm();
 
-        Ignite* startIgnite(char* cfgPath, char* igniteName) 
throw(IgniteException);
+        Ignite* startIgnite(char* cfgPath, char* igniteName);
 
         class Context;
     private:
-        IgniteJvm();
+        IgniteJvm(IgniteErrorCallback errCb);
 
         Context* ctx;
 
-        friend IGNITE_API_IMPORT_EXPORT IgniteJvm* testIgniteJvmStart();
+        friend IGNITE_API_IMPORT_EXPORT IgniteJvm* 
testIgniteJvmStart(IgniteErrorCallback errCb);
 
         friend class Ignite;
 
@@ -121,7 +251,7 @@ namespace ignite {
     /**
     * Initialization function for test.
     */
-    IGNITE_API_IMPORT_EXPORT extern IgniteJvm* testIgniteJvmStart();
+    IGNITE_API_IMPORT_EXPORT extern IgniteJvm* 
testIgniteJvmStart(IgniteErrorCallback errCb);
 }
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/39f9760b/modules/interop-api/src/main/cpp/src/ignite-interop-api.cpp
----------------------------------------------------------------------
diff --git a/modules/interop-api/src/main/cpp/src/ignite-interop-api.cpp 
b/modules/interop-api/src/main/cpp/src/ignite-interop-api.cpp
index 6e260c6..e5728b4 100644
--- a/modules/interop-api/src/main/cpp/src/ignite-interop-api.cpp
+++ b/modules/interop-api/src/main/cpp/src/ignite-interop-api.cpp
@@ -86,6 +86,12 @@ namespace ignite {
      */
     class IgniteJvm::Context {
     public:
+               Context(IgniteErrorCallback errCb) : errCb(errCb) {
+                       // No-op.
+               }
+
+               IgniteErrorCallback errCb;
+
         JavaVM* jvm;
 
         jclass c_Throwable;
@@ -143,16 +149,19 @@ namespace ignite {
     }
 
     /*
-    * Clear pending exception and throw it. Callee of this method must first 
ensure
+    * Clear pending exception and call error callback. Callee of this method 
must first ensure
     * that exception really happened.
     */
-    void clearAndThrow(JNIEnv* env, IgniteJvm::Context* jvmCtx) 
throw(IgniteException) {
+    void clearErrorAndRunCallback(JNIEnv* env, IgniteJvm::Context* jvmCtx) {
         assert (env->ExceptionCheck());
 
         jthrowable err = env->ExceptionOccurred();
 
-        if (!err)
-            throw IgniteException("Exception handler was called, but there is 
no pending Java exception.");
+        if (!err) {
+            jvmCtx->errCb("Exception handler was called, but there is no 
pending Java exception.", "");
+
+                       return;
+               }
 
         env->ExceptionDescribe();
 
@@ -169,13 +178,13 @@ namespace ignite {
 
             env->ReleaseStringUTFChars(msg, str);
 
-            throw IgniteException(msgStr);
+                       jvmCtx->errCb(msgStr, "");
         }
         else {
             if (env->ExceptionCheck())
-                clearAndThrow(env, jvmCtx);
+                clearErrorAndRunCallback(env, jvmCtx);
             else
-                throw IgniteException("Unknown ignite exception.");
+                               jvmCtx->errCb("Unknown ignite exception.", "");
         }
     }
 
@@ -186,7 +195,7 @@ namespace ignite {
             env->DeleteLocalRef(localRef); // Clear local ref irrespective of 
result.
 
             if (!globalRef)
-                clearAndThrow(env, jvmCtx);
+                clearErrorAndRunCallback(env, jvmCtx);
 
             return globalRef;
         }
@@ -205,11 +214,11 @@ namespace ignite {
 
         ~IgniteInteropTarget();
 
-        jint inOp(jint type, void* ptr, jint len);
+        bool inOp(jint type, void* ptr, jint len);
 
         void* inOutOp(jint type, void* ptr, jint len);
 
-        void inOpAsync(jint type, void* ptr, jint len, IgniteAsyncCallback cb, 
void* data);
+        bool inOpAsync(jint type, void* ptr, jint len, IgniteAsyncCallback cb, 
void* data);
 
     private:
         /** */
@@ -228,20 +237,18 @@ namespace ignite {
         env->DeleteGlobalRef(obj);
     }
 
-    jint IgniteInteropTarget::inOp(jint type, void* ptr, jint len) {
+    bool IgniteInteropTarget::inOp(jint type, void* ptr, jint len) {
         JNIEnv* env = attach(jvmCtx);
 
         jint res = env->CallNonvirtualIntMethod(this->obj, this->cls, 
jvmCtx->m_InteropTarget_inOp, type, ptr, len);
 
         if (env->ExceptionCheck()) {
-            clearAndThrow(env, jvmCtx);
-
-            assert(false);
+            clearErrorAndRunCallback(env, jvmCtx);
 
             return 0;
         }
 
-        return res;
+        return 1;
     }
 
     void* IgniteInteropTarget::inOutOp(jint type, void* ptr, jint len) {
@@ -250,9 +257,7 @@ namespace ignite {
         jlong res = env->CallNonvirtualLongMethod(this->obj, this->cls, 
jvmCtx->m_InteropTarget_inOutOp, type, ptr, len);
 
         if (env->ExceptionCheck()) {
-            clearAndThrow(env, jvmCtx);
-
-            assert(false);
+            clearErrorAndRunCallback(env, jvmCtx);
 
             return NULL;
         }
@@ -260,13 +265,18 @@ namespace ignite {
         return (void*)res;
     }
 
-    void IgniteInteropTarget::inOpAsync(jint type, void* ptr, jint len, 
IgniteAsyncCallback cb, void* data) {
+    bool IgniteInteropTarget::inOpAsync(jint type, void* ptr, jint len, 
IgniteAsyncCallback cb, void* data) {
         JNIEnv* env = attach(jvmCtx);
 
         env->CallNonvirtualVoidMethod(this->obj, this->cls, 
jvmCtx->m_InteropTarget_inOutOpAsync, type, ptr, len, cb, data);
 
-        if (env->ExceptionCheck())
-            clearAndThrow(env, jvmCtx);
+        if (env->ExceptionCheck()) {
+            clearErrorAndRunCallback(env, jvmCtx);
+
+                       return 0;
+               }
+
+               return 1;
     }
 
     class IgniteCache::Impl : public IgniteInteropTarget {
@@ -276,15 +286,17 @@ namespace ignite {
         }
     };
 
-    IgniteJvm::IgniteJvm() {
-        ctx = new Context();
+    IgniteJvm::IgniteJvm(IgniteErrorCallback errCb) {
+        assert (errCb);
+
+               ctx = new Context(errCb);
     }
 
     IgniteJvm::~IgniteJvm() {
         delete ctx;
     }
 
-    Ignite* IgniteJvm::startIgnite(char* cfgPath, char* igniteName) 
throw(IgniteException){
+    Ignite* IgniteJvm::startIgnite(char* cfgPath, char* igniteName) {
         JNIEnv* env = attach(ctx);
 
         jstring cfgPath0 = env->NewStringUTF(cfgPath);
@@ -305,12 +317,15 @@ namespace ignite {
         if (env->ExceptionCheck()) {
             assert (!igniteObj);
 
-            clearAndThrow(env, ctx);
+            clearErrorAndRunCallback(env, ctx);
 
-            assert (false);
+            return NULL;
         }
-        else if (!igniteObj)
-            throw IgniteException("Failed to start Ignite.");
+        else if (!igniteObj) {
+                       ctx->errCb("Failed to start Ignite.", "");
+
+                       return NULL;
+               }
 
         cout << "Started ignite" << endl;
 
@@ -323,12 +338,15 @@ namespace ignite {
         if (env->ExceptionCheck()) {
             assert (!interopProc);
 
-            clearAndThrow(env, ctx);
+            clearErrorAndRunCallback(env, ctx);
 
-            assert (false);
+            return NULL;
         }
-        else if (!interopProc)
-            throw IgniteException("Failed to get InteropProcessor.");
+        else if (!interopProc) {
+                       ctx->errCb("Failed to get InteropProcessor.", "");
+
+                       return NULL;
+               }
 
         Ignite* ignite0 = new Ignite(this);
 
@@ -360,9 +378,7 @@ namespace ignite {
             if (name0)
                 env->DeleteLocalRef(name0);
 
-            clearAndThrow(env, jvm->ctx);
-
-            assert(false);
+            clearErrorAndRunCallback(env, jvm->ctx);
 
             return NULL;
         }
@@ -373,14 +389,15 @@ namespace ignite {
             env->DeleteLocalRef(name0);
 
         if (env->ExceptionCheck()) {
-            clearAndThrow(env, jvm->ctx);
-
-            assert(false);
+            clearErrorAndRunCallback(env, jvm->ctx);
 
             return NULL;
         }
-        else if (!cache)
-            throw IgniteException("Failed to create cache.");
+        else if (!cache) {
+            jvm->ctx->errCb("Failed to create cache.", "");
+
+                       return NULL;
+               }
 
         cache = localToGlobal(env, cache, jvm->ctx);
 
@@ -646,8 +663,10 @@ namespace ignite {
         return res;
     }
 
-    IGNITE_API_IMPORT_EXPORT IgniteJvm* testIgniteJvmStart() {
-        char* igniteHome;
+    IGNITE_API_IMPORT_EXPORT IgniteJvm* testIgniteJvmStart(IgniteErrorCallback 
errCb) {
+        assert(errCb);
+
+               char* igniteHome;
 
         igniteHome = getenv("IGNITE_HOME");
 
@@ -690,7 +709,7 @@ namespace ignite {
         char* errClsName;
         char* errMsg;
 
-        IgniteJvm* jvm = new IgniteJvm();
+        IgniteJvm* jvm = new IgniteJvm(errCb);
 
         int res = ContextInit(args, *jvm->ctx, &errClsName, &errMsg);
 
@@ -701,6 +720,8 @@ namespace ignite {
 
             cout << "Failed to create JVM: " << errMsg << endl;
 
+                       errCb(errMsg, "");
+
             return NULL;
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/39f9760b/modules/interop-api/src/test/cpp/ingite-interop-api-test.cpp
----------------------------------------------------------------------
diff --git a/modules/interop-api/src/test/cpp/ingite-interop-api-test.cpp 
b/modules/interop-api/src/test/cpp/ingite-interop-api-test.cpp
index b95ab17..a565f1e 100644
--- a/modules/interop-api/src/test/cpp/ingite-interop-api-test.cpp
+++ b/modules/interop-api/src/test/cpp/ingite-interop-api-test.cpp
@@ -25,10 +25,45 @@
 using namespace ignite;
 using namespace std;
 
+class TestError {
+};
+
+void testErrorCallback(const string& errMsg, const string& errCls) {
+       cout << "Test error callback [err=" << errMsg << "]" << endl;
+       
+       throw TestError();
+}
+
+TEST_CASE("Stream", "[ignite]") {
+       IgniteOutputStream out(1);
+
+       REQUIRE(sizeof(out) == 16);
+
+       out.writeByte(1);
+       out.writeInt(1024);
+       out.writeLong(2048);
+
+       out.writeByte(-1);
+       out.writeInt(-1024);
+       out.writeLong(-2048);
+
+       IgniteInputStream in(out.dataPointer(), out.position(), 
out.allocatedSize());
+
+       REQUIRE(in.readByte() == 1);
+       REQUIRE(in.readInt() == 1024);
+       REQUIRE(in.readLong() == 2048);
+
+       REQUIRE(in.readByte() == -1);
+       REQUIRE(in.readInt() == -1024);
+       REQUIRE(in.readLong() == -2048);
+}
+
 TEST_CASE("StartIgnite", "[ignite]") {
-    IgniteJvm* jvm = testIgniteJvmStart();
+       IgniteJvm* jvm = testIgniteJvmStart(testErrorCallback);
+
+    REQUIRE(jvm);
 
-    REQUIRE_THROWS_AS(jvm->startIgnite("invalid config", "ignite1"), 
IgniteException);
+       REQUIRE_THROWS_AS(jvm->startIgnite("invalid config", "ignite1"), 
TestError);
 
     Ignite* ignite = 
jvm->startIgnite("modules\\interop-api\\src\\test\\config\\test-single-node.xml",
 "ignite1");
     

Reply via email to