コード例 #1
0
/**
 * Gets the MIDlet name for the given registered push connection.
 * <p>
 * Java declaration:
 * <pre>
 *     getEntry0([B[BI)I
 * </pre>
 *
 * @param connection The connection to add to the push registry
 * @param midlet A byte array to store the MIDlet name
 * @param midletsize The size of <tt>midlet</tt>
 *
 * @return <tt>0</tt> if successful, otherwise <tt>-1</tt>
 *
 * @throw IOException if the registry entry is too long.
 */
KNIEXPORT KNI_RETURNTYPE_INT
KNIDECL(com_sun_midp_io_j2me_push_ConnectionRegistry_getEntry0) {
    int midletsize;
    char *regentry;
    int regsize ;
    int ret = -1;
    int connLen;
    char *szConn = NULL;

    midletsize = KNI_GetParameterAsInt(3);

    KNI_StartHandles(2);
    KNI_DeclareHandle(conn);
    KNI_DeclareHandle(regObject);

    KNI_GetParameterAsObject(1, conn);
    connLen = KNI_GetArrayLength(conn);
    ret = -1;
    if ((szConn = midpMalloc(connLen)) != NULL) {
        KNI_GetRawArrayRegion(conn, 0, connLen, (jbyte*)szConn);

        KNI_GetParameterAsObject(2, regObject);

        regentry = pushfindconn(szConn);
        if (NULL != regentry) {
            regsize = strlen(regentry) + 1;
            if (regsize < midletsize) {
                KNI_SetRawArrayRegion(regObject, 0, regsize,
                                      (jbyte*)regentry);
                ret = 0;
            }
            else {
                KNI_ThrowNew(midpIOException, "registration too long");
            }
        }
        midpFree(szConn);
    }
    else {
        KNI_ThrowNew(midpOutOfMemoryError, NULL);
    }
    KNI_EndHandles();

    KNI_ReturnInt(ret);
}
コード例 #2
0
/**
 * Gets all registered push connections associated with the given MIDlet
 * suite.
 * <p>
 * Java declaration:
 * <pre>
 *     list0([BZ[BI)I
 * </pre>
 *
 * @param midlet The MIDlet suite to get push registry entries
 * @param available Which connections to return. If <tt>true</tt>,
 *                  only return the connections with available input.
 *                  Otherwise, return all connection.
 * @param connectionlist A comma separated string of connections stored
 *                       as a byte array.
 * @param listsz The maximum length of the byte array that will be
 *               accepted for <tt>connectionlist</tt>
 *
 * @return <tt>0</tt> if successful, otherwise <tt>-1</tt>
 *
 * @throw IllegalArgumentException If the length <tt>midlet</tt> is
 *                                 too long.
 */
KNIEXPORT KNI_RETURNTYPE_INT
KNIDECL(com_sun_midp_io_j2me_push_ConnectionRegistry_list0) {
    char *midletName = NULL;
    int available;
    int connsize;
    int nameLength;
    char *conn;
    int ret = -1;

    available = KNI_GetParameterAsBoolean(2);
    connsize = KNI_GetParameterAsInt(4);

    KNI_StartHandles(2);

    KNI_DeclareHandle(name);
    KNI_DeclareHandle(connections);
    KNI_GetParameterAsObject(1, name);
    KNI_GetParameterAsObject(3, connections);

    nameLength = KNI_GetArrayLength(name);
    midletName = (char*)midpMalloc(nameLength);
    if (midletName == NULL) {
        KNI_ThrowNew(midpOutOfMemoryError, NULL);
    }
    else {
        KNI_GetRawArrayRegion(name, 0, nameLength, (jbyte*)midletName);

        conn = pushfindsuite(midletName, available);

        if (conn != NULL) {
            KNI_SetRawArrayRegion(connections, 0, strlen(conn), (jbyte*)conn);
            midpFree(conn);
            ret = 0;
        }

        midpFree(midletName);
    }

    KNI_EndHandles();

    KNI_ReturnInt(ret);
}
コード例 #3
0
/**
 * Create pcsl_string from the specified KNI CharArray object.
 * The caller is responsible for freeing the created pcsl_string when done.
 *
 * @param java_arr pointer to the KNI CharArray instance
 * @param length length of the text in the CharArray
 * @param pcsl_str pointer to the pcsl_string instance
 * @return status of the operation
 */
