diff --git a/binding.gyp b/binding.gyp index b9a49947..951570ef 100644 --- a/binding.gyp +++ b/binding.gyp @@ -42,6 +42,7 @@ "include_dirs": [ "include", "include/logger", + "include/napi_helpers", "include/placeholders_interface", "include/sync_root_interface", "include/sync_root_interface/callbacks", diff --git a/dist/addon.node b/dist/addon.node index 5ec80a83..3fa8e008 100644 Binary files a/dist/addon.node and b/dist/addon.node differ diff --git a/include/napi_helpers/napi_extract_args.h b/include/napi_helpers/napi_extract_args.h new file mode 100644 index 00000000..11bc04c4 --- /dev/null +++ b/include/napi_helpers/napi_extract_args.h @@ -0,0 +1,20 @@ +#include +#include + +template +std::array napi_extract_args(napi_env env, napi_callback_info info) { + size_t argc = N; + napi_value argv[N]; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + + std::array result; + + for (size_t i = 0; i < N; ++i) { + size_t length; + napi_get_value_string_utf16(env, argv[i], nullptr, 0, &length); + result[i].resize(length); + napi_get_value_string_utf16(env, argv[i], reinterpret_cast(result[i].data()), length + 1, nullptr); + } + + return result; +} diff --git a/include/virtual_drive/napi_safe_wrap.h b/include/napi_helpers/napi_safe_wrap.h similarity index 81% rename from include/virtual_drive/napi_safe_wrap.h rename to include/napi_helpers/napi_safe_wrap.h index 7201e4f3..15df7255 100644 --- a/include/virtual_drive/napi_safe_wrap.h +++ b/include/napi_helpers/napi_safe_wrap.h @@ -12,9 +12,7 @@ napi_value napi_safe_wrap(napi_env env, napi_callback_info info, Fn&& fn, const try { return fn(env, info); } catch (const winrt::hresult_error& e) { - oss << "[" << function_name << "] WinRT error: " - << winrt::to_string(e.message()) - << " (HRESULT: 0x" << std::hex << e.code() << ")"; + oss << "[" << function_name << "] WinRT error: " << winrt::to_string(e.message()) << " (HRESULT: 0x" << std::hex << e.code() << ")"; } catch (const std::exception& e) { oss << "[" << function_name << "] " << e.what(); } catch (...) { diff --git a/include/virtual_drive/register_sync_root.h b/include/virtual_drive/register_sync_root.h deleted file mode 100644 index e12e343d..00000000 --- a/include/virtual_drive/register_sync_root.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include - -napi_value register_sync_root_impl(napi_env env, napi_callback_info args); diff --git a/include/virtual_drive/register_sync_root/register_sync_root.h b/include/virtual_drive/register_sync_root/register_sync_root.h index 2f143295..bbe45f13 100644 --- a/include/virtual_drive/register_sync_root/register_sync_root.h +++ b/include/virtual_drive/register_sync_root/register_sync_root.h @@ -6,4 +6,4 @@ #include #include -void register_sync_root(const wchar_t *syncRootPath, const wchar_t *providerName, const wchar_t *providerVersion, const wchar_t *providerId, const wchar_t *logoPath); \ No newline at end of file +void register_sync_root(const wchar_t *syncRootPath, const wchar_t *providerName, const wchar_t *providerVersion, const wchar_t *providerId, const wchar_t *logoPath); diff --git a/native-src/virtual_drive/convert_to_placeholder.cpp b/native-src/virtual_drive/convert_to_placeholder.cpp index 96a4c5b0..4d5ff546 100644 --- a/native-src/virtual_drive/convert_to_placeholder.cpp +++ b/native-src/virtual_drive/convert_to_placeholder.cpp @@ -1,21 +1,9 @@ #include +#include "napi_extract_args.h" #include "Placeholders.h" -napi_value convert_to_placeholder_impl(napi_env env, napi_callback_info args) -{ - size_t argc = 2; - napi_value argv[2]; - napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr); - - size_t pathLen, serverIdentityLen; - napi_get_value_string_utf8(env, argv[0], nullptr, 0, &pathLen); - napi_get_value_string_utf8(env, argv[1], nullptr, 0, &serverIdentityLen); - - std::string path(pathLen, '\0'); - std::string serverIdentity(serverIdentityLen, '\0'); - - napi_get_value_string_utf8(env, argv[0], &path[0], pathLen + 1, nullptr); - napi_get_value_string_utf8(env, argv[1], &serverIdentity[0], serverIdentityLen + 1, nullptr); +napi_value convert_to_placeholder_impl(napi_env env, napi_callback_info info) { + auto [path, serverIdentity] = napi_extract_args<2>(env, info); std::wstring wPath(path.begin(), path.end()); std::wstring wServerIdentity(serverIdentity.begin(), serverIdentity.end()); diff --git a/native-src/virtual_drive/get_file_identity.cpp b/native-src/virtual_drive/get_file_identity.cpp index b86bdcd3..0642ec22 100644 --- a/native-src/virtual_drive/get_file_identity.cpp +++ b/native-src/virtual_drive/get_file_identity.cpp @@ -1,31 +1,16 @@ #include +#include "napi_extract_args.h" #include "Placeholders.h" -napi_value get_file_identity_impl(napi_env env, napi_callback_info args) -{ - size_t argc = 1; - napi_value argv[1]; - napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr); +napi_value get_file_identity_impl(napi_env env, napi_callback_info info) { + auto [path] = napi_extract_args<1>(env, info); - if (argc < 1) - { - napi_throw_error(env, nullptr, "The path is required for GetFileIdentity"); - return nullptr; - } - - LPCWSTR fullPath; - size_t pathLength; - napi_get_value_string_utf16(env, argv[0], nullptr, 0, &pathLength); - fullPath = new WCHAR[pathLength + 1]; - napi_get_value_string_utf16(env, argv[0], reinterpret_cast(const_cast(fullPath)), pathLength + 1, nullptr); - - std::string fileIdentity = Placeholders::GetFileIdentity(fullPath); + std::string fileIdentity = Placeholders::GetFileIdentity(path); fileIdentity.erase(std::remove(fileIdentity.begin(), fileIdentity.end(), '\0'), fileIdentity.end()); fileIdentity.erase(std::remove(fileIdentity.begin(), fileIdentity.end(), ' '), fileIdentity.end()); napi_value jsFileIdentity; napi_create_string_utf8(env, fileIdentity.c_str(), fileIdentity.length(), &jsFileIdentity); - delete[] fullPath; return jsFileIdentity; } diff --git a/native-src/virtual_drive/hydrate_file.cpp b/native-src/virtual_drive/hydrate_file.cpp index db399cae..490c9568 100644 --- a/native-src/virtual_drive/hydrate_file.cpp +++ b/native-src/virtual_drive/hydrate_file.cpp @@ -1,13 +1,13 @@ #include #include #include -#include "Logger.h" +#include "napi_extract_args.h" #include "SyncRoot.h" struct AsyncWork { napi_async_work work; napi_deferred deferred; - std::wstring fullPath; + std::wstring path; std::string error; bool success; }; @@ -16,8 +16,7 @@ void execute_work(napi_env env, void* data) { AsyncWork* asyncWork = static_cast(data); try { - SyncRoot::HydrateFile(asyncWork->fullPath.c_str()); - Logger::getInstance().log("finish... " + Logger::fromWStringToString(asyncWork->fullPath.c_str()), LogLevel::INFO); + SyncRoot::HydrateFile(asyncWork->path.c_str()); asyncWork->success = true; } catch (const std::exception& e) { asyncWork->error = e.what(); @@ -45,18 +44,8 @@ void complete_work(napi_env env, napi_status status, void* data) { delete asyncWork; } -napi_value hydrate_file_impl(napi_env env, napi_callback_info args) -{ - size_t argc = 1; - napi_value argv[1]; - napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr); - - // Get string length and content - size_t pathLength; - napi_get_value_string_utf16(env, argv[0], nullptr, 0, &pathLength); - - std::wstring fullPath(pathLength, L'\0'); - napi_get_value_string_utf16(env, argv[0], reinterpret_cast(&fullPath[0]), pathLength + 1, nullptr); +napi_value hydrate_file_impl(napi_env env, napi_callback_info info) { + auto [path] = napi_extract_args<1>(env, info); // Create promise napi_deferred deferred; @@ -66,7 +55,7 @@ napi_value hydrate_file_impl(napi_env env, napi_callback_info args) // Create and queue async work AsyncWork* asyncWork = new AsyncWork{}; asyncWork->deferred = deferred; - asyncWork->fullPath = std::move(fullPath); + asyncWork->path = std::move(path); napi_value resourceName; napi_create_string_utf8(env, "HydrateFileAsync", NAPI_AUTO_LENGTH, &resourceName); diff --git a/native-src/virtual_drive/register_sync_root.cpp b/native-src/virtual_drive/register_sync_root.cpp deleted file mode 100644 index 54e8f35e..00000000 --- a/native-src/virtual_drive/register_sync_root.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include "SyncRoot.h" - -napi_value register_sync_root_impl(napi_env env, napi_callback_info args) -{ - size_t argc = 5; - napi_value argv[5]; - - napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr); - - if (argc < 5) - { - napi_throw_error(env, nullptr, "5 arguments are required for RegisterSyncRoot"); - return nullptr; - } - - LPCWSTR syncRootPath; - size_t syncRootPathLength; - napi_get_value_string_utf16(env, argv[0], nullptr, 0, &syncRootPathLength); - syncRootPath = new WCHAR[syncRootPathLength + 1]; - napi_get_value_string_utf16(env, argv[0], reinterpret_cast(const_cast(syncRootPath)), syncRootPathLength + 1, nullptr); - - LPCWSTR providerName; - size_t providerNameLength; - napi_get_value_string_utf16(env, argv[1], nullptr, 0, &providerNameLength); - providerName = new WCHAR[providerNameLength + 1]; - napi_get_value_string_utf16(env, argv[1], reinterpret_cast(const_cast(providerName)), providerNameLength + 1, nullptr); - - LPCWSTR providerVersion; - size_t providerVersionLength; - napi_get_value_string_utf16(env, argv[2], nullptr, 0, &providerVersionLength); - providerVersion = new WCHAR[providerVersionLength + 1]; - napi_get_value_string_utf16(env, argv[2], reinterpret_cast(const_cast(providerVersion)), providerVersionLength + 1, nullptr); - - GUID providerId; - LPCWSTR providerIdStr; - size_t providerIdStrLength; - napi_get_value_string_utf16(env, argv[3], nullptr, 0, &providerIdStrLength); - providerIdStr = new WCHAR[providerIdStrLength + 1]; - napi_get_value_string_utf16(env, argv[3], reinterpret_cast(const_cast(providerIdStr)), providerIdStrLength + 1, nullptr); - - if (FAILED(CLSIDFromString(providerIdStr, &providerId))) - { - napi_throw_error(env, nullptr, "Invalid GUID format"); - delete[] syncRootPath; - delete[] providerName; - delete[] providerVersion; - delete[] providerIdStr; - return nullptr; - } - - LPCWSTR logoPath; - size_t logoPathLength; - napi_get_value_string_utf16(env, argv[4], nullptr, 0, &logoPathLength); - logoPath = new WCHAR[logoPathLength + 1]; - napi_get_value_string_utf16(env, argv[4], reinterpret_cast(const_cast(logoPath)), logoPathLength + 1, nullptr); - - HRESULT result = SyncRoot::RegisterSyncRoot(syncRootPath, providerName, providerVersion, providerId, logoPath); - - delete[] providerIdStr; - - napi_value napiResult; - napi_create_int32(env, static_cast(result), &napiResult); - return napiResult; -} diff --git a/native-src/virtual_drive/register_sync_root/register_sync_root_wrapper.cpp b/native-src/virtual_drive/register_sync_root/register_sync_root_wrapper.cpp index a697ec78..d9cc4132 100644 --- a/native-src/virtual_drive/register_sync_root/register_sync_root_wrapper.cpp +++ b/native-src/virtual_drive/register_sync_root/register_sync_root_wrapper.cpp @@ -1,35 +1,9 @@ #include +#include "napi_extract_args.h" #include "register_sync_root.h" -napi_value register_sync_root_wrapper(napi_env env, napi_callback_info args) { - size_t argc = 5; - napi_value argv[5]; - napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr); - - size_t syncRootPathLength; - napi_get_value_string_utf16(env, argv[0], nullptr, 0, &syncRootPathLength); - std::wstring syncRootPath(syncRootPathLength, L'\0'); - napi_get_value_string_utf16(env, argv[0], reinterpret_cast(&syncRootPath[0]), syncRootPathLength + 1, nullptr); - - size_t providerNameLength; - napi_get_value_string_utf16(env, argv[1], nullptr, 0, &providerNameLength); - std::wstring providerName(providerNameLength, L'\0'); - napi_get_value_string_utf16(env, argv[1], reinterpret_cast(&providerName[0]), providerNameLength + 1, nullptr); - - size_t providerVersionLength; - napi_get_value_string_utf16(env, argv[2], nullptr, 0, &providerVersionLength); - std::wstring providerVersion(providerVersionLength, L'\0'); - napi_get_value_string_utf16(env, argv[2], reinterpret_cast(&providerVersion[0]), providerVersionLength + 1, nullptr); - - size_t providerIdLength; - napi_get_value_string_utf16(env, argv[3], nullptr, 0, &providerIdLength); - std::wstring providerId(providerIdLength, L'\0'); - napi_get_value_string_utf16(env, argv[3], reinterpret_cast(&providerId[0]), providerIdLength + 1, nullptr); - - size_t logoPathLength; - napi_get_value_string_utf16(env, argv[4], nullptr, 0, &logoPathLength); - std::wstring logoPath(logoPathLength, L'\0'); - napi_get_value_string_utf16(env, argv[4], reinterpret_cast(&logoPath[0]), logoPathLength + 1, nullptr); +napi_value register_sync_root_wrapper(napi_env env, napi_callback_info info) { + auto [syncRootPath, providerName, providerVersion, providerId, logoPath] = napi_extract_args<5>(env, info); register_sync_root(syncRootPath.c_str(), providerName.c_str(), providerVersion.c_str(), providerId.c_str(), logoPath.c_str()); diff --git a/native-src/virtual_drive/unregister_sync_root_wrapper.cpp b/native-src/virtual_drive/unregister_sync_root_wrapper.cpp index b2ad4688..c6e04577 100644 --- a/native-src/virtual_drive/unregister_sync_root_wrapper.cpp +++ b/native-src/virtual_drive/unregister_sync_root_wrapper.cpp @@ -1,17 +1,11 @@ #include #include #include +#include "napi_extract_args.h" #include "stdafx.h" -napi_value unregister_sync_root_wrapper(napi_env env, napi_callback_info args) { - size_t argc = 1; - napi_value argv[1]; - napi_get_cb_info(env, args, &argc, argv, nullptr, nullptr); - - size_t providerIdLength; - napi_get_value_string_utf16(env, argv[0], nullptr, 0, &providerIdLength); - std::wstring providerId(providerIdLength, L'\0'); - napi_get_value_string_utf16(env, argv[0], reinterpret_cast(&providerId[0]), providerIdLength + 1, nullptr); +napi_value unregister_sync_root_wrapper(napi_env env, napi_callback_info info) { + auto [providerId] = napi_extract_args<1>(env, info); winrt::StorageProviderSyncRootManager::Unregister(providerId);