musikr: fix memory leaks
This commit is contained in:
parent
3aae8ea534
commit
1bf44eba91
4 changed files with 76 additions and 49 deletions
|
@ -23,12 +23,11 @@
|
||||||
// TODO: Handle stream exceptions
|
// TODO: Handle stream exceptions
|
||||||
JVMInputStream::JVMInputStream(JNIEnv *env, jobject inputStream) : env(env), inputStream(
|
JVMInputStream::JVMInputStream(JNIEnv *env, jobject inputStream) : env(env), inputStream(
|
||||||
inputStream) {
|
inputStream) {
|
||||||
if (!env->IsInstanceOf(inputStream,
|
|
||||||
env->FindClass("org/oxycblt/musikr/metadata/NativeInputStream"))) {
|
|
||||||
throw std::runtime_error("oStream is not an instance of TagLibOStream");
|
|
||||||
}
|
|
||||||
jclass inputStreamClass = env->FindClass(
|
jclass inputStreamClass = env->FindClass(
|
||||||
"org/oxycblt/musikr/metadata/NativeInputStream");
|
"org/oxycblt/musikr/metadata/NativeInputStream");
|
||||||
|
if (!env->IsInstanceOf(inputStream, inputStreamClass)) {
|
||||||
|
throw std::runtime_error("oStream is not an instance of TagLibOStream");
|
||||||
|
}
|
||||||
inputStreamReadBlockMethod = env->GetMethodID(inputStreamClass, "readBlock",
|
inputStreamReadBlockMethod = env->GetMethodID(inputStreamClass, "readBlock",
|
||||||
"(J)[B");
|
"(J)[B");
|
||||||
inputStreamIsOpenMethod = env->GetMethodID(inputStreamClass, "isOpen",
|
inputStreamIsOpenMethod = env->GetMethodID(inputStreamClass, "isOpen",
|
||||||
|
@ -57,7 +56,7 @@ TagLib::FileName JVMInputStream::name() const {
|
||||||
|
|
||||||
TagLib::ByteVector JVMInputStream::readBlock(size_t length) {
|
TagLib::ByteVector JVMInputStream::readBlock(size_t length) {
|
||||||
auto data = (jbyteArray) env->CallObjectMethod(inputStream,
|
auto data = (jbyteArray) env->CallObjectMethod(inputStream,
|
||||||
inputStreamReadBlockMethod, length);
|
inputStreamReadBlockMethod, static_cast<jlong>(length));
|
||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
throw std::runtime_error("Failed to read block, see logs");
|
throw std::runtime_error("Failed to read block, see logs");
|
||||||
}
|
}
|
||||||
|
@ -66,6 +65,7 @@ TagLib::ByteVector JVMInputStream::readBlock(size_t length) {
|
||||||
TagLib::ByteVector byteVector(reinterpret_cast<const char*>(dataBytes),
|
TagLib::ByteVector byteVector(reinterpret_cast<const char*>(dataBytes),
|
||||||
dataLength);
|
dataLength);
|
||||||
env->ReleaseByteArrayElements(data, dataBytes, JNI_ABORT);
|
env->ReleaseByteArrayElements(data, dataBytes, JNI_ABORT);
|
||||||
|
env->DeleteLocalRef(data);
|
||||||
return byteVector;
|
return byteVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,10 +188,11 @@ jobject JVMMetadataBuilder::build() {
|
||||||
"org/oxycblt/musikr/metadata/Properties");
|
"org/oxycblt/musikr/metadata/Properties");
|
||||||
jmethodID propertiesInit = env->GetMethodID(propertiesClass, "<init>",
|
jmethodID propertiesInit = env->GetMethodID(propertiesClass, "<init>",
|
||||||
"(Ljava/lang/String;JII)V");
|
"(Ljava/lang/String;JII)V");
|
||||||
|
jstring jmimeType = env->NewStringUTF(mimeType.data());
|
||||||
jobject propertiesObj = env->NewObject(propertiesClass, propertiesInit,
|
jobject propertiesObj = env->NewObject(propertiesClass, propertiesInit,
|
||||||
env->NewStringUTF(mimeType.data()),
|
jmimeType, (jlong) properties->lengthInMilliseconds(),
|
||||||
(jlong) properties->lengthInMilliseconds(), properties->bitrate(),
|
properties->bitrate(), properties->sampleRate());
|
||||||
properties->sampleRate());
|
env->DeleteLocalRef(jmimeType);
|
||||||
env->DeleteLocalRef(propertiesClass);
|
env->DeleteLocalRef(propertiesClass);
|
||||||
|
|
||||||
jclass metadataClass = env->FindClass(
|
jclass metadataClass = env->FindClass(
|
||||||
|
@ -211,6 +212,11 @@ jobject JVMMetadataBuilder::build() {
|
||||||
}
|
}
|
||||||
jobject metadataObj = env->NewObject(metadataClass, metadataInit, id3v2Map,
|
jobject metadataObj = env->NewObject(metadataClass, metadataInit, id3v2Map,
|
||||||
xiphMap, mp4Map, coverArray, propertiesObj);
|
xiphMap, mp4Map, coverArray, propertiesObj);
|
||||||
|
env->DeleteLocalRef(propertiesObj);
|
||||||
env->DeleteLocalRef(metadataClass);
|
env->DeleteLocalRef(metadataClass);
|
||||||
|
env->DeleteLocalRef(coverArray);
|
||||||
|
env->DeleteLocalRef(id3v2Map);
|
||||||
|
env->DeleteLocalRef(xiphMap);
|
||||||
|
env->DeleteLocalRef(mp4Map);
|
||||||
return metadataObj;
|
return metadataObj;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,57 +52,78 @@ JVMTagMap::~JVMTagMap() {
|
||||||
env->DeleteLocalRef(arrayListClass);
|
env->DeleteLocalRef(arrayListClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JVMTagMap::add_id(TagLib::String id, TagLib::String value) {
|
void JVMTagMap::add_id(const TagLib::String id, const TagLib::String value) {
|
||||||
env->CallVoidMethod(tagMap, tagMapAddIdSingleMethod,
|
jstring jid = env->NewStringUTF(id.toCString(true));
|
||||||
env->NewStringUTF(id.toCString(true)),
|
jstring jvalue = env->NewStringUTF(value.toCString(true));
|
||||||
env->NewStringUTF(value.toCString(true)));
|
env->CallVoidMethod(tagMap, tagMapAddIdSingleMethod, jid, jvalue);
|
||||||
|
env->DeleteLocalRef(jid);
|
||||||
|
env->DeleteLocalRef(jvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JVMTagMap::add_id(TagLib::String id, TagLib::StringList value) {
|
void JVMTagMap::add_id(const TagLib::String id,
|
||||||
jobject arrayList = env->NewObject(arrayListClass, arrayListInitMethod);
|
const TagLib::StringList values) {
|
||||||
for (auto &item : value) {
|
jstring jid = env->NewStringUTF(id.toCString(true));
|
||||||
env->CallBooleanMethod(arrayList, arrayListAddMethod,
|
jobject jvalues = env->NewObject(arrayListClass, arrayListInitMethod);
|
||||||
env->NewStringUTF(item.toCString(true)));
|
for (auto &item : values) {
|
||||||
|
jstring jvalue = env->NewStringUTF(item.toCString(true));
|
||||||
|
env->CallBooleanMethod(jvalues, arrayListAddMethod, jvalue);
|
||||||
|
env->DeleteLocalRef(jvalue);
|
||||||
}
|
}
|
||||||
env->CallVoidMethod(tagMap, tagMapAddIdListMethod,
|
env->CallVoidMethod(tagMap, tagMapAddIdListMethod, jid, jvalues);
|
||||||
env->NewStringUTF(id.toCString(true)), arrayList);
|
env->DeleteLocalRef(jid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JVMTagMap::add_custom(TagLib::String description, TagLib::String value) {
|
void JVMTagMap::add_custom(const TagLib::String description,
|
||||||
env->CallVoidMethod(tagMap, tagMapAddCustomSingleMethod,
|
const TagLib::String value) {
|
||||||
env->NewStringUTF(description.toCString(true)),
|
jstring jdescription = env->NewStringUTF(description.toCString(true));
|
||||||
env->NewStringUTF(value.toCString(true)));
|
jstring jvalue = env->NewStringUTF(value.toCString(true));
|
||||||
|
env->CallVoidMethod(tagMap, tagMapAddCustomSingleMethod, jdescription,
|
||||||
|
jvalue);
|
||||||
|
env->DeleteLocalRef(jdescription);
|
||||||
|
env->DeleteLocalRef(jvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JVMTagMap::add_custom(TagLib::String description,
|
void JVMTagMap::add_custom(const TagLib::String description,
|
||||||
TagLib::StringList value) {
|
const TagLib::StringList values) {
|
||||||
jobject arrayList = env->NewObject(arrayListClass, arrayListInitMethod);
|
jstring jid = env->NewStringUTF(description.toCString(true));
|
||||||
for (auto &item : value) {
|
jobject jvalues = env->NewObject(arrayListClass, arrayListInitMethod);
|
||||||
env->CallBooleanMethod(arrayList, arrayListAddMethod,
|
for (auto &item : values) {
|
||||||
env->NewStringUTF(item.toCString(true)));
|
jstring jvalue = env->NewStringUTF(item.toCString(true));
|
||||||
|
env->CallBooleanMethod(jvalues, arrayListAddMethod, jvalue);
|
||||||
|
env->DeleteLocalRef(jvalue);
|
||||||
}
|
}
|
||||||
env->CallVoidMethod(tagMap, tagMapAddCustomListMethod,
|
env->CallVoidMethod(tagMap, tagMapAddCustomListMethod, jid, jvalues);
|
||||||
env->NewStringUTF(description.toCString(true)), arrayList);
|
env->DeleteLocalRef(jid);
|
||||||
|
env->DeleteLocalRef(jvalues);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JVMTagMap::add_combined(TagLib::String id, TagLib::String description,
|
void JVMTagMap::add_combined(const TagLib::String id,
|
||||||
TagLib::String value) {
|
const TagLib::String description, const TagLib::String value) {
|
||||||
env->CallVoidMethod(tagMap, tagMapAddCombinedSingleMethod,
|
jstring jid = env->NewStringUTF(id.toCString(true));
|
||||||
env->NewStringUTF(id.toCString(true)),
|
jstring jdescription = env->NewStringUTF(description.toCString(true));
|
||||||
env->NewStringUTF(description.toCString(true)),
|
jstring jvalue = env->NewStringUTF(value.toCString(true));
|
||||||
env->NewStringUTF(value.toCString(true)));
|
env->CallVoidMethod(tagMap, tagMapAddCombinedSingleMethod, jid,
|
||||||
|
jdescription, jvalue);
|
||||||
|
env->DeleteLocalRef(jid);
|
||||||
|
env->DeleteLocalRef(jdescription);
|
||||||
|
env->DeleteLocalRef(jvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JVMTagMap::add_combined(TagLib::String id, TagLib::String description,
|
void JVMTagMap::add_combined(const TagLib::String id,
|
||||||
TagLib::StringList value) {
|
const TagLib::String description, const TagLib::StringList values) {
|
||||||
jobject arrayList = env->NewObject(arrayListClass, arrayListInitMethod);
|
jstring jid = env->NewStringUTF(id.toCString(true));
|
||||||
for (auto &item : value) {
|
jstring jdescription = env->NewStringUTF(description.toCString(true));
|
||||||
env->CallBooleanMethod(arrayList, arrayListAddMethod,
|
jobject jvalues = env->NewObject(arrayListClass, arrayListInitMethod);
|
||||||
env->NewStringUTF(item.toCString(true)));
|
for (auto &item : values) {
|
||||||
|
jstring jvalue = env->NewStringUTF(item.toCString(true));
|
||||||
|
env->CallBooleanMethod(jvalues, arrayListAddMethod, jvalue);
|
||||||
|
env->DeleteLocalRef(jvalue);
|
||||||
}
|
}
|
||||||
env->CallVoidMethod(tagMap, tagMapAddCombinedListMethod,
|
env->CallVoidMethod(tagMap, tagMapAddCombinedListMethod, jid, jdescription,
|
||||||
env->NewStringUTF(id.toCString(true)),
|
jvalues);
|
||||||
env->NewStringUTF(description.toCString(true)), arrayList);
|
env->DeleteLocalRef(jid);
|
||||||
|
env->DeleteLocalRef(jdescription);
|
||||||
|
env->DeleteLocalRef(jvalues);
|
||||||
}
|
}
|
||||||
|
|
||||||
jobject JVMTagMap::getObject() {
|
jobject JVMTagMap::getObject() {
|
||||||
|
|
|
@ -33,15 +33,15 @@ public:
|
||||||
JVMTagMap& operator=(const JVMTagMap&) = delete;
|
JVMTagMap& operator=(const JVMTagMap&) = delete;
|
||||||
|
|
||||||
void add_id(TagLib::String id, TagLib::String value);
|
void add_id(TagLib::String id, TagLib::String value);
|
||||||
void add_id(TagLib::String id, TagLib::StringList value);
|
void add_id(TagLib::String id, TagLib::StringList values);
|
||||||
|
|
||||||
void add_custom(TagLib::String description, TagLib::String value);
|
void add_custom(TagLib::String description, TagLib::String value);
|
||||||
void add_custom(TagLib::String description, TagLib::StringList value);
|
void add_custom(TagLib::String description, TagLib::StringList values);
|
||||||
|
|
||||||
void add_combined(TagLib::String id, TagLib::String description,
|
void add_combined(TagLib::String id, TagLib::String description,
|
||||||
TagLib::String value);
|
TagLib::String value);
|
||||||
void add_combined(TagLib::String id, TagLib::String description,
|
void add_combined(TagLib::String id, TagLib::String description,
|
||||||
TagLib::StringList value);
|
TagLib::StringList values);
|
||||||
|
|
||||||
jobject getObject();
|
jobject getObject();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue