/* ** Copyright 2002-2007 by LivingLogic AG, Bayreuth, Germany. ** Copyright 2002-2007 by Walter Dörwald ** ** All Rights Reserved ** ** See __init__.py for the license */ #include "Python.h" static char escape__doc__[] = "escape(string, safe) -> string\n\ \n\ Escape any character not in safe with a %xx sequence.\n\ If safe is not specified all 7bit characters are considered safe."; static char hexdigits[16] = "0123456789abcdef"; static PyObject *escape(PyObject *self, PyObject *args) { PyObject *str; PyObject *uni; char *safe = NULL; PyObject *res; unsigned char *s; unsigned char *starts; unsigned char *ends; char *r; char *startr; char *endr; int newsize; if (!PyArg_ParseTuple(args, "O|s:escape", &str, &safe)) return NULL; uni = PyUnicode_FromObject(str); if (!uni) return NULL; str = PyUnicode_EncodeUTF8(PyUnicode_AS_UNICODE(uni), PyUnicode_GET_SIZE(uni), NULL); if (!str) { Py_DECREF(uni); return NULL; } starts = PyString_AS_STRING(str); ends = starts + PyString_GET_SIZE(str); for (newsize = 0, s = starts; s < ends; ++s) { if (safe ? (strchr(safe, *s)!=NULL) : (*s<0x80)) ++newsize; else newsize += 3; } res = PyString_FromStringAndSize(NULL, newsize); if (res) { startr = PyString_AS_STRING(res); endr = startr + PyString_GET_SIZE(res); for (s = starts, r = startr; s < ends;) { if (safe ? (strchr(safe, *s)!=NULL) : (*s<0x80)) *r++ = *s++; else { *r++ = '%'; *r++ = hexdigits[((*s)>>4) & 0xf]; *r++ = hexdigits[(*s++) & 0xf]; } } } Py_DECREF(str); Py_DECREF(uni); return res; } static void widechar_to_utf8(unsigned long widechar, char **out) { unsigned long first_bits = 0; int trail = 0; if (widechar >= 0x80) { if (widechar < 0x00000800) { first_bits = 0xc0; trail = 1; } else if (widechar < 0x00010000) { first_bits = 0xe0; trail = 2; } } { int i; for (i = trail; i; --i) { (*out)[i] = (char)((widechar & 0x3f) | 0x80); widechar >>= 6; } (*out)[0] = (char) (widechar | first_bits); } *out += trail + 1; } static char unescape__doc__[] = "unescape(string) -> unicode\n\ \n\ Unescape a %-escaped string. The result will be UTF-8 decoded if possible.\n\ If this fails, ISO-8859-1 will be tried."; static PyObject *unescape(PyObject *self, PyObject *args) { char *in; int len; PyObject *res; int pos = 0; char *start; char *out; PyObject *uni; if (!PyArg_ParseTuple(args, "s#:unescape", &in, &len)) return NULL; res = PyString_FromStringAndSize(NULL, len); if (!res) return NULL; start = out = PyString_AS_STRING(res); while (poslen || (in[pos+1] == 'u' && pos+6>len)) { sprintf(buffer, "truncated escape at position %d", pos); if (PyErr_Warn(PyExc_UserWarning, buffer)) { Py_DECREF(res); return NULL; } /* copy the characters literally */ while (pos