Skip to content
Snippets Groups Projects
Commit 805ca9d3 authored by Sander Mathijs van Veen's avatar Sander Mathijs van Veen
Browse files

Refactoring and close buffer when read() returns an empty string.

parent 687b4238
No related branches found
No related tags found
No related merge requests found
......@@ -33,12 +33,14 @@
#define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0)
static PyObject *py_callback_hook_handler_name;
static PyObject *py_callback_hook_read_after_name;
static PyObject *py_callback_hook_read_before_name;
static PyObject *py_attr_hook_handler_name;
static PyObject *py_attr_hook_read_after_name;
static PyObject *py_attr_hook_read_before_name;
static PyObject *py_callback_handle_name;
static PyObject *py_callback_read_name;
static PyObject *py_attr_handle_name;
static PyObject *py_attr_read_name;
static PyObject *py_attr_file_name;
static PyObject *py_attr_close_name;
// Construct attribute names (only the first time)
// TODO: where do we Py_DECREF(handle_name) ??
......@@ -78,11 +80,11 @@ PyObject* py_callback(PyObject *parser, char *target, int option, int nargs,
va_end(ap);
INIT_ATTR(py_callback_handle_name, "_handle");
INIT_ATTR(py_callback_hook_handler_name, "hook_handler");
INIT_ATTR(py_attr_handle_name, "_handle");
INIT_ATTR(py_attr_hook_handler_name, "hook_handler");
// Call the handler with the arguments
PyObject *handle = PyObject_GetAttr(parser, py_callback_handle_name);
PyObject *handle = PyObject_GetAttr(parser, py_attr_handle_name);
if (unlikely(!handle)) return NULL;
......@@ -97,10 +99,10 @@ PyObject* py_callback(PyObject *parser, char *target, int option, int nargs,
if (unlikely(!res)) return res;
// Check if the "hook_handler" callback exists
if (unlikely(!PyObject_HasAttr(parser, py_callback_hook_handler_name)))
if (unlikely(!PyObject_HasAttr(parser, py_attr_hook_handler_name)))
return res;
handle = PyObject_GetAttr(parser, py_callback_hook_handler_name);
handle = PyObject_GetAttr(parser, py_attr_hook_handler_name);
if (unlikely(!handle)) {
Py_DECREF(res);
......@@ -124,14 +126,16 @@ void py_input(PyObject *parser, char *buf, int *result, int max_size)
PyObject *handle, *arglist, *res;
char *bufstr;
INIT_ATTR(py_callback_hook_read_after_name, "hook_read_after");
INIT_ATTR(py_callback_hook_read_before_name, "hook_read_before");
INIT_ATTR(py_callback_read_name, "read");
INIT_ATTR(py_attr_hook_read_after_name, "hook_read_after");
INIT_ATTR(py_attr_hook_read_before_name, "hook_read_before");
INIT_ATTR(py_attr_read_name, "read");
INIT_ATTR(py_attr_file_name, "file");
INIT_ATTR(py_attr_close_name, "close");
// Check if the "hook_READ_BEFORE" callback exists
if (unlikely(!PyObject_HasAttr(parser, py_callback_hook_read_before_name)))
if (unlikely(!PyObject_HasAttr(parser, py_attr_hook_read_before_name)))
{
handle = PyObject_GetAttr(parser, py_callback_hook_read_before_name);
handle = PyObject_GetAttr(parser, py_attr_hook_read_before_name);
if (unlikely(!handle)) return;
// Call the "hook_READ_BEFORE" callback
......@@ -145,7 +149,7 @@ void py_input(PyObject *parser, char *buf, int *result, int max_size)
}
// Read the input string and catch keyboard interrupt exceptions.
handle = PyObject_GetAttr(parser, py_callback_read_name);
handle = PyObject_GetAttr(parser, py_attr_read_name);
if (unlikely(!handle)) {
// TODO: set exception message for missing attribute error
return;
......@@ -162,10 +166,10 @@ void py_input(PyObject *parser, char *buf, int *result, int max_size)
if (unlikely(!res)) { return; }
// Check if the "hook_read_after" callback exists
if (unlikely(!PyObject_HasAttr(parser, py_callback_hook_read_after_name)))
if (unlikely(!PyObject_HasAttr(parser, py_attr_hook_read_after_name)))
goto finish_input;
handle = PyObject_GetAttr(parser, py_callback_hook_read_after_name);
handle = PyObject_GetAttr(parser, py_attr_hook_read_after_name);
if (unlikely(!handle)) return;
// Call the "hook_READ_AFTER" callback
......@@ -174,6 +178,7 @@ void py_input(PyObject *parser, char *buf, int *result, int max_size)
res = PyObject_CallObject(handle, arglist);
Py_DECREF(res);
Py_DECREF(handle);
Py_DECREF(arglist);
......@@ -186,10 +191,28 @@ finish_input:
*result = strlen(bufstr);
memcpy(buf, bufstr, *result);
// TODO: translate the following code snippet to the Python C aPI
//if buflen == 0 and parser.file:
// # Marks the Python file object as being closed from Python's point of
// # view. This does not close the associated C stream (which is not
// # necessary here, otherwise use "os.close(0)").
// parser.file.close()
// Close the read buffer if nothing is read. Marks the Python file object
// as being closed from Python's point of view. This does not close the
// associated C stream (which is not necessary here, otherwise use
// "os.close(0)").
if (!*result && PyObject_HasAttr(parser, py_attr_file_name)) {
PyObject *file_handle = PyObject_GetAttr(parser, py_attr_file_name);
if (unlikely(!file_handle)) return;
handle = PyObject_GetAttr(file_handle, py_attr_close_name);
Py_DECREF(file_handle);
if (unlikely(!handle)) return;
arglist = PyTuple_New(0);
if (unlikely(!arglist)) { Py_DECREF(handle); return; }
res = PyObject_CallObject(handle, arglist);
Py_DECREF(res);
Py_DECREF(handle);
Py_DECREF(arglist);
// TODO: something went wrong while closing the buffer.
if (unlikely(!res)) return;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment