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 @@ ...@@ -33,12 +33,14 @@
#define likely(x) __builtin_expect((x),1) #define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0) #define unlikely(x) __builtin_expect((x),0)
static PyObject *py_callback_hook_handler_name; static PyObject *py_attr_hook_handler_name;
static PyObject *py_callback_hook_read_after_name; static PyObject *py_attr_hook_read_after_name;
static PyObject *py_callback_hook_read_before_name; static PyObject *py_attr_hook_read_before_name;
static PyObject *py_callback_handle_name; static PyObject *py_attr_handle_name;
static PyObject *py_callback_read_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) // Construct attribute names (only the first time)
// TODO: where do we Py_DECREF(handle_name) ?? // TODO: where do we Py_DECREF(handle_name) ??
...@@ -78,11 +80,11 @@ PyObject* py_callback(PyObject *parser, char *target, int option, int nargs, ...@@ -78,11 +80,11 @@ PyObject* py_callback(PyObject *parser, char *target, int option, int nargs,
va_end(ap); va_end(ap);
INIT_ATTR(py_callback_handle_name, "_handle"); INIT_ATTR(py_attr_handle_name, "_handle");
INIT_ATTR(py_callback_hook_handler_name, "hook_handler"); INIT_ATTR(py_attr_hook_handler_name, "hook_handler");
// Call the handler with the arguments // 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; if (unlikely(!handle)) return NULL;
...@@ -97,10 +99,10 @@ PyObject* py_callback(PyObject *parser, char *target, int option, int nargs, ...@@ -97,10 +99,10 @@ PyObject* py_callback(PyObject *parser, char *target, int option, int nargs,
if (unlikely(!res)) return res; if (unlikely(!res)) return res;
// Check if the "hook_handler" callback exists // 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; return res;
handle = PyObject_GetAttr(parser, py_callback_hook_handler_name); handle = PyObject_GetAttr(parser, py_attr_hook_handler_name);
if (unlikely(!handle)) { if (unlikely(!handle)) {
Py_DECREF(res); Py_DECREF(res);
...@@ -124,14 +126,16 @@ void py_input(PyObject *parser, char *buf, int *result, int max_size) ...@@ -124,14 +126,16 @@ void py_input(PyObject *parser, char *buf, int *result, int max_size)
PyObject *handle, *arglist, *res; PyObject *handle, *arglist, *res;
char *bufstr; char *bufstr;
INIT_ATTR(py_callback_hook_read_after_name, "hook_read_after"); INIT_ATTR(py_attr_hook_read_after_name, "hook_read_after");
INIT_ATTR(py_callback_hook_read_before_name, "hook_read_before"); INIT_ATTR(py_attr_hook_read_before_name, "hook_read_before");
INIT_ATTR(py_callback_read_name, "read"); 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 // 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; if (unlikely(!handle)) return;
// Call the "hook_READ_BEFORE" callback // Call the "hook_READ_BEFORE" callback
...@@ -145,7 +149,7 @@ void py_input(PyObject *parser, char *buf, int *result, int max_size) ...@@ -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. // 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)) { if (unlikely(!handle)) {
// TODO: set exception message for missing attribute error // TODO: set exception message for missing attribute error
return; return;
...@@ -162,10 +166,10 @@ void py_input(PyObject *parser, char *buf, int *result, int max_size) ...@@ -162,10 +166,10 @@ void py_input(PyObject *parser, char *buf, int *result, int max_size)
if (unlikely(!res)) { return; } if (unlikely(!res)) { return; }
// Check if the "hook_read_after" callback exists // 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; 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; if (unlikely(!handle)) return;
// Call the "hook_READ_AFTER" callback // Call the "hook_READ_AFTER" callback
...@@ -174,6 +178,7 @@ void py_input(PyObject *parser, char *buf, int *result, int max_size) ...@@ -174,6 +178,7 @@ void py_input(PyObject *parser, char *buf, int *result, int max_size)
res = PyObject_CallObject(handle, arglist); res = PyObject_CallObject(handle, arglist);
Py_DECREF(res);
Py_DECREF(handle); Py_DECREF(handle);
Py_DECREF(arglist); Py_DECREF(arglist);
...@@ -186,10 +191,28 @@ finish_input: ...@@ -186,10 +191,28 @@ finish_input:
*result = strlen(bufstr); *result = strlen(bufstr);
memcpy(buf, bufstr, *result); memcpy(buf, bufstr, *result);
// TODO: translate the following code snippet to the Python C aPI // Close the read buffer if nothing is read. Marks the Python file object
//if buflen == 0 and parser.file: // as being closed from Python's point of view. This does not close the
// # Marks the Python file object as being closed from Python's point of // associated C stream (which is not necessary here, otherwise use
// # view. This does not close the associated C stream (which is not // "os.close(0)").
// # necessary here, otherwise use "os.close(0)"). if (!*result && PyObject_HasAttr(parser, py_attr_file_name)) {
// parser.file.close() 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