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",
|
"name": "fast_css_transform",
|
||||||
|
"headers": "calibre/utils/cpp_binding.h",
|
||||||
"sources": "calibre/srv/fast_css_transform.cpp",
|
"sources": "calibre/srv/fast_css_transform.cpp",
|
||||||
"inc_dirs": "perfect-hashing",
|
"inc_dirs": "perfect-hashing",
|
||||||
"needs_c++14": true
|
"needs_c++14": true
|
||||||
@ -145,7 +146,7 @@
|
|||||||
{
|
{
|
||||||
"name": "winutil",
|
"name": "winutil",
|
||||||
"only": "windows",
|
"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",
|
"sources": "calibre/utils/windows/winutil.cpp",
|
||||||
"libraries": "shell32 wininet advapi32",
|
"libraries": "shell32 wininet advapi32",
|
||||||
"cflags": "/X"
|
"cflags": "/X"
|
||||||
@ -153,7 +154,7 @@
|
|||||||
{
|
{
|
||||||
"name": "winsapi",
|
"name": "winsapi",
|
||||||
"only": "windows",
|
"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",
|
"sources": "calibre/utils/windows/winsapi.cpp",
|
||||||
"libraries": "SAPI Ole32",
|
"libraries": "SAPI Ole32",
|
||||||
"cflags": "/X"
|
"cflags": "/X"
|
||||||
@ -162,7 +163,7 @@
|
|||||||
"name": "wpd",
|
"name": "wpd",
|
||||||
"only": "windows",
|
"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",
|
"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",
|
"libraries": "ole32 oleaut32 portabledeviceguids user32",
|
||||||
"cflags": "/X"
|
"cflags": "/X"
|
||||||
},
|
},
|
||||||
|
@ -127,7 +127,7 @@ get_storage_info(IPortableDevice *device) { // {{{
|
|||||||
Py_END_ALLOW_THREADS;
|
Py_END_ALLOW_THREADS;
|
||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
com_wchar_raii cleanup[arraysz(object_ids)];
|
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++) {
|
for(i = 0; i < fetched; i++) {
|
||||||
CComPtr<IPortableDeviceValues> values;
|
CComPtr<IPortableDeviceValues> values;
|
||||||
Py_BEGIN_ALLOW_THREADS;
|
Py_BEGIN_ALLOW_THREADS;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
#include <frozen/unordered_map.h>
|
#include <frozen/unordered_map.h>
|
||||||
#include <frozen/string.h>
|
#include <frozen/string.h>
|
||||||
|
#include "../utils/cpp_binding.h"
|
||||||
|
|
||||||
// character classes {{{
|
// character classes {{{
|
||||||
static inline bool
|
static inline bool
|
||||||
@ -78,25 +79,6 @@ class python_error : public std::runtime_error {
|
|||||||
python_error(const char *msg) : std::runtime_error(msg) {}
|
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 {{{
|
// Parse numbers {{{
|
||||||
|
|
||||||
typedef long long integer_type;
|
typedef long long integer_type;
|
||||||
@ -670,9 +652,10 @@ class TokenQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TokenQueue(const size_t src_sz, PyObject *url_callback=NULL) :
|
TokenQueue(const size_t src_sz, PyObject *url_callback_pointer=NULL) :
|
||||||
pool(), queue(), out(), scratch(), scratch2(), url_callback(url_callback, true) {
|
pool(), queue(), out(), scratch(), scratch2(), url_callback(url_callback_pointer) {
|
||||||
out.reserve(src_sz * 2); scratch.reserve(16); scratch2.reserve(16);
|
out.reserve(src_sz * 2); scratch.reserve(16); scratch2.reserve(16);
|
||||||
|
Py_XINCREF(url_callback.ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
void rewind_output() { out.pop_back(); }
|
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 <Windows.h>
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <comdef.h>
|
#include <comdef.h>
|
||||||
#define arraysz(x) (sizeof(x)/sizeof(x[0]))
|
#include "../cpp_binding.h"
|
||||||
|
|
||||||
static inline PyObject*
|
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) {
|
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__)
|
#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;
|
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); }
|
static inline void handle_destructor(HANDLE p) { CloseHandle(p); }
|
||||||
typedef generic_raii<HANDLE, handle_destructor, INVALID_HANDLE_VALUE> handle_raii;
|
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
|
Py_END_ALLOW_THREADS
|
||||||
if (needed_size >= current_size - 32) {
|
if (needed_size >= current_size - 32) {
|
||||||
current_size = needed_size + 32;
|
current_size = needed_size + 32;
|
||||||
PyMem_Free(buf.ptr());
|
buf.attach((wchar_t*)PyMem_Malloc(current_size * sizeof(wchar_t)));
|
||||||
buf.set_ptr((wchar_t*)PyMem_Malloc(current_size * sizeof(wchar_t)));
|
|
||||||
if (!buf) return PyErr_NoMemory();
|
if (!buf) return PyErr_NoMemory();
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
needed_size = GetLongPathNameW(path.ptr(), buf.ptr(), current_size);
|
needed_size = GetLongPathNameW(path.ptr(), buf.ptr(), current_size);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user