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

parent 687b4238
...@@ -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;
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment