From 3538b0aa88af689284d7d2e84b9f1f375b909ff2 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 31 Jul 2019 18:05:19 +0530 Subject: [PATCH 33/71] Cleanup conversion of python strings to podofo strings --- src/calibre/utils/podofo/doc.cpp | 40 +++++++++++----------------- src/calibre/utils/podofo/global.h | 11 +++----- src/calibre/utils/podofo/outline.cpp | 14 +++++----- src/calibre/utils/podofo/utils.cpp | 30 ++++++++------------- 4 files changed, 38 insertions(+), 57 deletions(-) diff --git a/src/calibre/utils/podofo/doc.cpp b/src/calibre/utils/podofo/doc.cpp index 8eb48d97f9..60bb6d69b9 100644 --- a/src/calibre/utils/podofo/doc.cpp +++ b/src/calibre/utils/podofo/doc.cpp @@ -243,35 +243,35 @@ static PyObject * PDFDoc_create_outline(PDFDoc *self, PyObject *args) { PyObject *p; PDFOutlineItem *ans; - PdfString *title; int pagenum; if (!PyArg_ParseTuple(args, "Ui", &p, &pagenum)) return NULL; - title = podofo_convert_pystring(p); - if (title == NULL) return NULL; ans = PyObject_New(PDFOutlineItem, &PDFOutlineItemType); if (ans == NULL) goto error; try { + const PdfString title = podofo_convert_pystring(p); PdfOutlines *outlines = self->doc->GetOutlines(); if (outlines == NULL) {PyErr_NoMemory(); goto error;} - ans->item = outlines->CreateRoot(*title); + ans->item = outlines->CreateRoot(title); if (ans->item == NULL) {PyErr_NoMemory(); goto error;} ans->doc = self->doc; PdfDestination dest(self->doc->GetPage(pagenum)); ans->item->SetDestination(dest); } catch(const PdfError & err) { podofo_set_exception(err); goto error; + } catch(const std::exception & err) { + PyErr_Format(PyExc_ValueError, "An error occurred while trying to create the outline: %s", err.what()); + goto error; } catch (...) { PyErr_SetString(PyExc_ValueError, "An unknown error occurred while trying to create the outline"); goto error; } - delete title; return (PyObject*)ans; error: - Py_XDECREF(ans); delete title; + Py_XDECREF(ans); return NULL; } // }}} @@ -427,33 +427,25 @@ PDFDoc_setter(PDFDoc *self, PyObject *val, int field) { PyErr_SetString(PyExc_ValueError, "Must use unicode objects to set metadata"); return -1; } - PdfInfo *info = new PdfInfo(*self->doc->GetInfo()); - if (info == NULL) { - PyErr_SetString(PyExc_Exception, "You must first load a PDF Document"); - return -1; - } - PdfString *s = NULL; - - if (self->doc->GetEncrypted()) s = podofo_convert_pystring_single_byte(val); - else s = podofo_convert_pystring(val); - if (s == NULL) return -1; - + PdfInfo *info = self->doc->GetInfo(); + if (!info) { PyErr_SetString(Error, "You must first load a PDF Document"); return -1; } + const PdfString s = podofo_convert_pystring(val); switch (field) { case 0: - info->SetTitle(*s); break; + info->SetTitle(s); break; case 1: - info->SetAuthor(*s); break; + info->SetAuthor(s); break; case 2: - info->SetSubject(*s); break; + info->SetSubject(s); break; case 3: - info->SetKeywords(*s); break; + info->SetKeywords(s); break; case 4: - info->SetCreator(*s); break; + info->SetCreator(s); break; case 5: - info->SetProducer(*s); break; + info->SetProducer(s); break; default: - PyErr_SetString(PyExc_Exception, "Bad field"); + PyErr_SetString(Error, "Bad field"); return -1; } diff --git a/src/calibre/utils/podofo/global.h b/src/calibre/utils/podofo/global.h index 4a180d86a0..6d97159c18 100644 --- a/src/calibre/utils/podofo/global.h +++ b/src/calibre/utils/podofo/global.h @@ -37,11 +37,8 @@ extern PyTypeObject PDFOutlineItemType; extern PyObject *Error; // Utilities -extern void podofo_set_exception(const PdfError &err); -extern PyObject * podofo_convert_pdfstring(const PdfString &s); -extern PdfString * podofo_convert_pystring(PyObject *py); -extern PdfString * podofo_convert_pystring_single_byte(PyObject *py); -extern PyObject* write_doc(PdfMemDocument *doc, PyObject *f); - +void podofo_set_exception(const PdfError &err); +PyObject * podofo_convert_pdfstring(const PdfString &s); +const PdfString podofo_convert_pystring(PyObject *py); +PyObject* write_doc(PdfMemDocument *doc, PyObject *f); } - diff --git a/src/calibre/utils/podofo/outline.cpp b/src/calibre/utils/podofo/outline.cpp index 01a3b186d9..d7a4d8a79b 100644 --- a/src/calibre/utils/podofo/outline.cpp +++ b/src/calibre/utils/podofo/outline.cpp @@ -47,36 +47,36 @@ create(PDFOutlineItem *self, PyObject *args) { PyObject *ptitle, *as_child = NULL; PDFOutlineItem *ans; int num; - PdfString *title; PdfPage *page; if (!PyArg_ParseTuple(args, "Ui|O", &ptitle, &num, &as_child)) return NULL; - title = podofo_convert_pystring(ptitle); - if (title == NULL) return NULL; ans = PyObject_New(PDFOutlineItem, &PDFOutlineItemType); if (ans == NULL) goto error; ans->doc = self->doc; try { + const PdfString title = podofo_convert_pystring(ptitle); page = self->doc->GetPage(num); if (page == NULL) { PyErr_Format(PyExc_ValueError, "Invalid page number: %d", num); goto error; } PdfDestination dest(page); if (as_child != NULL && PyObject_IsTrue(as_child)) { - ans->item = self->item->CreateChild(*title, dest); + ans->item = self->item->CreateChild(title, dest); } else - ans->item = self->item->CreateNext(*title, dest); + ans->item = self->item->CreateNext(title, dest); } catch (const PdfError &err) { podofo_set_exception(err); goto error; + } catch(const std::exception & err) { + PyErr_Format(PyExc_ValueError, "An error occurred while trying to create the outline: %s", err.what()); + goto error; } catch (...) { PyErr_SetString(PyExc_Exception, "An unknown error occurred while trying to create the outline item"); goto error; } - delete title; return (PyObject*) ans; error: - Py_XDECREF(ans); delete title; + Py_XDECREF(ans); return NULL; } diff --git a/src/calibre/utils/podofo/utils.cpp b/src/calibre/utils/podofo/utils.cpp index 6ecf1ec7fd..830fc5052e 100644 --- a/src/calibre/utils/podofo/utils.cpp +++ b/src/calibre/utils/podofo/utils.cpp @@ -28,23 +28,15 @@ pdf::podofo_convert_pdfstring(const PdfString &s) { return PyUnicode_FromString(s.GetStringUtf8().c_str()); } -PdfString * -pdf::podofo_convert_pystring(PyObject *py) { - PyObject *u8 = PyUnicode_AsEncodedString(py, "UTF-8", "replace"); - if (u8 == NULL) { return NULL; } - pdf_utf8 *s8 = reinterpret_cast(PyBytes_AS_STRING(u8)); - PdfString *ans = new PdfString(s8); - Py_DECREF(u8); - if (ans == NULL) PyErr_NoMemory(); - return ans; -} - -PdfString * -pdf::podofo_convert_pystring_single_byte(PyObject *py) { - PyObject *s = PyUnicode_AsEncodedString(py, "cp1252", "replace"); - if (s == NULL) { return NULL; } - PdfString *ans = new PdfString(PyBytes_AS_STRING(s)); - Py_DECREF(s); - if (ans == NULL) PyErr_NoMemory(); - return ans; +const PdfString +pdf::podofo_convert_pystring(PyObject *val) { +#if PY_MAJOR_VERSION > 2 + return s(reinterpret_cast(PyUnicode_AsUTF8(val))); +#else + PyObject *temp = PyUnicode_AsUTF8String(val); + if (!temp) throw std::bad_alloc(); + PdfString s(reinterpret_cast(PyBytes_AS_STRING(temp))); + Py_DECREF(temp); + return s; +#endif }