mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
DRYer
This commit is contained in:
parent
10e5697740
commit
902f25985b
@ -116,6 +116,7 @@
|
||||
},
|
||||
{
|
||||
"name": "fast_css_transform",
|
||||
"headers": "calibre/utils/cpp_binding.h",
|
||||
"sources": "calibre/srv/fast_css_transform.cpp",
|
||||
"inc_dirs": "perfect-hashing",
|
||||
"needs_c++14": true
|
||||
@ -145,7 +146,7 @@
|
||||
{
|
||||
"name": "winutil",
|
||||
"only": "windows",
|
||||
"headers": "calibre/utils/windows/common.h",
|
||||
"headers": "calibre/utils/cpp_binding.h calibre/utils/windows/common.h",
|
||||
"sources": "calibre/utils/windows/winutil.cpp",
|
||||
"libraries": "shell32 wininet advapi32",
|
||||
"cflags": "/X"
|
||||
@ -153,7 +154,7 @@
|
||||
{
|
||||
"name": "winsapi",
|
||||
"only": "windows",
|
||||
"headers": "calibre/utils/windows/common.h",
|
||||
"headers": "calibre/utils/cpp_binding.h calibre/utils/windows/common.h",
|
||||
"sources": "calibre/utils/windows/winsapi.cpp",
|
||||
"libraries": "SAPI Ole32",
|
||||
"cflags": "/X"
|
||||
@ -162,7 +163,7 @@
|
||||
"name": "wpd",
|
||||
"only": "windows",
|
||||
"sources": "calibre/devices/mtp/windows/utils.cpp calibre/devices/mtp/windows/device_enumeration.cpp calibre/devices/mtp/windows/content_enumeration.cpp calibre/devices/mtp/windows/device.cpp calibre/devices/mtp/windows/wpd.cpp",
|
||||
"headers": "calibre/devices/mtp/windows/global.h calibre/utils/windows/common.h",
|
||||
"headers": "calibre/utils/cpp_binding.h calibre/devices/mtp/windows/global.h calibre/utils/windows/common.h",
|
||||
"libraries": "ole32 oleaut32 portabledeviceguids user32",
|
||||
"cflags": "/X"
|
||||
},
|
||||
|
@ -127,7 +127,7 @@ get_storage_info(IPortableDevice *device) { // {{{
|
||||
Py_END_ALLOW_THREADS;
|
||||
if (SUCCEEDED(hr)) {
|
||||
com_wchar_raii cleanup[arraysz(object_ids)];
|
||||
for (i = 0; i < arraysz(object_ids); i++) { cleanup[i].set_ptr(object_ids[i]); };
|
||||
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;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <codecvt>
|
||||
#include <frozen/unordered_map.h>
|
||||
#include <frozen/string.h>
|
||||
#include "../utils/cpp_binding.h"
|
||||
|
||||
// character classes {{{
|
||||
static inline bool
|
||||
@ -78,25 +79,6 @@ class python_error : public std::runtime_error {
|
||||
python_error(const char *msg) : std::runtime_error(msg) {}
|
||||
};
|
||||
|
||||
class pyobject_raii {
|
||||
private:
|
||||
PyObject *handle;
|
||||
pyobject_raii( const pyobject_raii & ) ;
|
||||
pyobject_raii & operator=( const pyobject_raii & ) ;
|
||||
|
||||
public:
|
||||
pyobject_raii() : handle(NULL) {}
|
||||
pyobject_raii(PyObject* h, bool incref=false) : handle(h) { if (incref && handle) Py_INCREF(handle); }
|
||||
|
||||
~pyobject_raii() { Py_CLEAR(handle); }
|
||||
|
||||
PyObject *ptr() { return handle; }
|
||||
void set_ptr(PyObject *val) { handle = val; }
|
||||
PyObject **address() { return &handle; }
|
||||
explicit operator bool() const { return handle != NULL; }
|
||||
PyObject *detach() { PyObject *ans = handle; handle = NULL; return ans; }
|
||||
};
|
||||
|
||||
// Parse numbers {{{
|
||||
|
||||
typedef long long integer_type;
|
||||
@ -670,9 +652,10 @@ class TokenQueue {
|
||||
}
|
||||
|
||||
public:
|
||||
TokenQueue(const size_t src_sz, PyObject *url_callback=NULL) :
|
||||
pool(), queue(), out(), scratch(), scratch2(), url_callback(url_callback, true) {
|
||||
TokenQueue(const size_t src_sz, PyObject *url_callback_pointer=NULL) :
|
||||
pool(), queue(), out(), scratch(), scratch2(), url_callback(url_callback_pointer) {
|
||||
out.reserve(src_sz * 2); scratch.reserve(16); scratch2.reserve(16);
|
||||
Py_XINCREF(url_callback.ptr());
|
||||
}
|
||||
|
||||
void rewind_output() { out.pop_back(); }
|
||||
|
71
src/calibre/utils/cpp_binding.h
Normal file
71
src/calibre/utils/cpp_binding.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#define UNICODE
|
||||
#define _UNICODE
|
||||
#include <Python.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#define arraysz(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
template<typename T, void free_T(void*), T null=reinterpret_cast<T>(NULL)>
|
||||
class generic_raii {
|
||||
private:
|
||||
T handle;
|
||||
generic_raii( const generic_raii & ) ;
|
||||
generic_raii & operator=( const generic_raii & ) ;
|
||||
|
||||
public:
|
||||
explicit generic_raii(T h = null) : handle(h) {}
|
||||
~generic_raii() { release(); }
|
||||
|
||||
void release() {
|
||||
if (handle != null) {
|
||||
free_T(handle);
|
||||
handle = null;
|
||||
}
|
||||
}
|
||||
|
||||
T ptr() { return handle; }
|
||||
T detach() { T ans = handle; handle = null; return ans; }
|
||||
void attach(T val) { release(); handle = val; }
|
||||
T* address() { return &handle; }
|
||||
explicit operator bool() const { return handle != null; }
|
||||
T* operator &() { return &handle; }
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
|
||||
static inline int
|
||||
py_to_wchar(PyObject *obj, wchar_raii *output) {
|
||||
if (!PyUnicode_Check(obj)) {
|
||||
if (obj == Py_None) { return 1; }
|
||||
PyErr_SetString(PyExc_TypeError, "unicode object expected");
|
||||
return 0;
|
||||
}
|
||||
wchar_t *buf = PyUnicode_AsWideCharString(obj, NULL);
|
||||
if (!buf) { PyErr_NoMemory(); return 0; }
|
||||
output->attach(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
py_to_wchar_no_none(PyObject *obj, wchar_raii *output) {
|
||||
if (!PyUnicode_Check(obj)) {
|
||||
PyErr_SetString(PyExc_TypeError, "unicode object expected");
|
||||
return 0;
|
||||
}
|
||||
wchar_t *buf = PyUnicode_AsWideCharString(obj, NULL);
|
||||
if (!buf) { PyErr_NoMemory(); return 0; }
|
||||
output->attach(buf);
|
||||
return 1;
|
||||
}
|
@ -11,7 +11,7 @@
|
||||
#include <Windows.h>
|
||||
#include <Python.h>
|
||||
#include <comdef.h>
|
||||
#define arraysz(x) (sizeof(x)/sizeof(x[0]))
|
||||
#include "../cpp_binding.h"
|
||||
|
||||
static inline PyObject*
|
||||
set_error_from_hresult(PyObject *exc_type, const char *file, const int line, const HRESULT hr, const char *prefix="", PyObject *name=NULL) {
|
||||
@ -24,61 +24,6 @@ set_error_from_hresult(PyObject *exc_type, const char *file, const int line, con
|
||||
}
|
||||
#define error_from_hresult(hr, ...) set_error_from_hresult(PyExc_OSError, __FILE__, __LINE__, hr, __VA_ARGS__)
|
||||
|
||||
template<typename T, void free_T(void*), T null>
|
||||
class generic_raii {
|
||||
private:
|
||||
T handle;
|
||||
generic_raii( const generic_raii & ) ;
|
||||
generic_raii & operator=( const generic_raii & ) ;
|
||||
|
||||
public:
|
||||
explicit generic_raii(T h = null) : handle(h) {}
|
||||
~generic_raii() { release(); }
|
||||
|
||||
void release() {
|
||||
if (handle != null) {
|
||||
free_T(handle);
|
||||
handle = null;
|
||||
}
|
||||
}
|
||||
|
||||
T ptr() { return handle; }
|
||||
T detach() { T ans = handle; handle = null; return ans; }
|
||||
void set_ptr(T val) { handle = val; }
|
||||
T* address() { return &handle; }
|
||||
explicit operator bool() const { return handle != null; }
|
||||
T* operator &() { return &handle; }
|
||||
};
|
||||
|
||||
typedef generic_raii<wchar_t*, PyMem_Free, NULL> wchar_raii;
|
||||
typedef generic_raii<wchar_t*, CoTaskMemFree, NULL> com_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, NULL> pyobject_raii;
|
||||
static inline void handle_destructor(HANDLE p) { CloseHandle(p); }
|
||||
typedef generic_raii<HANDLE, handle_destructor, INVALID_HANDLE_VALUE> handle_raii;
|
||||
|
||||
|
||||
static int
|
||||
py_to_wchar(PyObject *obj, wchar_raii *output) {
|
||||
if (!PyUnicode_Check(obj)) {
|
||||
if (obj == Py_None) { return 1; }
|
||||
PyErr_SetString(PyExc_TypeError, "unicode object expected");
|
||||
return 0;
|
||||
}
|
||||
wchar_t *buf = PyUnicode_AsWideCharString(obj, NULL);
|
||||
if (!buf) { PyErr_NoMemory(); return 0; }
|
||||
output->set_ptr(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
py_to_wchar_no_none(PyObject *obj, wchar_raii *output) {
|
||||
if (!PyUnicode_Check(obj)) {
|
||||
PyErr_SetString(PyExc_TypeError, "unicode object expected");
|
||||
return 0;
|
||||
}
|
||||
wchar_t *buf = PyUnicode_AsWideCharString(obj, NULL);
|
||||
if (!buf) { PyErr_NoMemory(); return 0; }
|
||||
output->set_ptr(buf);
|
||||
return 1;
|
||||
}
|
||||
|
@ -832,8 +832,7 @@ get_long_path_name(PyObject *self, PyObject *args) {
|
||||
Py_END_ALLOW_THREADS
|
||||
if (needed_size >= current_size - 32) {
|
||||
current_size = needed_size + 32;
|
||||
PyMem_Free(buf.ptr());
|
||||
buf.set_ptr((wchar_t*)PyMem_Malloc(current_size * sizeof(wchar_t)));
|
||||
buf.attach((wchar_t*)PyMem_Malloc(current_size * sizeof(wchar_t)));
|
||||
if (!buf) return PyErr_NoMemory();
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
needed_size = GetLongPathNameW(path.ptr(), buf.ptr(), current_size);
|
||||
|
Loading…
x
Reference in New Issue
Block a user