Kaydet (Commit) a72e78b3 authored tarafından Martin v. Löwis's avatar Martin v. Löwis

Replace Py_UCS4_ API with Unicode API.

üst d1029c48
...@@ -63,115 +63,110 @@ static PyObject *get_module_code(ZipImporter *self, PyObject *fullname, ...@@ -63,115 +63,110 @@ static PyObject *get_module_code(ZipImporter *self, PyObject *fullname,
static int static int
zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds) zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
{ {
PyObject *pathobj, *files; PyObject *path, *files, *tmp;
Py_UCS4 *path, *p, *prefix, buf[MAXPATHLEN+2]; PyObject *filename = NULL;
Py_ssize_t len; Py_ssize_t len, flen;
#ifdef ALTSEP
_Py_IDENTIFIER(replace);
#endif
if (!_PyArg_NoKeywords("zipimporter()", kwds)) if (!_PyArg_NoKeywords("zipimporter()", kwds))
return -1; return -1;
if (!PyArg_ParseTuple(args, "O&:zipimporter", if (!PyArg_ParseTuple(args, "O&:zipimporter",
PyUnicode_FSDecoder, &pathobj)) PyUnicode_FSDecoder, &path))
return -1; return -1;
if (PyUnicode_READY(pathobj) == -1) if (PyUnicode_READY(path) == -1)
return -1; return -1;
/* copy path to buf */ len = PyUnicode_GET_LENGTH(path);
len = PyUnicode_GET_LENGTH(pathobj);
if (len == 0) { if (len == 0) {
PyErr_SetString(ZipImportError, "archive path is empty"); PyErr_SetString(ZipImportError, "archive path is empty");
goto error; goto error;
} }
if (len >= MAXPATHLEN) {
PyErr_SetString(ZipImportError,
"archive path too long");
goto error;
}
if (!PyUnicode_AsUCS4(pathobj, buf, Py_ARRAY_LENGTH(buf), 1))
goto error;
#ifdef ALTSEP #ifdef ALTSEP
for (p = buf; *p; p++) { tmp = PyObject_CallMethodId(path, &PyId_replace, "CC",
if (*p == ALTSEP) ALTSEP, SEP);
*p = SEP; if (!tmp)
} goto error;
Py_DECREF(path);
path = tmp;
#endif #endif
path = NULL; filename = path;
prefix = NULL; Py_INCREF(filename);
flen = len;
for (;;) { for (;;) {
struct stat statbuf; struct stat statbuf;
int rv; int rv;
if (pathobj == NULL) { rv = _Py_stat(filename, &statbuf);
pathobj = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
buf, len);
if (pathobj == NULL)
goto error;
}
rv = _Py_stat(pathobj, &statbuf);
if (rv == 0) { if (rv == 0) {
/* it exists */ /* it exists */
if (S_ISREG(statbuf.st_mode)) if (!S_ISREG(statbuf.st_mode))
/* it's a file */ /* it's a not file */
path = buf; Py_CLEAR(filename);
break; break;
} }
else if (PyErr_Occurred()) else if (PyErr_Occurred())
goto error; goto error;
Py_CLEAR(filename);
/* back up one path element */ /* back up one path element */
p = Py_UCS4_strrchr(buf, SEP); flen = PyUnicode_FindChar(path, SEP, 0, flen, -1);
if (prefix != NULL) if (flen == -1)
*prefix = SEP;
if (p == NULL)
break; break;
*p = '\0'; filename = PyUnicode_Substring(path, 0, flen);
len = p - buf;
prefix = p;
Py_CLEAR(pathobj);
} }
if (path == NULL) { if (filename == NULL) {
PyErr_SetString(ZipImportError, "not a Zip file"); PyErr_SetString(ZipImportError, "not a Zip file");
goto error; goto error;
} }
files = PyDict_GetItem(zip_directory_cache, pathobj); if (PyUnicode_READY(filename) < 0)
goto error;
files = PyDict_GetItem(zip_directory_cache, filename);
if (files == NULL) { if (files == NULL) {
files = read_directory(pathobj); files = read_directory(filename);
if (files == NULL) if (files == NULL)
goto error; goto error;
if (PyDict_SetItem(zip_directory_cache, pathobj, files) != 0) if (PyDict_SetItem(zip_directory_cache, filename, files) != 0)
goto error; goto error;
} }
else else
Py_INCREF(files); Py_INCREF(files);
self->files = files; self->files = files;
self->archive = pathobj; /* Transfer reference */
pathobj = NULL; self->archive = filename;
filename = NULL;
if (prefix != NULL) { /* Check if there is a prefix directory following the filename. */
prefix++; if (flen != len) {
len = Py_UCS4_strlen(prefix); tmp = PyUnicode_Substring(path, flen+1,
if (prefix[len-1] != SEP) { PyUnicode_GET_LENGTH(path));
if (tmp == NULL)
goto error;
self->prefix = tmp;
if (PyUnicode_READ_CHAR(path, len-1) != SEP) {
/* add trailing SEP */ /* add trailing SEP */
prefix[len] = SEP; tmp = PyUnicode_FromFormat("%U%c", self->prefix, SEP);
prefix[len + 1] = '\0'; if (tmp == NULL)
len++; goto error;
Py_DECREF(self->prefix);
self->prefix = tmp;
} }
} }
else else
len = 0; self->prefix = PyUnicode_New(0, 0);
self->prefix = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, Py_DECREF(path);
prefix, len);
if (self->prefix == NULL)
goto error;
return 0; return 0;
error: error:
Py_XDECREF(pathobj); Py_DECREF(path);
Py_XDECREF(filename);
return -1; return -1;
} }
...@@ -211,26 +206,16 @@ zipimporter_repr(ZipImporter *self) ...@@ -211,26 +206,16 @@ zipimporter_repr(ZipImporter *self)
static PyObject * static PyObject *
get_subname(PyObject *fullname) get_subname(PyObject *fullname)
{ {
Py_ssize_t len; Py_ssize_t len, dot;
Py_UCS4 *subname, *fullname_ucs4; if (PyUnicode_READY(fullname) < 0)
fullname_ucs4 = PyUnicode_AsUCS4Copy(fullname);
if (!fullname_ucs4)
return NULL; return NULL;
subname = Py_UCS4_strrchr(fullname_ucs4, '.'); len = PyUnicode_GET_LENGTH(fullname);
if (subname == NULL) { dot = PyUnicode_FindChar(fullname, '.', 0, len, -1);
PyMem_Free(fullname_ucs4); if (dot == -1) {
Py_INCREF(fullname); Py_INCREF(fullname);
return fullname; return fullname;
} else { } else
PyObject *result; return PyUnicode_Substring(fullname, dot+1, len);
subname++;
len = PyUnicode_GET_LENGTH(fullname);
len -= subname - fullname_ucs4;
result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
subname, len);
PyMem_Free(fullname_ucs4);
return result;
}
} }
/* Given a (sub)modulename, write the potential file path in the /* Given a (sub)modulename, write the potential file path in the
...@@ -453,58 +438,51 @@ static PyObject * ...@@ -453,58 +438,51 @@ static PyObject *
zipimporter_get_data(PyObject *obj, PyObject *args) zipimporter_get_data(PyObject *obj, PyObject *args)
{ {
ZipImporter *self = (ZipImporter *)obj; ZipImporter *self = (ZipImporter *)obj;
PyObject *pathobj, *key; PyObject *path, *key;
const Py_UCS4 *path;
#ifdef ALTSEP #ifdef ALTSEP
Py_UCS4 *p; PyObject *tmp;
_Py_IDENTIFIER(replace);
#endif #endif
PyObject *toc_entry; PyObject *toc_entry;
Py_ssize_t path_len, len; Py_ssize_t path_start, path_len, len;
Py_UCS4 buf[MAXPATHLEN + 1], archive[MAXPATHLEN + 1];
if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &pathobj))
return NULL;
if (PyUnicode_READY(pathobj) == -1) if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &path))
return NULL; return NULL;
path_len = PyUnicode_GET_LENGTH(pathobj);
if (path_len >= MAXPATHLEN) {
PyErr_SetString(ZipImportError, "path too long");
return NULL;
}
if (!PyUnicode_AsUCS4(pathobj, buf, Py_ARRAY_LENGTH(buf), 1))
return NULL;
path = buf;
#ifdef ALTSEP #ifdef ALTSEP
for (p = buf; *p; p++) { path = PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
if (*p == ALTSEP) if (!path)
*p = SEP; return NULL;
} #else
Py_INCREF(path);
#endif #endif
if (PyUnicode_READY(path) == -1)
goto error;
path_len = PyUnicode_GET_LENGTH(path);
len = PyUnicode_GET_LENGTH(self->archive); len = PyUnicode_GET_LENGTH(self->archive);
if ((size_t)len < Py_UCS4_strlen(path)) { path_start = 0;
if (!PyUnicode_AsUCS4(self->archive, archive, Py_ARRAY_LENGTH(archive), 1)) if (PyUnicode_Tailmatch(path, self->archive, 0, len, -1)
return NULL; && PyUnicode_READ_CHAR(path, len) == SEP) {
if (Py_UCS4_strncmp(path, archive, len) == 0 && path_start = len + 1;
path[len] == SEP) {
path += len + 1;
path_len -= len + 1;
}
} }
key = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, key = PyUnicode_Substring(path, path_start, path_len);
path, path_len);
if (key == NULL) if (key == NULL)
return NULL; goto error;
toc_entry = PyDict_GetItem(self->files, key); toc_entry = PyDict_GetItem(self->files, key);
if (toc_entry == NULL) { if (toc_entry == NULL) {
PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key); PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
Py_DECREF(key); Py_DECREF(key);
return NULL; goto error;
} }
Py_DECREF(key); Py_DECREF(key);
Py_DECREF(path);
return get_data(self->archive, toc_entry); return get_data(self->archive, toc_entry);
error:
Py_DECREF(path);
return NULL;
} }
static PyObject * static PyObject *
...@@ -756,24 +734,14 @@ read_directory(PyObject *archive) ...@@ -756,24 +734,14 @@ read_directory(PyObject *archive)
long header_offset, name_size, header_size, header_position; long header_offset, name_size, header_size, header_position;
long l, count; long l, count;
Py_ssize_t i; Py_ssize_t i;
size_t length;
Py_UCS4 path[MAXPATHLEN + 5];
char name[MAXPATHLEN + 5]; char name[MAXPATHLEN + 5];
PyObject *nameobj = NULL; PyObject *nameobj = NULL;
char *p, endof_central_dir[22]; char *p, endof_central_dir[22];
long arc_offset; /* offset from beginning of file to start of zip-archive */ long arc_offset; /* offset from beginning of file to start of zip-archive */
PyObject *pathobj; PyObject *path;
const char *charset; const char *charset;
int bootstrap; int bootstrap;
if (PyUnicode_GET_LENGTH(archive) > MAXPATHLEN) {
PyErr_SetString(PyExc_OverflowError,
"Zip path name is too long");
return NULL;
}
if (!PyUnicode_AsUCS4(archive, path, Py_ARRAY_LENGTH(path), 1))
return NULL;
fp = _Py_fopen(archive, "rb"); fp = _Py_fopen(archive, "rb");
if (fp == NULL) { if (fp == NULL) {
PyErr_Format(ZipImportError, "can't open Zip file: %R", archive); PyErr_Format(ZipImportError, "can't open Zip file: %R", archive);
...@@ -802,9 +770,6 @@ read_directory(PyObject *archive) ...@@ -802,9 +770,6 @@ read_directory(PyObject *archive)
if (files == NULL) if (files == NULL)
goto error; goto error;
length = Py_UCS4_strlen(path);
path[length] = SEP;
/* Start of Central Directory */ /* Start of Central Directory */
count = 0; count = 0;
for (;;) { for (;;) {
...@@ -868,15 +833,10 @@ read_directory(PyObject *archive) ...@@ -868,15 +833,10 @@ read_directory(PyObject *archive)
PY_MAJOR_VERSION, PY_MINOR_VERSION); PY_MAJOR_VERSION, PY_MINOR_VERSION);
goto error; goto error;
} }
for (i = 0; (i < (MAXPATHLEN - (Py_ssize_t)length - 1)) && path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
(i < PyUnicode_GET_LENGTH(nameobj)); i++) if (path == NULL)
path[length + 1 + i] = PyUnicode_READ_CHAR(nameobj, i);
path[length + 1 + i] = 0;
pathobj = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
path, Py_UCS4_strlen(path));
if (pathobj == NULL)
goto error; goto error;
t = Py_BuildValue("Niiiiiii", pathobj, compress, data_size, t = Py_BuildValue("Niiiiiii", path, compress, data_size,
file_size, file_offset, time, date, crc); file_size, file_offset, time, date, crc);
if (t == NULL) if (t == NULL)
goto error; goto error;
......
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