17db96d56Sopenharmony_ci/* struct module -- pack values into and (out of) bytes objects */ 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci/* New version supporting byte order, alignment and size options, 47db96d56Sopenharmony_ci character strings, and unsigned numbers */ 57db96d56Sopenharmony_ci 67db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE_BUILTIN 77db96d56Sopenharmony_ci# define Py_BUILD_CORE_MODULE 1 87db96d56Sopenharmony_ci#endif 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci#include "Python.h" 137db96d56Sopenharmony_ci#include "pycore_moduleobject.h" // _PyModule_GetState() 147db96d56Sopenharmony_ci#include "structmember.h" // PyMemberDef 157db96d56Sopenharmony_ci#include <ctype.h> 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ci/*[clinic input] 187db96d56Sopenharmony_ciclass Struct "PyStructObject *" "&PyStructType" 197db96d56Sopenharmony_ci[clinic start generated code]*/ 207db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b032058a83ed7c3]*/ 217db96d56Sopenharmony_ci 227db96d56Sopenharmony_citypedef struct { 237db96d56Sopenharmony_ci PyObject *cache; 247db96d56Sopenharmony_ci PyObject *PyStructType; 257db96d56Sopenharmony_ci PyObject *unpackiter_type; 267db96d56Sopenharmony_ci PyObject *StructError; 277db96d56Sopenharmony_ci} _structmodulestate; 287db96d56Sopenharmony_ci 297db96d56Sopenharmony_cistatic inline _structmodulestate* 307db96d56Sopenharmony_ciget_struct_state(PyObject *module) 317db96d56Sopenharmony_ci{ 327db96d56Sopenharmony_ci void *state = _PyModule_GetState(module); 337db96d56Sopenharmony_ci assert(state != NULL); 347db96d56Sopenharmony_ci return (_structmodulestate *)state; 357db96d56Sopenharmony_ci} 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_cistatic struct PyModuleDef _structmodule; 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci#define get_struct_state_structinst(self) \ 407db96d56Sopenharmony_ci (get_struct_state(PyType_GetModuleByDef(Py_TYPE(self), &_structmodule))) 417db96d56Sopenharmony_ci#define get_struct_state_iterinst(self) \ 427db96d56Sopenharmony_ci (get_struct_state(PyType_GetModule(Py_TYPE(self)))) 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci/* The translation function for each format character is table driven */ 457db96d56Sopenharmony_citypedef struct _formatdef { 467db96d56Sopenharmony_ci char format; 477db96d56Sopenharmony_ci Py_ssize_t size; 487db96d56Sopenharmony_ci Py_ssize_t alignment; 497db96d56Sopenharmony_ci PyObject* (*unpack)(_structmodulestate *, const char *, 507db96d56Sopenharmony_ci const struct _formatdef *); 517db96d56Sopenharmony_ci int (*pack)(_structmodulestate *, char *, PyObject *, 527db96d56Sopenharmony_ci const struct _formatdef *); 537db96d56Sopenharmony_ci} formatdef; 547db96d56Sopenharmony_ci 557db96d56Sopenharmony_citypedef struct _formatcode { 567db96d56Sopenharmony_ci const struct _formatdef *fmtdef; 577db96d56Sopenharmony_ci Py_ssize_t offset; 587db96d56Sopenharmony_ci Py_ssize_t size; 597db96d56Sopenharmony_ci Py_ssize_t repeat; 607db96d56Sopenharmony_ci} formatcode; 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci/* Struct object interface */ 637db96d56Sopenharmony_ci 647db96d56Sopenharmony_citypedef struct { 657db96d56Sopenharmony_ci PyObject_HEAD 667db96d56Sopenharmony_ci Py_ssize_t s_size; 677db96d56Sopenharmony_ci Py_ssize_t s_len; 687db96d56Sopenharmony_ci formatcode *s_codes; 697db96d56Sopenharmony_ci PyObject *s_format; 707db96d56Sopenharmony_ci PyObject *weakreflist; /* List of weak references */ 717db96d56Sopenharmony_ci} PyStructObject; 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci#define PyStruct_Check(op, state) PyObject_TypeCheck(op, (PyTypeObject *)(state)->PyStructType) 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ci/* Define various structs to figure out the alignments of types */ 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_citypedef struct { char c; short x; } st_short; 797db96d56Sopenharmony_citypedef struct { char c; int x; } st_int; 807db96d56Sopenharmony_citypedef struct { char c; long x; } st_long; 817db96d56Sopenharmony_citypedef struct { char c; float x; } st_float; 827db96d56Sopenharmony_citypedef struct { char c; double x; } st_double; 837db96d56Sopenharmony_citypedef struct { char c; void *x; } st_void_p; 847db96d56Sopenharmony_citypedef struct { char c; size_t x; } st_size_t; 857db96d56Sopenharmony_citypedef struct { char c; _Bool x; } st_bool; 867db96d56Sopenharmony_ci 877db96d56Sopenharmony_ci#define SHORT_ALIGN (sizeof(st_short) - sizeof(short)) 887db96d56Sopenharmony_ci#define INT_ALIGN (sizeof(st_int) - sizeof(int)) 897db96d56Sopenharmony_ci#define LONG_ALIGN (sizeof(st_long) - sizeof(long)) 907db96d56Sopenharmony_ci#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float)) 917db96d56Sopenharmony_ci#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double)) 927db96d56Sopenharmony_ci#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *)) 937db96d56Sopenharmony_ci#define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t)) 947db96d56Sopenharmony_ci#define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool)) 957db96d56Sopenharmony_ci 967db96d56Sopenharmony_ci/* We can't support q and Q in native mode unless the compiler does; 977db96d56Sopenharmony_ci in std mode, they're 8 bytes on all platforms. */ 987db96d56Sopenharmony_citypedef struct { char c; long long x; } s_long_long; 997db96d56Sopenharmony_ci#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long)) 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ci#ifdef __powerc 1027db96d56Sopenharmony_ci#pragma options align=reset 1037db96d56Sopenharmony_ci#endif 1047db96d56Sopenharmony_ci 1057db96d56Sopenharmony_ci/*[python input] 1067db96d56Sopenharmony_ciclass cache_struct_converter(CConverter): 1077db96d56Sopenharmony_ci type = 'PyStructObject *' 1087db96d56Sopenharmony_ci converter = 'cache_struct_converter' 1097db96d56Sopenharmony_ci c_default = "NULL" 1107db96d56Sopenharmony_ci 1117db96d56Sopenharmony_ci def parse_arg(self, argname, displayname): 1127db96d56Sopenharmony_ci return """ 1137db96d56Sopenharmony_ci if (!{converter}(module, {argname}, &{paramname})) {{{{ 1147db96d56Sopenharmony_ci goto exit; 1157db96d56Sopenharmony_ci }}}} 1167db96d56Sopenharmony_ci """.format(argname=argname, paramname=self.name, 1177db96d56Sopenharmony_ci converter=self.converter) 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci def cleanup(self): 1207db96d56Sopenharmony_ci return "Py_XDECREF(%s);\n" % self.name 1217db96d56Sopenharmony_ci[python start generated code]*/ 1227db96d56Sopenharmony_ci/*[python end generated code: output=da39a3ee5e6b4b0d input=d6746621c2fb1a7d]*/ 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_cistatic int cache_struct_converter(PyObject *, PyObject *, PyStructObject **); 1257db96d56Sopenharmony_ci 1267db96d56Sopenharmony_ci#include "clinic/_struct.c.h" 1277db96d56Sopenharmony_ci 1287db96d56Sopenharmony_ci/* Helper for integer format codes: converts an arbitrary Python object to a 1297db96d56Sopenharmony_ci PyLongObject if possible, otherwise fails. Caller should decref. */ 1307db96d56Sopenharmony_ci 1317db96d56Sopenharmony_cistatic PyObject * 1327db96d56Sopenharmony_ciget_pylong(_structmodulestate *state, PyObject *v) 1337db96d56Sopenharmony_ci{ 1347db96d56Sopenharmony_ci assert(v != NULL); 1357db96d56Sopenharmony_ci if (!PyLong_Check(v)) { 1367db96d56Sopenharmony_ci /* Not an integer; try to use __index__ to convert. */ 1377db96d56Sopenharmony_ci if (PyIndex_Check(v)) { 1387db96d56Sopenharmony_ci v = _PyNumber_Index(v); 1397db96d56Sopenharmony_ci if (v == NULL) 1407db96d56Sopenharmony_ci return NULL; 1417db96d56Sopenharmony_ci } 1427db96d56Sopenharmony_ci else { 1437db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 1447db96d56Sopenharmony_ci "required argument is not an integer"); 1457db96d56Sopenharmony_ci return NULL; 1467db96d56Sopenharmony_ci } 1477db96d56Sopenharmony_ci } 1487db96d56Sopenharmony_ci else 1497db96d56Sopenharmony_ci Py_INCREF(v); 1507db96d56Sopenharmony_ci 1517db96d56Sopenharmony_ci assert(PyLong_Check(v)); 1527db96d56Sopenharmony_ci return v; 1537db96d56Sopenharmony_ci} 1547db96d56Sopenharmony_ci 1557db96d56Sopenharmony_ci/* Helper routine to get a C long and raise the appropriate error if it isn't 1567db96d56Sopenharmony_ci one */ 1577db96d56Sopenharmony_ci 1587db96d56Sopenharmony_cistatic int 1597db96d56Sopenharmony_ciget_long(_structmodulestate *state, PyObject *v, long *p) 1607db96d56Sopenharmony_ci{ 1617db96d56Sopenharmony_ci long x; 1627db96d56Sopenharmony_ci 1637db96d56Sopenharmony_ci v = get_pylong(state, v); 1647db96d56Sopenharmony_ci if (v == NULL) 1657db96d56Sopenharmony_ci return -1; 1667db96d56Sopenharmony_ci assert(PyLong_Check(v)); 1677db96d56Sopenharmony_ci x = PyLong_AsLong(v); 1687db96d56Sopenharmony_ci Py_DECREF(v); 1697db96d56Sopenharmony_ci if (x == (long)-1 && PyErr_Occurred()) { 1707db96d56Sopenharmony_ci if (PyErr_ExceptionMatches(PyExc_OverflowError)) 1717db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 1727db96d56Sopenharmony_ci "argument out of range"); 1737db96d56Sopenharmony_ci return -1; 1747db96d56Sopenharmony_ci } 1757db96d56Sopenharmony_ci *p = x; 1767db96d56Sopenharmony_ci return 0; 1777db96d56Sopenharmony_ci} 1787db96d56Sopenharmony_ci 1797db96d56Sopenharmony_ci 1807db96d56Sopenharmony_ci/* Same, but handling unsigned long */ 1817db96d56Sopenharmony_ci 1827db96d56Sopenharmony_cistatic int 1837db96d56Sopenharmony_ciget_ulong(_structmodulestate *state, PyObject *v, unsigned long *p) 1847db96d56Sopenharmony_ci{ 1857db96d56Sopenharmony_ci unsigned long x; 1867db96d56Sopenharmony_ci 1877db96d56Sopenharmony_ci v = get_pylong(state, v); 1887db96d56Sopenharmony_ci if (v == NULL) 1897db96d56Sopenharmony_ci return -1; 1907db96d56Sopenharmony_ci assert(PyLong_Check(v)); 1917db96d56Sopenharmony_ci x = PyLong_AsUnsignedLong(v); 1927db96d56Sopenharmony_ci Py_DECREF(v); 1937db96d56Sopenharmony_ci if (x == (unsigned long)-1 && PyErr_Occurred()) { 1947db96d56Sopenharmony_ci if (PyErr_ExceptionMatches(PyExc_OverflowError)) 1957db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 1967db96d56Sopenharmony_ci "argument out of range"); 1977db96d56Sopenharmony_ci return -1; 1987db96d56Sopenharmony_ci } 1997db96d56Sopenharmony_ci *p = x; 2007db96d56Sopenharmony_ci return 0; 2017db96d56Sopenharmony_ci} 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_ci/* Same, but handling native long long. */ 2047db96d56Sopenharmony_ci 2057db96d56Sopenharmony_cistatic int 2067db96d56Sopenharmony_ciget_longlong(_structmodulestate *state, PyObject *v, long long *p) 2077db96d56Sopenharmony_ci{ 2087db96d56Sopenharmony_ci long long x; 2097db96d56Sopenharmony_ci 2107db96d56Sopenharmony_ci v = get_pylong(state, v); 2117db96d56Sopenharmony_ci if (v == NULL) 2127db96d56Sopenharmony_ci return -1; 2137db96d56Sopenharmony_ci assert(PyLong_Check(v)); 2147db96d56Sopenharmony_ci x = PyLong_AsLongLong(v); 2157db96d56Sopenharmony_ci Py_DECREF(v); 2167db96d56Sopenharmony_ci if (x == (long long)-1 && PyErr_Occurred()) { 2177db96d56Sopenharmony_ci if (PyErr_ExceptionMatches(PyExc_OverflowError)) 2187db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 2197db96d56Sopenharmony_ci "argument out of range"); 2207db96d56Sopenharmony_ci return -1; 2217db96d56Sopenharmony_ci } 2227db96d56Sopenharmony_ci *p = x; 2237db96d56Sopenharmony_ci return 0; 2247db96d56Sopenharmony_ci} 2257db96d56Sopenharmony_ci 2267db96d56Sopenharmony_ci/* Same, but handling native unsigned long long. */ 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_cistatic int 2297db96d56Sopenharmony_ciget_ulonglong(_structmodulestate *state, PyObject *v, unsigned long long *p) 2307db96d56Sopenharmony_ci{ 2317db96d56Sopenharmony_ci unsigned long long x; 2327db96d56Sopenharmony_ci 2337db96d56Sopenharmony_ci v = get_pylong(state, v); 2347db96d56Sopenharmony_ci if (v == NULL) 2357db96d56Sopenharmony_ci return -1; 2367db96d56Sopenharmony_ci assert(PyLong_Check(v)); 2377db96d56Sopenharmony_ci x = PyLong_AsUnsignedLongLong(v); 2387db96d56Sopenharmony_ci Py_DECREF(v); 2397db96d56Sopenharmony_ci if (x == (unsigned long long)-1 && PyErr_Occurred()) { 2407db96d56Sopenharmony_ci if (PyErr_ExceptionMatches(PyExc_OverflowError)) 2417db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 2427db96d56Sopenharmony_ci "argument out of range"); 2437db96d56Sopenharmony_ci return -1; 2447db96d56Sopenharmony_ci } 2457db96d56Sopenharmony_ci *p = x; 2467db96d56Sopenharmony_ci return 0; 2477db96d56Sopenharmony_ci} 2487db96d56Sopenharmony_ci 2497db96d56Sopenharmony_ci/* Same, but handling Py_ssize_t */ 2507db96d56Sopenharmony_ci 2517db96d56Sopenharmony_cistatic int 2527db96d56Sopenharmony_ciget_ssize_t(_structmodulestate *state, PyObject *v, Py_ssize_t *p) 2537db96d56Sopenharmony_ci{ 2547db96d56Sopenharmony_ci Py_ssize_t x; 2557db96d56Sopenharmony_ci 2567db96d56Sopenharmony_ci v = get_pylong(state, v); 2577db96d56Sopenharmony_ci if (v == NULL) 2587db96d56Sopenharmony_ci return -1; 2597db96d56Sopenharmony_ci assert(PyLong_Check(v)); 2607db96d56Sopenharmony_ci x = PyLong_AsSsize_t(v); 2617db96d56Sopenharmony_ci Py_DECREF(v); 2627db96d56Sopenharmony_ci if (x == (Py_ssize_t)-1 && PyErr_Occurred()) { 2637db96d56Sopenharmony_ci if (PyErr_ExceptionMatches(PyExc_OverflowError)) 2647db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 2657db96d56Sopenharmony_ci "argument out of range"); 2667db96d56Sopenharmony_ci return -1; 2677db96d56Sopenharmony_ci } 2687db96d56Sopenharmony_ci *p = x; 2697db96d56Sopenharmony_ci return 0; 2707db96d56Sopenharmony_ci} 2717db96d56Sopenharmony_ci 2727db96d56Sopenharmony_ci/* Same, but handling size_t */ 2737db96d56Sopenharmony_ci 2747db96d56Sopenharmony_cistatic int 2757db96d56Sopenharmony_ciget_size_t(_structmodulestate *state, PyObject *v, size_t *p) 2767db96d56Sopenharmony_ci{ 2777db96d56Sopenharmony_ci size_t x; 2787db96d56Sopenharmony_ci 2797db96d56Sopenharmony_ci v = get_pylong(state, v); 2807db96d56Sopenharmony_ci if (v == NULL) 2817db96d56Sopenharmony_ci return -1; 2827db96d56Sopenharmony_ci assert(PyLong_Check(v)); 2837db96d56Sopenharmony_ci x = PyLong_AsSize_t(v); 2847db96d56Sopenharmony_ci Py_DECREF(v); 2857db96d56Sopenharmony_ci if (x == (size_t)-1 && PyErr_Occurred()) { 2867db96d56Sopenharmony_ci if (PyErr_ExceptionMatches(PyExc_OverflowError)) 2877db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 2887db96d56Sopenharmony_ci "argument out of range"); 2897db96d56Sopenharmony_ci return -1; 2907db96d56Sopenharmony_ci } 2917db96d56Sopenharmony_ci *p = x; 2927db96d56Sopenharmony_ci return 0; 2937db96d56Sopenharmony_ci} 2947db96d56Sopenharmony_ci 2957db96d56Sopenharmony_ci 2967db96d56Sopenharmony_ci#define RANGE_ERROR(state, x, f, flag, mask) return _range_error(state, f, flag) 2977db96d56Sopenharmony_ci 2987db96d56Sopenharmony_ci 2997db96d56Sopenharmony_ci/* Floating point helpers */ 3007db96d56Sopenharmony_ci 3017db96d56Sopenharmony_cistatic PyObject * 3027db96d56Sopenharmony_ciunpack_halffloat(const char *p, /* start of 2-byte string */ 3037db96d56Sopenharmony_ci int le) /* true for little-endian, false for big-endian */ 3047db96d56Sopenharmony_ci{ 3057db96d56Sopenharmony_ci double x = PyFloat_Unpack2(p, le); 3067db96d56Sopenharmony_ci if (x == -1.0 && PyErr_Occurred()) { 3077db96d56Sopenharmony_ci return NULL; 3087db96d56Sopenharmony_ci } 3097db96d56Sopenharmony_ci return PyFloat_FromDouble(x); 3107db96d56Sopenharmony_ci} 3117db96d56Sopenharmony_ci 3127db96d56Sopenharmony_cistatic int 3137db96d56Sopenharmony_cipack_halffloat(_structmodulestate *state, 3147db96d56Sopenharmony_ci char *p, /* start of 2-byte string */ 3157db96d56Sopenharmony_ci PyObject *v, /* value to pack */ 3167db96d56Sopenharmony_ci int le) /* true for little-endian, false for big-endian */ 3177db96d56Sopenharmony_ci{ 3187db96d56Sopenharmony_ci double x = PyFloat_AsDouble(v); 3197db96d56Sopenharmony_ci if (x == -1.0 && PyErr_Occurred()) { 3207db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 3217db96d56Sopenharmony_ci "required argument is not a float"); 3227db96d56Sopenharmony_ci return -1; 3237db96d56Sopenharmony_ci } 3247db96d56Sopenharmony_ci return PyFloat_Pack2(x, p, le); 3257db96d56Sopenharmony_ci} 3267db96d56Sopenharmony_ci 3277db96d56Sopenharmony_cistatic PyObject * 3287db96d56Sopenharmony_ciunpack_float(const char *p, /* start of 4-byte string */ 3297db96d56Sopenharmony_ci int le) /* true for little-endian, false for big-endian */ 3307db96d56Sopenharmony_ci{ 3317db96d56Sopenharmony_ci double x; 3327db96d56Sopenharmony_ci 3337db96d56Sopenharmony_ci x = PyFloat_Unpack4(p, le); 3347db96d56Sopenharmony_ci if (x == -1.0 && PyErr_Occurred()) 3357db96d56Sopenharmony_ci return NULL; 3367db96d56Sopenharmony_ci return PyFloat_FromDouble(x); 3377db96d56Sopenharmony_ci} 3387db96d56Sopenharmony_ci 3397db96d56Sopenharmony_cistatic PyObject * 3407db96d56Sopenharmony_ciunpack_double(const char *p, /* start of 8-byte string */ 3417db96d56Sopenharmony_ci int le) /* true for little-endian, false for big-endian */ 3427db96d56Sopenharmony_ci{ 3437db96d56Sopenharmony_ci double x; 3447db96d56Sopenharmony_ci 3457db96d56Sopenharmony_ci x = PyFloat_Unpack8(p, le); 3467db96d56Sopenharmony_ci if (x == -1.0 && PyErr_Occurred()) 3477db96d56Sopenharmony_ci return NULL; 3487db96d56Sopenharmony_ci return PyFloat_FromDouble(x); 3497db96d56Sopenharmony_ci} 3507db96d56Sopenharmony_ci 3517db96d56Sopenharmony_ci/* Helper to format the range error exceptions */ 3527db96d56Sopenharmony_cistatic int 3537db96d56Sopenharmony_ci_range_error(_structmodulestate *state, const formatdef *f, int is_unsigned) 3547db96d56Sopenharmony_ci{ 3557db96d56Sopenharmony_ci /* ulargest is the largest unsigned value with f->size bytes. 3567db96d56Sopenharmony_ci * Note that the simpler: 3577db96d56Sopenharmony_ci * ((size_t)1 << (f->size * 8)) - 1 3587db96d56Sopenharmony_ci * doesn't work when f->size == sizeof(size_t) because C doesn't 3597db96d56Sopenharmony_ci * define what happens when a left shift count is >= the number of 3607db96d56Sopenharmony_ci * bits in the integer being shifted; e.g., on some boxes it doesn't 3617db96d56Sopenharmony_ci * shift at all when they're equal. 3627db96d56Sopenharmony_ci */ 3637db96d56Sopenharmony_ci const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8); 3647db96d56Sopenharmony_ci assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T); 3657db96d56Sopenharmony_ci if (is_unsigned) 3667db96d56Sopenharmony_ci PyErr_Format(state->StructError, 3677db96d56Sopenharmony_ci "'%c' format requires 0 <= number <= %zu", 3687db96d56Sopenharmony_ci f->format, 3697db96d56Sopenharmony_ci ulargest); 3707db96d56Sopenharmony_ci else { 3717db96d56Sopenharmony_ci const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1); 3727db96d56Sopenharmony_ci PyErr_Format(state->StructError, 3737db96d56Sopenharmony_ci "'%c' format requires %zd <= number <= %zd", 3747db96d56Sopenharmony_ci f->format, 3757db96d56Sopenharmony_ci ~ largest, 3767db96d56Sopenharmony_ci largest); 3777db96d56Sopenharmony_ci } 3787db96d56Sopenharmony_ci 3797db96d56Sopenharmony_ci return -1; 3807db96d56Sopenharmony_ci} 3817db96d56Sopenharmony_ci 3827db96d56Sopenharmony_ci 3837db96d56Sopenharmony_ci 3847db96d56Sopenharmony_ci/* A large number of small routines follow, with names of the form 3857db96d56Sopenharmony_ci 3867db96d56Sopenharmony_ci [bln][up]_TYPE 3877db96d56Sopenharmony_ci 3887db96d56Sopenharmony_ci [bln] distinguishes among big-endian, little-endian and native. 3897db96d56Sopenharmony_ci [pu] distinguishes between pack (to struct) and unpack (from struct). 3907db96d56Sopenharmony_ci TYPE is one of char, byte, ubyte, etc. 3917db96d56Sopenharmony_ci*/ 3927db96d56Sopenharmony_ci 3937db96d56Sopenharmony_ci/* Native mode routines. ****************************************************/ 3947db96d56Sopenharmony_ci/* NOTE: 3957db96d56Sopenharmony_ci In all n[up]_<type> routines handling types larger than 1 byte, there is 3967db96d56Sopenharmony_ci *no* guarantee that the p pointer is properly aligned for each type, 3977db96d56Sopenharmony_ci therefore memcpy is called. An intermediate variable is used to 3987db96d56Sopenharmony_ci compensate for big-endian architectures. 3997db96d56Sopenharmony_ci Normally both the intermediate variable and the memcpy call will be 4007db96d56Sopenharmony_ci skipped by C optimisation in little-endian architectures (gcc >= 2.91 4017db96d56Sopenharmony_ci does this). */ 4027db96d56Sopenharmony_ci 4037db96d56Sopenharmony_cistatic PyObject * 4047db96d56Sopenharmony_cinu_char(_structmodulestate *state, const char *p, const formatdef *f) 4057db96d56Sopenharmony_ci{ 4067db96d56Sopenharmony_ci return PyBytes_FromStringAndSize(p, 1); 4077db96d56Sopenharmony_ci} 4087db96d56Sopenharmony_ci 4097db96d56Sopenharmony_cistatic PyObject * 4107db96d56Sopenharmony_cinu_byte(_structmodulestate *state, const char *p, const formatdef *f) 4117db96d56Sopenharmony_ci{ 4127db96d56Sopenharmony_ci return PyLong_FromLong((long) *(signed char *)p); 4137db96d56Sopenharmony_ci} 4147db96d56Sopenharmony_ci 4157db96d56Sopenharmony_cistatic PyObject * 4167db96d56Sopenharmony_cinu_ubyte(_structmodulestate *state, const char *p, const formatdef *f) 4177db96d56Sopenharmony_ci{ 4187db96d56Sopenharmony_ci return PyLong_FromLong((long) *(unsigned char *)p); 4197db96d56Sopenharmony_ci} 4207db96d56Sopenharmony_ci 4217db96d56Sopenharmony_cistatic PyObject * 4227db96d56Sopenharmony_cinu_short(_structmodulestate *state, const char *p, const formatdef *f) 4237db96d56Sopenharmony_ci{ 4247db96d56Sopenharmony_ci short x; 4257db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 4267db96d56Sopenharmony_ci return PyLong_FromLong((long)x); 4277db96d56Sopenharmony_ci} 4287db96d56Sopenharmony_ci 4297db96d56Sopenharmony_cistatic PyObject * 4307db96d56Sopenharmony_cinu_ushort(_structmodulestate *state, const char *p, const formatdef *f) 4317db96d56Sopenharmony_ci{ 4327db96d56Sopenharmony_ci unsigned short x; 4337db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 4347db96d56Sopenharmony_ci return PyLong_FromLong((long)x); 4357db96d56Sopenharmony_ci} 4367db96d56Sopenharmony_ci 4377db96d56Sopenharmony_cistatic PyObject * 4387db96d56Sopenharmony_cinu_int(_structmodulestate *state, const char *p, const formatdef *f) 4397db96d56Sopenharmony_ci{ 4407db96d56Sopenharmony_ci int x; 4417db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 4427db96d56Sopenharmony_ci return PyLong_FromLong((long)x); 4437db96d56Sopenharmony_ci} 4447db96d56Sopenharmony_ci 4457db96d56Sopenharmony_cistatic PyObject * 4467db96d56Sopenharmony_cinu_uint(_structmodulestate *state, const char *p, const formatdef *f) 4477db96d56Sopenharmony_ci{ 4487db96d56Sopenharmony_ci unsigned int x; 4497db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 4507db96d56Sopenharmony_ci return PyLong_FromUnsignedLong((unsigned long)x); 4517db96d56Sopenharmony_ci} 4527db96d56Sopenharmony_ci 4537db96d56Sopenharmony_cistatic PyObject * 4547db96d56Sopenharmony_cinu_long(_structmodulestate *state, const char *p, const formatdef *f) 4557db96d56Sopenharmony_ci{ 4567db96d56Sopenharmony_ci long x; 4577db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 4587db96d56Sopenharmony_ci return PyLong_FromLong(x); 4597db96d56Sopenharmony_ci} 4607db96d56Sopenharmony_ci 4617db96d56Sopenharmony_cistatic PyObject * 4627db96d56Sopenharmony_cinu_ulong(_structmodulestate *state, const char *p, const formatdef *f) 4637db96d56Sopenharmony_ci{ 4647db96d56Sopenharmony_ci unsigned long x; 4657db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 4667db96d56Sopenharmony_ci return PyLong_FromUnsignedLong(x); 4677db96d56Sopenharmony_ci} 4687db96d56Sopenharmony_ci 4697db96d56Sopenharmony_cistatic PyObject * 4707db96d56Sopenharmony_cinu_ssize_t(_structmodulestate *state, const char *p, const formatdef *f) 4717db96d56Sopenharmony_ci{ 4727db96d56Sopenharmony_ci Py_ssize_t x; 4737db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 4747db96d56Sopenharmony_ci return PyLong_FromSsize_t(x); 4757db96d56Sopenharmony_ci} 4767db96d56Sopenharmony_ci 4777db96d56Sopenharmony_cistatic PyObject * 4787db96d56Sopenharmony_cinu_size_t(_structmodulestate *state, const char *p, const formatdef *f) 4797db96d56Sopenharmony_ci{ 4807db96d56Sopenharmony_ci size_t x; 4817db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 4827db96d56Sopenharmony_ci return PyLong_FromSize_t(x); 4837db96d56Sopenharmony_ci} 4847db96d56Sopenharmony_ci 4857db96d56Sopenharmony_cistatic PyObject * 4867db96d56Sopenharmony_cinu_longlong(_structmodulestate *state, const char *p, const formatdef *f) 4877db96d56Sopenharmony_ci{ 4887db96d56Sopenharmony_ci long long x; 4897db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 4907db96d56Sopenharmony_ci return PyLong_FromLongLong(x); 4917db96d56Sopenharmony_ci} 4927db96d56Sopenharmony_ci 4937db96d56Sopenharmony_cistatic PyObject * 4947db96d56Sopenharmony_cinu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f) 4957db96d56Sopenharmony_ci{ 4967db96d56Sopenharmony_ci unsigned long long x; 4977db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 4987db96d56Sopenharmony_ci return PyLong_FromUnsignedLongLong(x); 4997db96d56Sopenharmony_ci} 5007db96d56Sopenharmony_ci 5017db96d56Sopenharmony_cistatic PyObject * 5027db96d56Sopenharmony_cinu_bool(_structmodulestate *state, const char *p, const formatdef *f) 5037db96d56Sopenharmony_ci{ 5047db96d56Sopenharmony_ci _Bool x; 5057db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 5067db96d56Sopenharmony_ci return PyBool_FromLong(x != 0); 5077db96d56Sopenharmony_ci} 5087db96d56Sopenharmony_ci 5097db96d56Sopenharmony_ci 5107db96d56Sopenharmony_cistatic PyObject * 5117db96d56Sopenharmony_cinu_halffloat(_structmodulestate *state, const char *p, const formatdef *f) 5127db96d56Sopenharmony_ci{ 5137db96d56Sopenharmony_ci#if PY_LITTLE_ENDIAN 5147db96d56Sopenharmony_ci return unpack_halffloat(p, 1); 5157db96d56Sopenharmony_ci#else 5167db96d56Sopenharmony_ci return unpack_halffloat(p, 0); 5177db96d56Sopenharmony_ci#endif 5187db96d56Sopenharmony_ci} 5197db96d56Sopenharmony_ci 5207db96d56Sopenharmony_cistatic PyObject * 5217db96d56Sopenharmony_cinu_float(_structmodulestate *state, const char *p, const formatdef *f) 5227db96d56Sopenharmony_ci{ 5237db96d56Sopenharmony_ci float x; 5247db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 5257db96d56Sopenharmony_ci return PyFloat_FromDouble((double)x); 5267db96d56Sopenharmony_ci} 5277db96d56Sopenharmony_ci 5287db96d56Sopenharmony_cistatic PyObject * 5297db96d56Sopenharmony_cinu_double(_structmodulestate *state, const char *p, const formatdef *f) 5307db96d56Sopenharmony_ci{ 5317db96d56Sopenharmony_ci double x; 5327db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 5337db96d56Sopenharmony_ci return PyFloat_FromDouble(x); 5347db96d56Sopenharmony_ci} 5357db96d56Sopenharmony_ci 5367db96d56Sopenharmony_cistatic PyObject * 5377db96d56Sopenharmony_cinu_void_p(_structmodulestate *state, const char *p, const formatdef *f) 5387db96d56Sopenharmony_ci{ 5397db96d56Sopenharmony_ci void *x; 5407db96d56Sopenharmony_ci memcpy((char *)&x, p, sizeof x); 5417db96d56Sopenharmony_ci return PyLong_FromVoidPtr(x); 5427db96d56Sopenharmony_ci} 5437db96d56Sopenharmony_ci 5447db96d56Sopenharmony_cistatic int 5457db96d56Sopenharmony_cinp_byte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 5467db96d56Sopenharmony_ci{ 5477db96d56Sopenharmony_ci long x; 5487db96d56Sopenharmony_ci if (get_long(state, v, &x) < 0) 5497db96d56Sopenharmony_ci return -1; 5507db96d56Sopenharmony_ci if (x < -128 || x > 127) { 5517db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 5527db96d56Sopenharmony_ci "byte format requires -128 <= number <= 127"); 5537db96d56Sopenharmony_ci return -1; 5547db96d56Sopenharmony_ci } 5557db96d56Sopenharmony_ci *p = (char)x; 5567db96d56Sopenharmony_ci return 0; 5577db96d56Sopenharmony_ci} 5587db96d56Sopenharmony_ci 5597db96d56Sopenharmony_cistatic int 5607db96d56Sopenharmony_cinp_ubyte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 5617db96d56Sopenharmony_ci{ 5627db96d56Sopenharmony_ci long x; 5637db96d56Sopenharmony_ci if (get_long(state, v, &x) < 0) 5647db96d56Sopenharmony_ci return -1; 5657db96d56Sopenharmony_ci if (x < 0 || x > 255) { 5667db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 5677db96d56Sopenharmony_ci "ubyte format requires 0 <= number <= 255"); 5687db96d56Sopenharmony_ci return -1; 5697db96d56Sopenharmony_ci } 5707db96d56Sopenharmony_ci *(unsigned char *)p = (unsigned char)x; 5717db96d56Sopenharmony_ci return 0; 5727db96d56Sopenharmony_ci} 5737db96d56Sopenharmony_ci 5747db96d56Sopenharmony_cistatic int 5757db96d56Sopenharmony_cinp_char(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 5767db96d56Sopenharmony_ci{ 5777db96d56Sopenharmony_ci if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) { 5787db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 5797db96d56Sopenharmony_ci "char format requires a bytes object of length 1"); 5807db96d56Sopenharmony_ci return -1; 5817db96d56Sopenharmony_ci } 5827db96d56Sopenharmony_ci *p = *PyBytes_AS_STRING(v); 5837db96d56Sopenharmony_ci return 0; 5847db96d56Sopenharmony_ci} 5857db96d56Sopenharmony_ci 5867db96d56Sopenharmony_cistatic int 5877db96d56Sopenharmony_cinp_short(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 5887db96d56Sopenharmony_ci{ 5897db96d56Sopenharmony_ci long x; 5907db96d56Sopenharmony_ci short y; 5917db96d56Sopenharmony_ci if (get_long(state, v, &x) < 0) 5927db96d56Sopenharmony_ci return -1; 5937db96d56Sopenharmony_ci if (x < SHRT_MIN || x > SHRT_MAX) { 5947db96d56Sopenharmony_ci PyErr_Format(state->StructError, 5957db96d56Sopenharmony_ci "short format requires %d <= number <= %d", 5967db96d56Sopenharmony_ci (int)SHRT_MIN, (int)SHRT_MAX); 5977db96d56Sopenharmony_ci return -1; 5987db96d56Sopenharmony_ci } 5997db96d56Sopenharmony_ci y = (short)x; 6007db96d56Sopenharmony_ci memcpy(p, (char *)&y, sizeof y); 6017db96d56Sopenharmony_ci return 0; 6027db96d56Sopenharmony_ci} 6037db96d56Sopenharmony_ci 6047db96d56Sopenharmony_cistatic int 6057db96d56Sopenharmony_cinp_ushort(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 6067db96d56Sopenharmony_ci{ 6077db96d56Sopenharmony_ci long x; 6087db96d56Sopenharmony_ci unsigned short y; 6097db96d56Sopenharmony_ci if (get_long(state, v, &x) < 0) 6107db96d56Sopenharmony_ci return -1; 6117db96d56Sopenharmony_ci if (x < 0 || x > USHRT_MAX) { 6127db96d56Sopenharmony_ci PyErr_Format(state->StructError, 6137db96d56Sopenharmony_ci "ushort format requires 0 <= number <= %u", 6147db96d56Sopenharmony_ci (unsigned int)USHRT_MAX); 6157db96d56Sopenharmony_ci return -1; 6167db96d56Sopenharmony_ci } 6177db96d56Sopenharmony_ci y = (unsigned short)x; 6187db96d56Sopenharmony_ci memcpy(p, (char *)&y, sizeof y); 6197db96d56Sopenharmony_ci return 0; 6207db96d56Sopenharmony_ci} 6217db96d56Sopenharmony_ci 6227db96d56Sopenharmony_cistatic int 6237db96d56Sopenharmony_cinp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 6247db96d56Sopenharmony_ci{ 6257db96d56Sopenharmony_ci long x; 6267db96d56Sopenharmony_ci int y; 6277db96d56Sopenharmony_ci if (get_long(state, v, &x) < 0) 6287db96d56Sopenharmony_ci return -1; 6297db96d56Sopenharmony_ci#if (SIZEOF_LONG > SIZEOF_INT) 6307db96d56Sopenharmony_ci if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX))) 6317db96d56Sopenharmony_ci RANGE_ERROR(state, x, f, 0, -1); 6327db96d56Sopenharmony_ci#endif 6337db96d56Sopenharmony_ci y = (int)x; 6347db96d56Sopenharmony_ci memcpy(p, (char *)&y, sizeof y); 6357db96d56Sopenharmony_ci return 0; 6367db96d56Sopenharmony_ci} 6377db96d56Sopenharmony_ci 6387db96d56Sopenharmony_cistatic int 6397db96d56Sopenharmony_cinp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 6407db96d56Sopenharmony_ci{ 6417db96d56Sopenharmony_ci unsigned long x; 6427db96d56Sopenharmony_ci unsigned int y; 6437db96d56Sopenharmony_ci if (get_ulong(state, v, &x) < 0) 6447db96d56Sopenharmony_ci return -1; 6457db96d56Sopenharmony_ci y = (unsigned int)x; 6467db96d56Sopenharmony_ci#if (SIZEOF_LONG > SIZEOF_INT) 6477db96d56Sopenharmony_ci if (x > ((unsigned long)UINT_MAX)) 6487db96d56Sopenharmony_ci RANGE_ERROR(state, y, f, 1, -1); 6497db96d56Sopenharmony_ci#endif 6507db96d56Sopenharmony_ci memcpy(p, (char *)&y, sizeof y); 6517db96d56Sopenharmony_ci return 0; 6527db96d56Sopenharmony_ci} 6537db96d56Sopenharmony_ci 6547db96d56Sopenharmony_cistatic int 6557db96d56Sopenharmony_cinp_long(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 6567db96d56Sopenharmony_ci{ 6577db96d56Sopenharmony_ci long x; 6587db96d56Sopenharmony_ci if (get_long(state, v, &x) < 0) 6597db96d56Sopenharmony_ci return -1; 6607db96d56Sopenharmony_ci memcpy(p, (char *)&x, sizeof x); 6617db96d56Sopenharmony_ci return 0; 6627db96d56Sopenharmony_ci} 6637db96d56Sopenharmony_ci 6647db96d56Sopenharmony_cistatic int 6657db96d56Sopenharmony_cinp_ulong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 6667db96d56Sopenharmony_ci{ 6677db96d56Sopenharmony_ci unsigned long x; 6687db96d56Sopenharmony_ci if (get_ulong(state, v, &x) < 0) 6697db96d56Sopenharmony_ci return -1; 6707db96d56Sopenharmony_ci memcpy(p, (char *)&x, sizeof x); 6717db96d56Sopenharmony_ci return 0; 6727db96d56Sopenharmony_ci} 6737db96d56Sopenharmony_ci 6747db96d56Sopenharmony_cistatic int 6757db96d56Sopenharmony_cinp_ssize_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 6767db96d56Sopenharmony_ci{ 6777db96d56Sopenharmony_ci Py_ssize_t x; 6787db96d56Sopenharmony_ci if (get_ssize_t(state, v, &x) < 0) 6797db96d56Sopenharmony_ci return -1; 6807db96d56Sopenharmony_ci memcpy(p, (char *)&x, sizeof x); 6817db96d56Sopenharmony_ci return 0; 6827db96d56Sopenharmony_ci} 6837db96d56Sopenharmony_ci 6847db96d56Sopenharmony_cistatic int 6857db96d56Sopenharmony_cinp_size_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 6867db96d56Sopenharmony_ci{ 6877db96d56Sopenharmony_ci size_t x; 6887db96d56Sopenharmony_ci if (get_size_t(state, v, &x) < 0) 6897db96d56Sopenharmony_ci return -1; 6907db96d56Sopenharmony_ci memcpy(p, (char *)&x, sizeof x); 6917db96d56Sopenharmony_ci return 0; 6927db96d56Sopenharmony_ci} 6937db96d56Sopenharmony_ci 6947db96d56Sopenharmony_cistatic int 6957db96d56Sopenharmony_cinp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 6967db96d56Sopenharmony_ci{ 6977db96d56Sopenharmony_ci long long x; 6987db96d56Sopenharmony_ci if (get_longlong(state, v, &x) < 0) 6997db96d56Sopenharmony_ci return -1; 7007db96d56Sopenharmony_ci memcpy(p, (char *)&x, sizeof x); 7017db96d56Sopenharmony_ci return 0; 7027db96d56Sopenharmony_ci} 7037db96d56Sopenharmony_ci 7047db96d56Sopenharmony_cistatic int 7057db96d56Sopenharmony_cinp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 7067db96d56Sopenharmony_ci{ 7077db96d56Sopenharmony_ci unsigned long long x; 7087db96d56Sopenharmony_ci if (get_ulonglong(state, v, &x) < 0) 7097db96d56Sopenharmony_ci return -1; 7107db96d56Sopenharmony_ci memcpy(p, (char *)&x, sizeof x); 7117db96d56Sopenharmony_ci return 0; 7127db96d56Sopenharmony_ci} 7137db96d56Sopenharmony_ci 7147db96d56Sopenharmony_ci 7157db96d56Sopenharmony_cistatic int 7167db96d56Sopenharmony_cinp_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 7177db96d56Sopenharmony_ci{ 7187db96d56Sopenharmony_ci int y; 7197db96d56Sopenharmony_ci _Bool x; 7207db96d56Sopenharmony_ci y = PyObject_IsTrue(v); 7217db96d56Sopenharmony_ci if (y < 0) 7227db96d56Sopenharmony_ci return -1; 7237db96d56Sopenharmony_ci x = y; 7247db96d56Sopenharmony_ci memcpy(p, (char *)&x, sizeof x); 7257db96d56Sopenharmony_ci return 0; 7267db96d56Sopenharmony_ci} 7277db96d56Sopenharmony_ci 7287db96d56Sopenharmony_cistatic int 7297db96d56Sopenharmony_cinp_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 7307db96d56Sopenharmony_ci{ 7317db96d56Sopenharmony_ci#if PY_LITTLE_ENDIAN 7327db96d56Sopenharmony_ci return pack_halffloat(state, p, v, 1); 7337db96d56Sopenharmony_ci#else 7347db96d56Sopenharmony_ci return pack_halffloat(state, p, v, 0); 7357db96d56Sopenharmony_ci#endif 7367db96d56Sopenharmony_ci} 7377db96d56Sopenharmony_ci 7387db96d56Sopenharmony_cistatic int 7397db96d56Sopenharmony_cinp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 7407db96d56Sopenharmony_ci{ 7417db96d56Sopenharmony_ci float x = (float)PyFloat_AsDouble(v); 7427db96d56Sopenharmony_ci if (x == -1 && PyErr_Occurred()) { 7437db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 7447db96d56Sopenharmony_ci "required argument is not a float"); 7457db96d56Sopenharmony_ci return -1; 7467db96d56Sopenharmony_ci } 7477db96d56Sopenharmony_ci memcpy(p, (char *)&x, sizeof x); 7487db96d56Sopenharmony_ci return 0; 7497db96d56Sopenharmony_ci} 7507db96d56Sopenharmony_ci 7517db96d56Sopenharmony_cistatic int 7527db96d56Sopenharmony_cinp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 7537db96d56Sopenharmony_ci{ 7547db96d56Sopenharmony_ci double x = PyFloat_AsDouble(v); 7557db96d56Sopenharmony_ci if (x == -1 && PyErr_Occurred()) { 7567db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 7577db96d56Sopenharmony_ci "required argument is not a float"); 7587db96d56Sopenharmony_ci return -1; 7597db96d56Sopenharmony_ci } 7607db96d56Sopenharmony_ci memcpy(p, (char *)&x, sizeof(double)); 7617db96d56Sopenharmony_ci return 0; 7627db96d56Sopenharmony_ci} 7637db96d56Sopenharmony_ci 7647db96d56Sopenharmony_cistatic int 7657db96d56Sopenharmony_cinp_void_p(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 7667db96d56Sopenharmony_ci{ 7677db96d56Sopenharmony_ci void *x; 7687db96d56Sopenharmony_ci 7697db96d56Sopenharmony_ci v = get_pylong(state, v); 7707db96d56Sopenharmony_ci if (v == NULL) 7717db96d56Sopenharmony_ci return -1; 7727db96d56Sopenharmony_ci assert(PyLong_Check(v)); 7737db96d56Sopenharmony_ci x = PyLong_AsVoidPtr(v); 7747db96d56Sopenharmony_ci Py_DECREF(v); 7757db96d56Sopenharmony_ci if (x == NULL && PyErr_Occurred()) 7767db96d56Sopenharmony_ci return -1; 7777db96d56Sopenharmony_ci memcpy(p, (char *)&x, sizeof x); 7787db96d56Sopenharmony_ci return 0; 7797db96d56Sopenharmony_ci} 7807db96d56Sopenharmony_ci 7817db96d56Sopenharmony_cistatic const formatdef native_table[] = { 7827db96d56Sopenharmony_ci {'x', sizeof(char), 0, NULL}, 7837db96d56Sopenharmony_ci {'b', sizeof(char), 0, nu_byte, np_byte}, 7847db96d56Sopenharmony_ci {'B', sizeof(char), 0, nu_ubyte, np_ubyte}, 7857db96d56Sopenharmony_ci {'c', sizeof(char), 0, nu_char, np_char}, 7867db96d56Sopenharmony_ci {'s', sizeof(char), 0, NULL}, 7877db96d56Sopenharmony_ci {'p', sizeof(char), 0, NULL}, 7887db96d56Sopenharmony_ci {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short}, 7897db96d56Sopenharmony_ci {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort}, 7907db96d56Sopenharmony_ci {'i', sizeof(int), INT_ALIGN, nu_int, np_int}, 7917db96d56Sopenharmony_ci {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint}, 7927db96d56Sopenharmony_ci {'l', sizeof(long), LONG_ALIGN, nu_long, np_long}, 7937db96d56Sopenharmony_ci {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong}, 7947db96d56Sopenharmony_ci {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t}, 7957db96d56Sopenharmony_ci {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t}, 7967db96d56Sopenharmony_ci {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong}, 7977db96d56Sopenharmony_ci {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong}, 7987db96d56Sopenharmony_ci {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool}, 7997db96d56Sopenharmony_ci {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat}, 8007db96d56Sopenharmony_ci {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float}, 8017db96d56Sopenharmony_ci {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double}, 8027db96d56Sopenharmony_ci {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p}, 8037db96d56Sopenharmony_ci {0} 8047db96d56Sopenharmony_ci}; 8057db96d56Sopenharmony_ci 8067db96d56Sopenharmony_ci/* Big-endian routines. *****************************************************/ 8077db96d56Sopenharmony_ci 8087db96d56Sopenharmony_cistatic PyObject * 8097db96d56Sopenharmony_cibu_int(_structmodulestate *state, const char *p, const formatdef *f) 8107db96d56Sopenharmony_ci{ 8117db96d56Sopenharmony_ci long x = 0; 8127db96d56Sopenharmony_ci Py_ssize_t i = f->size; 8137db96d56Sopenharmony_ci const unsigned char *bytes = (const unsigned char *)p; 8147db96d56Sopenharmony_ci do { 8157db96d56Sopenharmony_ci x = (x<<8) | *bytes++; 8167db96d56Sopenharmony_ci } while (--i > 0); 8177db96d56Sopenharmony_ci /* Extend the sign bit. */ 8187db96d56Sopenharmony_ci if (SIZEOF_LONG > f->size) 8197db96d56Sopenharmony_ci x |= -(x & (1L << ((8 * f->size) - 1))); 8207db96d56Sopenharmony_ci return PyLong_FromLong(x); 8217db96d56Sopenharmony_ci} 8227db96d56Sopenharmony_ci 8237db96d56Sopenharmony_cistatic PyObject * 8247db96d56Sopenharmony_cibu_uint(_structmodulestate *state, const char *p, const formatdef *f) 8257db96d56Sopenharmony_ci{ 8267db96d56Sopenharmony_ci unsigned long x = 0; 8277db96d56Sopenharmony_ci Py_ssize_t i = f->size; 8287db96d56Sopenharmony_ci const unsigned char *bytes = (const unsigned char *)p; 8297db96d56Sopenharmony_ci do { 8307db96d56Sopenharmony_ci x = (x<<8) | *bytes++; 8317db96d56Sopenharmony_ci } while (--i > 0); 8327db96d56Sopenharmony_ci return PyLong_FromUnsignedLong(x); 8337db96d56Sopenharmony_ci} 8347db96d56Sopenharmony_ci 8357db96d56Sopenharmony_cistatic PyObject * 8367db96d56Sopenharmony_cibu_longlong(_structmodulestate *state, const char *p, const formatdef *f) 8377db96d56Sopenharmony_ci{ 8387db96d56Sopenharmony_ci long long x = 0; 8397db96d56Sopenharmony_ci Py_ssize_t i = f->size; 8407db96d56Sopenharmony_ci const unsigned char *bytes = (const unsigned char *)p; 8417db96d56Sopenharmony_ci do { 8427db96d56Sopenharmony_ci x = (x<<8) | *bytes++; 8437db96d56Sopenharmony_ci } while (--i > 0); 8447db96d56Sopenharmony_ci /* Extend the sign bit. */ 8457db96d56Sopenharmony_ci if (SIZEOF_LONG_LONG > f->size) 8467db96d56Sopenharmony_ci x |= -(x & ((long long)1 << ((8 * f->size) - 1))); 8477db96d56Sopenharmony_ci return PyLong_FromLongLong(x); 8487db96d56Sopenharmony_ci} 8497db96d56Sopenharmony_ci 8507db96d56Sopenharmony_cistatic PyObject * 8517db96d56Sopenharmony_cibu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f) 8527db96d56Sopenharmony_ci{ 8537db96d56Sopenharmony_ci unsigned long long x = 0; 8547db96d56Sopenharmony_ci Py_ssize_t i = f->size; 8557db96d56Sopenharmony_ci const unsigned char *bytes = (const unsigned char *)p; 8567db96d56Sopenharmony_ci do { 8577db96d56Sopenharmony_ci x = (x<<8) | *bytes++; 8587db96d56Sopenharmony_ci } while (--i > 0); 8597db96d56Sopenharmony_ci return PyLong_FromUnsignedLongLong(x); 8607db96d56Sopenharmony_ci} 8617db96d56Sopenharmony_ci 8627db96d56Sopenharmony_cistatic PyObject * 8637db96d56Sopenharmony_cibu_halffloat(_structmodulestate *state, const char *p, const formatdef *f) 8647db96d56Sopenharmony_ci{ 8657db96d56Sopenharmony_ci return unpack_halffloat(p, 0); 8667db96d56Sopenharmony_ci} 8677db96d56Sopenharmony_ci 8687db96d56Sopenharmony_cistatic PyObject * 8697db96d56Sopenharmony_cibu_float(_structmodulestate *state, const char *p, const formatdef *f) 8707db96d56Sopenharmony_ci{ 8717db96d56Sopenharmony_ci return unpack_float(p, 0); 8727db96d56Sopenharmony_ci} 8737db96d56Sopenharmony_ci 8747db96d56Sopenharmony_cistatic PyObject * 8757db96d56Sopenharmony_cibu_double(_structmodulestate *state, const char *p, const formatdef *f) 8767db96d56Sopenharmony_ci{ 8777db96d56Sopenharmony_ci return unpack_double(p, 0); 8787db96d56Sopenharmony_ci} 8797db96d56Sopenharmony_ci 8807db96d56Sopenharmony_cistatic PyObject * 8817db96d56Sopenharmony_cibu_bool(_structmodulestate *state, const char *p, const formatdef *f) 8827db96d56Sopenharmony_ci{ 8837db96d56Sopenharmony_ci return PyBool_FromLong(*p != 0); 8847db96d56Sopenharmony_ci} 8857db96d56Sopenharmony_ci 8867db96d56Sopenharmony_cistatic int 8877db96d56Sopenharmony_cibp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 8887db96d56Sopenharmony_ci{ 8897db96d56Sopenharmony_ci long x; 8907db96d56Sopenharmony_ci Py_ssize_t i; 8917db96d56Sopenharmony_ci unsigned char *q = (unsigned char *)p; 8927db96d56Sopenharmony_ci if (get_long(state, v, &x) < 0) 8937db96d56Sopenharmony_ci return -1; 8947db96d56Sopenharmony_ci i = f->size; 8957db96d56Sopenharmony_ci if (i != SIZEOF_LONG) { 8967db96d56Sopenharmony_ci if ((i == 2) && (x < -32768 || x > 32767)) 8977db96d56Sopenharmony_ci RANGE_ERROR(state, x, f, 0, 0xffffL); 8987db96d56Sopenharmony_ci#if (SIZEOF_LONG != 4) 8997db96d56Sopenharmony_ci else if ((i == 4) && (x < -2147483648L || x > 2147483647L)) 9007db96d56Sopenharmony_ci RANGE_ERROR(state, x, f, 0, 0xffffffffL); 9017db96d56Sopenharmony_ci#endif 9027db96d56Sopenharmony_ci } 9037db96d56Sopenharmony_ci do { 9047db96d56Sopenharmony_ci q[--i] = (unsigned char)(x & 0xffL); 9057db96d56Sopenharmony_ci x >>= 8; 9067db96d56Sopenharmony_ci } while (i > 0); 9077db96d56Sopenharmony_ci return 0; 9087db96d56Sopenharmony_ci} 9097db96d56Sopenharmony_ci 9107db96d56Sopenharmony_cistatic int 9117db96d56Sopenharmony_cibp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 9127db96d56Sopenharmony_ci{ 9137db96d56Sopenharmony_ci unsigned long x; 9147db96d56Sopenharmony_ci Py_ssize_t i; 9157db96d56Sopenharmony_ci unsigned char *q = (unsigned char *)p; 9167db96d56Sopenharmony_ci if (get_ulong(state, v, &x) < 0) 9177db96d56Sopenharmony_ci return -1; 9187db96d56Sopenharmony_ci i = f->size; 9197db96d56Sopenharmony_ci if (i != SIZEOF_LONG) { 9207db96d56Sopenharmony_ci unsigned long maxint = 1; 9217db96d56Sopenharmony_ci maxint <<= (unsigned long)(i * 8); 9227db96d56Sopenharmony_ci if (x >= maxint) 9237db96d56Sopenharmony_ci RANGE_ERROR(state, x, f, 1, maxint - 1); 9247db96d56Sopenharmony_ci } 9257db96d56Sopenharmony_ci do { 9267db96d56Sopenharmony_ci q[--i] = (unsigned char)(x & 0xffUL); 9277db96d56Sopenharmony_ci x >>= 8; 9287db96d56Sopenharmony_ci } while (i > 0); 9297db96d56Sopenharmony_ci return 0; 9307db96d56Sopenharmony_ci} 9317db96d56Sopenharmony_ci 9327db96d56Sopenharmony_cistatic int 9337db96d56Sopenharmony_cibp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 9347db96d56Sopenharmony_ci{ 9357db96d56Sopenharmony_ci int res; 9367db96d56Sopenharmony_ci v = get_pylong(state, v); 9377db96d56Sopenharmony_ci if (v == NULL) 9387db96d56Sopenharmony_ci return -1; 9397db96d56Sopenharmony_ci res = _PyLong_AsByteArray((PyLongObject *)v, 9407db96d56Sopenharmony_ci (unsigned char *)p, 9417db96d56Sopenharmony_ci 8, 9427db96d56Sopenharmony_ci 0, /* little_endian */ 9437db96d56Sopenharmony_ci 1 /* signed */); 9447db96d56Sopenharmony_ci Py_DECREF(v); 9457db96d56Sopenharmony_ci return res; 9467db96d56Sopenharmony_ci} 9477db96d56Sopenharmony_ci 9487db96d56Sopenharmony_cistatic int 9497db96d56Sopenharmony_cibp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 9507db96d56Sopenharmony_ci{ 9517db96d56Sopenharmony_ci int res; 9527db96d56Sopenharmony_ci v = get_pylong(state, v); 9537db96d56Sopenharmony_ci if (v == NULL) 9547db96d56Sopenharmony_ci return -1; 9557db96d56Sopenharmony_ci res = _PyLong_AsByteArray((PyLongObject *)v, 9567db96d56Sopenharmony_ci (unsigned char *)p, 9577db96d56Sopenharmony_ci 8, 9587db96d56Sopenharmony_ci 0, /* little_endian */ 9597db96d56Sopenharmony_ci 0 /* signed */); 9607db96d56Sopenharmony_ci Py_DECREF(v); 9617db96d56Sopenharmony_ci return res; 9627db96d56Sopenharmony_ci} 9637db96d56Sopenharmony_ci 9647db96d56Sopenharmony_cistatic int 9657db96d56Sopenharmony_cibp_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 9667db96d56Sopenharmony_ci{ 9677db96d56Sopenharmony_ci return pack_halffloat(state, p, v, 0); 9687db96d56Sopenharmony_ci} 9697db96d56Sopenharmony_ci 9707db96d56Sopenharmony_cistatic int 9717db96d56Sopenharmony_cibp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 9727db96d56Sopenharmony_ci{ 9737db96d56Sopenharmony_ci double x = PyFloat_AsDouble(v); 9747db96d56Sopenharmony_ci if (x == -1 && PyErr_Occurred()) { 9757db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 9767db96d56Sopenharmony_ci "required argument is not a float"); 9777db96d56Sopenharmony_ci return -1; 9787db96d56Sopenharmony_ci } 9797db96d56Sopenharmony_ci return PyFloat_Pack4(x, p, 0); 9807db96d56Sopenharmony_ci} 9817db96d56Sopenharmony_ci 9827db96d56Sopenharmony_cistatic int 9837db96d56Sopenharmony_cibp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 9847db96d56Sopenharmony_ci{ 9857db96d56Sopenharmony_ci double x = PyFloat_AsDouble(v); 9867db96d56Sopenharmony_ci if (x == -1 && PyErr_Occurred()) { 9877db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 9887db96d56Sopenharmony_ci "required argument is not a float"); 9897db96d56Sopenharmony_ci return -1; 9907db96d56Sopenharmony_ci } 9917db96d56Sopenharmony_ci return PyFloat_Pack8(x, p, 0); 9927db96d56Sopenharmony_ci} 9937db96d56Sopenharmony_ci 9947db96d56Sopenharmony_cistatic int 9957db96d56Sopenharmony_cibp_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 9967db96d56Sopenharmony_ci{ 9977db96d56Sopenharmony_ci int y; 9987db96d56Sopenharmony_ci y = PyObject_IsTrue(v); 9997db96d56Sopenharmony_ci if (y < 0) 10007db96d56Sopenharmony_ci return -1; 10017db96d56Sopenharmony_ci *p = (char)y; 10027db96d56Sopenharmony_ci return 0; 10037db96d56Sopenharmony_ci} 10047db96d56Sopenharmony_ci 10057db96d56Sopenharmony_cistatic formatdef bigendian_table[] = { 10067db96d56Sopenharmony_ci {'x', 1, 0, NULL}, 10077db96d56Sopenharmony_ci {'b', 1, 0, nu_byte, np_byte}, 10087db96d56Sopenharmony_ci {'B', 1, 0, nu_ubyte, np_ubyte}, 10097db96d56Sopenharmony_ci {'c', 1, 0, nu_char, np_char}, 10107db96d56Sopenharmony_ci {'s', 1, 0, NULL}, 10117db96d56Sopenharmony_ci {'p', 1, 0, NULL}, 10127db96d56Sopenharmony_ci {'h', 2, 0, bu_int, bp_int}, 10137db96d56Sopenharmony_ci {'H', 2, 0, bu_uint, bp_uint}, 10147db96d56Sopenharmony_ci {'i', 4, 0, bu_int, bp_int}, 10157db96d56Sopenharmony_ci {'I', 4, 0, bu_uint, bp_uint}, 10167db96d56Sopenharmony_ci {'l', 4, 0, bu_int, bp_int}, 10177db96d56Sopenharmony_ci {'L', 4, 0, bu_uint, bp_uint}, 10187db96d56Sopenharmony_ci {'q', 8, 0, bu_longlong, bp_longlong}, 10197db96d56Sopenharmony_ci {'Q', 8, 0, bu_ulonglong, bp_ulonglong}, 10207db96d56Sopenharmony_ci {'?', 1, 0, bu_bool, bp_bool}, 10217db96d56Sopenharmony_ci {'e', 2, 0, bu_halffloat, bp_halffloat}, 10227db96d56Sopenharmony_ci {'f', 4, 0, bu_float, bp_float}, 10237db96d56Sopenharmony_ci {'d', 8, 0, bu_double, bp_double}, 10247db96d56Sopenharmony_ci {0} 10257db96d56Sopenharmony_ci}; 10267db96d56Sopenharmony_ci 10277db96d56Sopenharmony_ci/* Little-endian routines. *****************************************************/ 10287db96d56Sopenharmony_ci 10297db96d56Sopenharmony_cistatic PyObject * 10307db96d56Sopenharmony_cilu_int(_structmodulestate *state, const char *p, const formatdef *f) 10317db96d56Sopenharmony_ci{ 10327db96d56Sopenharmony_ci long x = 0; 10337db96d56Sopenharmony_ci Py_ssize_t i = f->size; 10347db96d56Sopenharmony_ci const unsigned char *bytes = (const unsigned char *)p; 10357db96d56Sopenharmony_ci do { 10367db96d56Sopenharmony_ci x = (x<<8) | bytes[--i]; 10377db96d56Sopenharmony_ci } while (i > 0); 10387db96d56Sopenharmony_ci /* Extend the sign bit. */ 10397db96d56Sopenharmony_ci if (SIZEOF_LONG > f->size) 10407db96d56Sopenharmony_ci x |= -(x & (1L << ((8 * f->size) - 1))); 10417db96d56Sopenharmony_ci return PyLong_FromLong(x); 10427db96d56Sopenharmony_ci} 10437db96d56Sopenharmony_ci 10447db96d56Sopenharmony_cistatic PyObject * 10457db96d56Sopenharmony_cilu_uint(_structmodulestate *state, const char *p, const formatdef *f) 10467db96d56Sopenharmony_ci{ 10477db96d56Sopenharmony_ci unsigned long x = 0; 10487db96d56Sopenharmony_ci Py_ssize_t i = f->size; 10497db96d56Sopenharmony_ci const unsigned char *bytes = (const unsigned char *)p; 10507db96d56Sopenharmony_ci do { 10517db96d56Sopenharmony_ci x = (x<<8) | bytes[--i]; 10527db96d56Sopenharmony_ci } while (i > 0); 10537db96d56Sopenharmony_ci return PyLong_FromUnsignedLong(x); 10547db96d56Sopenharmony_ci} 10557db96d56Sopenharmony_ci 10567db96d56Sopenharmony_cistatic PyObject * 10577db96d56Sopenharmony_cilu_longlong(_structmodulestate *state, const char *p, const formatdef *f) 10587db96d56Sopenharmony_ci{ 10597db96d56Sopenharmony_ci long long x = 0; 10607db96d56Sopenharmony_ci Py_ssize_t i = f->size; 10617db96d56Sopenharmony_ci const unsigned char *bytes = (const unsigned char *)p; 10627db96d56Sopenharmony_ci do { 10637db96d56Sopenharmony_ci x = (x<<8) | bytes[--i]; 10647db96d56Sopenharmony_ci } while (i > 0); 10657db96d56Sopenharmony_ci /* Extend the sign bit. */ 10667db96d56Sopenharmony_ci if (SIZEOF_LONG_LONG > f->size) 10677db96d56Sopenharmony_ci x |= -(x & ((long long)1 << ((8 * f->size) - 1))); 10687db96d56Sopenharmony_ci return PyLong_FromLongLong(x); 10697db96d56Sopenharmony_ci} 10707db96d56Sopenharmony_ci 10717db96d56Sopenharmony_cistatic PyObject * 10727db96d56Sopenharmony_cilu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f) 10737db96d56Sopenharmony_ci{ 10747db96d56Sopenharmony_ci unsigned long long x = 0; 10757db96d56Sopenharmony_ci Py_ssize_t i = f->size; 10767db96d56Sopenharmony_ci const unsigned char *bytes = (const unsigned char *)p; 10777db96d56Sopenharmony_ci do { 10787db96d56Sopenharmony_ci x = (x<<8) | bytes[--i]; 10797db96d56Sopenharmony_ci } while (i > 0); 10807db96d56Sopenharmony_ci return PyLong_FromUnsignedLongLong(x); 10817db96d56Sopenharmony_ci} 10827db96d56Sopenharmony_ci 10837db96d56Sopenharmony_cistatic PyObject * 10847db96d56Sopenharmony_cilu_halffloat(_structmodulestate *state, const char *p, const formatdef *f) 10857db96d56Sopenharmony_ci{ 10867db96d56Sopenharmony_ci return unpack_halffloat(p, 1); 10877db96d56Sopenharmony_ci} 10887db96d56Sopenharmony_ci 10897db96d56Sopenharmony_cistatic PyObject * 10907db96d56Sopenharmony_cilu_float(_structmodulestate *state, const char *p, const formatdef *f) 10917db96d56Sopenharmony_ci{ 10927db96d56Sopenharmony_ci return unpack_float(p, 1); 10937db96d56Sopenharmony_ci} 10947db96d56Sopenharmony_ci 10957db96d56Sopenharmony_cistatic PyObject * 10967db96d56Sopenharmony_cilu_double(_structmodulestate *state, const char *p, const formatdef *f) 10977db96d56Sopenharmony_ci{ 10987db96d56Sopenharmony_ci return unpack_double(p, 1); 10997db96d56Sopenharmony_ci} 11007db96d56Sopenharmony_ci 11017db96d56Sopenharmony_cistatic int 11027db96d56Sopenharmony_cilp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 11037db96d56Sopenharmony_ci{ 11047db96d56Sopenharmony_ci long x; 11057db96d56Sopenharmony_ci Py_ssize_t i; 11067db96d56Sopenharmony_ci unsigned char *q = (unsigned char *)p; 11077db96d56Sopenharmony_ci if (get_long(state, v, &x) < 0) 11087db96d56Sopenharmony_ci return -1; 11097db96d56Sopenharmony_ci i = f->size; 11107db96d56Sopenharmony_ci if (i != SIZEOF_LONG) { 11117db96d56Sopenharmony_ci if ((i == 2) && (x < -32768 || x > 32767)) 11127db96d56Sopenharmony_ci RANGE_ERROR(state, x, f, 0, 0xffffL); 11137db96d56Sopenharmony_ci#if (SIZEOF_LONG != 4) 11147db96d56Sopenharmony_ci else if ((i == 4) && (x < -2147483648L || x > 2147483647L)) 11157db96d56Sopenharmony_ci RANGE_ERROR(state, x, f, 0, 0xffffffffL); 11167db96d56Sopenharmony_ci#endif 11177db96d56Sopenharmony_ci } 11187db96d56Sopenharmony_ci do { 11197db96d56Sopenharmony_ci *q++ = (unsigned char)(x & 0xffL); 11207db96d56Sopenharmony_ci x >>= 8; 11217db96d56Sopenharmony_ci } while (--i > 0); 11227db96d56Sopenharmony_ci return 0; 11237db96d56Sopenharmony_ci} 11247db96d56Sopenharmony_ci 11257db96d56Sopenharmony_cistatic int 11267db96d56Sopenharmony_cilp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 11277db96d56Sopenharmony_ci{ 11287db96d56Sopenharmony_ci unsigned long x; 11297db96d56Sopenharmony_ci Py_ssize_t i; 11307db96d56Sopenharmony_ci unsigned char *q = (unsigned char *)p; 11317db96d56Sopenharmony_ci if (get_ulong(state, v, &x) < 0) 11327db96d56Sopenharmony_ci return -1; 11337db96d56Sopenharmony_ci i = f->size; 11347db96d56Sopenharmony_ci if (i != SIZEOF_LONG) { 11357db96d56Sopenharmony_ci unsigned long maxint = 1; 11367db96d56Sopenharmony_ci maxint <<= (unsigned long)(i * 8); 11377db96d56Sopenharmony_ci if (x >= maxint) 11387db96d56Sopenharmony_ci RANGE_ERROR(state, x, f, 1, maxint - 1); 11397db96d56Sopenharmony_ci } 11407db96d56Sopenharmony_ci do { 11417db96d56Sopenharmony_ci *q++ = (unsigned char)(x & 0xffUL); 11427db96d56Sopenharmony_ci x >>= 8; 11437db96d56Sopenharmony_ci } while (--i > 0); 11447db96d56Sopenharmony_ci return 0; 11457db96d56Sopenharmony_ci} 11467db96d56Sopenharmony_ci 11477db96d56Sopenharmony_cistatic int 11487db96d56Sopenharmony_cilp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 11497db96d56Sopenharmony_ci{ 11507db96d56Sopenharmony_ci int res; 11517db96d56Sopenharmony_ci v = get_pylong(state, v); 11527db96d56Sopenharmony_ci if (v == NULL) 11537db96d56Sopenharmony_ci return -1; 11547db96d56Sopenharmony_ci res = _PyLong_AsByteArray((PyLongObject*)v, 11557db96d56Sopenharmony_ci (unsigned char *)p, 11567db96d56Sopenharmony_ci 8, 11577db96d56Sopenharmony_ci 1, /* little_endian */ 11587db96d56Sopenharmony_ci 1 /* signed */); 11597db96d56Sopenharmony_ci Py_DECREF(v); 11607db96d56Sopenharmony_ci return res; 11617db96d56Sopenharmony_ci} 11627db96d56Sopenharmony_ci 11637db96d56Sopenharmony_cistatic int 11647db96d56Sopenharmony_cilp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 11657db96d56Sopenharmony_ci{ 11667db96d56Sopenharmony_ci int res; 11677db96d56Sopenharmony_ci v = get_pylong(state, v); 11687db96d56Sopenharmony_ci if (v == NULL) 11697db96d56Sopenharmony_ci return -1; 11707db96d56Sopenharmony_ci res = _PyLong_AsByteArray((PyLongObject*)v, 11717db96d56Sopenharmony_ci (unsigned char *)p, 11727db96d56Sopenharmony_ci 8, 11737db96d56Sopenharmony_ci 1, /* little_endian */ 11747db96d56Sopenharmony_ci 0 /* signed */); 11757db96d56Sopenharmony_ci Py_DECREF(v); 11767db96d56Sopenharmony_ci return res; 11777db96d56Sopenharmony_ci} 11787db96d56Sopenharmony_ci 11797db96d56Sopenharmony_cistatic int 11807db96d56Sopenharmony_cilp_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 11817db96d56Sopenharmony_ci{ 11827db96d56Sopenharmony_ci return pack_halffloat(state, p, v, 1); 11837db96d56Sopenharmony_ci} 11847db96d56Sopenharmony_ci 11857db96d56Sopenharmony_cistatic int 11867db96d56Sopenharmony_cilp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 11877db96d56Sopenharmony_ci{ 11887db96d56Sopenharmony_ci double x = PyFloat_AsDouble(v); 11897db96d56Sopenharmony_ci if (x == -1 && PyErr_Occurred()) { 11907db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 11917db96d56Sopenharmony_ci "required argument is not a float"); 11927db96d56Sopenharmony_ci return -1; 11937db96d56Sopenharmony_ci } 11947db96d56Sopenharmony_ci return PyFloat_Pack4(x, p, 1); 11957db96d56Sopenharmony_ci} 11967db96d56Sopenharmony_ci 11977db96d56Sopenharmony_cistatic int 11987db96d56Sopenharmony_cilp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 11997db96d56Sopenharmony_ci{ 12007db96d56Sopenharmony_ci double x = PyFloat_AsDouble(v); 12017db96d56Sopenharmony_ci if (x == -1 && PyErr_Occurred()) { 12027db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 12037db96d56Sopenharmony_ci "required argument is not a float"); 12047db96d56Sopenharmony_ci return -1; 12057db96d56Sopenharmony_ci } 12067db96d56Sopenharmony_ci return PyFloat_Pack8(x, p, 1); 12077db96d56Sopenharmony_ci} 12087db96d56Sopenharmony_ci 12097db96d56Sopenharmony_cistatic formatdef lilendian_table[] = { 12107db96d56Sopenharmony_ci {'x', 1, 0, NULL}, 12117db96d56Sopenharmony_ci {'b', 1, 0, nu_byte, np_byte}, 12127db96d56Sopenharmony_ci {'B', 1, 0, nu_ubyte, np_ubyte}, 12137db96d56Sopenharmony_ci {'c', 1, 0, nu_char, np_char}, 12147db96d56Sopenharmony_ci {'s', 1, 0, NULL}, 12157db96d56Sopenharmony_ci {'p', 1, 0, NULL}, 12167db96d56Sopenharmony_ci {'h', 2, 0, lu_int, lp_int}, 12177db96d56Sopenharmony_ci {'H', 2, 0, lu_uint, lp_uint}, 12187db96d56Sopenharmony_ci {'i', 4, 0, lu_int, lp_int}, 12197db96d56Sopenharmony_ci {'I', 4, 0, lu_uint, lp_uint}, 12207db96d56Sopenharmony_ci {'l', 4, 0, lu_int, lp_int}, 12217db96d56Sopenharmony_ci {'L', 4, 0, lu_uint, lp_uint}, 12227db96d56Sopenharmony_ci {'q', 8, 0, lu_longlong, lp_longlong}, 12237db96d56Sopenharmony_ci {'Q', 8, 0, lu_ulonglong, lp_ulonglong}, 12247db96d56Sopenharmony_ci {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep, 12257db96d56Sopenharmony_ci but potentially different from native rep -- reuse bx_bool funcs. */ 12267db96d56Sopenharmony_ci {'e', 2, 0, lu_halffloat, lp_halffloat}, 12277db96d56Sopenharmony_ci {'f', 4, 0, lu_float, lp_float}, 12287db96d56Sopenharmony_ci {'d', 8, 0, lu_double, lp_double}, 12297db96d56Sopenharmony_ci {0} 12307db96d56Sopenharmony_ci}; 12317db96d56Sopenharmony_ci 12327db96d56Sopenharmony_ci 12337db96d56Sopenharmony_cistatic const formatdef * 12347db96d56Sopenharmony_ciwhichtable(const char **pfmt) 12357db96d56Sopenharmony_ci{ 12367db96d56Sopenharmony_ci const char *fmt = (*pfmt)++; /* May be backed out of later */ 12377db96d56Sopenharmony_ci switch (*fmt) { 12387db96d56Sopenharmony_ci case '<': 12397db96d56Sopenharmony_ci return lilendian_table; 12407db96d56Sopenharmony_ci case '>': 12417db96d56Sopenharmony_ci case '!': /* Network byte order is big-endian */ 12427db96d56Sopenharmony_ci return bigendian_table; 12437db96d56Sopenharmony_ci case '=': { /* Host byte order -- different from native in alignment! */ 12447db96d56Sopenharmony_ci#if PY_LITTLE_ENDIAN 12457db96d56Sopenharmony_ci return lilendian_table; 12467db96d56Sopenharmony_ci#else 12477db96d56Sopenharmony_ci return bigendian_table; 12487db96d56Sopenharmony_ci#endif 12497db96d56Sopenharmony_ci } 12507db96d56Sopenharmony_ci default: 12517db96d56Sopenharmony_ci --*pfmt; /* Back out of pointer increment */ 12527db96d56Sopenharmony_ci /* Fall through */ 12537db96d56Sopenharmony_ci case '@': 12547db96d56Sopenharmony_ci return native_table; 12557db96d56Sopenharmony_ci } 12567db96d56Sopenharmony_ci} 12577db96d56Sopenharmony_ci 12587db96d56Sopenharmony_ci 12597db96d56Sopenharmony_ci/* Get the table entry for a format code */ 12607db96d56Sopenharmony_ci 12617db96d56Sopenharmony_cistatic const formatdef * 12627db96d56Sopenharmony_cigetentry(_structmodulestate *state, int c, const formatdef *f) 12637db96d56Sopenharmony_ci{ 12647db96d56Sopenharmony_ci for (; f->format != '\0'; f++) { 12657db96d56Sopenharmony_ci if (f->format == c) { 12667db96d56Sopenharmony_ci return f; 12677db96d56Sopenharmony_ci } 12687db96d56Sopenharmony_ci } 12697db96d56Sopenharmony_ci PyErr_SetString(state->StructError, "bad char in struct format"); 12707db96d56Sopenharmony_ci return NULL; 12717db96d56Sopenharmony_ci} 12727db96d56Sopenharmony_ci 12737db96d56Sopenharmony_ci 12747db96d56Sopenharmony_ci/* Align a size according to a format code. Return -1 on overflow. */ 12757db96d56Sopenharmony_ci 12767db96d56Sopenharmony_cistatic Py_ssize_t 12777db96d56Sopenharmony_cialign(Py_ssize_t size, char c, const formatdef *e) 12787db96d56Sopenharmony_ci{ 12797db96d56Sopenharmony_ci Py_ssize_t extra; 12807db96d56Sopenharmony_ci 12817db96d56Sopenharmony_ci if (e->format == c) { 12827db96d56Sopenharmony_ci if (e->alignment && size > 0) { 12837db96d56Sopenharmony_ci extra = (e->alignment - 1) - (size - 1) % (e->alignment); 12847db96d56Sopenharmony_ci if (extra > PY_SSIZE_T_MAX - size) 12857db96d56Sopenharmony_ci return -1; 12867db96d56Sopenharmony_ci size += extra; 12877db96d56Sopenharmony_ci } 12887db96d56Sopenharmony_ci } 12897db96d56Sopenharmony_ci return size; 12907db96d56Sopenharmony_ci} 12917db96d56Sopenharmony_ci 12927db96d56Sopenharmony_ci/* 12937db96d56Sopenharmony_ci * Struct object implementation. 12947db96d56Sopenharmony_ci */ 12957db96d56Sopenharmony_ci 12967db96d56Sopenharmony_ci/* calculate the size of a format string */ 12977db96d56Sopenharmony_ci 12987db96d56Sopenharmony_cistatic int 12997db96d56Sopenharmony_ciprepare_s(PyStructObject *self) 13007db96d56Sopenharmony_ci{ 13017db96d56Sopenharmony_ci const formatdef *f; 13027db96d56Sopenharmony_ci const formatdef *e; 13037db96d56Sopenharmony_ci formatcode *codes; 13047db96d56Sopenharmony_ci 13057db96d56Sopenharmony_ci const char *s; 13067db96d56Sopenharmony_ci const char *fmt; 13077db96d56Sopenharmony_ci char c; 13087db96d56Sopenharmony_ci Py_ssize_t size, len, num, itemsize; 13097db96d56Sopenharmony_ci size_t ncodes; 13107db96d56Sopenharmony_ci 13117db96d56Sopenharmony_ci _structmodulestate *state = get_struct_state_structinst(self); 13127db96d56Sopenharmony_ci 13137db96d56Sopenharmony_ci fmt = PyBytes_AS_STRING(self->s_format); 13147db96d56Sopenharmony_ci if (strlen(fmt) != (size_t)PyBytes_GET_SIZE(self->s_format)) { 13157db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 13167db96d56Sopenharmony_ci "embedded null character"); 13177db96d56Sopenharmony_ci return -1; 13187db96d56Sopenharmony_ci } 13197db96d56Sopenharmony_ci 13207db96d56Sopenharmony_ci f = whichtable(&fmt); 13217db96d56Sopenharmony_ci 13227db96d56Sopenharmony_ci s = fmt; 13237db96d56Sopenharmony_ci size = 0; 13247db96d56Sopenharmony_ci len = 0; 13257db96d56Sopenharmony_ci ncodes = 0; 13267db96d56Sopenharmony_ci while ((c = *s++) != '\0') { 13277db96d56Sopenharmony_ci if (Py_ISSPACE(c)) 13287db96d56Sopenharmony_ci continue; 13297db96d56Sopenharmony_ci if ('0' <= c && c <= '9') { 13307db96d56Sopenharmony_ci num = c - '0'; 13317db96d56Sopenharmony_ci while ('0' <= (c = *s++) && c <= '9') { 13327db96d56Sopenharmony_ci /* overflow-safe version of 13337db96d56Sopenharmony_ci if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */ 13347db96d56Sopenharmony_ci if (num >= PY_SSIZE_T_MAX / 10 && ( 13357db96d56Sopenharmony_ci num > PY_SSIZE_T_MAX / 10 || 13367db96d56Sopenharmony_ci (c - '0') > PY_SSIZE_T_MAX % 10)) 13377db96d56Sopenharmony_ci goto overflow; 13387db96d56Sopenharmony_ci num = num*10 + (c - '0'); 13397db96d56Sopenharmony_ci } 13407db96d56Sopenharmony_ci if (c == '\0') { 13417db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 13427db96d56Sopenharmony_ci "repeat count given without format specifier"); 13437db96d56Sopenharmony_ci return -1; 13447db96d56Sopenharmony_ci } 13457db96d56Sopenharmony_ci } 13467db96d56Sopenharmony_ci else 13477db96d56Sopenharmony_ci num = 1; 13487db96d56Sopenharmony_ci 13497db96d56Sopenharmony_ci e = getentry(state, c, f); 13507db96d56Sopenharmony_ci if (e == NULL) 13517db96d56Sopenharmony_ci return -1; 13527db96d56Sopenharmony_ci 13537db96d56Sopenharmony_ci switch (c) { 13547db96d56Sopenharmony_ci case 's': /* fall through */ 13557db96d56Sopenharmony_ci case 'p': len++; ncodes++; break; 13567db96d56Sopenharmony_ci case 'x': break; 13577db96d56Sopenharmony_ci default: len += num; if (num) ncodes++; break; 13587db96d56Sopenharmony_ci } 13597db96d56Sopenharmony_ci 13607db96d56Sopenharmony_ci itemsize = e->size; 13617db96d56Sopenharmony_ci size = align(size, c, e); 13627db96d56Sopenharmony_ci if (size == -1) 13637db96d56Sopenharmony_ci goto overflow; 13647db96d56Sopenharmony_ci 13657db96d56Sopenharmony_ci /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */ 13667db96d56Sopenharmony_ci if (num > (PY_SSIZE_T_MAX - size) / itemsize) 13677db96d56Sopenharmony_ci goto overflow; 13687db96d56Sopenharmony_ci size += num * itemsize; 13697db96d56Sopenharmony_ci } 13707db96d56Sopenharmony_ci 13717db96d56Sopenharmony_ci /* check for overflow */ 13727db96d56Sopenharmony_ci if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) { 13737db96d56Sopenharmony_ci PyErr_NoMemory(); 13747db96d56Sopenharmony_ci return -1; 13757db96d56Sopenharmony_ci } 13767db96d56Sopenharmony_ci 13777db96d56Sopenharmony_ci self->s_size = size; 13787db96d56Sopenharmony_ci self->s_len = len; 13797db96d56Sopenharmony_ci codes = PyMem_Malloc((ncodes + 1) * sizeof(formatcode)); 13807db96d56Sopenharmony_ci if (codes == NULL) { 13817db96d56Sopenharmony_ci PyErr_NoMemory(); 13827db96d56Sopenharmony_ci return -1; 13837db96d56Sopenharmony_ci } 13847db96d56Sopenharmony_ci /* Free any s_codes value left over from a previous initialization. */ 13857db96d56Sopenharmony_ci if (self->s_codes != NULL) 13867db96d56Sopenharmony_ci PyMem_Free(self->s_codes); 13877db96d56Sopenharmony_ci self->s_codes = codes; 13887db96d56Sopenharmony_ci 13897db96d56Sopenharmony_ci s = fmt; 13907db96d56Sopenharmony_ci size = 0; 13917db96d56Sopenharmony_ci while ((c = *s++) != '\0') { 13927db96d56Sopenharmony_ci if (Py_ISSPACE(c)) 13937db96d56Sopenharmony_ci continue; 13947db96d56Sopenharmony_ci if ('0' <= c && c <= '9') { 13957db96d56Sopenharmony_ci num = c - '0'; 13967db96d56Sopenharmony_ci while ('0' <= (c = *s++) && c <= '9') 13977db96d56Sopenharmony_ci num = num*10 + (c - '0'); 13987db96d56Sopenharmony_ci } 13997db96d56Sopenharmony_ci else 14007db96d56Sopenharmony_ci num = 1; 14017db96d56Sopenharmony_ci 14027db96d56Sopenharmony_ci e = getentry(state, c, f); 14037db96d56Sopenharmony_ci 14047db96d56Sopenharmony_ci size = align(size, c, e); 14057db96d56Sopenharmony_ci if (c == 's' || c == 'p') { 14067db96d56Sopenharmony_ci codes->offset = size; 14077db96d56Sopenharmony_ci codes->size = num; 14087db96d56Sopenharmony_ci codes->fmtdef = e; 14097db96d56Sopenharmony_ci codes->repeat = 1; 14107db96d56Sopenharmony_ci codes++; 14117db96d56Sopenharmony_ci size += num; 14127db96d56Sopenharmony_ci } else if (c == 'x') { 14137db96d56Sopenharmony_ci size += num; 14147db96d56Sopenharmony_ci } else if (num) { 14157db96d56Sopenharmony_ci codes->offset = size; 14167db96d56Sopenharmony_ci codes->size = e->size; 14177db96d56Sopenharmony_ci codes->fmtdef = e; 14187db96d56Sopenharmony_ci codes->repeat = num; 14197db96d56Sopenharmony_ci codes++; 14207db96d56Sopenharmony_ci size += e->size * num; 14217db96d56Sopenharmony_ci } 14227db96d56Sopenharmony_ci } 14237db96d56Sopenharmony_ci codes->fmtdef = NULL; 14247db96d56Sopenharmony_ci codes->offset = size; 14257db96d56Sopenharmony_ci codes->size = 0; 14267db96d56Sopenharmony_ci codes->repeat = 0; 14277db96d56Sopenharmony_ci 14287db96d56Sopenharmony_ci return 0; 14297db96d56Sopenharmony_ci 14307db96d56Sopenharmony_ci overflow: 14317db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 14327db96d56Sopenharmony_ci "total struct size too long"); 14337db96d56Sopenharmony_ci return -1; 14347db96d56Sopenharmony_ci} 14357db96d56Sopenharmony_ci 14367db96d56Sopenharmony_cistatic PyObject * 14377db96d56Sopenharmony_cis_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 14387db96d56Sopenharmony_ci{ 14397db96d56Sopenharmony_ci PyObject *self; 14407db96d56Sopenharmony_ci 14417db96d56Sopenharmony_ci assert(type != NULL); 14427db96d56Sopenharmony_ci allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc); 14437db96d56Sopenharmony_ci assert(alloc_func != NULL); 14447db96d56Sopenharmony_ci 14457db96d56Sopenharmony_ci self = alloc_func(type, 0); 14467db96d56Sopenharmony_ci if (self != NULL) { 14477db96d56Sopenharmony_ci PyStructObject *s = (PyStructObject*)self; 14487db96d56Sopenharmony_ci s->s_format = Py_NewRef(Py_None); 14497db96d56Sopenharmony_ci s->s_codes = NULL; 14507db96d56Sopenharmony_ci s->s_size = -1; 14517db96d56Sopenharmony_ci s->s_len = -1; 14527db96d56Sopenharmony_ci } 14537db96d56Sopenharmony_ci return self; 14547db96d56Sopenharmony_ci} 14557db96d56Sopenharmony_ci 14567db96d56Sopenharmony_ci/*[clinic input] 14577db96d56Sopenharmony_ciStruct.__init__ 14587db96d56Sopenharmony_ci 14597db96d56Sopenharmony_ci format: object 14607db96d56Sopenharmony_ci 14617db96d56Sopenharmony_ciCreate a compiled struct object. 14627db96d56Sopenharmony_ci 14637db96d56Sopenharmony_ciReturn a new Struct object which writes and reads binary data according to 14647db96d56Sopenharmony_cithe format string. 14657db96d56Sopenharmony_ci 14667db96d56Sopenharmony_ciSee help(struct) for more on format strings. 14677db96d56Sopenharmony_ci[clinic start generated code]*/ 14687db96d56Sopenharmony_ci 14697db96d56Sopenharmony_cistatic int 14707db96d56Sopenharmony_ciStruct___init___impl(PyStructObject *self, PyObject *format) 14717db96d56Sopenharmony_ci/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/ 14727db96d56Sopenharmony_ci{ 14737db96d56Sopenharmony_ci int ret = 0; 14747db96d56Sopenharmony_ci 14757db96d56Sopenharmony_ci if (PyUnicode_Check(format)) { 14767db96d56Sopenharmony_ci format = PyUnicode_AsASCIIString(format); 14777db96d56Sopenharmony_ci if (format == NULL) 14787db96d56Sopenharmony_ci return -1; 14797db96d56Sopenharmony_ci } 14807db96d56Sopenharmony_ci else { 14817db96d56Sopenharmony_ci Py_INCREF(format); 14827db96d56Sopenharmony_ci } 14837db96d56Sopenharmony_ci 14847db96d56Sopenharmony_ci if (!PyBytes_Check(format)) { 14857db96d56Sopenharmony_ci Py_DECREF(format); 14867db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 14877db96d56Sopenharmony_ci "Struct() argument 1 must be a str or bytes object, " 14887db96d56Sopenharmony_ci "not %.200s", 14897db96d56Sopenharmony_ci _PyType_Name(Py_TYPE(format))); 14907db96d56Sopenharmony_ci return -1; 14917db96d56Sopenharmony_ci } 14927db96d56Sopenharmony_ci 14937db96d56Sopenharmony_ci Py_SETREF(self->s_format, format); 14947db96d56Sopenharmony_ci 14957db96d56Sopenharmony_ci ret = prepare_s(self); 14967db96d56Sopenharmony_ci return ret; 14977db96d56Sopenharmony_ci} 14987db96d56Sopenharmony_ci 14997db96d56Sopenharmony_cistatic int 15007db96d56Sopenharmony_cis_clear(PyStructObject *s) 15017db96d56Sopenharmony_ci{ 15027db96d56Sopenharmony_ci Py_CLEAR(s->s_format); 15037db96d56Sopenharmony_ci return 0; 15047db96d56Sopenharmony_ci} 15057db96d56Sopenharmony_ci 15067db96d56Sopenharmony_cistatic int 15077db96d56Sopenharmony_cis_traverse(PyStructObject *s, visitproc visit, void *arg) 15087db96d56Sopenharmony_ci{ 15097db96d56Sopenharmony_ci Py_VISIT(Py_TYPE(s)); 15107db96d56Sopenharmony_ci Py_VISIT(s->s_format); 15117db96d56Sopenharmony_ci return 0; 15127db96d56Sopenharmony_ci} 15137db96d56Sopenharmony_ci 15147db96d56Sopenharmony_cistatic void 15157db96d56Sopenharmony_cis_dealloc(PyStructObject *s) 15167db96d56Sopenharmony_ci{ 15177db96d56Sopenharmony_ci PyTypeObject *tp = Py_TYPE(s); 15187db96d56Sopenharmony_ci PyObject_GC_UnTrack(s); 15197db96d56Sopenharmony_ci if (s->weakreflist != NULL) 15207db96d56Sopenharmony_ci PyObject_ClearWeakRefs((PyObject *)s); 15217db96d56Sopenharmony_ci if (s->s_codes != NULL) { 15227db96d56Sopenharmony_ci PyMem_Free(s->s_codes); 15237db96d56Sopenharmony_ci } 15247db96d56Sopenharmony_ci Py_XDECREF(s->s_format); 15257db96d56Sopenharmony_ci freefunc free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free); 15267db96d56Sopenharmony_ci free_func(s); 15277db96d56Sopenharmony_ci Py_DECREF(tp); 15287db96d56Sopenharmony_ci} 15297db96d56Sopenharmony_ci 15307db96d56Sopenharmony_cistatic PyObject * 15317db96d56Sopenharmony_cis_unpack_internal(PyStructObject *soself, const char *startfrom, 15327db96d56Sopenharmony_ci _structmodulestate *state) { 15337db96d56Sopenharmony_ci formatcode *code; 15347db96d56Sopenharmony_ci Py_ssize_t i = 0; 15357db96d56Sopenharmony_ci PyObject *result = PyTuple_New(soself->s_len); 15367db96d56Sopenharmony_ci if (result == NULL) 15377db96d56Sopenharmony_ci return NULL; 15387db96d56Sopenharmony_ci 15397db96d56Sopenharmony_ci for (code = soself->s_codes; code->fmtdef != NULL; code++) { 15407db96d56Sopenharmony_ci const formatdef *e = code->fmtdef; 15417db96d56Sopenharmony_ci const char *res = startfrom + code->offset; 15427db96d56Sopenharmony_ci Py_ssize_t j = code->repeat; 15437db96d56Sopenharmony_ci while (j--) { 15447db96d56Sopenharmony_ci PyObject *v; 15457db96d56Sopenharmony_ci if (e->format == 's') { 15467db96d56Sopenharmony_ci v = PyBytes_FromStringAndSize(res, code->size); 15477db96d56Sopenharmony_ci } else if (e->format == 'p') { 15487db96d56Sopenharmony_ci Py_ssize_t n = *(unsigned char*)res; 15497db96d56Sopenharmony_ci if (n >= code->size) 15507db96d56Sopenharmony_ci n = code->size - 1; 15517db96d56Sopenharmony_ci v = PyBytes_FromStringAndSize(res + 1, n); 15527db96d56Sopenharmony_ci } else { 15537db96d56Sopenharmony_ci v = e->unpack(state, res, e); 15547db96d56Sopenharmony_ci } 15557db96d56Sopenharmony_ci if (v == NULL) 15567db96d56Sopenharmony_ci goto fail; 15577db96d56Sopenharmony_ci PyTuple_SET_ITEM(result, i++, v); 15587db96d56Sopenharmony_ci res += code->size; 15597db96d56Sopenharmony_ci } 15607db96d56Sopenharmony_ci } 15617db96d56Sopenharmony_ci 15627db96d56Sopenharmony_ci return result; 15637db96d56Sopenharmony_cifail: 15647db96d56Sopenharmony_ci Py_DECREF(result); 15657db96d56Sopenharmony_ci return NULL; 15667db96d56Sopenharmony_ci} 15677db96d56Sopenharmony_ci 15687db96d56Sopenharmony_ci 15697db96d56Sopenharmony_ci/*[clinic input] 15707db96d56Sopenharmony_ciStruct.unpack 15717db96d56Sopenharmony_ci 15727db96d56Sopenharmony_ci buffer: Py_buffer 15737db96d56Sopenharmony_ci / 15747db96d56Sopenharmony_ci 15757db96d56Sopenharmony_ciReturn a tuple containing unpacked values. 15767db96d56Sopenharmony_ci 15777db96d56Sopenharmony_ciUnpack according to the format string Struct.format. The buffer's size 15787db96d56Sopenharmony_ciin bytes must be Struct.size. 15797db96d56Sopenharmony_ci 15807db96d56Sopenharmony_ciSee help(struct) for more on format strings. 15817db96d56Sopenharmony_ci[clinic start generated code]*/ 15827db96d56Sopenharmony_ci 15837db96d56Sopenharmony_cistatic PyObject * 15847db96d56Sopenharmony_ciStruct_unpack_impl(PyStructObject *self, Py_buffer *buffer) 15857db96d56Sopenharmony_ci/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/ 15867db96d56Sopenharmony_ci{ 15877db96d56Sopenharmony_ci _structmodulestate *state = get_struct_state_structinst(self); 15887db96d56Sopenharmony_ci assert(self->s_codes != NULL); 15897db96d56Sopenharmony_ci if (buffer->len != self->s_size) { 15907db96d56Sopenharmony_ci PyErr_Format(state->StructError, 15917db96d56Sopenharmony_ci "unpack requires a buffer of %zd bytes", 15927db96d56Sopenharmony_ci self->s_size); 15937db96d56Sopenharmony_ci return NULL; 15947db96d56Sopenharmony_ci } 15957db96d56Sopenharmony_ci return s_unpack_internal(self, buffer->buf, state); 15967db96d56Sopenharmony_ci} 15977db96d56Sopenharmony_ci 15987db96d56Sopenharmony_ci/*[clinic input] 15997db96d56Sopenharmony_ciStruct.unpack_from 16007db96d56Sopenharmony_ci 16017db96d56Sopenharmony_ci buffer: Py_buffer 16027db96d56Sopenharmony_ci offset: Py_ssize_t = 0 16037db96d56Sopenharmony_ci 16047db96d56Sopenharmony_ciReturn a tuple containing unpacked values. 16057db96d56Sopenharmony_ci 16067db96d56Sopenharmony_ciValues are unpacked according to the format string Struct.format. 16077db96d56Sopenharmony_ci 16087db96d56Sopenharmony_ciThe buffer's size in bytes, starting at position offset, must be 16097db96d56Sopenharmony_ciat least Struct.size. 16107db96d56Sopenharmony_ci 16117db96d56Sopenharmony_ciSee help(struct) for more on format strings. 16127db96d56Sopenharmony_ci[clinic start generated code]*/ 16137db96d56Sopenharmony_ci 16147db96d56Sopenharmony_cistatic PyObject * 16157db96d56Sopenharmony_ciStruct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, 16167db96d56Sopenharmony_ci Py_ssize_t offset) 16177db96d56Sopenharmony_ci/*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/ 16187db96d56Sopenharmony_ci{ 16197db96d56Sopenharmony_ci _structmodulestate *state = get_struct_state_structinst(self); 16207db96d56Sopenharmony_ci assert(self->s_codes != NULL); 16217db96d56Sopenharmony_ci 16227db96d56Sopenharmony_ci if (offset < 0) { 16237db96d56Sopenharmony_ci if (offset + self->s_size > 0) { 16247db96d56Sopenharmony_ci PyErr_Format(state->StructError, 16257db96d56Sopenharmony_ci "not enough data to unpack %zd bytes at offset %zd", 16267db96d56Sopenharmony_ci self->s_size, 16277db96d56Sopenharmony_ci offset); 16287db96d56Sopenharmony_ci return NULL; 16297db96d56Sopenharmony_ci } 16307db96d56Sopenharmony_ci 16317db96d56Sopenharmony_ci if (offset + buffer->len < 0) { 16327db96d56Sopenharmony_ci PyErr_Format(state->StructError, 16337db96d56Sopenharmony_ci "offset %zd out of range for %zd-byte buffer", 16347db96d56Sopenharmony_ci offset, 16357db96d56Sopenharmony_ci buffer->len); 16367db96d56Sopenharmony_ci return NULL; 16377db96d56Sopenharmony_ci } 16387db96d56Sopenharmony_ci offset += buffer->len; 16397db96d56Sopenharmony_ci } 16407db96d56Sopenharmony_ci 16417db96d56Sopenharmony_ci if ((buffer->len - offset) < self->s_size) { 16427db96d56Sopenharmony_ci PyErr_Format(state->StructError, 16437db96d56Sopenharmony_ci "unpack_from requires a buffer of at least %zu bytes for " 16447db96d56Sopenharmony_ci "unpacking %zd bytes at offset %zd " 16457db96d56Sopenharmony_ci "(actual buffer size is %zd)", 16467db96d56Sopenharmony_ci (size_t)self->s_size + (size_t)offset, 16477db96d56Sopenharmony_ci self->s_size, 16487db96d56Sopenharmony_ci offset, 16497db96d56Sopenharmony_ci buffer->len); 16507db96d56Sopenharmony_ci return NULL; 16517db96d56Sopenharmony_ci } 16527db96d56Sopenharmony_ci return s_unpack_internal(self, (char*)buffer->buf + offset, state); 16537db96d56Sopenharmony_ci} 16547db96d56Sopenharmony_ci 16557db96d56Sopenharmony_ci 16567db96d56Sopenharmony_ci 16577db96d56Sopenharmony_ci/* Unpack iterator type */ 16587db96d56Sopenharmony_ci 16597db96d56Sopenharmony_citypedef struct { 16607db96d56Sopenharmony_ci PyObject_HEAD 16617db96d56Sopenharmony_ci PyStructObject *so; 16627db96d56Sopenharmony_ci Py_buffer buf; 16637db96d56Sopenharmony_ci Py_ssize_t index; 16647db96d56Sopenharmony_ci} unpackiterobject; 16657db96d56Sopenharmony_ci 16667db96d56Sopenharmony_cistatic void 16677db96d56Sopenharmony_ciunpackiter_dealloc(unpackiterobject *self) 16687db96d56Sopenharmony_ci{ 16697db96d56Sopenharmony_ci /* bpo-31095: UnTrack is needed before calling any callbacks */ 16707db96d56Sopenharmony_ci PyTypeObject *tp = Py_TYPE(self); 16717db96d56Sopenharmony_ci PyObject_GC_UnTrack(self); 16727db96d56Sopenharmony_ci Py_XDECREF(self->so); 16737db96d56Sopenharmony_ci PyBuffer_Release(&self->buf); 16747db96d56Sopenharmony_ci PyObject_GC_Del(self); 16757db96d56Sopenharmony_ci Py_DECREF(tp); 16767db96d56Sopenharmony_ci} 16777db96d56Sopenharmony_ci 16787db96d56Sopenharmony_cistatic int 16797db96d56Sopenharmony_ciunpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg) 16807db96d56Sopenharmony_ci{ 16817db96d56Sopenharmony_ci Py_VISIT(Py_TYPE(self)); 16827db96d56Sopenharmony_ci Py_VISIT(self->so); 16837db96d56Sopenharmony_ci Py_VISIT(self->buf.obj); 16847db96d56Sopenharmony_ci return 0; 16857db96d56Sopenharmony_ci} 16867db96d56Sopenharmony_ci 16877db96d56Sopenharmony_cistatic PyObject * 16887db96d56Sopenharmony_ciunpackiter_len(unpackiterobject *self, PyObject *Py_UNUSED(ignored)) 16897db96d56Sopenharmony_ci{ 16907db96d56Sopenharmony_ci Py_ssize_t len; 16917db96d56Sopenharmony_ci if (self->so == NULL) 16927db96d56Sopenharmony_ci len = 0; 16937db96d56Sopenharmony_ci else 16947db96d56Sopenharmony_ci len = (self->buf.len - self->index) / self->so->s_size; 16957db96d56Sopenharmony_ci return PyLong_FromSsize_t(len); 16967db96d56Sopenharmony_ci} 16977db96d56Sopenharmony_ci 16987db96d56Sopenharmony_cistatic PyMethodDef unpackiter_methods[] = { 16997db96d56Sopenharmony_ci {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL}, 17007db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 17017db96d56Sopenharmony_ci}; 17027db96d56Sopenharmony_ci 17037db96d56Sopenharmony_cistatic PyObject * 17047db96d56Sopenharmony_ciunpackiter_iternext(unpackiterobject *self) 17057db96d56Sopenharmony_ci{ 17067db96d56Sopenharmony_ci _structmodulestate *state = get_struct_state_iterinst(self); 17077db96d56Sopenharmony_ci PyObject *result; 17087db96d56Sopenharmony_ci if (self->so == NULL) 17097db96d56Sopenharmony_ci return NULL; 17107db96d56Sopenharmony_ci if (self->index >= self->buf.len) { 17117db96d56Sopenharmony_ci /* Iterator exhausted */ 17127db96d56Sopenharmony_ci Py_CLEAR(self->so); 17137db96d56Sopenharmony_ci PyBuffer_Release(&self->buf); 17147db96d56Sopenharmony_ci return NULL; 17157db96d56Sopenharmony_ci } 17167db96d56Sopenharmony_ci assert(self->index + self->so->s_size <= self->buf.len); 17177db96d56Sopenharmony_ci result = s_unpack_internal(self->so, 17187db96d56Sopenharmony_ci (char*) self->buf.buf + self->index, 17197db96d56Sopenharmony_ci state); 17207db96d56Sopenharmony_ci self->index += self->so->s_size; 17217db96d56Sopenharmony_ci return result; 17227db96d56Sopenharmony_ci} 17237db96d56Sopenharmony_ci 17247db96d56Sopenharmony_ciPyObject *unpackiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { 17257db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, "Cannot create '%.200s objects", _PyType_Name(type)); 17267db96d56Sopenharmony_ci return NULL; 17277db96d56Sopenharmony_ci} 17287db96d56Sopenharmony_ci 17297db96d56Sopenharmony_cistatic PyType_Slot unpackiter_type_slots[] = { 17307db96d56Sopenharmony_ci {Py_tp_dealloc, unpackiter_dealloc}, 17317db96d56Sopenharmony_ci {Py_tp_getattro, PyObject_GenericGetAttr}, 17327db96d56Sopenharmony_ci {Py_tp_traverse, unpackiter_traverse}, 17337db96d56Sopenharmony_ci {Py_tp_iter, PyObject_SelfIter}, 17347db96d56Sopenharmony_ci {Py_tp_iternext, unpackiter_iternext}, 17357db96d56Sopenharmony_ci {Py_tp_methods, unpackiter_methods}, 17367db96d56Sopenharmony_ci {Py_tp_new, unpackiter_new}, 17377db96d56Sopenharmony_ci {0, 0}, 17387db96d56Sopenharmony_ci}; 17397db96d56Sopenharmony_ci 17407db96d56Sopenharmony_cistatic PyType_Spec unpackiter_type_spec = { 17417db96d56Sopenharmony_ci "_struct.unpack_iterator", 17427db96d56Sopenharmony_ci sizeof(unpackiterobject), 17437db96d56Sopenharmony_ci 0, 17447db96d56Sopenharmony_ci (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 17457db96d56Sopenharmony_ci Py_TPFLAGS_IMMUTABLETYPE), 17467db96d56Sopenharmony_ci unpackiter_type_slots 17477db96d56Sopenharmony_ci}; 17487db96d56Sopenharmony_ci 17497db96d56Sopenharmony_ci/*[clinic input] 17507db96d56Sopenharmony_ciStruct.iter_unpack 17517db96d56Sopenharmony_ci 17527db96d56Sopenharmony_ci buffer: object 17537db96d56Sopenharmony_ci / 17547db96d56Sopenharmony_ci 17557db96d56Sopenharmony_ciReturn an iterator yielding tuples. 17567db96d56Sopenharmony_ci 17577db96d56Sopenharmony_ciTuples are unpacked from the given bytes source, like a repeated 17587db96d56Sopenharmony_ciinvocation of unpack_from(). 17597db96d56Sopenharmony_ci 17607db96d56Sopenharmony_ciRequires that the bytes length be a multiple of the struct size. 17617db96d56Sopenharmony_ci[clinic start generated code]*/ 17627db96d56Sopenharmony_ci 17637db96d56Sopenharmony_cistatic PyObject * 17647db96d56Sopenharmony_ciStruct_iter_unpack(PyStructObject *self, PyObject *buffer) 17657db96d56Sopenharmony_ci/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/ 17667db96d56Sopenharmony_ci{ 17677db96d56Sopenharmony_ci _structmodulestate *state = get_struct_state_structinst(self); 17687db96d56Sopenharmony_ci unpackiterobject *iter; 17697db96d56Sopenharmony_ci 17707db96d56Sopenharmony_ci assert(self->s_codes != NULL); 17717db96d56Sopenharmony_ci 17727db96d56Sopenharmony_ci if (self->s_size == 0) { 17737db96d56Sopenharmony_ci PyErr_Format(state->StructError, 17747db96d56Sopenharmony_ci "cannot iteratively unpack with a struct of length 0"); 17757db96d56Sopenharmony_ci return NULL; 17767db96d56Sopenharmony_ci } 17777db96d56Sopenharmony_ci 17787db96d56Sopenharmony_ci iter = (unpackiterobject *) PyType_GenericAlloc((PyTypeObject *)state->unpackiter_type, 0); 17797db96d56Sopenharmony_ci if (iter == NULL) 17807db96d56Sopenharmony_ci return NULL; 17817db96d56Sopenharmony_ci 17827db96d56Sopenharmony_ci if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) { 17837db96d56Sopenharmony_ci Py_DECREF(iter); 17847db96d56Sopenharmony_ci return NULL; 17857db96d56Sopenharmony_ci } 17867db96d56Sopenharmony_ci if (iter->buf.len % self->s_size != 0) { 17877db96d56Sopenharmony_ci PyErr_Format(state->StructError, 17887db96d56Sopenharmony_ci "iterative unpacking requires a buffer of " 17897db96d56Sopenharmony_ci "a multiple of %zd bytes", 17907db96d56Sopenharmony_ci self->s_size); 17917db96d56Sopenharmony_ci Py_DECREF(iter); 17927db96d56Sopenharmony_ci return NULL; 17937db96d56Sopenharmony_ci } 17947db96d56Sopenharmony_ci Py_INCREF(self); 17957db96d56Sopenharmony_ci iter->so = self; 17967db96d56Sopenharmony_ci iter->index = 0; 17977db96d56Sopenharmony_ci return (PyObject *)iter; 17987db96d56Sopenharmony_ci} 17997db96d56Sopenharmony_ci 18007db96d56Sopenharmony_ci 18017db96d56Sopenharmony_ci/* 18027db96d56Sopenharmony_ci * Guts of the pack function. 18037db96d56Sopenharmony_ci * 18047db96d56Sopenharmony_ci * Takes a struct object, a tuple of arguments, and offset in that tuple of 18057db96d56Sopenharmony_ci * argument for where to start processing the arguments for packing, and a 18067db96d56Sopenharmony_ci * character buffer for writing the packed string. The caller must insure 18077db96d56Sopenharmony_ci * that the buffer may contain the required length for packing the arguments. 18087db96d56Sopenharmony_ci * 0 is returned on success, 1 is returned if there is an error. 18097db96d56Sopenharmony_ci * 18107db96d56Sopenharmony_ci */ 18117db96d56Sopenharmony_cistatic int 18127db96d56Sopenharmony_cis_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, 18137db96d56Sopenharmony_ci char* buf, _structmodulestate *state) 18147db96d56Sopenharmony_ci{ 18157db96d56Sopenharmony_ci formatcode *code; 18167db96d56Sopenharmony_ci /* XXX(nnorwitz): why does i need to be a local? can we use 18177db96d56Sopenharmony_ci the offset parameter or do we need the wider width? */ 18187db96d56Sopenharmony_ci Py_ssize_t i; 18197db96d56Sopenharmony_ci 18207db96d56Sopenharmony_ci memset(buf, '\0', soself->s_size); 18217db96d56Sopenharmony_ci i = offset; 18227db96d56Sopenharmony_ci for (code = soself->s_codes; code->fmtdef != NULL; code++) { 18237db96d56Sopenharmony_ci const formatdef *e = code->fmtdef; 18247db96d56Sopenharmony_ci char *res = buf + code->offset; 18257db96d56Sopenharmony_ci Py_ssize_t j = code->repeat; 18267db96d56Sopenharmony_ci while (j--) { 18277db96d56Sopenharmony_ci PyObject *v = args[i++]; 18287db96d56Sopenharmony_ci if (e->format == 's') { 18297db96d56Sopenharmony_ci Py_ssize_t n; 18307db96d56Sopenharmony_ci int isstring; 18317db96d56Sopenharmony_ci const void *p; 18327db96d56Sopenharmony_ci isstring = PyBytes_Check(v); 18337db96d56Sopenharmony_ci if (!isstring && !PyByteArray_Check(v)) { 18347db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 18357db96d56Sopenharmony_ci "argument for 's' must be a bytes object"); 18367db96d56Sopenharmony_ci return -1; 18377db96d56Sopenharmony_ci } 18387db96d56Sopenharmony_ci if (isstring) { 18397db96d56Sopenharmony_ci n = PyBytes_GET_SIZE(v); 18407db96d56Sopenharmony_ci p = PyBytes_AS_STRING(v); 18417db96d56Sopenharmony_ci } 18427db96d56Sopenharmony_ci else { 18437db96d56Sopenharmony_ci n = PyByteArray_GET_SIZE(v); 18447db96d56Sopenharmony_ci p = PyByteArray_AS_STRING(v); 18457db96d56Sopenharmony_ci } 18467db96d56Sopenharmony_ci if (n > code->size) 18477db96d56Sopenharmony_ci n = code->size; 18487db96d56Sopenharmony_ci if (n > 0) 18497db96d56Sopenharmony_ci memcpy(res, p, n); 18507db96d56Sopenharmony_ci } else if (e->format == 'p') { 18517db96d56Sopenharmony_ci Py_ssize_t n; 18527db96d56Sopenharmony_ci int isstring; 18537db96d56Sopenharmony_ci const void *p; 18547db96d56Sopenharmony_ci isstring = PyBytes_Check(v); 18557db96d56Sopenharmony_ci if (!isstring && !PyByteArray_Check(v)) { 18567db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 18577db96d56Sopenharmony_ci "argument for 'p' must be a bytes object"); 18587db96d56Sopenharmony_ci return -1; 18597db96d56Sopenharmony_ci } 18607db96d56Sopenharmony_ci if (isstring) { 18617db96d56Sopenharmony_ci n = PyBytes_GET_SIZE(v); 18627db96d56Sopenharmony_ci p = PyBytes_AS_STRING(v); 18637db96d56Sopenharmony_ci } 18647db96d56Sopenharmony_ci else { 18657db96d56Sopenharmony_ci n = PyByteArray_GET_SIZE(v); 18667db96d56Sopenharmony_ci p = PyByteArray_AS_STRING(v); 18677db96d56Sopenharmony_ci } 18687db96d56Sopenharmony_ci if (n > (code->size - 1)) 18697db96d56Sopenharmony_ci n = code->size - 1; 18707db96d56Sopenharmony_ci if (n > 0) 18717db96d56Sopenharmony_ci memcpy(res + 1, p, n); 18727db96d56Sopenharmony_ci if (n > 255) 18737db96d56Sopenharmony_ci n = 255; 18747db96d56Sopenharmony_ci *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char); 18757db96d56Sopenharmony_ci } else { 18767db96d56Sopenharmony_ci if (e->pack(state, res, v, e) < 0) { 18777db96d56Sopenharmony_ci if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError)) 18787db96d56Sopenharmony_ci PyErr_SetString(state->StructError, 18797db96d56Sopenharmony_ci "int too large to convert"); 18807db96d56Sopenharmony_ci return -1; 18817db96d56Sopenharmony_ci } 18827db96d56Sopenharmony_ci } 18837db96d56Sopenharmony_ci res += code->size; 18847db96d56Sopenharmony_ci } 18857db96d56Sopenharmony_ci } 18867db96d56Sopenharmony_ci 18877db96d56Sopenharmony_ci /* Success */ 18887db96d56Sopenharmony_ci return 0; 18897db96d56Sopenharmony_ci} 18907db96d56Sopenharmony_ci 18917db96d56Sopenharmony_ci 18927db96d56Sopenharmony_ciPyDoc_STRVAR(s_pack__doc__, 18937db96d56Sopenharmony_ci"S.pack(v1, v2, ...) -> bytes\n\ 18947db96d56Sopenharmony_ci\n\ 18957db96d56Sopenharmony_ciReturn a bytes object containing values v1, v2, ... packed according\n\ 18967db96d56Sopenharmony_cito the format string S.format. See help(struct) for more on format\n\ 18977db96d56Sopenharmony_cistrings."); 18987db96d56Sopenharmony_ci 18997db96d56Sopenharmony_cistatic PyObject * 19007db96d56Sopenharmony_cis_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs) 19017db96d56Sopenharmony_ci{ 19027db96d56Sopenharmony_ci char *buf; 19037db96d56Sopenharmony_ci PyStructObject *soself; 19047db96d56Sopenharmony_ci _structmodulestate *state = get_struct_state_structinst(self); 19057db96d56Sopenharmony_ci 19067db96d56Sopenharmony_ci /* Validate arguments. */ 19077db96d56Sopenharmony_ci soself = (PyStructObject *)self; 19087db96d56Sopenharmony_ci assert(PyStruct_Check(self, state)); 19097db96d56Sopenharmony_ci assert(soself->s_codes != NULL); 19107db96d56Sopenharmony_ci if (nargs != soself->s_len) 19117db96d56Sopenharmony_ci { 19127db96d56Sopenharmony_ci PyErr_Format(state->StructError, 19137db96d56Sopenharmony_ci "pack expected %zd items for packing (got %zd)", soself->s_len, nargs); 19147db96d56Sopenharmony_ci return NULL; 19157db96d56Sopenharmony_ci } 19167db96d56Sopenharmony_ci 19177db96d56Sopenharmony_ci /* Allocate a new string */ 19187db96d56Sopenharmony_ci _PyBytesWriter writer; 19197db96d56Sopenharmony_ci _PyBytesWriter_Init(&writer); 19207db96d56Sopenharmony_ci buf = _PyBytesWriter_Alloc(&writer, soself->s_size); 19217db96d56Sopenharmony_ci if (buf == NULL) { 19227db96d56Sopenharmony_ci _PyBytesWriter_Dealloc(&writer); 19237db96d56Sopenharmony_ci return NULL; 19247db96d56Sopenharmony_ci } 19257db96d56Sopenharmony_ci 19267db96d56Sopenharmony_ci /* Call the guts */ 19277db96d56Sopenharmony_ci if ( s_pack_internal(soself, args, 0, buf, state) != 0 ) { 19287db96d56Sopenharmony_ci _PyBytesWriter_Dealloc(&writer); 19297db96d56Sopenharmony_ci return NULL; 19307db96d56Sopenharmony_ci } 19317db96d56Sopenharmony_ci 19327db96d56Sopenharmony_ci return _PyBytesWriter_Finish(&writer, buf + soself->s_size); 19337db96d56Sopenharmony_ci} 19347db96d56Sopenharmony_ci 19357db96d56Sopenharmony_ciPyDoc_STRVAR(s_pack_into__doc__, 19367db96d56Sopenharmony_ci"S.pack_into(buffer, offset, v1, v2, ...)\n\ 19377db96d56Sopenharmony_ci\n\ 19387db96d56Sopenharmony_ciPack the values v1, v2, ... according to the format string S.format\n\ 19397db96d56Sopenharmony_ciand write the packed bytes into the writable buffer buf starting at\n\ 19407db96d56Sopenharmony_cioffset. Note that the offset is a required argument. See\n\ 19417db96d56Sopenharmony_cihelp(struct) for more on format strings."); 19427db96d56Sopenharmony_ci 19437db96d56Sopenharmony_cistatic PyObject * 19447db96d56Sopenharmony_cis_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs) 19457db96d56Sopenharmony_ci{ 19467db96d56Sopenharmony_ci PyStructObject *soself; 19477db96d56Sopenharmony_ci Py_buffer buffer; 19487db96d56Sopenharmony_ci Py_ssize_t offset; 19497db96d56Sopenharmony_ci _structmodulestate *state = get_struct_state_structinst(self); 19507db96d56Sopenharmony_ci 19517db96d56Sopenharmony_ci /* Validate arguments. +1 is for the first arg as buffer. */ 19527db96d56Sopenharmony_ci soself = (PyStructObject *)self; 19537db96d56Sopenharmony_ci assert(PyStruct_Check(self, state)); 19547db96d56Sopenharmony_ci assert(soself->s_codes != NULL); 19557db96d56Sopenharmony_ci if (nargs != (soself->s_len + 2)) 19567db96d56Sopenharmony_ci { 19577db96d56Sopenharmony_ci if (nargs == 0) { 19587db96d56Sopenharmony_ci PyErr_Format(state->StructError, 19597db96d56Sopenharmony_ci "pack_into expected buffer argument"); 19607db96d56Sopenharmony_ci } 19617db96d56Sopenharmony_ci else if (nargs == 1) { 19627db96d56Sopenharmony_ci PyErr_Format(state->StructError, 19637db96d56Sopenharmony_ci "pack_into expected offset argument"); 19647db96d56Sopenharmony_ci } 19657db96d56Sopenharmony_ci else { 19667db96d56Sopenharmony_ci PyErr_Format(state->StructError, 19677db96d56Sopenharmony_ci "pack_into expected %zd items for packing (got %zd)", 19687db96d56Sopenharmony_ci soself->s_len, (nargs - 2)); 19697db96d56Sopenharmony_ci } 19707db96d56Sopenharmony_ci return NULL; 19717db96d56Sopenharmony_ci } 19727db96d56Sopenharmony_ci 19737db96d56Sopenharmony_ci /* Extract a writable memory buffer from the first argument */ 19747db96d56Sopenharmony_ci if (!PyArg_Parse(args[0], "w*", &buffer)) 19757db96d56Sopenharmony_ci return NULL; 19767db96d56Sopenharmony_ci assert(buffer.len >= 0); 19777db96d56Sopenharmony_ci 19787db96d56Sopenharmony_ci /* Extract the offset from the first argument */ 19797db96d56Sopenharmony_ci offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError); 19807db96d56Sopenharmony_ci if (offset == -1 && PyErr_Occurred()) { 19817db96d56Sopenharmony_ci PyBuffer_Release(&buffer); 19827db96d56Sopenharmony_ci return NULL; 19837db96d56Sopenharmony_ci } 19847db96d56Sopenharmony_ci 19857db96d56Sopenharmony_ci /* Support negative offsets. */ 19867db96d56Sopenharmony_ci if (offset < 0) { 19877db96d56Sopenharmony_ci /* Check that negative offset is low enough to fit data */ 19887db96d56Sopenharmony_ci if (offset + soself->s_size > 0) { 19897db96d56Sopenharmony_ci PyErr_Format(state->StructError, 19907db96d56Sopenharmony_ci "no space to pack %zd bytes at offset %zd", 19917db96d56Sopenharmony_ci soself->s_size, 19927db96d56Sopenharmony_ci offset); 19937db96d56Sopenharmony_ci PyBuffer_Release(&buffer); 19947db96d56Sopenharmony_ci return NULL; 19957db96d56Sopenharmony_ci } 19967db96d56Sopenharmony_ci 19977db96d56Sopenharmony_ci /* Check that negative offset is not crossing buffer boundary */ 19987db96d56Sopenharmony_ci if (offset + buffer.len < 0) { 19997db96d56Sopenharmony_ci PyErr_Format(state->StructError, 20007db96d56Sopenharmony_ci "offset %zd out of range for %zd-byte buffer", 20017db96d56Sopenharmony_ci offset, 20027db96d56Sopenharmony_ci buffer.len); 20037db96d56Sopenharmony_ci PyBuffer_Release(&buffer); 20047db96d56Sopenharmony_ci return NULL; 20057db96d56Sopenharmony_ci } 20067db96d56Sopenharmony_ci 20077db96d56Sopenharmony_ci offset += buffer.len; 20087db96d56Sopenharmony_ci } 20097db96d56Sopenharmony_ci 20107db96d56Sopenharmony_ci /* Check boundaries */ 20117db96d56Sopenharmony_ci if ((buffer.len - offset) < soself->s_size) { 20127db96d56Sopenharmony_ci assert(offset >= 0); 20137db96d56Sopenharmony_ci assert(soself->s_size >= 0); 20147db96d56Sopenharmony_ci 20157db96d56Sopenharmony_ci PyErr_Format(state->StructError, 20167db96d56Sopenharmony_ci "pack_into requires a buffer of at least %zu bytes for " 20177db96d56Sopenharmony_ci "packing %zd bytes at offset %zd " 20187db96d56Sopenharmony_ci "(actual buffer size is %zd)", 20197db96d56Sopenharmony_ci (size_t)soself->s_size + (size_t)offset, 20207db96d56Sopenharmony_ci soself->s_size, 20217db96d56Sopenharmony_ci offset, 20227db96d56Sopenharmony_ci buffer.len); 20237db96d56Sopenharmony_ci PyBuffer_Release(&buffer); 20247db96d56Sopenharmony_ci return NULL; 20257db96d56Sopenharmony_ci } 20267db96d56Sopenharmony_ci 20277db96d56Sopenharmony_ci /* Call the guts */ 20287db96d56Sopenharmony_ci if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset, state) != 0) { 20297db96d56Sopenharmony_ci PyBuffer_Release(&buffer); 20307db96d56Sopenharmony_ci return NULL; 20317db96d56Sopenharmony_ci } 20327db96d56Sopenharmony_ci 20337db96d56Sopenharmony_ci PyBuffer_Release(&buffer); 20347db96d56Sopenharmony_ci Py_RETURN_NONE; 20357db96d56Sopenharmony_ci} 20367db96d56Sopenharmony_ci 20377db96d56Sopenharmony_cistatic PyObject * 20387db96d56Sopenharmony_cis_get_format(PyStructObject *self, void *unused) 20397db96d56Sopenharmony_ci{ 20407db96d56Sopenharmony_ci return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format), 20417db96d56Sopenharmony_ci PyBytes_GET_SIZE(self->s_format)); 20427db96d56Sopenharmony_ci} 20437db96d56Sopenharmony_ci 20447db96d56Sopenharmony_cistatic PyObject * 20457db96d56Sopenharmony_cis_get_size(PyStructObject *self, void *unused) 20467db96d56Sopenharmony_ci{ 20477db96d56Sopenharmony_ci return PyLong_FromSsize_t(self->s_size); 20487db96d56Sopenharmony_ci} 20497db96d56Sopenharmony_ci 20507db96d56Sopenharmony_ciPyDoc_STRVAR(s_sizeof__doc__, 20517db96d56Sopenharmony_ci"S.__sizeof__() -> size of S in memory, in bytes"); 20527db96d56Sopenharmony_ci 20537db96d56Sopenharmony_cistatic PyObject * 20547db96d56Sopenharmony_cis_sizeof(PyStructObject *self, void *unused) 20557db96d56Sopenharmony_ci{ 20567db96d56Sopenharmony_ci Py_ssize_t size; 20577db96d56Sopenharmony_ci formatcode *code; 20587db96d56Sopenharmony_ci 20597db96d56Sopenharmony_ci size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode); 20607db96d56Sopenharmony_ci for (code = self->s_codes; code->fmtdef != NULL; code++) 20617db96d56Sopenharmony_ci size += sizeof(formatcode); 20627db96d56Sopenharmony_ci return PyLong_FromSsize_t(size); 20637db96d56Sopenharmony_ci} 20647db96d56Sopenharmony_ci 20657db96d56Sopenharmony_ci/* List of functions */ 20667db96d56Sopenharmony_ci 20677db96d56Sopenharmony_cistatic struct PyMethodDef s_methods[] = { 20687db96d56Sopenharmony_ci STRUCT_ITER_UNPACK_METHODDEF 20697db96d56Sopenharmony_ci {"pack", _PyCFunction_CAST(s_pack), METH_FASTCALL, s_pack__doc__}, 20707db96d56Sopenharmony_ci {"pack_into", _PyCFunction_CAST(s_pack_into), METH_FASTCALL, s_pack_into__doc__}, 20717db96d56Sopenharmony_ci STRUCT_UNPACK_METHODDEF 20727db96d56Sopenharmony_ci STRUCT_UNPACK_FROM_METHODDEF 20737db96d56Sopenharmony_ci {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__}, 20747db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 20757db96d56Sopenharmony_ci}; 20767db96d56Sopenharmony_ci 20777db96d56Sopenharmony_cistatic PyMemberDef s_members[] = { 20787db96d56Sopenharmony_ci {"__weaklistoffset__", T_PYSSIZET, offsetof(PyStructObject, weakreflist), READONLY}, 20797db96d56Sopenharmony_ci {NULL} /* sentinel */ 20807db96d56Sopenharmony_ci}; 20817db96d56Sopenharmony_ci 20827db96d56Sopenharmony_cistatic PyGetSetDef s_getsetlist[] = { 20837db96d56Sopenharmony_ci {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL}, 20847db96d56Sopenharmony_ci {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL}, 20857db96d56Sopenharmony_ci {NULL} /* sentinel */ 20867db96d56Sopenharmony_ci}; 20877db96d56Sopenharmony_ci 20887db96d56Sopenharmony_ciPyDoc_STRVAR(s__doc__, 20897db96d56Sopenharmony_ci"Struct(fmt) --> compiled struct object\n" 20907db96d56Sopenharmony_ci"\n" 20917db96d56Sopenharmony_ci); 20927db96d56Sopenharmony_ci 20937db96d56Sopenharmony_cistatic PyType_Slot PyStructType_slots[] = { 20947db96d56Sopenharmony_ci {Py_tp_dealloc, s_dealloc}, 20957db96d56Sopenharmony_ci {Py_tp_getattro, PyObject_GenericGetAttr}, 20967db96d56Sopenharmony_ci {Py_tp_setattro, PyObject_GenericSetAttr}, 20977db96d56Sopenharmony_ci {Py_tp_doc, (void*)s__doc__}, 20987db96d56Sopenharmony_ci {Py_tp_traverse, s_traverse}, 20997db96d56Sopenharmony_ci {Py_tp_clear, s_clear}, 21007db96d56Sopenharmony_ci {Py_tp_methods, s_methods}, 21017db96d56Sopenharmony_ci {Py_tp_members, s_members}, 21027db96d56Sopenharmony_ci {Py_tp_getset, s_getsetlist}, 21037db96d56Sopenharmony_ci {Py_tp_init, Struct___init__}, 21047db96d56Sopenharmony_ci {Py_tp_alloc, PyType_GenericAlloc}, 21057db96d56Sopenharmony_ci {Py_tp_new, s_new}, 21067db96d56Sopenharmony_ci {Py_tp_free, PyObject_GC_Del}, 21077db96d56Sopenharmony_ci {0, 0}, 21087db96d56Sopenharmony_ci}; 21097db96d56Sopenharmony_ci 21107db96d56Sopenharmony_cistatic PyType_Spec PyStructType_spec = { 21117db96d56Sopenharmony_ci "_struct.Struct", 21127db96d56Sopenharmony_ci sizeof(PyStructObject), 21137db96d56Sopenharmony_ci 0, 21147db96d56Sopenharmony_ci (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | 21157db96d56Sopenharmony_ci Py_TPFLAGS_BASETYPE | Py_TPFLAGS_IMMUTABLETYPE), 21167db96d56Sopenharmony_ci PyStructType_slots 21177db96d56Sopenharmony_ci}; 21187db96d56Sopenharmony_ci 21197db96d56Sopenharmony_ci 21207db96d56Sopenharmony_ci/* ---- Standalone functions ---- */ 21217db96d56Sopenharmony_ci 21227db96d56Sopenharmony_ci#define MAXCACHE 100 21237db96d56Sopenharmony_ci 21247db96d56Sopenharmony_cistatic int 21257db96d56Sopenharmony_cicache_struct_converter(PyObject *module, PyObject *fmt, PyStructObject **ptr) 21267db96d56Sopenharmony_ci{ 21277db96d56Sopenharmony_ci PyObject * s_object; 21287db96d56Sopenharmony_ci _structmodulestate *state = get_struct_state(module); 21297db96d56Sopenharmony_ci 21307db96d56Sopenharmony_ci if (fmt == NULL) { 21317db96d56Sopenharmony_ci Py_DECREF(*ptr); 21327db96d56Sopenharmony_ci *ptr = NULL; 21337db96d56Sopenharmony_ci return 1; 21347db96d56Sopenharmony_ci } 21357db96d56Sopenharmony_ci 21367db96d56Sopenharmony_ci if (state->cache == NULL) { 21377db96d56Sopenharmony_ci state->cache = PyDict_New(); 21387db96d56Sopenharmony_ci if (state->cache == NULL) 21397db96d56Sopenharmony_ci return 0; 21407db96d56Sopenharmony_ci } 21417db96d56Sopenharmony_ci 21427db96d56Sopenharmony_ci s_object = PyDict_GetItemWithError(state->cache, fmt); 21437db96d56Sopenharmony_ci if (s_object != NULL) { 21447db96d56Sopenharmony_ci Py_INCREF(s_object); 21457db96d56Sopenharmony_ci *ptr = (PyStructObject *)s_object; 21467db96d56Sopenharmony_ci return Py_CLEANUP_SUPPORTED; 21477db96d56Sopenharmony_ci } 21487db96d56Sopenharmony_ci else if (PyErr_Occurred()) { 21497db96d56Sopenharmony_ci return 0; 21507db96d56Sopenharmony_ci } 21517db96d56Sopenharmony_ci 21527db96d56Sopenharmony_ci s_object = PyObject_CallOneArg(state->PyStructType, fmt); 21537db96d56Sopenharmony_ci if (s_object != NULL) { 21547db96d56Sopenharmony_ci if (PyDict_GET_SIZE(state->cache) >= MAXCACHE) 21557db96d56Sopenharmony_ci PyDict_Clear(state->cache); 21567db96d56Sopenharmony_ci /* Attempt to cache the result */ 21577db96d56Sopenharmony_ci if (PyDict_SetItem(state->cache, fmt, s_object) == -1) 21587db96d56Sopenharmony_ci PyErr_Clear(); 21597db96d56Sopenharmony_ci *ptr = (PyStructObject *)s_object; 21607db96d56Sopenharmony_ci return Py_CLEANUP_SUPPORTED; 21617db96d56Sopenharmony_ci } 21627db96d56Sopenharmony_ci return 0; 21637db96d56Sopenharmony_ci} 21647db96d56Sopenharmony_ci 21657db96d56Sopenharmony_ci/*[clinic input] 21667db96d56Sopenharmony_ci_clearcache 21677db96d56Sopenharmony_ci 21687db96d56Sopenharmony_ciClear the internal cache. 21697db96d56Sopenharmony_ci[clinic start generated code]*/ 21707db96d56Sopenharmony_ci 21717db96d56Sopenharmony_cistatic PyObject * 21727db96d56Sopenharmony_ci_clearcache_impl(PyObject *module) 21737db96d56Sopenharmony_ci/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/ 21747db96d56Sopenharmony_ci{ 21757db96d56Sopenharmony_ci Py_CLEAR(get_struct_state(module)->cache); 21767db96d56Sopenharmony_ci Py_RETURN_NONE; 21777db96d56Sopenharmony_ci} 21787db96d56Sopenharmony_ci 21797db96d56Sopenharmony_ci 21807db96d56Sopenharmony_ci/*[clinic input] 21817db96d56Sopenharmony_cicalcsize -> Py_ssize_t 21827db96d56Sopenharmony_ci 21837db96d56Sopenharmony_ci format as s_object: cache_struct 21847db96d56Sopenharmony_ci / 21857db96d56Sopenharmony_ci 21867db96d56Sopenharmony_ciReturn size in bytes of the struct described by the format string. 21877db96d56Sopenharmony_ci[clinic start generated code]*/ 21887db96d56Sopenharmony_ci 21897db96d56Sopenharmony_cistatic Py_ssize_t 21907db96d56Sopenharmony_cicalcsize_impl(PyObject *module, PyStructObject *s_object) 21917db96d56Sopenharmony_ci/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/ 21927db96d56Sopenharmony_ci{ 21937db96d56Sopenharmony_ci return s_object->s_size; 21947db96d56Sopenharmony_ci} 21957db96d56Sopenharmony_ci 21967db96d56Sopenharmony_ciPyDoc_STRVAR(pack_doc, 21977db96d56Sopenharmony_ci"pack(format, v1, v2, ...) -> bytes\n\ 21987db96d56Sopenharmony_ci\n\ 21997db96d56Sopenharmony_ciReturn a bytes object containing the values v1, v2, ... packed according\n\ 22007db96d56Sopenharmony_cito the format string. See help(struct) for more on format strings."); 22017db96d56Sopenharmony_ci 22027db96d56Sopenharmony_cistatic PyObject * 22037db96d56Sopenharmony_cipack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) 22047db96d56Sopenharmony_ci{ 22057db96d56Sopenharmony_ci PyObject *s_object = NULL; 22067db96d56Sopenharmony_ci PyObject *format, *result; 22077db96d56Sopenharmony_ci 22087db96d56Sopenharmony_ci if (nargs == 0) { 22097db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "missing format argument"); 22107db96d56Sopenharmony_ci return NULL; 22117db96d56Sopenharmony_ci } 22127db96d56Sopenharmony_ci format = args[0]; 22137db96d56Sopenharmony_ci 22147db96d56Sopenharmony_ci if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) { 22157db96d56Sopenharmony_ci return NULL; 22167db96d56Sopenharmony_ci } 22177db96d56Sopenharmony_ci result = s_pack(s_object, args + 1, nargs - 1); 22187db96d56Sopenharmony_ci Py_DECREF(s_object); 22197db96d56Sopenharmony_ci return result; 22207db96d56Sopenharmony_ci} 22217db96d56Sopenharmony_ci 22227db96d56Sopenharmony_ciPyDoc_STRVAR(pack_into_doc, 22237db96d56Sopenharmony_ci"pack_into(format, buffer, offset, v1, v2, ...)\n\ 22247db96d56Sopenharmony_ci\n\ 22257db96d56Sopenharmony_ciPack the values v1, v2, ... according to the format string and write\n\ 22267db96d56Sopenharmony_cithe packed bytes into the writable buffer buf starting at offset. Note\n\ 22277db96d56Sopenharmony_cithat the offset is a required argument. See help(struct) for more\n\ 22287db96d56Sopenharmony_cion format strings."); 22297db96d56Sopenharmony_ci 22307db96d56Sopenharmony_cistatic PyObject * 22317db96d56Sopenharmony_cipack_into(PyObject *module, PyObject *const *args, Py_ssize_t nargs) 22327db96d56Sopenharmony_ci{ 22337db96d56Sopenharmony_ci PyObject *s_object = NULL; 22347db96d56Sopenharmony_ci PyObject *format, *result; 22357db96d56Sopenharmony_ci 22367db96d56Sopenharmony_ci if (nargs == 0) { 22377db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, "missing format argument"); 22387db96d56Sopenharmony_ci return NULL; 22397db96d56Sopenharmony_ci } 22407db96d56Sopenharmony_ci format = args[0]; 22417db96d56Sopenharmony_ci 22427db96d56Sopenharmony_ci if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) { 22437db96d56Sopenharmony_ci return NULL; 22447db96d56Sopenharmony_ci } 22457db96d56Sopenharmony_ci result = s_pack_into(s_object, args + 1, nargs - 1); 22467db96d56Sopenharmony_ci Py_DECREF(s_object); 22477db96d56Sopenharmony_ci return result; 22487db96d56Sopenharmony_ci} 22497db96d56Sopenharmony_ci 22507db96d56Sopenharmony_ci/*[clinic input] 22517db96d56Sopenharmony_ciunpack 22527db96d56Sopenharmony_ci 22537db96d56Sopenharmony_ci format as s_object: cache_struct 22547db96d56Sopenharmony_ci buffer: Py_buffer 22557db96d56Sopenharmony_ci / 22567db96d56Sopenharmony_ci 22577db96d56Sopenharmony_ciReturn a tuple containing values unpacked according to the format string. 22587db96d56Sopenharmony_ci 22597db96d56Sopenharmony_ciThe buffer's size in bytes must be calcsize(format). 22607db96d56Sopenharmony_ci 22617db96d56Sopenharmony_ciSee help(struct) for more on format strings. 22627db96d56Sopenharmony_ci[clinic start generated code]*/ 22637db96d56Sopenharmony_ci 22647db96d56Sopenharmony_cistatic PyObject * 22657db96d56Sopenharmony_ciunpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer) 22667db96d56Sopenharmony_ci/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/ 22677db96d56Sopenharmony_ci{ 22687db96d56Sopenharmony_ci return Struct_unpack_impl(s_object, buffer); 22697db96d56Sopenharmony_ci} 22707db96d56Sopenharmony_ci 22717db96d56Sopenharmony_ci/*[clinic input] 22727db96d56Sopenharmony_ciunpack_from 22737db96d56Sopenharmony_ci 22747db96d56Sopenharmony_ci format as s_object: cache_struct 22757db96d56Sopenharmony_ci / 22767db96d56Sopenharmony_ci buffer: Py_buffer 22777db96d56Sopenharmony_ci offset: Py_ssize_t = 0 22787db96d56Sopenharmony_ci 22797db96d56Sopenharmony_ciReturn a tuple containing values unpacked according to the format string. 22807db96d56Sopenharmony_ci 22817db96d56Sopenharmony_ciThe buffer's size, minus offset, must be at least calcsize(format). 22827db96d56Sopenharmony_ci 22837db96d56Sopenharmony_ciSee help(struct) for more on format strings. 22847db96d56Sopenharmony_ci[clinic start generated code]*/ 22857db96d56Sopenharmony_ci 22867db96d56Sopenharmony_cistatic PyObject * 22877db96d56Sopenharmony_ciunpack_from_impl(PyObject *module, PyStructObject *s_object, 22887db96d56Sopenharmony_ci Py_buffer *buffer, Py_ssize_t offset) 22897db96d56Sopenharmony_ci/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/ 22907db96d56Sopenharmony_ci{ 22917db96d56Sopenharmony_ci return Struct_unpack_from_impl(s_object, buffer, offset); 22927db96d56Sopenharmony_ci} 22937db96d56Sopenharmony_ci 22947db96d56Sopenharmony_ci/*[clinic input] 22957db96d56Sopenharmony_ciiter_unpack 22967db96d56Sopenharmony_ci 22977db96d56Sopenharmony_ci format as s_object: cache_struct 22987db96d56Sopenharmony_ci buffer: object 22997db96d56Sopenharmony_ci / 23007db96d56Sopenharmony_ci 23017db96d56Sopenharmony_ciReturn an iterator yielding tuples unpacked from the given bytes. 23027db96d56Sopenharmony_ci 23037db96d56Sopenharmony_ciThe bytes are unpacked according to the format string, like 23047db96d56Sopenharmony_cia repeated invocation of unpack_from(). 23057db96d56Sopenharmony_ci 23067db96d56Sopenharmony_ciRequires that the bytes length be a multiple of the format struct size. 23077db96d56Sopenharmony_ci[clinic start generated code]*/ 23087db96d56Sopenharmony_ci 23097db96d56Sopenharmony_cistatic PyObject * 23107db96d56Sopenharmony_ciiter_unpack_impl(PyObject *module, PyStructObject *s_object, 23117db96d56Sopenharmony_ci PyObject *buffer) 23127db96d56Sopenharmony_ci/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/ 23137db96d56Sopenharmony_ci{ 23147db96d56Sopenharmony_ci return Struct_iter_unpack(s_object, buffer); 23157db96d56Sopenharmony_ci} 23167db96d56Sopenharmony_ci 23177db96d56Sopenharmony_cistatic struct PyMethodDef module_functions[] = { 23187db96d56Sopenharmony_ci _CLEARCACHE_METHODDEF 23197db96d56Sopenharmony_ci CALCSIZE_METHODDEF 23207db96d56Sopenharmony_ci ITER_UNPACK_METHODDEF 23217db96d56Sopenharmony_ci {"pack", _PyCFunction_CAST(pack), METH_FASTCALL, pack_doc}, 23227db96d56Sopenharmony_ci {"pack_into", _PyCFunction_CAST(pack_into), METH_FASTCALL, pack_into_doc}, 23237db96d56Sopenharmony_ci UNPACK_METHODDEF 23247db96d56Sopenharmony_ci UNPACK_FROM_METHODDEF 23257db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 23267db96d56Sopenharmony_ci}; 23277db96d56Sopenharmony_ci 23287db96d56Sopenharmony_ci 23297db96d56Sopenharmony_ci/* Module initialization */ 23307db96d56Sopenharmony_ci 23317db96d56Sopenharmony_ciPyDoc_STRVAR(module_doc, 23327db96d56Sopenharmony_ci"Functions to convert between Python values and C structs.\n\ 23337db96d56Sopenharmony_ciPython bytes objects are used to hold the data representing the C struct\n\ 23347db96d56Sopenharmony_ciand also as format strings (explained below) to describe the layout of data\n\ 23357db96d56Sopenharmony_ciin the C struct.\n\ 23367db96d56Sopenharmony_ci\n\ 23377db96d56Sopenharmony_ciThe optional first format char indicates byte order, size and alignment:\n\ 23387db96d56Sopenharmony_ci @: native order, size & alignment (default)\n\ 23397db96d56Sopenharmony_ci =: native order, std. size & alignment\n\ 23407db96d56Sopenharmony_ci <: little-endian, std. size & alignment\n\ 23417db96d56Sopenharmony_ci >: big-endian, std. size & alignment\n\ 23427db96d56Sopenharmony_ci !: same as >\n\ 23437db96d56Sopenharmony_ci\n\ 23447db96d56Sopenharmony_ciThe remaining chars indicate types of args and must match exactly;\n\ 23457db96d56Sopenharmony_cithese can be preceded by a decimal repeat count:\n\ 23467db96d56Sopenharmony_ci x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\ 23477db96d56Sopenharmony_ci ?: _Bool (requires C99; if not available, char is used instead)\n\ 23487db96d56Sopenharmony_ci h:short; H:unsigned short; i:int; I:unsigned int;\n\ 23497db96d56Sopenharmony_ci l:long; L:unsigned long; f:float; d:double; e:half-float.\n\ 23507db96d56Sopenharmony_ciSpecial cases (preceding decimal count indicates length):\n\ 23517db96d56Sopenharmony_ci s:string (array of char); p: pascal string (with count byte).\n\ 23527db96d56Sopenharmony_ciSpecial cases (only available in native format):\n\ 23537db96d56Sopenharmony_ci n:ssize_t; N:size_t;\n\ 23547db96d56Sopenharmony_ci P:an integer type that is wide enough to hold a pointer.\n\ 23557db96d56Sopenharmony_ciSpecial case (not in native mode unless 'long long' in platform C):\n\ 23567db96d56Sopenharmony_ci q:long long; Q:unsigned long long\n\ 23577db96d56Sopenharmony_ciWhitespace between formats is ignored.\n\ 23587db96d56Sopenharmony_ci\n\ 23597db96d56Sopenharmony_ciThe variable struct.error is an exception raised on errors.\n"); 23607db96d56Sopenharmony_ci 23617db96d56Sopenharmony_ci 23627db96d56Sopenharmony_cistatic int 23637db96d56Sopenharmony_ci_structmodule_traverse(PyObject *module, visitproc visit, void *arg) 23647db96d56Sopenharmony_ci{ 23657db96d56Sopenharmony_ci _structmodulestate *state = get_struct_state(module); 23667db96d56Sopenharmony_ci if (state) { 23677db96d56Sopenharmony_ci Py_VISIT(state->cache); 23687db96d56Sopenharmony_ci Py_VISIT(state->PyStructType); 23697db96d56Sopenharmony_ci Py_VISIT(state->unpackiter_type); 23707db96d56Sopenharmony_ci Py_VISIT(state->StructError); 23717db96d56Sopenharmony_ci } 23727db96d56Sopenharmony_ci return 0; 23737db96d56Sopenharmony_ci} 23747db96d56Sopenharmony_ci 23757db96d56Sopenharmony_cistatic int 23767db96d56Sopenharmony_ci_structmodule_clear(PyObject *module) 23777db96d56Sopenharmony_ci{ 23787db96d56Sopenharmony_ci _structmodulestate *state = get_struct_state(module); 23797db96d56Sopenharmony_ci if (state) { 23807db96d56Sopenharmony_ci Py_CLEAR(state->cache); 23817db96d56Sopenharmony_ci Py_CLEAR(state->PyStructType); 23827db96d56Sopenharmony_ci Py_CLEAR(state->unpackiter_type); 23837db96d56Sopenharmony_ci Py_CLEAR(state->StructError); 23847db96d56Sopenharmony_ci } 23857db96d56Sopenharmony_ci return 0; 23867db96d56Sopenharmony_ci} 23877db96d56Sopenharmony_ci 23887db96d56Sopenharmony_cistatic void 23897db96d56Sopenharmony_ci_structmodule_free(void *module) 23907db96d56Sopenharmony_ci{ 23917db96d56Sopenharmony_ci _structmodule_clear((PyObject *)module); 23927db96d56Sopenharmony_ci} 23937db96d56Sopenharmony_ci 23947db96d56Sopenharmony_cistatic int 23957db96d56Sopenharmony_ci_structmodule_exec(PyObject *m) 23967db96d56Sopenharmony_ci{ 23977db96d56Sopenharmony_ci _structmodulestate *state = get_struct_state(m); 23987db96d56Sopenharmony_ci 23997db96d56Sopenharmony_ci state->PyStructType = PyType_FromModuleAndSpec( 24007db96d56Sopenharmony_ci m, &PyStructType_spec, NULL); 24017db96d56Sopenharmony_ci if (state->PyStructType == NULL) { 24027db96d56Sopenharmony_ci return -1; 24037db96d56Sopenharmony_ci } 24047db96d56Sopenharmony_ci if (PyModule_AddType(m, (PyTypeObject *)state->PyStructType) < 0) { 24057db96d56Sopenharmony_ci return -1; 24067db96d56Sopenharmony_ci } 24077db96d56Sopenharmony_ci 24087db96d56Sopenharmony_ci state->unpackiter_type = PyType_FromModuleAndSpec( 24097db96d56Sopenharmony_ci m, &unpackiter_type_spec, NULL); 24107db96d56Sopenharmony_ci if (state->unpackiter_type == NULL) { 24117db96d56Sopenharmony_ci return -1; 24127db96d56Sopenharmony_ci } 24137db96d56Sopenharmony_ci 24147db96d56Sopenharmony_ci /* Check endian and swap in faster functions */ 24157db96d56Sopenharmony_ci { 24167db96d56Sopenharmony_ci const formatdef *native = native_table; 24177db96d56Sopenharmony_ci formatdef *other, *ptr; 24187db96d56Sopenharmony_ci#if PY_LITTLE_ENDIAN 24197db96d56Sopenharmony_ci other = lilendian_table; 24207db96d56Sopenharmony_ci#else 24217db96d56Sopenharmony_ci other = bigendian_table; 24227db96d56Sopenharmony_ci#endif 24237db96d56Sopenharmony_ci /* Scan through the native table, find a matching 24247db96d56Sopenharmony_ci entry in the endian table and swap in the 24257db96d56Sopenharmony_ci native implementations whenever possible 24267db96d56Sopenharmony_ci (64-bit platforms may not have "standard" sizes) */ 24277db96d56Sopenharmony_ci while (native->format != '\0' && other->format != '\0') { 24287db96d56Sopenharmony_ci ptr = other; 24297db96d56Sopenharmony_ci while (ptr->format != '\0') { 24307db96d56Sopenharmony_ci if (ptr->format == native->format) { 24317db96d56Sopenharmony_ci /* Match faster when formats are 24327db96d56Sopenharmony_ci listed in the same order */ 24337db96d56Sopenharmony_ci if (ptr == other) 24347db96d56Sopenharmony_ci other++; 24357db96d56Sopenharmony_ci /* Only use the trick if the 24367db96d56Sopenharmony_ci size matches */ 24377db96d56Sopenharmony_ci if (ptr->size != native->size) 24387db96d56Sopenharmony_ci break; 24397db96d56Sopenharmony_ci /* Skip float and double, could be 24407db96d56Sopenharmony_ci "unknown" float format */ 24417db96d56Sopenharmony_ci if (ptr->format == 'd' || ptr->format == 'f') 24427db96d56Sopenharmony_ci break; 24437db96d56Sopenharmony_ci /* Skip _Bool, semantics are different for standard size */ 24447db96d56Sopenharmony_ci if (ptr->format == '?') 24457db96d56Sopenharmony_ci break; 24467db96d56Sopenharmony_ci ptr->pack = native->pack; 24477db96d56Sopenharmony_ci ptr->unpack = native->unpack; 24487db96d56Sopenharmony_ci break; 24497db96d56Sopenharmony_ci } 24507db96d56Sopenharmony_ci ptr++; 24517db96d56Sopenharmony_ci } 24527db96d56Sopenharmony_ci native++; 24537db96d56Sopenharmony_ci } 24547db96d56Sopenharmony_ci } 24557db96d56Sopenharmony_ci 24567db96d56Sopenharmony_ci /* Add some symbolic constants to the module */ 24577db96d56Sopenharmony_ci state->StructError = PyErr_NewException("struct.error", NULL, NULL); 24587db96d56Sopenharmony_ci if (state->StructError == NULL) { 24597db96d56Sopenharmony_ci return -1; 24607db96d56Sopenharmony_ci } 24617db96d56Sopenharmony_ci if (PyModule_AddObjectRef(m, "error", state->StructError) < 0) { 24627db96d56Sopenharmony_ci return -1; 24637db96d56Sopenharmony_ci } 24647db96d56Sopenharmony_ci 24657db96d56Sopenharmony_ci return 0; 24667db96d56Sopenharmony_ci} 24677db96d56Sopenharmony_ci 24687db96d56Sopenharmony_cistatic PyModuleDef_Slot _structmodule_slots[] = { 24697db96d56Sopenharmony_ci {Py_mod_exec, _structmodule_exec}, 24707db96d56Sopenharmony_ci {0, NULL} 24717db96d56Sopenharmony_ci}; 24727db96d56Sopenharmony_ci 24737db96d56Sopenharmony_cistatic struct PyModuleDef _structmodule = { 24747db96d56Sopenharmony_ci PyModuleDef_HEAD_INIT, 24757db96d56Sopenharmony_ci .m_name = "_struct", 24767db96d56Sopenharmony_ci .m_doc = module_doc, 24777db96d56Sopenharmony_ci .m_size = sizeof(_structmodulestate), 24787db96d56Sopenharmony_ci .m_methods = module_functions, 24797db96d56Sopenharmony_ci .m_slots = _structmodule_slots, 24807db96d56Sopenharmony_ci .m_traverse = _structmodule_traverse, 24817db96d56Sopenharmony_ci .m_clear = _structmodule_clear, 24827db96d56Sopenharmony_ci .m_free = _structmodule_free, 24837db96d56Sopenharmony_ci}; 24847db96d56Sopenharmony_ci 24857db96d56Sopenharmony_ciPyMODINIT_FUNC 24867db96d56Sopenharmony_ciPyInit__struct(void) 24877db96d56Sopenharmony_ci{ 24887db96d56Sopenharmony_ci return PyModuleDef_Init(&_structmodule); 24897db96d56Sopenharmony_ci} 2490