From e36971f84096e5309f8b148f21b5af22b7bf5594 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 23 Apr 2021 13:21:48 +0530 Subject: [PATCH] Avoid needing an extra array for RAII --- .../mtp/windows/content_enumeration.cpp | 10 +++---- .../mtp/windows/device_enumeration.cpp | 6 ++-- src/calibre/utils/cpp_binding.h | 28 +++++++++++++++++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/calibre/devices/mtp/windows/content_enumeration.cpp b/src/calibre/devices/mtp/windows/content_enumeration.cpp index 2907857d1a..93d94c5e9a 100644 --- a/src/calibre/devices/mtp/windows/content_enumeration.cpp +++ b/src/calibre/devices/mtp/windows/content_enumeration.cpp @@ -314,8 +314,6 @@ find_objects_in(CComPtr &content, CComPtr children; HRESULT hr = S_OK, hr2 = S_OK; - PWSTR child_ids[10]; - prop_variant pv(VT_LPWSTR); Py_BEGIN_ALLOW_THREADS; hr = content->EnumObjects(0, parent_id, NULL, &children); @@ -327,13 +325,13 @@ find_objects_in(CComPtr &content, CComPtr child_ids; Py_BEGIN_ALLOW_THREADS; - hr = children->Next(arraysz(child_ids), child_ids, &fetched); + hr = children->Next((ULONG)child_ids.size(), child_ids.ptr(), &fetched); Py_END_ALLOW_THREADS; if (SUCCEEDED(hr)) { - com_wchar_raii cleanup[arraysz(child_ids)]; - for(DWORD i = 0; i < fetched; i++) { cleanup[i].attach(child_ids[i]); } - for(DWORD i = 0; i < fetched; i++) { + for (DWORD i = 0; i < fetched; i++) { pv.pwszVal = child_ids[i]; hr2 = object_ids->Add(&pv); pv.pwszVal = NULL; diff --git a/src/calibre/devices/mtp/windows/device_enumeration.cpp b/src/calibre/devices/mtp/windows/device_enumeration.cpp index 98319a4fc4..addf854730 100644 --- a/src/calibre/devices/mtp/windows/device_enumeration.cpp +++ b/src/calibre/devices/mtp/windows/device_enumeration.cpp @@ -85,13 +85,11 @@ get_storage_info(IPortableDevice *device) { // {{{ hr = S_OK; while (hr == S_OK) { - wchar_t* object_ids[16] = {0}; + generic_raii_array object_ids; Py_BEGIN_ALLOW_THREADS; - hr = objects->Next(arraysz(object_ids), object_ids, &fetched); + hr = objects->Next((ULONG)object_ids.size(), object_ids.ptr(), &fetched); Py_END_ALLOW_THREADS; if (SUCCEEDED(hr)) { - com_wchar_raii cleanup[arraysz(object_ids)]; - for (i = 0; i < arraysz(object_ids); i++) { cleanup[i].attach(object_ids[i]); }; for(i = 0; i < fetched; i++) { CComPtr values; Py_BEGIN_ALLOW_THREADS; diff --git a/src/calibre/utils/cpp_binding.h b/src/calibre/utils/cpp_binding.h index d8ec8c31a8..359d0e4759 100644 --- a/src/calibre/utils/cpp_binding.h +++ b/src/calibre/utils/cpp_binding.h @@ -45,6 +45,34 @@ typedef generic_raii wchar_raii; static inline void python_object_destructor(void *p) { PyObject *x = reinterpret_cast(p); Py_XDECREF(x); } typedef generic_raii pyobject_raii; +template(NULL)> +class generic_raii_array { + private: + generic_raii_array( const generic_raii_array & ) noexcept; + generic_raii_array & operator=( const generic_raii_array & ) noexcept ; + + protected: + T array[sz]; + + public: + explicit generic_raii_array() noexcept : array() {} + ~generic_raii_array() noexcept { release(); } + + void release() noexcept { + for (size_t i = 0; i < sz; i++) { + if (array[i] != null) { + free_T(array[i]); + array[i] = null; + } + } + } + + T* ptr() noexcept { return reinterpret_cast(array); } + size_t size() const noexcept { return sz; } + T operator [](size_t i) noexcept { return array[i]; } + const T operator[](size_t i) const noexcept { return array[i]; } +}; + static inline int py_to_wchar(PyObject *obj, wchar_raii *output) {