Avoid needing an extra array for RAII

This commit is contained in:
Kovid Goyal 2021-04-23 13:21:48 +05:30
parent ddc405a337
commit e36971f840
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 34 additions and 10 deletions

View File

@ -314,8 +314,6 @@ find_objects_in(CComPtr<IPortableDeviceContent> &content, CComPtr<IPortableDevic
*/
CComPtr<IEnumPortableDeviceObjectIDs> 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<IPortableDeviceContent> &content, CComPtr<IPortableDevic
while (hr == S_OK) {
DWORD fetched;
prop_variant pv(VT_LPWSTR);
generic_raii_array<wchar_t*, CoTaskMemFree, 16> 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;

View File

@ -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<wchar_t*, CoTaskMemFree, 16> 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<IPortableDeviceValues> values;
Py_BEGIN_ALLOW_THREADS;

View File

@ -45,6 +45,34 @@ typedef generic_raii<wchar_t*, PyMem_Free> wchar_raii;
static inline void python_object_destructor(void *p) { PyObject *x = reinterpret_cast<PyObject*>(p); Py_XDECREF(x); }
typedef generic_raii<PyObject*, python_object_destructor> pyobject_raii;
template<typename T, void free_T(void*), size_t sz, T null=reinterpret_cast<T>(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<T*>(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) {