diff --git a/ktaglib/src/main/cpp/JVMTagMap.cpp b/ktaglib/src/main/cpp/JVMTagMap.cpp new file mode 100644 index 000000000..db572b251 --- /dev/null +++ b/ktaglib/src/main/cpp/JVMTagMap.cpp @@ -0,0 +1,70 @@ +// +// Created by oxycblt on 12/12/24. +// + +#include "JVMTagMap.h" + +JVMTagMap::JVMTagMap(JNIEnv *env) : env(env) { + jclass hashMapClass = env->FindClass("java/util/HashMap"); + jmethodID init = env->GetMethodID(hashMapClass, "", "()V"); + hashMap = env->NewObject(hashMapClass, init); + hashMapGetMethod = env->GetMethodID(hashMapClass, "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); + hashMapPutMethod = env->GetMethodID(hashMapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); + env->DeleteLocalRef(hashMapClass); + + jclass arrayListClass = env->FindClass("java/util/ArrayList"); + arrayListInitMethod = env->GetMethodID(arrayListClass, "", "()V"); + arrayListAddMethod = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z"); + env->DeleteLocalRef(arrayListClass); +} + +JVMTagMap::~JVMTagMap() { + env->DeleteLocalRef(hashMap); +} + +void JVMTagMap::add(TagLib::String &key, TagLib::String &value) { + jstring jKey = env->NewStringUTF(key.toCString(true)); + jstring jValue = env->NewStringUTF(value.toCString(true)); + + // check if theres already a value arraylist in the map + jobject existingValue = env->CallObjectMethod(hashMap, hashMapGetMethod, jKey); + // if there is, add to the value to the existing arraylist + if (existingValue != nullptr) { + env->CallBooleanMethod(existingValue, arrayListAddMethod, jValue); + } else { + // if there isn't, create a new arraylist and add the value to it + jclass arrayListClass = env->FindClass("java/util/ArrayList"); + jobject arrayList = env->NewObject(arrayListClass, arrayListInitMethod); + env->CallBooleanMethod(arrayList, arrayListAddMethod, jValue); + env->CallObjectMethod(hashMap, hashMapPutMethod, jKey, arrayList); + env->DeleteLocalRef(arrayListClass); + } +} + +void JVMTagMap::add(TagLib::String &key, TagLib::StringList &value) { + jstring jKey = env->NewStringUTF(key.toCString(true)); + + // check if theres already a value arraylist in the map + jobject existingValue = env->CallObjectMethod(hashMap, hashMapGetMethod, jKey); + // if there is, add to the value to the existing arraylist + if (existingValue != nullptr) { + for (auto &val : value) { + jstring jValue = env->NewStringUTF(val.toCString(true)); + env->CallBooleanMethod(existingValue, arrayListAddMethod, jValue); + } + } else { + // if there isn't, create a new arraylist and add the value to it + jclass arrayListClass = env->FindClass("java/util/ArrayList"); + jobject arrayList = env->NewObject(arrayListClass, arrayListInitMethod); + for (auto &val : value) { + jstring jValue = env->NewStringUTF(val.toCString(true)); + env->CallBooleanMethod(arrayList, arrayListAddMethod, jValue); + } + env->CallObjectMethod(hashMap, hashMapPutMethod, jKey, arrayList); + env->DeleteLocalRef(arrayListClass); + } +} + +jobject JVMTagMap::getObject() { + return hashMap; +} \ No newline at end of file diff --git a/ktaglib/src/main/cpp/JVMTagMap.h b/ktaglib/src/main/cpp/JVMTagMap.h new file mode 100644 index 000000000..db6f543ab --- /dev/null +++ b/ktaglib/src/main/cpp/JVMTagMap.h @@ -0,0 +1,36 @@ +// +// Created by oxycblt on 12/12/24. +// + +#ifndef AUXIO_JVMTAGMAP_H +#define AUXIO_JVMTAGMAP_H + +#include +#include +#include +#include + +class JVMTagMap { +public: + JVMTagMap(JNIEnv *env); + ~JVMTagMap(); + + JVMTagMap(const JVMTagMap &) = delete; + JVMTagMap &operator=(const JVMTagMap &) = delete; + + void add(TagLib::String &key, TagLib::String &value); + void add(TagLib::String &key, TagLib::StringList &value); + + jobject getObject(); + +private: + JNIEnv *env; + jobject hashMap; + jmethodID hashMapGetMethod; + jmethodID hashMapPutMethod; + jmethodID arrayListInitMethod; + jmethodID arrayListAddMethod; +}; + + +#endif //AUXIO_JVMTAGMAP_H