ZipCtx * MinizipUtils::open_output_file(std::string path)
{
    ZipCtx *ctx = new(std::nothrow) ZipCtx();
    if (!ctx) {
        return nullptr;
    }

#if defined(MINIZIP_WIN32)
    auto converted = utf8_to_wcs(path);
    if (!converted) {
        delete ctx;
        return nullptr;
    }
    ctx->path = std::move(converted.value());

    fill_win32_filefunc64W(&ctx->buf.filefunc64);
#elif defined(MINIZIP_ANDROID)
    fill_android_filefunc64(&ctx->buf.filefunc64);
    ctx->path = std::move(path);
#else
    fill_fopen64_filefunc(&ctx->buf.filefunc64);
    ctx->path = std::move(path);
#endif

    fill_buffer_filefunc64(&ctx->z_func, &ctx->buf);
    ctx->zf = zipOpen2_64(ctx->path.c_str(), 0, nullptr, &ctx->z_func);
    if (!ctx->zf) {
        delete ctx;
        return nullptr;
    }

    return ctx;
}
FileUtils::MzZipCtx * FileUtils::mzOpenOutputFile(std::string path)
{
    MzZipCtx *ctx = new(std::nothrow) MzZipCtx();
    if (!ctx) {
        return nullptr;
    }

#if defined(MINIZIP_WIN32)
    fill_win32_filefunc64W(&ctx->buf.filefunc64);
    ctx->path = utf8::utf8ToUtf16(path);
#elif defined(MINIZIP_ANDROID)
    fill_android_filefunc64(&ctx->buf.filefunc64);
    ctx->path = std::move(path);
#else
    fill_fopen64_filefunc(&ctx->buf.filefunc64);
    ctx->path = std::move(path);
#endif

    fill_buffer_filefunc64(&ctx->zFunc, &ctx->buf);
    ctx->zf = zipOpen2_64(ctx->path.c_str(), 0, nullptr, &ctx->zFunc);
    if (!ctx->zf) {
        free(ctx);
        return nullptr;
    }

    return ctx;
}
zipFile FileUtils::mzOpenOutputFile(const std::string &path)
{
#if defined(MINIZIP_WIN32)
    zlib_filefunc64_def zFunc;
    memset(&zFunc, 0, sizeof(zFunc));
    fill_win32_filefunc64W(&zFunc);
    return zipOpen2_64(utf8::utf8ToUtf16(path).c_str(), 0, nullptr, &zFunc);
#elif defined(MINIZIP_ANDROID)
    zlib_filefunc64_def zFunc;
    memset(&zFunc, 0, sizeof(zFunc));
    fill_android_filefunc64(&zFunc);
    return zipOpen2_64(path.c_str(), 0, nullptr, &zFunc);
#else
    return zipOpen64(path.c_str(), 0);
#endif
}