pcsl_string_status
midp_jchar_array_to_pcsl_string(jcharArray java_arr, jint length,
                                pcsl_string * pcsl_str) {
    if (pcsl_str == NULL) {
        return PCSL_STRING_EINVAL;
    }

    if (KNI_IsNullHandle(java_arr)) {
        *pcsl_str = PCSL_STRING_NULL;
        return PCSL_STRING_OK;
    } else if (length < 0) {
        *pcsl_str = PCSL_STRING_NULL;
        return PCSL_STRING_ERR;
    } else if (length == 0) {
        *pcsl_str = PCSL_STRING_EMPTY;
        return PCSL_STRING_OK;
    } else {
        jchar * buffer = pcsl_mem_malloc(length * sizeof(jchar));

        if (buffer == NULL) {
              * pcsl_str = PCSL_STRING_NULL;
            return PCSL_STRING_ENOMEM;
        }

          KNI_GetRawArrayRegion(java_arr, 0,
                                          length * sizeof(jchar),
                                          (jbyte *) buffer);

        {
            pcsl_string_status status =
                  pcsl_string_convert_from_utf16(buffer, length, pcsl_str);

              pcsl_mem_free(buffer);

            return status;
        }
    }
}
コード例 #4
0
/*  private native int _eglCreatePbufferSurface ( int display , int config , int [ ] attrib_list ) ; */
KNIEXPORT KNI_RETURNTYPE_INT
Java_javax_microedition_khronos_egl_EGL10Impl__1eglCreatePbufferSurface() {

    jint display = KNI_GetParameterAsInt(1);
    jint config = KNI_GetParameterAsInt(2);
    EGLint *attrib_list = (EGLint *)0;

    jint returnValue = (jint)EGL_NO_SURFACE;

    KNI_StartHandles(2);
    KNI_DeclareHandle(attrib_listHandle);
    KNI_DeclareHandle(thisHandle);

    KNI_GetParameterAsObject(3, attrib_listHandle);
    KNI_GetThisPointer(thisHandle);

    /* Construct attrib_list as a copy of attrib_listHandle if non-null */
    if (!KNI_IsNullHandle(attrib_listHandle)) {
        jint attrib_list_length, attrib_list_size;

	attrib_list_length = KNI_GetArrayLength(attrib_listHandle);
	attrib_list_size = attrib_list_length*sizeof(jint);
	attrib_list = (EGLint *)JSR239_malloc(attrib_list_size);
	if (!attrib_list) {
            KNI_ThrowNew("java.lang.OutOfMemoryException",
			 "eglCreatePbufferSurface");
	    goto exit;
	}
	KNI_GetRawArrayRegion(attrib_listHandle, 0, attrib_list_size,
			      (jbyte *) attrib_list);
    }

#ifdef DEBUG
    {
        int idx = 0;
        int attr;
     
#ifdef DEBUG
        printf("In eglCreatePbufferSurface:\n");
#endif
        if (!attrib_list) {
#ifdef DEBUG
            printf("attrib_list is null!\n");
#endif
        } else {
            while (1) {
                attr = attrib_list[idx++];
#ifdef DEBUG
                printf("attr[%d] = 0x%x\n", idx, attr);
#endif
                if (attr == EGL_NONE) {
                    break;
                }
            }
        }
    }
#endif
        
    returnValue = (jint)eglCreatePbufferSurface((EGLDisplay)display,
						(EGLConfig)config,
						(EGLint const *) attrib_list);

#ifdef DEBUG
    if (returnValue > 0) {
        ++surfaces;
    }

    printf("eglCreatePbufferSurface(0x%x, 0x%x, attrib_list) = %d, surfaces = %d\n",
	   display, config, returnValue, surfaces);

    {
        EGLint error; /* debugging */
        error = eglGetError();
        if (error != EGL_SUCCESS) {
            printf("egl error = 0x%x\n", error);
        }
    }
#endif

 exit:
    if (attrib_list) {
	JSR239_free(attrib_list);
    }

    KNI_EndHandles();
    KNI_ReturnInt(returnValue);
}
コード例 #5
0
/*  private native int _eglChooseConfig ( int display , int [ ] attrib_list , int [ ] configs , int config_size , int [ ] num_config ) ; */
KNIEXPORT KNI_RETURNTYPE_INT
Java_javax_microedition_khronos_egl_EGL10Impl__1eglChooseConfig() {
    
    jint display = KNI_GetParameterAsInt(1);
    jint config_size = KNI_GetParameterAsInt(4);
    EGLint *attrib_list = (EGLint *)0;
    EGLConfig *configs = (EGLConfig *)0;
    EGLint num_config;

    jint returnValue = EGL_FALSE;

    KNI_StartHandles(3);
    KNI_DeclareHandle(attrib_listHandle);
    KNI_DeclareHandle(configsHandle);
    KNI_DeclareHandle(num_configHandle);

    KNI_GetParameterAsObject(2, attrib_listHandle);
    KNI_GetParameterAsObject(3, configsHandle);
    KNI_GetParameterAsObject(5, num_configHandle);

    if (!KNI_IsNullHandle(attrib_listHandle)) {
        jint attrib_list_length, attrib_list_size;
        /* Construct attrib_list as a copy of attrib_listHandle */
        attrib_list_length = KNI_GetArrayLength(attrib_listHandle);
        attrib_list_size = (attrib_list_length + 2)*sizeof(jint);
        attrib_list = (EGLint *)JSR239_malloc(attrib_list_size);
        if (!attrib_list) {
            KNI_ThrowNew("java.lang.OutOfMemoryException", "eglChooseConfig");
            goto exit;
        }
        KNI_GetRawArrayRegion(attrib_listHandle, 0, attrib_list_size,
                              (jbyte *)attrib_list);
    }

#ifdef ALL_WINDOWS_ARE_PIXMAPS
    // Force queries with SURFACE_TYPE == WINDOW to actually query pixmap
    if (attrib_list) {
        jint attr, val, idx;

        idx = 0;
        while (1) {
            attr = attrib_list[idx];
#ifdef DEBUG
            printf("attr[%d] = %d\n", idx, attr);
#endif
            if (attr == EGL_NONE) {
#ifdef DEBUG
                printf("attr = EGL_NONE, done\n");
#endif
                break;
            }
            if (attr == EGL_SURFACE_TYPE) {
#ifdef DEBUG
                printf("attr = EGL_SURFACE_TYPE\n");
#endif
                val = attrib_list[idx + 1];
                if ((val & EGL_WINDOW_BIT) != 0) {
#ifdef DEBUG
                    printf("Switching WINDOW_BIT to PIXMAP_BIT\n");
#endif
                    val |= EGL_PIXMAP_BIT;
                    val &= ~EGL_WINDOW_BIT;
                }   
            }
            idx += 2;
        }
    }
#endif

    /* Allocate config_size elements if configsHandle is non-null */
    if (!KNI_IsNullHandle(configsHandle)) {
	configs = (EGLConfig *)JSR239_malloc(config_size*sizeof(EGLint));
	if (!configs) {
            KNI_ThrowNew("java.lang.OutOfMemoryException", "eglChooseConfig");
	    goto exit;
	}
    }
    
    returnValue = (jint)eglChooseConfig((EGLDisplay)display, attrib_list,
					configs, config_size, &num_config);
#ifdef DEBUG
    printf("eglChooseConfig(0x%x, attrib_list, configs, %d, num_config<-%d) = %d\n",
	   display, config_size, num_config, returnValue);
#endif

    /* Copy configs back to Java */
    if (returnValue == EGL_TRUE && !KNI_IsNullHandle(configsHandle)) {
	KNI_SetRawArrayRegion(configsHandle, 0, config_size*sizeof(EGLint),
			      (const jbyte *)configs);
    }
    /* Set output parameter via num_configHandle */
    if ((returnValue == EGL_TRUE) && !KNI_IsNullHandle(num_configHandle)) {
        KNI_SetIntArrayElement(num_configHandle, 0, num_config);
    }

 exit:
    if (attrib_list) {
	JSR239_free(attrib_list);
    }
    if (configs) {
	JSR239_free(configs);
    }

    KNI_EndHandles();
    KNI_ReturnInt(returnValue);
}
コード例 #6
0
ファイル: invocStore.c プロジェクト: sfsy1989/j2me
/**
 * Extract the parameters ID, Type, URL, arguments and data
 * and update/copy their values to the InvocStore instance.
 * @param invoc the StoreInvoc to update
 * @param invocObj the Java invoc instance
 * @param tmp1 a temporary object
 * @param tmp2 a 2nd temporary object 
 * @return TRUE if all the allocations and modifications worked
 */
