##// END OF EJS Templates
hg: raise Abort on invalid path...
hg: raise Abort on invalid path Currently, some os.path functions when opening repositories may raise an uncaught TypeError or ValueError if the path is invalid. Let's catch these exceptions and turn them into an Abort for convenience. Differential Revision: https://phab.mercurial-scm.org/D5772

File last commit:

r37513:b1fb341d default
r41522:2fe2f1ba default
Show More
decompressionwriter.c
188 lines | 5.5 KiB | text/x-c | CLexer
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 /**
* Copyright (c) 2016-present, Gregory Szorc
* All rights reserved.
*
* This software may be modified and distributed under the terms
* of the BSD license. See the LICENSE file for details.
*/
#include "python-zstandard.h"
extern PyObject* ZstdError;
PyDoc_STRVAR(ZstdDecompressionWriter__doc,
"""A context manager used for writing decompressed output.\n"
);
static void ZstdDecompressionWriter_dealloc(ZstdDecompressionWriter* self) {
Py_XDECREF(self->decompressor);
Py_XDECREF(self->writer);
PyObject_Del(self);
}
static PyObject* ZstdDecompressionWriter_enter(ZstdDecompressionWriter* self) {
if (self->entered) {
PyErr_SetString(ZstdError, "cannot __enter__ multiple times");
return NULL;
}
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 if (ensure_dctx(self->decompressor, 1)) {
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 return NULL;
}
self->entered = 1;
Py_INCREF(self);
return (PyObject*)self;
}
static PyObject* ZstdDecompressionWriter_exit(ZstdDecompressionWriter* self, PyObject* args) {
self->entered = 0;
Py_RETURN_FALSE;
}
static PyObject* ZstdDecompressionWriter_memory_size(ZstdDecompressionWriter* self) {
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 return PyLong_FromSize_t(ZSTD_sizeof_DCtx(self->decompressor->dctx));
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 }
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 static PyObject* ZstdDecompressionWriter_write(ZstdDecompressionWriter* self, PyObject* args, PyObject* kwargs) {
static char* kwlist[] = {
"data",
NULL
};
PyObject* result = NULL;
Py_buffer source;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 size_t zresult = 0;
ZSTD_inBuffer input;
ZSTD_outBuffer output;
PyObject* res;
Gregory Szorc
zstd: vendor python-zstandard 0.7.0...
r30895 Py_ssize_t totalWrite = 0;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435
#if PY_MAJOR_VERSION >= 3
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*:write",
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 #else
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*:write",
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 #endif
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 kwlist, &source)) {
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 return NULL;
}
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 if (!PyBuffer_IsContiguous(&source, 'C') || source.ndim > 1) {
PyErr_SetString(PyExc_ValueError,
"data buffer should be contiguous and have at most one dimension");
goto finally;
}
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 if (!self->entered) {
PyErr_SetString(ZstdError, "write must be called from an active context manager");
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 goto finally;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 }
Gregory Szorc
zstd: vendor python-zstandard 0.6.0...
r30822 output.dst = PyMem_Malloc(self->outSize);
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 if (!output.dst) {
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 PyErr_NoMemory();
goto finally;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 }
output.size = self->outSize;
output.pos = 0;
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 input.src = source.buf;
input.size = source.len;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 input.pos = 0;
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 while ((ssize_t)input.pos < source.len) {
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 Py_BEGIN_ALLOW_THREADS
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 zresult = ZSTD_decompress_generic(self->decompressor->dctx, &output, &input);
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 Py_END_ALLOW_THREADS
if (ZSTD_isError(zresult)) {
Gregory Szorc
zstd: vendor python-zstandard 0.6.0...
r30822 PyMem_Free(output.dst);
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 PyErr_Format(ZstdError, "zstd decompress error: %s",
ZSTD_getErrorName(zresult));
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 goto finally;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 }
if (output.pos) {
#if PY_MAJOR_VERSION >= 3
res = PyObject_CallMethod(self->writer, "write", "y#",
#else
res = PyObject_CallMethod(self->writer, "write", "s#",
#endif
output.dst, output.pos);
Py_XDECREF(res);
Gregory Szorc
zstd: vendor python-zstandard 0.7.0...
r30895 totalWrite += output.pos;
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 output.pos = 0;
}
}
Gregory Szorc
zstd: vendor python-zstandard 0.6.0...
r30822 PyMem_Free(output.dst);
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 result = PyLong_FromSsize_t(totalWrite);
finally:
PyBuffer_Release(&source);
return result;
Gregory Szorc
zstd: vendor python-zstandard 0.7.0...
r30895 }
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435
static PyMethodDef ZstdDecompressionWriter_methods[] = {
{ "__enter__", (PyCFunction)ZstdDecompressionWriter_enter, METH_NOARGS,
PyDoc_STR("Enter a decompression context.") },
{ "__exit__", (PyCFunction)ZstdDecompressionWriter_exit, METH_VARARGS,
PyDoc_STR("Exit a decompression context.") },
{ "memory_size", (PyCFunction)ZstdDecompressionWriter_memory_size, METH_NOARGS,
PyDoc_STR("Obtain the memory size in bytes of the underlying decompressor.") },
Gregory Szorc
zstandard: vendor python-zstandard 0.9.0...
r37513 { "write", (PyCFunction)ZstdDecompressionWriter_write, METH_VARARGS | METH_KEYWORDS,
Gregory Szorc
zstd: vendor python-zstandard 0.5.0...
r30435 PyDoc_STR("Compress data") },
{ NULL, NULL }
};
PyTypeObject ZstdDecompressionWriterType = {
PyVarObject_HEAD_INIT(NULL, 0)
"zstd.ZstdDecompressionWriter", /* tp_name */
sizeof(ZstdDecompressionWriter),/* tp_basicsize */
0, /* tp_itemsize */
(destructor)ZstdDecompressionWriter_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
ZstdDecompressionWriter__doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
ZstdDecompressionWriter_methods,/* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
};
void decompressionwriter_module_init(PyObject* mod) {
Py_TYPE(&ZstdDecompressionWriterType) = &PyType_Type;
if (PyType_Ready(&ZstdDecompressionWriterType) < 0) {
return;
}
}