Ejemplo n.º 1
0
/* Copy an array from JS to Java;  Create a new Java array and populate its
   elements, one by one, with the result of converting each JS array element
   to the type of the array component. */
static JSBool
convert_js_array_to_java_array(JSContext *cx, JNIEnv *jEnv, JSObject *js_array,
                               JavaSignature *signature,
                               jobject *java_valuep)
{
    jsuint i;
    jsval js_val;
    jsuint length;
    jclass component_class;
    jarray java_array;
    JavaSignature *array_component_signature;

    if (!JS_GetArrayLength(cx, js_array, &length))
        return JS_FALSE;

    /* Get the Java class of each element of the array */
    array_component_signature = signature->array_component_signature;
    component_class = array_component_signature->java_class;

    /* Create a new empty Java array with the same length as the JS array */
    java_array = (*jEnv)->CallStaticObjectMethod(jEnv, jlrArray, jlrArray_newInstance,
                                                 component_class, length);
    if (!java_array) {
        jsj_ReportJavaError(cx, jEnv, "Error while constructing empty array of %s",
                            jsj_GetJavaClassName(cx, jEnv, component_class));
        return JS_FALSE;
    }

    /* Convert each element of the JS array to an element of the Java array.
       If an error occurs, there is no need to worry about releasing the
       individual elements of the Java array - they will eventually be GC'ed
       by the JVM. */
    for (i = 0; i < length; i++) {
        if (!JS_LookupElement(cx, js_array, i, &js_val))
            return JS_FALSE;

        if (!jsj_SetJavaArrayElement(cx, jEnv, java_array, i, array_component_signature, js_val))
            return JS_FALSE;
    }

    /* Return the result array */
    *java_valuep = java_array;
    return JS_TRUE;
}
Ejemplo n.º 2
0
static JSBool
access_java_array_element(JSContext *cx,
                          JNIEnv *jEnv,
                          JSObject *obj,
                          jsid id,
                          jsval *vp,
                          JSBool do_assignment)
{
    jsval idval;
    jarray java_array;
    JavaClassDescriptor *class_descriptor;
    JavaObjectWrapper *java_wrapper;
    jsize array_length, index;
    JavaSignature *array_component_signature;
    
    /* printf("In JavaArray_getProperty\n"); */
    
    java_wrapper = JS_GetPrivate(cx, obj);
    if (!java_wrapper) {
        const char *property_name;
        if (JS_IdToValue(cx, id, &idval) && JSVAL_IS_STRING(idval) &&
            (property_name = JS_GetStringBytes(JSVAL_TO_STRING(idval))) != NULL) {
            if (!strcmp(property_name, "constructor")) {
                if (vp)
                    *vp = JSVAL_VOID;
                return JS_TRUE;
            }
        }
        JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, 
                                                JSJMSG_BAD_OP_JARRAY);
        return JS_FALSE;
    }
    class_descriptor = java_wrapper->class_descriptor;
    java_array = java_wrapper->java_obj;
    
    JS_ASSERT(class_descriptor->type == JAVA_SIGNATURE_ARRAY);

    JS_IdToValue(cx, id, &idval);

    if (!JSVAL_IS_INT(idval))
        idval = try_convert_to_jsint(cx, idval);

    if (!JSVAL_IS_INT(idval)) {
        /*
         * Usually, properties of JavaArray objects are indexed by integers, but
         * Java arrays also inherit all the methods of java.lang.Object, so a
         * string-valued property is also possible.
         */
        if (JSVAL_IS_STRING(idval)) {
            const char *member_name;
            
            member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
            
            if (do_assignment) {
                JSVersion version = JS_GetVersion(cx);

                if (!JSVERSION_IS_ECMA(version)) {
 
                    JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, 
                                        JSJMSG_CANT_WRITE_JARRAY, member_name);
                    return JS_FALSE;
                } else {
                    if (vp)
                        *vp = JSVAL_VOID;
                    return JS_TRUE;
                }
            } else {
                if (!strcmp(member_name, "length")) {
                    array_length = jsj_GetJavaArrayLength(cx, jEnv, java_array);
                    if (array_length < 0)
                        return JS_FALSE;
                    if (vp)
                        *vp = INT_TO_JSVAL(array_length);
                    return JS_TRUE;
                }
                
                /* Check to see if we're reflecting a Java array method */
                return JavaObject_getPropertyById(cx, obj, id, vp);
            }
        }

        JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL, 
                                            JSJMSG_BAD_INDEX_EXPR);
        return JS_FALSE;
    }
    
    index = JSVAL_TO_INT(idval);

#if 0
    array_length = jsj_GetJavaArrayLength(cx, jEnv, java_array);
    if (array_length < 0)
        return JS_FALSE;

    /* Just let Java throw an exception instead of checking array bounds here */
    if (index < 0 || index >= array_length) {
        char numBuf[12];
        sprintf(numBuf, "%d", index);
        JS_ReportErrorNumber(cx, jsj_GetErrorMessage, NULL,
                                            JSJMSG_BAD_JARRAY_INDEX, numBuf);
        return JS_FALSE;
    }
#endif

    array_component_signature = class_descriptor->array_component_signature;

    if (!vp)
        return JS_TRUE;

    if (do_assignment) {
        return jsj_SetJavaArrayElement(cx, jEnv, java_array, index,
                                       array_component_signature, *vp);
    } else {
        return jsj_GetJavaArrayElement(cx, jEnv, java_array, index,
                                       array_component_signature, vp);
    }
}