static jboolean setParamsFromObj(StoredInvoc* invoc,
                     jobject invocObj,
                     jobject tmp1, jobject tmp2) {
    jboolean ret = KNI_ENOMEM;    /* Assume failure */
    do {
        /* On any error break out of this block */
        int len;
    
        KNI_GetObjectField(invocObj, urlFid, tmp1);
        if (PCSL_STRING_OK != midp_jstring_to_pcsl_string(tmp1, &invoc->url))
            break;
    
        KNI_GetObjectField(invocObj, typeFid, tmp1);
        if (PCSL_STRING_OK != midp_jstring_to_pcsl_string(tmp1, &invoc->type ))
            break;
    
        KNI_GetObjectField(invocObj, actionFid, tmp1);
        if (PCSL_STRING_OK != midp_jstring_to_pcsl_string(tmp1, &invoc->action ))
            break;
    
        KNI_GetObjectField(invocObj, IDFid, tmp1);
        if (PCSL_STRING_OK != midp_jstring_to_pcsl_string(tmp1, &invoc->ID))
            break;
    
        /*
         * Copy the arguments if non-empty.
         * Always keep the pointers safe so invocFree()
         * can function correctly.
         */
        KNI_GetObjectField(invocObj, argumentsFid, tmp2);
        len = (KNI_IsNullHandle(tmp2)? 0: KNI_GetArrayLength(tmp2));
        if (len <= 0) {
            invoc->argsLen = 0;
            invoc->args = NULL;
        } else {
            pcsl_string* args;
            args = (pcsl_string*)pcsl_mem_malloc(len * sizeof(pcsl_string));
            if (args == NULL)
                break;
            invoc->argsLen = len;
            invoc->args = args;
            args += len;
            while (len-- > 0) {
                KNI_GetObjectArrayElement(tmp2, len, tmp1);
                if (PCSL_STRING_OK != midp_jstring_to_pcsl_string(tmp1, --args))
                    break;
            }
        }
    
        /* Copy any data from the Invocation to malloc's memory. */
        KNI_GetObjectField(invocObj, dataFid, tmp2);
        len = (KNI_IsNullHandle(tmp2)? 0: KNI_GetArrayLength(tmp2));
        if (len <= 0) {
            invoc->data = NULL;
            invoc->dataLen = 0;
        } else {
            invoc->data = pcsl_mem_malloc(len);
            if (invoc->data == NULL)
                break;
    
            KNI_GetRawArrayRegion(tmp2, 0, len, invoc->data);
            invoc->dataLen = len;
        }
    
        /* Clear to indicate everything worked. */
        ret = KNI_TRUE;
    } while (0);

    return ret;
}
コード例 #7
0
/**
 * Copies the contents of fromMsg to the contents of toMsg. Both must be
 * instances of LinkMessage. The toLink object must be an instance of Link.
 * It's filled in if the contents of fromMsg are a Link.  Returns KNI_TRUE if
 * successful, otherwise KNI_FALSE.
 */
