summaryrefslogtreecommitdiffstats
path: root/python/hashstringlist.cc
diff options
context:
space:
mode:
Diffstat (limited to 'python/hashstringlist.cc')
-rw-r--r--python/hashstringlist.cc220
1 files changed, 220 insertions, 0 deletions
diff --git a/python/hashstringlist.cc b/python/hashstringlist.cc
new file mode 100644
index 0000000..f25f502
--- /dev/null
+++ b/python/hashstringlist.cc
@@ -0,0 +1,220 @@
+/* hashstringlist.cc - Wrapper around apt-pkg's Hashes.
+ *
+ * Copyright 2015 Julian Andres Klode <jak@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <Python.h>
+#include "generic.h"
+#include "apt_pkgmodule.h"
+#include <apt-pkg/hashes.h>
+
+static PyObject *hashstringlist_new(PyTypeObject *type, PyObject *args,
+ PyObject *kwds)
+{
+ return CppPyObject_NEW<HashStringList> (nullptr, type);
+}
+
+static int hashstringlist_init(PyObject *self, PyObject *args,
+ PyObject *kwds)
+{
+ char *kwlist[] = { NULL };
+
+ if (PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist) == 0)
+ return -1;
+
+ return 0;
+}
+
+
+static const char hashstringlist_find_doc[] =
+ "find(type: str = \"\") -> HashString\n\n"
+ "Find a hash of the given type, or the best one, if the argument\n"
+ "is empty or not specified.";
+static PyObject *hashstringlist_find(PyObject *self, PyObject *args)
+{
+ char *type = "";
+
+ if (PyArg_ParseTuple(args, "|s", &type) == 0)
+ return 0;
+
+ const HashString *hsf = GetCpp<HashStringList>(self).find(type);
+ if (hsf == nullptr)
+ return PyErr_Format(PyExc_KeyError, "Could not find hash type %s", type);
+
+
+ return HandleErrors(PyHashString_FromCpp(new HashString(*hsf), true, nullptr));
+}
+
+static const char hashstringlist_append_doc[] =
+ "append(object: HashString)\n\n"
+ "Append the given HashString to this list.";
+static PyObject *hashstringlist_append(PyObject *self, PyObject *args)
+{
+ PyObject *o;
+
+ if (PyArg_ParseTuple(args, "O!", &PyHashString_Type, &o) == 0)
+ return 0;
+
+ GetCpp<HashStringList>(self).push_back(*PyHashString_ToCpp(o));
+ Py_RETURN_NONE;
+}
+
+static const char hashstringlist_verify_file_doc[] =
+ "verify_file(filename: str) -> bool\n\n"
+ "Verify that the file with the given name matches all hashes in\n"
+ "the list.";
+static PyObject *hashstringlist_verify_file(PyObject *self, PyObject *args)
+{
+ PyApt_Filename filename;
+
+ if (PyArg_ParseTuple(args, "O&", PyApt_Filename::Converter, &filename) == 0)
+ return 0;
+
+ bool res = GetCpp<HashStringList>(self).VerifyFile(filename);
+
+ PyObject *PyRes = PyBool_FromLong(res);
+ return HandleErrors(PyRes);
+}
+
+static PyObject *hashstringlist_get_file_size(PyObject *self, void*) {
+ return MkPyNumber(GetCpp<HashStringList>(self).FileSize());
+}
+static PyObject *hashstringlist_get_usable(PyObject *self, void*) {
+ return PyBool_FromLong(GetCpp<HashStringList>(self).usable());
+}
+
+static int hashstringlist_set_file_size(PyObject *self, PyObject *value, void *) {
+ if (PyLong_Check(value)) {
+ if (PyLong_AsUnsignedLongLong(value) == (unsigned long long) -1) {
+ return 1;
+ }
+ GetCpp<HashStringList>(self).FileSize(PyLong_AsUnsignedLongLong(value));
+ } else if (PyInt_Check(value)) {
+ if (PyInt_AsLong(value) < 0) {
+ if (!PyErr_Occurred())
+ PyErr_SetString(PyExc_OverflowError,
+ "The file_size value must be positive");
+ return 1;
+ }
+ GetCpp<HashStringList>(self).FileSize(PyInt_AsLong(value));
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "The file_size value must be an integer or long");
+ return 1;
+ }
+
+ return 0;
+}
+
+/* The same for groups */
+static Py_ssize_t hashstringlist_len(PyObject *self)
+{
+ return GetCpp <HashStringList>(self).size();
+}
+
+static PyObject *hashstringlist_getitem(PyObject *iSelf, Py_ssize_t index)
+{
+ HashStringList &self = GetCpp<HashStringList>(iSelf);
+
+ if (index < 0 || (size_t) index >= self.size())
+ return PyErr_Format(PyExc_IndexError, "Out of range: %zd", index);
+
+ /* Copy over, safer than using a reference to the vector element */
+ HashString *hs = new HashString;
+ (*hs) = *(self.begin() + index);
+
+ return PyHashString_FromCpp(hs, true, nullptr);
+}
+
+static PySequenceMethods hashstringlist_seq_methods = {
+ hashstringlist_len,
+ 0, // concat
+ 0, // repeat
+ hashstringlist_getitem,
+ 0, // slice
+ 0, // assign item
+ 0 // assign slice
+};
+
+static PyMethodDef hashstringlist_methods[] =
+{
+ {"verify_file",hashstringlist_verify_file,METH_VARARGS,
+ hashstringlist_verify_file_doc},
+ {"find",hashstringlist_find,METH_VARARGS,
+ hashstringlist_find_doc},
+ {"append",hashstringlist_append,METH_VARARGS,
+ hashstringlist_append_doc},
+ {}
+};
+
+static PyGetSetDef hashstringlist_getset[] = {
+ {"file_size",hashstringlist_get_file_size,hashstringlist_set_file_size,
+ "If a file size is part of the list, return it, otherwise 0."},
+ {"usable",hashstringlist_get_usable,nullptr,
+ "True if at least one safe/trusted hash is in the list."},
+ {}
+};
+
+
+static char *hashstringlist_doc =
+ "HashStringList()\n\n"
+ "Manage a list of HashStrings.\n\n"
+ "The list knows which hash is the best and provides convenience\n"
+ "methods for file verification.\n\n"
+ ".. versionadded:: 1.1";
+
+PyTypeObject PyHashStringList_Type = {
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "apt_pkg.HashStringList", // tp_name
+ sizeof(CppPyObject<HashStringList>), // tp_basicsize
+ 0, // tp_itemsize
+ // Methods
+ CppDealloc<HashStringList>, // tp_dealloc
+ 0, // tp_print
+ 0, // tp_getattr
+ 0, // tp_setattr
+ 0, // tp_compare
+ 0, // tp_repr
+ 0, // tp_as_number
+ &hashstringlist_seq_methods, // tp_as_sequence
+ 0, // tp_as_mapping
+ 0, // tp_hash
+ 0, // tp_call
+ 0, // tp_str
+ 0, // tp_getattro
+ 0, // tp_setattro
+ 0, // tp_as_buffer
+ Py_TPFLAGS_DEFAULT, // tp_flags
+ hashstringlist_doc, // tp_doc
+ 0, // tp_traverse
+ 0, // tp_clear
+ 0, // tp_richcompare
+ 0, // tp_weaklistoffset
+ 0, // tp_iter
+ 0, // tp_iternext
+ hashstringlist_methods, // tp_methods
+ 0, // tp_members
+ hashstringlist_getset, // tp_getset
+ 0, // tp_base
+ 0, // tp_dict
+ 0, // tp_descr_get
+ 0, // tp_descr_set
+ 0, // tp_dictoffset
+ hashstringlist_init, // tp_init
+ 0, // tp_alloc
+ hashstringlist_new, // tp_new
+};