/*
 * Retrieves service record from the service search result.
 *
 * @param recHandle native handle of the service record
 * @param array byte array which will receive the data,
 *         or null for size query
 * @return size of the data read/required
 */
KNIEXPORT KNI_RETURNTYPE_INT
KNIDECL(com_sun_jsr082_bluetooth_SDPTransaction_getServiceRecord0)
{
    jint           retval  = 0;
    javacall_handle id      = 0;
    javacall_uint8  *data    = NULL;
    javacall_uint16 size    = 0;

    KNI_StartHandles(1);
    KNI_DeclareHandle(dataHandle);
    KNI_GetParameterAsObject(2, dataHandle);

    id = (javacall_handle)KNI_GetParameterAsInt(1);
    if (!KNI_IsNullHandle(dataHandle))
        size = KNI_GetArrayLength(dataHandle);

    data = JAVAME_MALLOC(size);
    if (data == NULL) {
        KNI_ThrowNew(jsropOutOfMemoryError, "Out of memory inside SDDB.readRecord()");
    } else {

        if (javacall_bt_sdp_get_service(id, data, &size) == JAVACALL_OK) {
            retval = size;
            if (!KNI_IsNullHandle(dataHandle)) {
                KNI_SetRawArrayRegion(dataHandle, 0, size, data);
            }
        } else {
            retval = 0;
        }
        JAVAME_FREE(data);
    }
    KNI_EndHandles();
    KNI_ReturnInt(retval);
}
/**
 * Get index of supported locales for device resources by its name.
 * <p>
 * Java declaration:
 * <pre>
 *     getDevLocaleIndex(Ljava/lang/String)I
 * </pre>
 *
 * @param locale name
 * @return internal index of locale or -1 if locale is not supported 
 */
KNIEXPORT KNI_RETURNTYPE_INT
KNIDECL(com_sun_j2me_global_DevResourceManagerFactory_getDevLocaleIndex) {
	jint result =-1, index = 0;
	jsize len = 0;
	int error = 0;
	jchar* locale_name;

	KNI_StartHandles(1);
	KNI_DeclareHandle(hstr1);
	KNI_GetParameterAsObject(1, hstr1);

	if (KNI_IsNullHandle(hstr1)) {
		locale_name = NULL;
	} else  {
		len = KNI_GetStringLength(hstr1);
		locale_name = (jchar *)JAVAME_MALLOC((len + 1) * sizeof(jchar));
		if (NULL == locale_name) {
		   KNI_ThrowNew(jsropOutOfMemoryError, 
			   "Out of memory");
		   error = 1;
		} else {
			KNI_GetStringRegion(hstr1, 0, len, locale_name);
			locale_name[len]=0;
		}
	}

	if (!error){
		result = jsr238_get_resource_locale_index(locale_name, &index);
		if (result < 0) index =-1;
		JAVAME_FREE(locale_name);
	}

	KNI_EndHandles();
	KNI_ReturnInt(index);
}
/* JAVADOC COMMENT ELIDED */
KNIEXPORT KNI_RETURNTYPE_VOID
    KNIDECL(com_sun_j2me_location_LocationPersistentStorage_updateLandmarkImpl) {
    
    jint landmarkID;
    javacall_result res;
    javacall_landmarkstore_landmark *landmark;
    jint numAddressFields;
    
    KNI_StartHandles(3);
    KNI_DeclareHandle(landmarkObj);
    KNI_DeclareHandle(stringObj);
    GET_PARAMETER_AS_UTF16_STRING(1, storeName)
    landmarkID = KNI_GetParameterAsInt(2);
    KNI_GetParameterAsObject(3, landmarkObj);
    numAddressFields = KNI_GetIntField(landmarkObj, 
            landmarkImplFieldID.numAddressInfoFields);
    landmark = JAVAME_MALLOC(SIZE_OF_LANDMARK_INFO(numAddressFields));

    if (landmark != NULL) {
        if (fill_landmark(landmarkObj, landmark, stringObj) == KNI_TRUE) {
            res = javacall_landmarkstore_landmark_update(storeName, 
                                    (javacall_handle)landmarkID, landmark);
            switch (res) {
                case JAVACALL_OK:
                    /* Landmark updated successfully */
                    break;
                case JAVACALL_INVALID_ARGUMENT:
                    /* wrong landmark ID */
                    KNI_ThrowNew(jsropIllegalArgumentException, 
                                "Landmark does not belong to this store");
                    break;
                default:
                    /* operation Failed */
                    KNI_ThrowNew(jsropIOException, "I/O error");
                    break;
            }
        }
        JAVAME_FREE(landmark);
    }

    RELEASE_UTF16_STRING_PARAMETER
    KNI_EndHandles();
    KNI_ReturnVoid();
}
/**
 * Retrieves resource data for the given ID and locale.
 * <p>
 * Java declaration:
 * <pre>
 *     getRawResourceData0(I,I,[B)Z
 * </pre>
 * 
 * @param hdata         byte array to store resource data
 * @param resource_id   resource identifier
 * @param locale_index  index of locale in array of supported locales
 * @param offset		offset of resource to start with
 * @param length		length in bytes to copy
 * @return length in bytes of copied data
 */
