#pragma once
#ifndef HEADER_JNI_H_
#define HEADER_JNI_H_
#include <jni.h>
#endif
class JByteArrayGuard {
private:
    JNIEnv* env;
    jbyteArray array;
    jbyte* data;
    jsize length;
    bool isCritical;
    jint releaseMode;
public:
    JByteArrayGuard(JNIEnv* env, jbyteArray array, bool critical = false, jint releaseMode = 0)
            : env(env), array(array), data(nullptr), length(0), isCritical(critical), releaseMode(releaseMode)
    {
        if (array) {
            length = env->GetArrayLength(array);
            if (isCritical) {
                data = (jbyte*) env->GetPrimitiveArrayCritical(array, nullptr);
            } else {
                data = env->GetByteArrayElements(array, nullptr);
            }
        }
    }
    ~JByteArrayGuard() {
        release();
    }
    // 显式释放方法
    void release() {
        if (data && array) {
            if (isCritical) {
                env->ReleasePrimitiveArrayCritical(array, data, releaseMode);
            } else {
                env->ReleaseByteArrayElements(array, data, releaseMode);
            }
            data = nullptr;  // 防止重复释放
            array = nullptr;
        }
    }

    // 提交修改但不释放（用于返回结果的情况）
    void commit() {
        if (data && array) {
            if (isCritical) {
                env->ReleasePrimitiveArrayCritical(array, data, 0);
            } else {
                env->ReleaseByteArrayElements(array, data, 0);
            }
            data = nullptr;  // 标记为已释放，防止析构函数再次释放
            array = nullptr;
        }
    }

    // 丢弃修改
    void abort() {
        if (data && array) {
            if (isCritical) {
                env->ReleasePrimitiveArrayCritical(array, data, JNI_ABORT);
            } else {
                env->ReleaseByteArrayElements(array, data, JNI_ABORT);
            }
            data = nullptr;
            array = nullptr;
        }
    }
    jbyte* get() { return data; }
    jsize size() const { return length; }
    bool isValid() { return data != nullptr; }

    JByteArrayGuard(const JByteArrayGuard&) = delete;
    JByteArrayGuard& operator=(const JByteArrayGuard&) = delete;
    JByteArrayGuard(JByteArrayGuard&& other) noexcept
            : env(other.env), array(other.array), data(other.data),
              length(other.length), isCritical(other.isCritical),
              releaseMode(other.releaseMode) {
        other.array = nullptr;
        other.data = nullptr;
        other.length = 0;
    }
};