view contrib/python-zstandard/c-ext/frameparams.c @ 51711:832a1aeb576f

pytype: only try the hacky way of finding PYTHON if not provided This allows us to work in more environments, like when using pyenv. This syntax is compatible with all POSIX shells.
author Raphaël Gomès <rgomes@octobus.net>
date Tue, 23 Jul 2024 12:10:31 +0200
parents e92ca942ddca
children
line wrap: on
line source

/**
* Copyright (c) 2017-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(FrameParameters__doc__,
	"FrameParameters: information about a zstd frame");

FrameParametersObject* get_frame_parameters(PyObject* self, PyObject* args, PyObject* kwargs) {
	static char* kwlist[] = {
		"data",
		NULL
	};

	Py_buffer source;
	ZSTD_frameHeader header;
	FrameParametersObject* result = NULL;
	size_t zresult;

#if PY_MAJOR_VERSION >= 3
	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y*:get_frame_parameters",
#else
	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s*:get_frame_parameters",
#endif
		kwlist, &source)) {
		return NULL;
	}

	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;
	}

	zresult = ZSTD_getFrameHeader(&header, source.buf, source.len);

	if (ZSTD_isError(zresult)) {
		PyErr_Format(ZstdError, "cannot get frame parameters: %s", ZSTD_getErrorName(zresult));
		goto finally;
	}

	if (zresult) {
		PyErr_Format(ZstdError, "not enough data for frame parameters; need %zu bytes", zresult);
		goto finally;
	}

	result = PyObject_New(FrameParametersObject, &FrameParametersType);
	if (!result) {
		goto finally;
	}

	result->frameContentSize = header.frameContentSize;
	result->windowSize = header.windowSize;
	result->dictID = header.dictID;
	result->checksumFlag = header.checksumFlag ? 1 : 0;

finally:
	PyBuffer_Release(&source);
	return result;
}

static void FrameParameters_dealloc(PyObject* self) {
	PyObject_Del(self);
}

static PyMemberDef FrameParameters_members[] = {
	{ "content_size", T_ULONGLONG,
	  offsetof(FrameParametersObject, frameContentSize), READONLY,
	  "frame content size" },
	{ "window_size", T_ULONGLONG,
	  offsetof(FrameParametersObject, windowSize), READONLY,
	  "window size" },
	{ "dict_id", T_UINT,
	  offsetof(FrameParametersObject, dictID), READONLY,
	  "dictionary ID" },
	{ "has_checksum", T_BOOL,
	  offsetof(FrameParametersObject, checksumFlag), READONLY,
	  "checksum flag" },
	{ NULL }
};

PyTypeObject FrameParametersType = {
	PyVarObject_HEAD_INIT(NULL, 0)
	"FrameParameters",          /* tp_name */
	sizeof(FrameParametersObject), /* tp_basicsize */
	0,                         /* tp_itemsize */
	(destructor)FrameParameters_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,        /* tp_flags */
	FrameParameters__doc__,    /* tp_doc */
	0,                         /* tp_traverse */
	0,                         /* tp_clear */
	0,                         /* tp_richcompare */
	0,                         /* tp_weaklistoffset */
	0,                         /* tp_iter */
	0,                         /* tp_iternext */
	0,                         /* tp_methods */
	FrameParameters_members,   /* 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 */
	0,                         /* tp_new */
};

void frameparams_module_init(PyObject* mod) {
	Py_SET_TYPE(&FrameParametersType, &PyType_Type);
	if (PyType_Ready(&FrameParametersType) < 0) {
		return;
	}

	Py_INCREF(&FrameParametersType);
	PyModule_AddObject(mod, "FrameParameters", (PyObject*)&FrameParametersType);
}