8000 Add long_asnativebytes() function · python/cpython@5d3e224 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5d3e224

Browse files
committed
Add long_asnativebytes() function
1 parent 90973d4 commit 5d3e224

File tree

1 file changed

+58
-48
lines changed

1 file changed

+58
-48
lines changed

Objects/longobject.c

Lines changed: 58 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,53 +1117,18 @@ _resolve_endianness(int *endianness)
11171117
return 0;
11181118
}
11191119

1120-
Py_ssize_t
1121-
PyLong_AsNativeBytes(PyObject* vv, void* buffer, Py_ssize_t n, int flags)
1120+
1121+
static Py_ssize_t
1122+
long_asnativebytes(PyLongObject *v, void* buffer, Py_ssize_t n,
1123+
int little_endian, int unsigned_buffer)
11221124
{
1123-
PyLongObject *v;
1125+
Py_ssize_t res = 0;
11241126
union {
11251127
Py_ssize_t v;
11261128
unsigned char b[sizeof(Py_ssize_t)];
11271129
} cv;
1128-
int do_decref = 0;
1129-
Py_ssize_t res = 0;
1130-
1131-
if (vv == NULL || n < 0) {
1132-
PyErr_BadInternalCall();
1133-
return -1;
1134-
}
1135-
1136-
int little_endian = flags;
1137-
if (_resolve_endianness(&little_endian) < 0) {
1138-
return -1;
1139-
}
1140-
1141-
if (PyLong_Check(vv)) {
1142-
v = (PyLongObject *)vv;
1143-
}
1144-
else if (flags != -1 && (flags & Py_ASNATIVEBYTES_ALLOW_INDEX)) {
1145-
v = (PyLongObject *)_PyNumber_Index(vv);
1146-
if (v == NULL) {
1147-
return -1;
1148-
}
1149-
do_decref = 1;
1150-
}
1151-
else {
1152-
PyErr_Format(PyExc_TypeError, "expect int, got %T", vv);
1153-
return -1;
1154-
}
1155-
1156-
if ((flags != -1 && (flags & Py_ASNATIVEBYTES_REJECT_NEGATIVE))
1157-
&& _PyLong_IsNegative(v)) {
1158-
PyErr_SetString(PyExc_ValueError, "Cannot convert negative int");
1159-
if (do_decref) {
1160-
Py_DECREF(v);
1161-
}
1162-
return -1;
1163-
}
11641130

11651131
if (_PyLong_IsCompact(v)) {
1166-
res = 0;
11671132
cv.v = _PyLong_CompactValue(v);
11681133
/* Most paths result in res = sizeof(compact value). Only the case
11691134
* where 0 < n < sizeof(compact value) do we need to check and adjust
@@ -1200,7 +1165,7 @@ PyLong_AsNativeBytes(PyObject* vv, void* buffer, Py_ssize_t n, int flags)
12001165
/* Positive values with the MSB set do not require an
12011166
* additional bit when the caller's intent is to treat them
12021167
* as unsigned. */
1203-
if (flags == -1 || (flags & Py_ASNATIVEBYTES_UNSIGNED_BUFFER)) {
1168+
if (unsigned_buffer) {
12041169
res = n;
12051170
} else {
12061171
res = n + 1;
@@ -1287,7 +1252,7 @@ PyLong_AsNativeBytes(PyObject* vv, void* buffer, Py_ssize_t n, int flags)
12871252
* as unsigned. */
12881253
unsigned char *b = (unsigned char *)buffer;
12891254
if (b[little_endian ? n - 1 : 0] & 0x80) {
1290-
if (flags == -1 || (flags & Py_ASNATIVEBYTES_UNSIGNED_BUFFER)) {
1255+
if (unsigned_buffer) {
12911256
res = n;
12921257
} else {
12931258
res = n + 1;
@@ -1296,6 +1261,54 @@ PyLong_AsNativeBytes(PyObject* vv, void* buffer, Py_ssize_t n, int flags)
12961261
}
12971262
}
12981263
}
1264+
return res;
1265+
}
1266+
1267+
1268+
Py_ssize_t
1269+
PyLong_AsNativeBytes(PyObject* vv, void* buffer, Py_ssize_t n, int flags)
1270+
{
1271+
PyLongObject *v;
1272+
int do_decref = 0;
1273+
Py_ssize_t res = 0;
1274+
1275+
if (vv == NULL || n < 0) {
1276+
PyErr_BadInternalCall();
1277+
return -1;
1278+
}
1279+
1280+
int little_endian = flags;
1281+
if (_resolve_endianness(&little_endian) < 0) {
1282+
return -1;
1283+
}
1284+
1285+
if (PyLong_Check(vv)) {
1286+
v = (PyLongObject *)vv;
1287+
}
1288+
else if (flags != -1 && (flags & Py_ASNATIVEBYTES_ALLOW_INDEX)) {
1289+
v = (PyLongObject *)_PyNumber_Index(vv);
1290+
if (v == NULL) {
1291+
return -1;
1292+
}
1293+
do_decref = 1;
1294+
}
1295+
else {
1296+
PyErr_Format(PyExc_TypeError, "expect int, got %T", vv);
1297+
return -1;
1298+
}
1299+
1300+
if ((flags != -1 && (flags & Py_ASNATIVEBYTES_REJECT_NEGATIVE))
1301+
&& _PyLong_IsNegative(v)) {
1302+
PyErr_SetString(PyExc_ValueError, "Cannot convert negative int");
1303+
if (do_decref) {
1304+
Py_DECREF(v);
1305+
}
1306+
return -1;
1307+
}
1308+
1309+
int unsigned_buffer = (flags == -1
1310+
|| (flags & Py_ASNATIVEBYTES_UNSIGNED_BUFFER));
1311+
res = long_asnativebytes(v, buffer, n, little_endian, unsigned_buffer);
12991312

13001313
if (do_decref) {
13011314
Py_DECREF(v);
@@ -6797,13 +6810,11 @@ PyLong_Export(PyObject *obj, PyLongExport *export_long)
67976810
PyErr_Format(PyExc_TypeError, "expect int, got %T", obj);
67986811
return -1;
67996812
}
6813+
PyLongObject *self = (PyLongObject*)obj;
68006814

68016815
int64_t value;
6802-
int flags = Py_ASNATIVEBYTES_NATIVE_ENDIAN;
6803-
Py_ssize_t bytes = PyLong_AsNativeBytes(obj, &value, sizeof(value), flags);
6804-
if (bytes < 0) {
6805-
return -1;
6806-
}
6816+
Py_ssize_t bytes = long_asnativebytes(self, &value, sizeof(value),
6817+
PY_LITTLE_ENDIAN, 0);
68076818

68086819
if ((size_t)bytes <= sizeof(value)) {
68096820
export_long->value = value;
@@ -6813,7 +6824,6 @@ PyLong_Export(PyObject *obj, PyLongExport *export_long)
68136824
export_long->_reserved = 0;
68146825
}
68156826
else {
6816-
PyLongObject *self = (PyLongObject*)obj;
68176827
export_long->value = 0;
68186828
export_long->negative = _PyLong_IsNegative(self);
68196829
export_long->ndigits = _PyLong_DigitCount(self);

0 commit comments

Comments
 (0)
0