mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
gh-111140: Adds PyLong_AsNativeBytes and PyLong_FromNative[Unsigned]Bytes functions (GH-114886)
This commit is contained in:
parent
a82fbc13d0
commit
7861dfd26a
14 changed files with 533 additions and 26 deletions
|
|
@ -2393,7 +2393,7 @@ textiowrapper_parse_cookie(cookie_type *cookie, PyObject *cookieObj)
|
|||
return -1;
|
||||
|
||||
if (_PyLong_AsByteArray(cookieLong, buffer, sizeof(buffer),
|
||||
PY_LITTLE_ENDIAN, 0) < 0) {
|
||||
PY_LITTLE_ENDIAN, 0, 1) < 0) {
|
||||
Py_DECREF(cookieLong);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2162,7 +2162,8 @@ save_long(PicklerObject *self, PyObject *obj)
|
|||
pdata = (unsigned char *)PyBytes_AS_STRING(repr);
|
||||
i = _PyLong_AsByteArray((PyLongObject *)obj,
|
||||
pdata, nbytes,
|
||||
1 /* little endian */ , 1 /* signed */ );
|
||||
1 /* little endian */ , 1 /* signed */ ,
|
||||
1 /* with exceptions */);
|
||||
if (i < 0)
|
||||
goto error;
|
||||
/* If the int is negative, this may be a byte more than
|
||||
|
|
|
|||
|
|
@ -342,7 +342,8 @@ random_seed(RandomObject *self, PyObject *arg)
|
|||
res = _PyLong_AsByteArray((PyLongObject *)n,
|
||||
(unsigned char *)key, keyused * 4,
|
||||
PY_LITTLE_ENDIAN,
|
||||
0); /* unsigned */
|
||||
0, /* unsigned */
|
||||
1); /* with exceptions */
|
||||
if (res == -1) {
|
||||
goto Done;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ _pysqlite_long_as_int64(PyObject * py_val)
|
|||
sqlite_int64 int64val;
|
||||
if (_PyLong_AsByteArray((PyLongObject *)py_val,
|
||||
(unsigned char *)&int64val, sizeof(int64val),
|
||||
IS_LITTLE_ENDIAN, 1 /* signed */) >= 0) {
|
||||
IS_LITTLE_ENDIAN, 1 /* signed */, 0) >= 0) {
|
||||
return int64val;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1000,9 +1000,10 @@ bp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
|
|||
(unsigned char *)p,
|
||||
8,
|
||||
0, /* little_endian */
|
||||
1 /* signed */);
|
||||
1, /* signed */
|
||||
0 /* !with_exceptions */);
|
||||
Py_DECREF(v);
|
||||
if (res == -1 && PyErr_Occurred()) {
|
||||
if (res < 0) {
|
||||
PyErr_Format(state->StructError,
|
||||
"'%c' format requires %lld <= number <= %lld",
|
||||
f->format,
|
||||
|
|
@ -1024,9 +1025,10 @@ bp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f
|
|||
(unsigned char *)p,
|
||||
8,
|
||||
0, /* little_endian */
|
||||
0 /* signed */);
|
||||
0, /* signed */
|
||||
0 /* !with_exceptions */);
|
||||
Py_DECREF(v);
|
||||
if (res == -1 && PyErr_Occurred()) {
|
||||
if (res < 0) {
|
||||
PyErr_Format(state->StructError,
|
||||
"'%c' format requires 0 <= number <= %llu",
|
||||
f->format,
|
||||
|
|
@ -1260,9 +1262,10 @@ lp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
|
|||
(unsigned char *)p,
|
||||
8,
|
||||
1, /* little_endian */
|
||||
1 /* signed */);
|
||||
1, /* signed */
|
||||
0 /* !with_exceptions */);
|
||||
Py_DECREF(v);
|
||||
if (res == -1 && PyErr_Occurred()) {
|
||||
if (res < 0) {
|
||||
PyErr_Format(state->StructError,
|
||||
"'%c' format requires %lld <= number <= %lld",
|
||||
f->format,
|
||||
|
|
@ -1284,9 +1287,10 @@ lp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f
|
|||
(unsigned char *)p,
|
||||
8,
|
||||
1, /* little_endian */
|
||||
0 /* signed */);
|
||||
0, /* signed */
|
||||
0 /* !with_exceptions */);
|
||||
Py_DECREF(v);
|
||||
if (res == -1 && PyErr_Occurred()) {
|
||||
if (res < 0) {
|
||||
PyErr_Format(state->StructError,
|
||||
"'%c' format requires 0 <= number <= %llu",
|
||||
f->format,
|
||||
|
|
|
|||
|
|
@ -776,6 +776,51 @@ pylong_asvoidptr(PyObject *module, PyObject *arg)
|
|||
return Py_NewRef((PyObject *)value);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pylong_asnativebytes(PyObject *module, PyObject *args)
|
||||
{
|
||||
PyObject *v;
|
||||
Py_buffer buffer;
|
||||
Py_ssize_t n, endianness;
|
||||
if (!PyArg_ParseTuple(args, "Ow*nn", &v, &buffer, &n, &endianness)) {
|
||||
return NULL;
|
||||
}
|
||||
if (buffer.readonly) {
|
||||
PyErr_SetString(PyExc_TypeError, "buffer must be writable");
|
||||
PyBuffer_Release(&buffer);
|
||||
return NULL;
|
||||
}
|
||||
if (buffer.len < n) {
|
||||
PyErr_SetString(PyExc_ValueError, "buffer must be at least 'n' bytes");
|
||||
PyBuffer_Release(&buffer);
|
||||
return NULL;
|
||||
}
|
||||
Py_ssize_t res = PyLong_AsNativeBytes(v, buffer.buf, n, (int)endianness);
|
||||
PyBuffer_Release(&buffer);
|
||||
return res >= 0 ? PyLong_FromSsize_t(res) : NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
pylong_fromnativebytes(PyObject *module, PyObject *args)
|
||||
{
|
||||
Py_buffer buffer;
|
||||
Py_ssize_t n, endianness, signed_;
|
||||
if (!PyArg_ParseTuple(args, "y*nnn", &buffer, &n, &endianness, &signed_)) {
|
||||
return NULL;
|
||||
}
|
||||
if (buffer.len < n) {
|
||||
PyErr_SetString(PyExc_ValueError, "buffer must be at least 'n' bytes");
|
||||
PyBuffer_Release(&buffer);
|
||||
return NULL;
|
||||
}
|
||||
PyObject *res = signed_
|
||||
? PyLong_FromNativeBytes(buffer.buf, n, (int)endianness)
|
||||
: PyLong_FromUnsignedNativeBytes(buffer.buf, n, (int)endianness);
|
||||
PyBuffer_Release(&buffer);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef test_methods[] = {
|
||||
_TESTCAPI_TEST_LONG_AND_OVERFLOW_METHODDEF
|
||||
_TESTCAPI_TEST_LONG_API_METHODDEF
|
||||
|
|
@ -804,6 +849,8 @@ static PyMethodDef test_methods[] = {
|
|||
{"pylong_as_size_t", pylong_as_size_t, METH_O},
|
||||
{"pylong_asdouble", pylong_asdouble, METH_O},
|
||||
{"pylong_asvoidptr", pylong_asvoidptr, METH_O},
|
||||
{"pylong_asnativebytes", pylong_asnativebytes, METH_VARARGS},
|
||||
{"pylong_fromnativebytes", pylong_fromnativebytes, METH_VARARGS},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
|
|
@ -813,6 +860,5 @@ _PyTestCapi_Init_Long(PyObject *mod)
|
|||
if (PyModule_AddFunctions(mod, test_methods) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -926,7 +926,8 @@ AsObj(PyObject *value)
|
|||
(unsigned char *)(void *)&wideValue,
|
||||
sizeof(wideValue),
|
||||
PY_LITTLE_ENDIAN,
|
||||
/* signed */ 1) == 0) {
|
||||
/* signed */ 1,
|
||||
/* with_exceptions */ 1) == 0) {
|
||||
return Tcl_NewWideIntObj(wideValue);
|
||||
}
|
||||
PyErr_Clear();
|
||||
|
|
|
|||
|
|
@ -973,7 +973,8 @@ _multibytecodec_MultibyteIncrementalEncoder_setstate_impl(MultibyteIncrementalEn
|
|||
|
||||
if (_PyLong_AsByteArray(statelong, statebytes, sizeof(statebytes),
|
||||
1 /* little-endian */ ,
|
||||
0 /* unsigned */ ) < 0) {
|
||||
0 /* unsigned */ ,
|
||||
1 /* with_exceptions */) < 0) {
|
||||
goto errorexit;
|
||||
}
|
||||
|
||||
|
|
@ -1255,7 +1256,8 @@ _multibytecodec_MultibyteIncrementalDecoder_setstate_impl(MultibyteIncrementalDe
|
|||
|
||||
if (_PyLong_AsByteArray(statelong, statebytes, sizeof(statebytes),
|
||||
1 /* little-endian */ ,
|
||||
0 /* unsigned */ ) < 0) {
|
||||
0 /* unsigned */ ,
|
||||
1 /* with_exceptions */) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue