blob: fdac48956acef1d36bc32c69cf40f4ae5adb89e8 [file] [log] [blame]
#include <jni.h>
#include <nativehelper/scoped_utf_chars.h>
#include "leveldb/db.h"
#ifndef _Included_com_android_providers_media_leveldb_LevelDBInstance
#define _Included_com_android_providers_media_leveldb_LevelDBInstance
#ifdef __cplusplus
extern "C" {
#endif
#undef com_android_providers_media_leveldb_LevelDBInstance_MAX_BULK_INSERT_ENTRIES
#define com_android_providers_media_leveldb_LevelDBInstance_MAX_BULK_INSERT_ENTRIES 100L
static std::string getStatusCode(leveldb::Status status) {
if (status.ok()) {
return "0";
} else if (status.IsNotFound()) {
return "1";
} else if (status.IsInvalidArgument()) {
return "2";
} else {
return "3";
}
}
static jobject createLevelDBResult(JNIEnv* env, leveldb::Status status, std::string value) {
// Create the object of the class LevelDBResult
jclass levelDbResultClass = env->FindClass("com/android/providers/media/leveldb/LevelDBResult");
jobject levelDbResultData = env->AllocObject(levelDbResultClass);
// Get the UserData fields to be set
jfieldID codeField = env->GetFieldID(levelDbResultClass, "mCode", "Ljava/lang/String;");
jfieldID messageField =
env->GetFieldID(levelDbResultClass, "mErrorMessage", "Ljava/lang/String;");
jfieldID valueField = env->GetFieldID(levelDbResultClass, "mValue", "Ljava/lang/String;");
std::string statusCode = getStatusCode(status);
env->SetObjectField(levelDbResultData, codeField, env->NewStringUTF(statusCode.c_str()));
env->SetObjectField(levelDbResultData, messageField,
env->NewStringUTF(status.ToString().c_str()));
env->SetObjectField(levelDbResultData, valueField, env->NewStringUTF(value.c_str()));
return levelDbResultData;
}
static leveldb::Status insertInLevelDB(JNIEnv* env, jobject obj, jlong leveldbptr,
jobject leveldbentry) {
jclass levelDbEntryClass = env->GetObjectClass(leveldbentry);
jmethodID getKeyMethodId =
env->GetMethodID(levelDbEntryClass, "getKey", "()Ljava/lang/String;");
jmethodID getValueMethodId =
env->GetMethodID(levelDbEntryClass, "getValue", "()Ljava/lang/String;");
jstring key = (jstring)env->CallObjectMethod(leveldbentry, getKeyMethodId);
jstring value = (jstring)env->CallObjectMethod(leveldbentry, getValueMethodId);
ScopedUtfChars utf_chars_key(env, key);
ScopedUtfChars utf_chars_value(env, value);
leveldb::DB* leveldb = reinterpret_cast<leveldb::DB*>(leveldbptr);
leveldb::Status status;
status = leveldb->Put(leveldb::WriteOptions(), utf_chars_key.c_str(), utf_chars_value.c_str());
return status;
}
static jobject insert(JNIEnv* env, jobject obj, jlong leveldbptr, jobject leveldbentry) {
return createLevelDBResult(env, insertInLevelDB(env, obj, leveldbptr, leveldbentry), "");
}
/*
* Class: com_android_providers_media_leveldb_LevelDBInstance
* Method: nativeCreateInstance
* Signature: (Ljava/lang/String;)J
*/
JNIEXPORT jlong JNICALL
Java_com_android_providers_media_leveldb_LevelDBInstance_nativeCreateInstance(
JNIEnv* env, jclass leveldbInstanceClass, jstring path) {
ScopedUtfChars utf_chars_path(env, path);
leveldb::Options options;
options.create_if_missing = true;
leveldb::DB* leveldb;
leveldb::Status status = leveldb::DB::Open(options, utf_chars_path.c_str(), &leveldb);
if (status.ok()) {
return reinterpret_cast<jlong>(leveldb);
} else {
long val = 0;
return (jlong)val;
}
}
/*
* Class: com_android_providers_media_leveldb_LevelDBInstance
* Method: nativeQuery
* Signature: (JLjava/lang/String;)Lcom/android/providers/media/leveldb/LevelDBResult;
*/
JNIEXPORT jobject JNICALL Java_com_android_providers_media_leveldb_LevelDBInstance_nativeQuery(
JNIEnv* env, jobject obj, jlong leveldbptr, jstring path) {
ScopedUtfChars utf_chars_path(env, path);
leveldb::DB* leveldb = reinterpret_cast<leveldb::DB*>(leveldbptr);
leveldb::Status status;
std::string value = "";
status = leveldb->Get(leveldb::ReadOptions(), utf_chars_path.c_str(), &value);
return createLevelDBResult(env, status, value);
}
/*
* Class: com_android_providers_media_leveldb_LevelDBInstance
* Method: nativeInsert
* Signature: (JLcom/android/providers/media/leveldb/LevelDBEntry;)
* Lcom/android/providers/media/leveldb/LevelDBResult;
*/
JNIEXPORT jobject JNICALL Java_com_android_providers_media_leveldb_LevelDBInstance_nativeInsert(
JNIEnv* env, jobject obj, jlong leveldbptr, jobject leveldbentry) {
return insert(env, obj, leveldbptr, leveldbentry);
}
/*
* Class: com_android_providers_media_leveldb_LevelDBInstance
* Method: nativeBulkInsert
* Signature: (JLjava/util/List;)Lcom/android/providers/media/leveldb/LevelDBResult;
*/
JNIEXPORT jobject JNICALL Java_com_android_providers_media_leveldb_LevelDBInstance_nativeBulkInsert(
JNIEnv* env, jobject obj, jlong leveldbptr, jobject entries) {
// Get the class of the list
jclass listClass = env->GetObjectClass(entries);
// Get the iterator method ID
jmethodID iteratorMethod = env->GetMethodID(listClass, "iterator", "()Ljava/util/Iterator;");
// Get the iterator object
jobject iterator = env->CallObjectMethod(entries, iteratorMethod);
// Get the iterator class
jclass iteratorClass = env->GetObjectClass(iterator);
// Get the hasNext and next method IDs
jmethodID hasNextMethod = env->GetMethodID(iteratorClass, "hasNext", "()Z");
jmethodID nextMethod = env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;");
leveldb::Status status;
// Iterate through the list
while (env->CallBooleanMethod(iterator, hasNextMethod)) {
jobject jLevelDBEntryObject = env->CallObjectMethod(iterator, nextMethod);
leveldb::Status status = insertInLevelDB(env, obj, leveldbptr, jLevelDBEntryObject);
if (!status.ok()) {
break;
}
}
return createLevelDBResult(env, status, "");
}
/*
* Class: com_android_providers_media_leveldb_LevelDBInstance
* Method: nativeDelete
* Signature: (JLjava/lang/String;)Lcom/android/providers/media/leveldb/LevelDBResult;
*/
JNIEXPORT jobject JNICALL Java_com_android_providers_media_leveldb_LevelDBInstance_nativeDelete(
JNIEnv* env, jobject obj, jlong leveldbptr, jstring key) {
ScopedUtfChars utf_chars_key(env, key);
leveldb::DB* leveldb = reinterpret_cast<leveldb::DB*>(leveldbptr);
leveldb::Status status;
status = leveldb->Delete(leveldb::WriteOptions(), utf_chars_key.c_str());
return createLevelDBResult(env, status, "");
}
/*
* Class: com_android_providers_media_leveldb_LevelDBInstance
* Method: nativeDeleteLevelDb
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_com_android_providers_media_leveldb_LevelDBInstance_nativeDeleteLevelDb(
JNIEnv* env, jobject obj, jlong leveldbptr) {
leveldb::DB* leveldb = reinterpret_cast<leveldb::DB*>(leveldbptr);
delete leveldb;
}
#ifdef __cplusplus
}
#endif
#endif