/**
 * Native method void finalize of
 * com.sun.midp.midletsuite.MIDletSuiteImpl.
 * <p>
 *
 * native finalizer
 *
 */
KNIEXPORT KNI_RETURNTYPE_VOID
KNIDECL(com_sun_midp_midletsuite_MIDletSuiteImpl_finalize) {
    SuiteIdType suiteId;
    jboolean locked;

    KNI_StartHandles(2);
    KNI_DeclareHandle(object);
    KNI_DeclareHandle(clazz);

    KNI_GetThisPointer(object);

    KNI_GetObjectClass(object, clazz);

    locked = KNI_GetBooleanField(object,
                                 midp_get_field_id(KNIPASSARGS clazz, "locked", "Z"));

    if (locked) {
        suiteId = KNI_GetIntField(object,
                                  midp_get_field_id(KNIPASSARGS clazz, "id", "I"));
        unlock_storage(suiteId);
    }

    KNI_EndHandles();
    KNI_ReturnVoid();
}
/**
 * Get a String from a field of an object and converts it to pcsl_string.
 *
 * @param obj a handle to Java object whose field will be set
 * @param classObj handle of the object's class
 * @param pszFieldName field name
 * @param fieldHandle handle where to put the resulting jstring
 * @param newValue a handle to the new Java value of the field
 * @param result pointer to the location where the result must be saved
 *
 * @return status of the operation
 */
pcsl_string_status midp_get_string_field(KNIDECLARGS jobject obj, jclass classObj,
                                  char* pszFieldName, jobject fieldHandle,
                                  pcsl_string* result) {
    KNI_GetObjectField(obj, midp_get_field_id(KNIPASSARGS classObj, pszFieldName,
        "Ljava/lang/String;"), fieldHandle);

    return midp_jstring_to_pcsl_string(fieldHandle, result);
}
/**
 * Restore the state of the MIDlet suite loader.
 * <p>
 * Java declaration:
 * <pre>
 *   restoreCommandState(Lcom/sun/midp/CommandState;)V
 * </pre>
 */
KNIEXPORT KNI_RETURNTYPE_VOID
KNIDECL(com_sun_midp_main_CommandState_restoreCommandState) {
    KNI_StartHandles(5);
    KNI_DeclareHandle(runtimeInfo);
    KNI_DeclareHandle(commandState);
    KNI_DeclareHandle(clazz);
    KNI_DeclareHandle(rtiClazz);
    KNI_DeclareHandle(string);

    KNI_GetParameterAsObject(1, commandState);
    KNI_GetObjectClass(commandState, clazz);

    KNI_GetObjectField(commandState, midp_get_field_id(KNIPASSARGS clazz,
        "runtimeInfo", "Lcom/sun/midp/main/RuntimeInfo;"), runtimeInfo);
    KNI_GetObjectClass(runtimeInfo, rtiClazz);

    KNI_RESTORE_INT_FIELD(commandState, clazz, "status",
                          MidpCommandState.status);
    KNI_RESTORE_BOOLEAN_FIELD(commandState, clazz, "logoDisplayed",
                              MidpCommandState.logoDisplayed);
    KNI_RESTORE_PCSL_STRING_FIELD(commandState, clazz, "midletClassName",
                                  &MidpCommandState.midletClassName, string);
    KNI_RESTORE_INT_FIELD(commandState, clazz, "suiteId",
                          MidpCommandState.suiteId);
    KNI_RESTORE_INT_FIELD(commandState, clazz, "lastSuiteId",
                          MidpCommandState.lastSuiteId);
    KNI_RESTORE_INT_FIELD(commandState, clazz, "debugMode",
                          MidpCommandState.debugMode);

    KNI_RESTORE_INT_FIELD(runtimeInfo, rtiClazz, "memoryReserved",
                          MidpCommandState.runtimeInfo.memoryReserved);
    KNI_RESTORE_INT_FIELD(runtimeInfo, rtiClazz, "memoryTotal",
                          MidpCommandState.runtimeInfo.memoryTotal);
    KNI_RESTORE_INT_FIELD(runtimeInfo, rtiClazz, "priority",
                          MidpCommandState.runtimeInfo.priority);

    KNI_RESTORE_PCSL_STRING_FIELD(commandState, clazz, "lastMidletClassName",
                                  &MidpCommandState.lastMidletClassName,
                                  string);
    KNI_RESTORE_PCSL_STRING_FIELD(commandState, clazz, "lastArg0",
                                  &MidpCommandState.lastArg0, string);
    KNI_RESTORE_PCSL_STRING_FIELD(commandState, clazz, "lastArg1",
                                  &MidpCommandState.lastArg1, string);
    KNI_RESTORE_PCSL_STRING_FIELD(commandState, clazz, "arg0",
                                  &MidpCommandState.arg0, string);
    KNI_RESTORE_PCSL_STRING_FIELD(commandState, clazz, "arg1",
                                  &MidpCommandState.arg1, string);
    KNI_RESTORE_PCSL_STRING_FIELD(commandState, clazz, "arg2",
                                  &MidpCommandState.arg2, string);
    KNI_RESTORE_PCSL_STRING_FIELD(runtimeInfo, rtiClazz, "profileName",
                                  &MidpCommandState.profileName, string);

    KNI_EndHandles();
    KNI_ReturnVoid();
}
/**
 * Set a jobject field from Java native functions.
 *
 * Always use KNI to set an object field instead of setting it directly
 * using SNI access, since there is more to setting a object in a field
 * than just moving a reference, there is a flag to tell the the garbage
 * collector that the field is set to an object and if this flag is not
 * set then the collector not count the field as a reference which can
 * lead to premature collection of the object the field is referencing
 * and then a crash since the field will reference will not be null, it
 * will be unchanged and invalid.
 *
 * @param obj a handle to Java object whose field will be set
 * @param fieldName field name
 * @param fieldSignature field signature string
 * @param newValue a handle to the new Java value of the field
 */