static jboolean
copy(jobject fromMsg, jobject toMsg, jobject toLink) {
    jboolean retval;

    KNI_StartHandles(6);
    KNI_DeclareHandle(byteArrayClass);
    KNI_DeclareHandle(stringClass);
    KNI_DeclareHandle(linkClass);
    KNI_DeclareHandle(fromContents);
    KNI_DeclareHandle(newString);
    KNI_DeclareHandle(newByteArray);

    KNI_FindClass("[B", byteArrayClass);
    KNI_FindClass("java/lang/String", stringClass);
    KNI_FindClass("com/sun/midp/links/Link", linkClass);
    getContents(fromMsg, fromContents);
    
    if (KNI_IsInstanceOf(fromContents, byteArrayClass)) {
        /* do a byte array copy */
        jint fromOffset;
        jint fromLength;

        getRange(fromMsg, &fromOffset, &fromLength);

        SNI_NewArray(SNI_BYTE_ARRAY, fromLength, newByteArray);
        if (KNI_IsNullHandle(newByteArray)) {
            retval = KNI_FALSE;
        } else {
            KNI_GetRawArrayRegion(fromContents, fromOffset, fromLength,
                SNI_GetRawArrayPointer(newByteArray));
            setContents(toMsg, newByteArray);
            setRange(toMsg, 0, fromLength);
            retval = KNI_TRUE;
        }
    } else if (KNI_IsInstanceOf(fromContents, stringClass)) {
        /* do a string copy */
        jchar *buf;
        jsize slen = KNI_GetStringLength(fromContents);

        SNI_NewArray(SNI_BYTE_ARRAY, slen*sizeof(jchar), newByteArray);

        if (KNI_IsNullHandle(newByteArray)) {
            retval = KNI_FALSE;
        } else {
            buf = SNI_GetRawArrayPointer(newByteArray);
            KNI_GetStringRegion(fromContents, 0, slen, buf);
            KNI_NewString(buf, slen, newString);
            setContents(toMsg, newString);
            retval = KNI_TRUE;
        }
    } else if (KNI_IsInstanceOf(fromContents, linkClass)) {
        /* copy the link */
        rendezvous *rp = getNativePointer(fromContents);
        setNativePointer(toLink, rp);
        rp_incref(rp);
        setContents(toMsg, toLink);
        retval = KNI_TRUE;
    } else {
        retval = KNI_FALSE;
    }

    KNI_EndHandles();
    return retval;
}
コード例 #8
0
/**
 * Sends an SMS message.
 *
 * @param handle The handle to the open SMS connection.
 * @param messageType The type of message: binary or text.
 * @param address The SMS-formatted address.
 * @param destPort The port number of the recipient.
 * @param sourcePort The port number of the sender.
 * @param messageBuffer The buffer containing the SMS message.
 *
 * @return Always returns <code>0</code>.
 */