KNIEXPORT KNI_RETURNTYPE_INT
KNIDECL(com_sun_j2me_global_DevResourceBundleReader_getRawResourceData0) {
    jint locale_index = KNI_GetParameterAsInt(1);
    jint resource_id = KNI_GetParameterAsInt(2);
	jint offset = KNI_GetParameterAsInt(4);
	jint length = KNI_GetParameterAsInt(5);
	jint array_len;

    jbyte* buffer;

    KNI_StartHandles(1);
    KNI_DeclareHandle(hdata);

    KNI_GetParameterAsObject(3, hdata);

    array_len = KNI_GetArrayLength(hdata);
	if (array_len < length){
        length = 0;
        KNI_ThrowNew(jsropIllegalArgumentException, 
            "Error! Array size is too few!");
	} else {
		buffer = JAVAME_MALLOC(array_len);
		if (NULL == buffer) {
			length = 0;
			KNI_ThrowNew(jsropOutOfMemoryError, 
				"Cannot allocate buffer for device resource");
		} else {
			if (JSR238_STATUSCODE_OK != jsr238_get_resource(locale_index,resource_id,
										buffer, offset, &length)) {
				length = 0;
			} else {
				KNI_SetRawArrayRegion(hdata, 0, length, buffer);
			}
			JAVAME_FREE(buffer);
		}
	}

    KNI_EndHandles();
    KNI_ReturnInt(length);
}
/* JAVADOC COMMENT ELIDED */
KNIEXPORT KNI_RETURNTYPE_INT
    KNIDECL(com_sun_j2me_location_LocationPersistentStorage_addLandmarkToStoreImpl) {
    
    javacall_handle landmarkID = 0;
    javacall_result res;
    javacall_utf16_string categoryName = NULL;
    javacall_landmarkstore_landmark *landmark;
    jint numAddressFields;
    
    KNI_StartHandles(3);
    KNI_DeclareHandle(landmarkObj);
    KNI_DeclareHandle(stringObj);

    GET_PARAMETER_AS_UTF16_STRING(1, storeName)
    KNI_GetParameterAsObject(2, landmarkObj);

    /* CategoryName can be NULL -> check it and extract */
    KNI_GetParameterAsObject(3, stringObj);
    if (!KNI_IsNullHandle(stringObj)) {
        if (JAVACALL_OK != 
            jsrop_jstring_to_utf16_string(stringObj, &categoryName)) {
            categoryName = NULL;
        }
    }
    
    numAddressFields = KNI_GetIntField(landmarkObj, 
            landmarkImplFieldID.numAddressInfoFields);
    landmark = JAVAME_MALLOC(SIZE_OF_LANDMARK_INFO(numAddressFields));

    if (landmark != NULL) {
        if ( fill_landmark(landmarkObj, landmark, stringObj) == KNI_TRUE ) {
            res = javacall_landmarkstore_landmark_add_to_landmarkstore(storeName, 
                                    landmark, categoryName, &landmarkID);
            switch (res) {
                case JAVACALL_OK:
                    /* Category added successfully */
                    break;
                case JAVACALL_INVALID_ARGUMENT:
                    /* wrong category name */
                    KNI_ThrowNew(jsropIllegalArgumentException, 
                                "category name is invalid");
                    break;
                default:
                    /* operation Failed */
                    KNI_ThrowNew(jsropIOException, "I/O error");
                    break;
            }
        } else {
            KNI_ThrowNew(jsropIllegalArgumentException, 
                        "landmark name is too long");
        }
        JAVAME_FREE(landmark);
    }
    if (categoryName != NULL) {
        JAVAME_FREE(categoryName);
    }

    RELEASE_UTF16_STRING_PARAMETER
    KNI_EndHandles();
    KNI_ReturnInt((jint)landmarkID);
}