void midp_set_jobject_field(KNIDECLARGS jobject obj,
			    const char *fieldName, const char *fieldSignature,
			    jobject newValue) {

    if (KNI_IsNullHandle(obj)) {
        return;
    }

    KNI_StartHandles(1);
    KNI_DeclareHandle(clazz);

    KNI_GetObjectClass(obj, clazz);

    KNI_SetObjectField(obj,
		       midp_get_field_id(KNIPASSARGS 
					 clazz, fieldName, fieldSignature),
		       newValue);

    KNI_EndHandles();
}
/**
 * Save the state of the MIDlet suite loader.
 * <p>
 * Java declaration:
 * <pre>
 *    saveCommandState(Lcom/sun/midp/CommandState;)V
 * </pre>
 */
KNIEXPORT KNI_RETURNTYPE_VOID
KNIDECL(com_sun_midp_main_CommandState_saveCommandState) {
    KNI_StartHandles(5);
    KNI_DeclareHandle(runtimeInfo);
    KNI_DeclareHandle(commandState);
    KNI_DeclareHandle(clazz);
    KNI_DeclareHandle(rtiClazz);
    KNI_DeclareHandle(string);

    KNI_GetParameterAsObject(1, commandState);
    KNI_GetObjectClass(commandState, clazz);

    KNI_GetObjectField(commandState, midp_get_field_id(KNIPASSARGS clazz,
        "runtimeInfo", "Lcom/sun/midp/main/RuntimeInfo;"), runtimeInfo);
    KNI_GetObjectClass(runtimeInfo, rtiClazz);

    KNI_SAVE_INT_FIELD(commandState, clazz, "status",
                       MidpCommandState.status);
    KNI_SAVE_INT_FIELD(commandState, clazz, "suiteId",
                       MidpCommandState.suiteId);
    KNI_SAVE_INT_FIELD(commandState, clazz, "lastSuiteId",
                       MidpCommandState.lastSuiteId);
    KNI_SAVE_BOOLEAN_FIELD(commandState, clazz, "logoDisplayed",
                           MidpCommandState.logoDisplayed);
    KNI_SAVE_INT_FIELD(commandState, clazz, "debugMode",
                        MidpCommandState.debugMode);

    KNI_SAVE_INT_FIELD(runtimeInfo, rtiClazz, "memoryReserved",
                       MidpCommandState.runtimeInfo.memoryReserved);
    KNI_SAVE_INT_FIELD(runtimeInfo, rtiClazz, "memoryTotal",
                       MidpCommandState.runtimeInfo.memoryTotal);
    KNI_SAVE_INT_FIELD(runtimeInfo, rtiClazz, "priority",
                       MidpCommandState.runtimeInfo.priority);
    /*
     * We need to put these in the do/while block since the SAVE_STRING
     * macros may throw an OutOfMemoryException. If this happens, we
     * must exit the native function immediately.
     */
    do {
        KNI_SAVE_PCSL_STRING_FIELD(commandState, clazz, "midletClassName",
                                   &MidpCommandState.midletClassName, string);
        KNI_SAVE_PCSL_STRING_FIELD(commandState, clazz, "lastMidletClassName",
                                   &MidpCommandState.lastMidletClassName,
                                   string);
        KNI_SAVE_PCSL_STRING_FIELD(commandState, clazz, "lastArg0",
                                   &MidpCommandState.lastArg0, string);
        KNI_SAVE_PCSL_STRING_FIELD(commandState, clazz, "lastArg1",
                                   &MidpCommandState.lastArg1, string);
        KNI_SAVE_PCSL_STRING_FIELD(commandState, clazz, "arg0",
                                   &MidpCommandState.arg0, string);
        KNI_SAVE_PCSL_STRING_FIELD(commandState, clazz, "arg1",
                                   &MidpCommandState.arg1, string);
        KNI_SAVE_PCSL_STRING_FIELD(commandState, clazz, "arg2",
                                   &MidpCommandState.arg2, string);

        KNI_SAVE_PCSL_STRING_FIELD(runtimeInfo, rtiClazz, "profileName",
                                   &MidpCommandState.profileName, string);
    } while (0);

    KNI_EndHandles();
    KNI_ReturnVoid();
}