KNIEXPORT KNI_RETURNTYPE_INT
KNIDECL(com_sun_midp_io_j2me_sms_Protocol_send0) {
    WMA_STATUS status = WMA_ERR;
    jint messageLength = 0;
    jint messageType;
    jint sourcePort;
    jint destPort;
    jint handle;
    jint msAddress_len;
    jchar* msAddress_data;
    int i;
    unsigned char *pAddress = NULL;
    unsigned char *pMessageBuffer = NULL;
    jboolean stillWaiting = KNI_FALSE;
    jboolean trySend = KNI_FALSE;
    void *pdContext = NULL;
#if ENABLE_REENTRY
    MidpReentryData *info;
    jsr120_sms_message_state_data *messageStateData = NULL;
#endif
    jboolean isOpen;

    KNI_StartHandles(4);

    KNI_DeclareHandle(this);
    KNI_DeclareHandle(thisClass);
    KNI_GetThisPointer(this);
    KNI_GetObjectClass(this, thisClass);
    isOpen = KNI_GetBooleanField(this, KNI_GetFieldID(thisClass, "open", "Z"));
    
    if (isOpen) { /* No close in progress */
        KNI_DeclareHandle(messageBuffer);
        KNI_DeclareHandle(address);

        handle = KNI_GetParameterAsInt(1);
        messageType = KNI_GetParameterAsInt(2);
        KNI_GetParameterAsObject(3, address);
        destPort = KNI_GetParameterAsInt(4);
        sourcePort = KNI_GetParameterAsInt(5);
        KNI_GetParameterAsObject(6, messageBuffer);

        do {
#if ENABLE_REENTRY
            info = (MidpReentryData*)SNI_GetReentryData(NULL);
            if (info == NULL) {	  /* First invocation. */
#endif
                if (KNI_IsNullHandle(address)) {

                    KNI_ThrowNew(midpIllegalArgumentException, NULL);
                    break;
                } else {
                    msAddress_len = KNI_GetStringLength(address);
                    msAddress_data = (jchar *)pcsl_mem_malloc(msAddress_len * sizeof (jchar));
                    if (msAddress_data == NULL) {

                        KNI_ThrowNew(midpOutOfMemoryError, NULL);
                        break;
                    } else {

                        KNI_GetStringRegion(address, 0, msAddress_len, msAddress_data);
                        pAddress = (unsigned char*)pcsl_mem_malloc(msAddress_len + 1);
                        if (pAddress != NULL) {
                            for (i = 0; i < msAddress_len; i++) {
                                pAddress[i] = (unsigned char)msAddress_data[i];
                            }	
                            pAddress[msAddress_len] = 0;
                        }
                        //pAddress = (unsigned char *)midpJcharsToChars(msAddress);
                        pcsl_mem_free(msAddress_data);

                        if (!KNI_IsNullHandle(messageBuffer)) {
                            messageLength = KNI_GetArrayLength(messageBuffer);
                        }
                        if (messageLength >= 0) {
                            if (messageLength > 0) {
                                pMessageBuffer = (unsigned char *)pcsl_mem_malloc(messageLength);
                                memset(pMessageBuffer, 0, messageLength);
                                KNI_GetRawArrayRegion(messageBuffer, 0, messageLength,
                                                      (jbyte *)pMessageBuffer);
                            }

                            trySend = KNI_TRUE;
                        }
                    }
                }
#if ENABLE_REENTRY
            } else { /* Reinvocation after unblocking the thread. */

                if (info->pResult == NULL) {
                    /* waiting for mms_send_completed event */
                    if (info->status == WMA_ERR) {
                        KNI_ThrowNew(midpInterruptedIOException, "Sending SMS");
                    }
                    break;
                }
                messageStateData = info->pResult;
                pMessageBuffer = messageStateData->pMessageBuffer;
                pAddress = messageStateData->pAddress;
                pdContext = messageStateData->pdContext;

                trySend = KNI_TRUE;
            }
#endif

            if (trySend == KNI_TRUE) {
                /* send message. */
                status = jsr120_send_sms((jchar)messageType,
                                         pAddress,
                                         pMessageBuffer,
                                         (jchar)messageLength,
                                         (jchar)sourcePort,
                                         (jchar)destPort,
                                         handle,
                                         &pdContext);

                if (status == WMA_ERR) {
                    KNI_ThrowNew(midpIOException, "Sending SMS");
                    break;
                } 
#if ENABLE_REENTRY
                else if (status == WMA_NET_WOULDBLOCK) {
                    if (messageStateData == NULL) {
                        messageStateData =
                            (jsr120_sms_message_state_data *)pcsl_mem_malloc(
                                sizeof(*messageStateData));
                        messageStateData->pMessageBuffer = pMessageBuffer;
                        messageStateData->pAddress = pAddress;
                    }

                    messageStateData->pdContext = pdContext;

                    /* Block calling Java Thread. */
                    midp_thread_wait(WMA_SMS_WRITE_SIGNAL, handle,
                                     messageStateData);

                    stillWaiting = KNI_TRUE;
                    break;
                } else {
                    /* waiting for sms_send_completed event */
                    midp_thread_wait(WMA_SMS_WRITE_SIGNAL, handle, NULL);
                }
#endif
            }
        } while (0);

        if (!stillWaiting) {
            pcsl_mem_free(pMessageBuffer);
            pcsl_mem_free(pAddress);
        }
    }

    KNI_EndHandles();

    KNI_ReturnInt(0); /* currently ignored. */
}
コード例 #9
0
/*=========================================================================
 * FUNCTION:      modExp([B[B[B[B[B)V (STATIC)
 * CLASS:         com/sun/midp/crypto/RSA
 * TYPE:          static native function
 * OVERVIEW:      Perform modular exponentiation.
 * INTERFACE (operand stack manipulation):
 *   parameters:  data      contains the data on which exponentiation is to
 *                           be performed
 *                exponent  contains the exponent, e.g. 65537 (decimal) is 
 *                           written as a three-byte array containing 
 *                           0x01, 0x00, 0x01
 *                modulus   contains the modulus
 *                result    the result of the modular exponentiation is 
 *                           returned in this array
 *   returns: the length of the result
 *=======================================================================*/
