#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include <Python.h>
#include <cStringIO.h>
#ifdef __cplusplus
}
#endif
#ifdef __GNUC__
# define TM_INLINE inline
#else
# define TM_INLINE
#endif
static PyObject* UrlargError;
#define OUTPUTCHAR(c,n) PycStringIO->cwrite(output, c, n)
#define STATE_INITIAL 0
#define STATE_PERCENT 1
#define STATE_HEXDIGIT 2
#define NOT_HEXDIGIT 255
unsigned char hexdigits[256];
TM_INLINE int ishexdigit(unsigned char c) {
return hexdigits[c];
}
static PyObject *unquote(PyObject *self, PyObject *args, PyObject *kwargs)
{
unsigned char *s, *r, *end;
unsigned char quotedchar, quotedchartmp = 0, tmp;
unsigned char escchar = '%';
static char *kwlist[] = {"s", "escchar", NULL};
int state = STATE_INITIAL, length;
PyObject *output, *str;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|c:unquote", kwlist, &s, &length, &escchar)) {
return NULL;
}
output = PycStringIO->NewOutput(length);
if (output == NULL) {
return NULL;
}
end = s + length;
s = s - 1;
while ((++s) < end) {
switch(state) {
case STATE_INITIAL:
if (*s == escchar) {
state = STATE_PERCENT;
} else {
r = s - 1;
while (*(++r) != escchar && r < end);
OUTPUTCHAR(s, r-s);
s = r-1;
}
break;
case STATE_PERCENT:
if ((quotedchartmp = ishexdigit(*s)) != NOT_HEXDIGIT) {
tmp = *s;
state = STATE_HEXDIGIT;
} else {
state = STATE_INITIAL;
OUTPUTCHAR(&escchar, 1);
s--;
}
break;
case STATE_HEXDIGIT:
state = STATE_INITIAL;
if ((quotedchar = ishexdigit(*s)) != NOT_HEXDIGIT) {
quotedchar |= (quotedchartmp << 4);
OUTPUTCHAR("edchar, 1);
} else {
OUTPUTCHAR(&escchar, 1);
s -= 2;
}
break;
}
}
switch(state) {
case STATE_PERCENT:
OUTPUTCHAR(&escchar, 1);
break;
case STATE_HEXDIGIT:
OUTPUTCHAR(&escchar, 1);
OUTPUTCHAR(&tmp, 1);
break;
}
str = PycStringIO->cgetvalue(output);
return str;
}
static PyMethodDef _c_urlarg_methods[] = {
{"unquote", (PyCFunction)unquote, METH_VARARGS|METH_KEYWORDS},
{NULL, NULL}
};
DL_EXPORT(void) init_c_urlarg(void)
{
PyObject* m;
PyObject* d;
unsigned char i;
PycString_IMPORT;
m = Py_InitModule("_c_urlarg", _c_urlarg_methods);
d = PyModule_GetDict(m);
UrlargError = PyErr_NewException("urlarg.UrlargError", PyExc_Exception, NULL);
PyDict_SetItemString(d, "UrlargError", UrlargError);
for(i = 0; i < 255; i++) {
hexdigits[i] = NOT_HEXDIGIT;
}
hexdigits[255] = NOT_HEXDIGIT;
for(i = '0'; i <= '9'; i++) {
hexdigits[i] = i - '0';
}
for(i = 'a'; i <= 'f'; i++) {
hexdigits[i] = 10 + (i - 'a');
}
for(i = 'A'; i <= 'F'; i++) {
hexdigits[i] = 10 + (i - 'A');
}
if (PyErr_Occurred()) {
PyErr_Print();
Py_FatalError("can't initialize module _c_urlarg");
}
}