KNIEXPORT KNI_RETURNTYPE_INT
Java_com_sun_midp_crypto_RSA_modExp() {
    jint dataLen, expLen, modLen, resLen;
    jint maxLen;
    INTEGER numbytes = 0;
    unsigned char *buf;
    BIGNUM *a, *b, *c, *d;
    BN_CTX *ctx;

    KNI_StartHandles(4);

    KNI_DeclareHandle(ires);
    KNI_DeclareHandle(imod);
    KNI_DeclareHandle(iexp);
    KNI_DeclareHandle(idata);

    KNI_GetParameterAsObject(4, ires);
    KNI_GetParameterAsObject(3, imod);
    KNI_GetParameterAsObject(2, iexp);
    KNI_GetParameterAsObject(1, idata);

    resLen    = KNI_GetArrayLength(ires);
    modLen    = KNI_GetArrayLength(imod);
    expLen    = KNI_GetArrayLength(iexp);
    dataLen   = KNI_GetArrayLength(idata);

    /* Find which parameter is largest and allocate that much space */
    maxLen = MAX(MAX(MAX(resLen, modLen), expLen), dataLen);
    if (maxLen > (BN_MAX_INTEGER / 8)) {
        /* The number of BITS must fit in a BN integer. */
        KNI_ThrowNew(midpIllegalArgumentException, "arg too long");
    } else {
        buf = (unsigned char *) midpMalloc(maxLen * sizeof(unsigned char));
        if (buf == NULL) {
            KNI_ThrowNew(midpOutOfMemoryError, NULL);
        } else {

            KNI_GetRawArrayRegion(idata, 0, dataLen, (jbyte*)buf);
            a = BN_bin2bn(buf, (INTEGER)dataLen, NULL);

            KNI_GetRawArrayRegion(iexp, 0, expLen, (jbyte*)buf);
            b = BN_bin2bn(buf, (INTEGER)expLen, NULL);

            KNI_GetRawArrayRegion(imod, 0, modLen, (jbyte*)buf);
            c = BN_bin2bn(buf, (INTEGER)modLen, NULL);

            d = BN_new((INTEGER)resLen);

            ctx = BN_CTX_new((INTEGER)maxLen);

            /* do the actual exponentiation */
            if (a != NULL && b != NULL && c != NULL && d != NULL &&
                    ctx != NULL && BN_mod_exp_mont(d,a,b,c,ctx)) {
                /* Covert result from BIGNUM d to char array */
                numbytes = BN_bn2bin(d, buf);
                KNI_SetRawArrayRegion(ires, 0, numbytes, (jbyte*)buf);
            } else {
                /* assume out of mem */
                KNI_ThrowNew(midpOutOfMemoryError, "Mod Exp");
            }

            midpFree(buf);

            BN_free(a);
            BN_free(b);
            BN_free(c);
            BN_free(d);
            BN_CTX_free(ctx);
        }
    }

    KNI_EndHandles();

    KNI_ReturnInt((jint)numbytes);
}