LCOV - code coverage report
Current view: | top level - Modules - _struct.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 229 | 1000 | 22.9 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 24 | 117 | 20.5 %
|  |  | Branches: | 117 | 584 | 20.0 %

               Branch data     Line data    Source code
           1                 :            : /* struct module -- pack values into and (out of) bytes objects */
           2                 :            :
           3                 :            : /* New version supporting byte order, alignment and size options,
           4                 :            :    character strings, and unsigned numbers */
           5                 :            :
           6                 :            : #ifndef Py_BUILD_CORE_BUILTIN
           7                 :            : #  define Py_BUILD_CORE_MODULE 1
           8                 :            : #endif
           9                 :            :
          10                 :            : #define PY_SSIZE_T_CLEAN
          11                 :            :
          12                 :            : #include "Python.h"
          13                 :            : #include "pycore_moduleobject.h"  // _PyModule_GetState()
          14                 :            : #include "structmember.h"         // PyMemberDef
          15                 :            : #include <ctype.h>
          16                 :            :
          17                 :            : /*[clinic input]
          18                 :            : class Struct "PyStructObject *" "&PyStructType"
          19                 :            : [clinic start generated code]*/
          20                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b032058a83ed7c3]*/
          21                 :            :
          22                 :            : typedef struct {
          23                 :            :     PyObject *cache;
          24                 :            :     PyObject *PyStructType;
          25                 :            :     PyObject *unpackiter_type;
          26                 :            :     PyObject *StructError;
          27                 :            : } _structmodulestate;
          28                 :            :
          29                 :            : static inline _structmodulestate*
          30                 :        885 : get_struct_state(PyObject *module)
          31                 :            : {
          32                 :        885 :     void *state = _PyModule_GetState(module);
          33                 :            :     assert(state != NULL);
          34                 :        885 :     return (_structmodulestate *)state;
          35                 :            : }
          36                 :            :
          37                 :            : static struct PyModuleDef _structmodule;
          38                 :            :
          39                 :            : #define get_struct_state_structinst(self) \
          40                 :            :     (get_struct_state(PyType_GetModuleByDef(Py_TYPE(self), &_structmodule)))
          41                 :            : #define get_struct_state_iterinst(self) \
          42                 :            :     (get_struct_state(PyType_GetModule(Py_TYPE(self))))
          43                 :            :
          44                 :            : /* The translation function for each format character is table driven */
          45                 :            : typedef struct _formatdef {
          46                 :            :     char format;
          47                 :            :     Py_ssize_t size;
          48                 :            :     Py_ssize_t alignment;
          49                 :            :     PyObject* (*unpack)(_structmodulestate *, const char *,
          50                 :            :                         const struct _formatdef *);
          51                 :            :     int (*pack)(_structmodulestate *, char *, PyObject *,
          52                 :            :                 const struct _formatdef *);
          53                 :            : } formatdef;
          54                 :            :
          55                 :            : typedef struct _formatcode {
          56                 :            :     const struct _formatdef *fmtdef;
          57                 :            :     Py_ssize_t offset;
          58                 :            :     Py_ssize_t size;
          59                 :            :     Py_ssize_t repeat;
          60                 :            : } formatcode;
          61                 :            :
          62                 :            : /* Struct object interface */
          63                 :            :
          64                 :            : typedef struct {
          65                 :            :     PyObject_HEAD
          66                 :            :     Py_ssize_t s_size;
          67                 :            :     Py_ssize_t s_len;
          68                 :            :     formatcode *s_codes;
          69                 :            :     PyObject *s_format;
          70                 :            :     PyObject *weakreflist; /* List of weak references */
          71                 :            : } PyStructObject;
          72                 :            :
          73                 :            : #define PyStruct_Check(op, state) PyObject_TypeCheck(op, (PyTypeObject *)(state)->PyStructType)
          74                 :            :
          75                 :            : /* Define various structs to figure out the alignments of types */
          76                 :            :
          77                 :            :
          78                 :            : typedef struct { char c; short x; } st_short;
          79                 :            : typedef struct { char c; int x; } st_int;
          80                 :            : typedef struct { char c; long x; } st_long;
          81                 :            : typedef struct { char c; float x; } st_float;
          82                 :            : typedef struct { char c; double x; } st_double;
          83                 :            : typedef struct { char c; void *x; } st_void_p;
          84                 :            : typedef struct { char c; size_t x; } st_size_t;
          85                 :            : typedef struct { char c; _Bool x; } st_bool;
          86                 :            :
          87                 :            : #define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
          88                 :            : #define INT_ALIGN (sizeof(st_int) - sizeof(int))
          89                 :            : #define LONG_ALIGN (sizeof(st_long) - sizeof(long))
          90                 :            : #define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
          91                 :            : #define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
          92                 :            : #define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
          93                 :            : #define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t))
          94                 :            : #define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool))
          95                 :            :
          96                 :            : /* We can't support q and Q in native mode unless the compiler does;
          97                 :            :    in std mode, they're 8 bytes on all platforms. */
          98                 :            : typedef struct { char c; long long x; } s_long_long;
          99                 :            : #define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long))
         100                 :            :
         101                 :            : #ifdef __powerc
         102                 :            : #pragma options align=reset
         103                 :            : #endif
         104                 :            :
         105                 :            : /*[python input]
         106                 :            : class cache_struct_converter(CConverter):
         107                 :            :     type = 'PyStructObject *'
         108                 :            :     converter = 'cache_struct_converter'
         109                 :            :     c_default = "NULL"
         110                 :            :
         111                 :            :     def parse_arg(self, argname, displayname):
         112                 :            :         return """
         113                 :            :             if (!{converter}(module, {argname}, &{paramname})) {{{{
         114                 :            :                 goto exit;
         115                 :            :             }}}}
         116                 :            :             """.format(argname=argname, paramname=self.name,
         117                 :            :                        converter=self.converter)
         118                 :            :
         119                 :            :     def cleanup(self):
         120                 :            :         return "Py_XDECREF(%s);\n" % self.name
         121                 :            : [python start generated code]*/
         122                 :            : /*[python end generated code: output=da39a3ee5e6b4b0d input=d6746621c2fb1a7d]*/
         123                 :            :
         124                 :            : static int cache_struct_converter(PyObject *, PyObject *, PyStructObject **);
         125                 :            :
         126                 :            : #include "clinic/_struct.c.h"
         127                 :            :
         128                 :            : /* Helper for integer format codes: converts an arbitrary Python object to a
         129                 :            :    PyLongObject if possible, otherwise fails.  Caller should decref. */
         130                 :            :
         131                 :            : static PyObject *
         132                 :          0 : get_pylong(_structmodulestate *state, PyObject *v)
         133                 :            : {
         134                 :            :     assert(v != NULL);
         135         [ #  # ]:          0 :     if (!PyLong_Check(v)) {
         136                 :            :         /* Not an integer;  try to use __index__ to convert. */
         137         [ #  # ]:          0 :         if (PyIndex_Check(v)) {
         138                 :          0 :             v = _PyNumber_Index(v);
         139         [ #  # ]:          0 :             if (v == NULL)
         140                 :          0 :                 return NULL;
         141                 :            :         }
         142                 :            :         else {
         143                 :          0 :             PyErr_SetString(state->StructError,
         144                 :            :                             "required argument is not an integer");
         145                 :          0 :             return NULL;
         146                 :            :         }
         147                 :            :     }
         148                 :            :     else
         149                 :          0 :         Py_INCREF(v);
         150                 :            :
         151                 :            :     assert(PyLong_Check(v));
         152                 :          0 :     return v;
         153                 :            : }
         154                 :            :
         155                 :            : /* Helper routine to get a C long and raise the appropriate error if it isn't
         156                 :            :    one */
         157                 :            :
         158                 :            : static int
         159                 :          0 : get_long(_structmodulestate *state, PyObject *v, long *p)
         160                 :            : {
         161                 :            :     long x;
         162                 :            :
         163                 :          0 :     v = get_pylong(state, v);
         164         [ #  # ]:          0 :     if (v == NULL)
         165                 :          0 :         return -1;
         166                 :            :     assert(PyLong_Check(v));
         167                 :          0 :     x = PyLong_AsLong(v);
         168                 :          0 :     Py_DECREF(v);
         169   [ #  #  #  # ]:          0 :     if (x == (long)-1 && PyErr_Occurred()) {
         170                 :          0 :         return -1;
         171                 :            :     }
         172                 :          0 :     *p = x;
         173                 :          0 :     return 0;
         174                 :            : }
         175                 :            :
         176                 :            :
         177                 :            : /* Same, but handling unsigned long */
         178                 :            :
         179                 :            : static int
         180                 :          0 : get_ulong(_structmodulestate *state, PyObject *v, unsigned long *p)
         181                 :            : {
         182                 :            :     unsigned long x;
         183                 :            :
         184                 :          0 :     v = get_pylong(state, v);
         185         [ #  # ]:          0 :     if (v == NULL)
         186                 :          0 :         return -1;
         187                 :            :     assert(PyLong_Check(v));
         188                 :          0 :     x = PyLong_AsUnsignedLong(v);
         189                 :          0 :     Py_DECREF(v);
         190   [ #  #  #  # ]:          0 :     if (x == (unsigned long)-1 && PyErr_Occurred()) {
         191                 :          0 :         return -1;
         192                 :            :     }
         193                 :          0 :     *p = x;
         194                 :          0 :     return 0;
         195                 :            : }
         196                 :            :
         197                 :            : /* Same, but handling native long long. */
         198                 :            :
         199                 :            : static int
         200                 :          0 : get_longlong(_structmodulestate *state, PyObject *v, long long *p)
         201                 :            : {
         202                 :            :     long long x;
         203                 :            :
         204                 :          0 :     v = get_pylong(state, v);
         205         [ #  # ]:          0 :     if (v == NULL)
         206                 :          0 :         return -1;
         207                 :            :     assert(PyLong_Check(v));
         208                 :          0 :     x = PyLong_AsLongLong(v);
         209                 :          0 :     Py_DECREF(v);
         210   [ #  #  #  # ]:          0 :     if (x == (long long)-1 && PyErr_Occurred()) {
         211                 :          0 :         return -1;
         212                 :            :     }
         213                 :          0 :     *p = x;
         214                 :          0 :     return 0;
         215                 :            : }
         216                 :            :
         217                 :            : /* Same, but handling native unsigned long long. */
         218                 :            :
         219                 :            : static int
         220                 :          0 : get_ulonglong(_structmodulestate *state, PyObject *v, unsigned long long *p)
         221                 :            : {
         222                 :            :     unsigned long long x;
         223                 :            :
         224                 :          0 :     v = get_pylong(state, v);
         225         [ #  # ]:          0 :     if (v == NULL)
         226                 :          0 :         return -1;
         227                 :            :     assert(PyLong_Check(v));
         228                 :          0 :     x = PyLong_AsUnsignedLongLong(v);
         229                 :          0 :     Py_DECREF(v);
         230   [ #  #  #  # ]:          0 :     if (x == (unsigned long long)-1 && PyErr_Occurred()) {
         231                 :          0 :         return -1;
         232                 :            :     }
         233                 :          0 :     *p = x;
         234                 :          0 :     return 0;
         235                 :            : }
         236                 :            :
         237                 :            : /* Same, but handling Py_ssize_t */
         238                 :            :
         239                 :            : static int
         240                 :          0 : get_ssize_t(_structmodulestate *state, PyObject *v, Py_ssize_t *p)
         241                 :            : {
         242                 :            :     Py_ssize_t x;
         243                 :            :
         244                 :          0 :     v = get_pylong(state, v);
         245         [ #  # ]:          0 :     if (v == NULL)
         246                 :          0 :         return -1;
         247                 :            :     assert(PyLong_Check(v));
         248                 :          0 :     x = PyLong_AsSsize_t(v);
         249                 :          0 :     Py_DECREF(v);
         250   [ #  #  #  # ]:          0 :     if (x == (Py_ssize_t)-1 && PyErr_Occurred()) {
         251                 :          0 :         return -1;
         252                 :            :     }
         253                 :          0 :     *p = x;
         254                 :          0 :     return 0;
         255                 :            : }
         256                 :            :
         257                 :            : /* Same, but handling size_t */
         258                 :            :
         259                 :            : static int
         260                 :          0 : get_size_t(_structmodulestate *state, PyObject *v, size_t *p)
         261                 :            : {
         262                 :            :     size_t x;
         263                 :            :
         264                 :          0 :     v = get_pylong(state, v);
         265         [ #  # ]:          0 :     if (v == NULL)
         266                 :          0 :         return -1;
         267                 :            :     assert(PyLong_Check(v));
         268                 :          0 :     x = PyLong_AsSize_t(v);
         269                 :          0 :     Py_DECREF(v);
         270   [ #  #  #  # ]:          0 :     if (x == (size_t)-1 && PyErr_Occurred()) {
         271                 :          0 :         return -1;
         272                 :            :     }
         273                 :          0 :     *p = x;
         274                 :          0 :     return 0;
         275                 :            : }
         276                 :            :
         277                 :            :
         278                 :            : #define RANGE_ERROR(state, f, flag) return _range_error(state, f, flag)
         279                 :            :
         280                 :            :
         281                 :            : /* Floating point helpers */
         282                 :            :
         283                 :            : static PyObject *
         284                 :          0 : unpack_halffloat(const char *p,  /* start of 2-byte string */
         285                 :            :                  int le)         /* true for little-endian, false for big-endian */
         286                 :            : {
         287                 :          0 :     double x = PyFloat_Unpack2(p, le);
         288   [ #  #  #  # ]:          0 :     if (x == -1.0 && PyErr_Occurred()) {
         289                 :          0 :         return NULL;
         290                 :            :     }
         291                 :          0 :     return PyFloat_FromDouble(x);
         292                 :            : }
         293                 :            :
         294                 :            : static int
         295                 :          0 : pack_halffloat(_structmodulestate *state,
         296                 :            :                char *p,      /* start of 2-byte string */
         297                 :            :                PyObject *v,  /* value to pack */
         298                 :            :                int le)       /* true for little-endian, false for big-endian */
         299                 :            : {
         300                 :          0 :     double x = PyFloat_AsDouble(v);
         301   [ #  #  #  # ]:          0 :     if (x == -1.0 && PyErr_Occurred()) {
         302                 :          0 :         PyErr_SetString(state->StructError,
         303                 :            :                         "required argument is not a float");
         304                 :          0 :         return -1;
         305                 :            :     }
         306                 :          0 :     return PyFloat_Pack2(x, p, le);
         307                 :            : }
         308                 :            :
         309                 :            : static PyObject *
         310                 :          0 : unpack_float(const char *p,  /* start of 4-byte string */
         311                 :            :          int le)             /* true for little-endian, false for big-endian */
         312                 :            : {
         313                 :            :     double x;
         314                 :            :
         315                 :          0 :     x = PyFloat_Unpack4(p, le);
         316   [ #  #  #  # ]:          0 :     if (x == -1.0 && PyErr_Occurred())
         317                 :          0 :         return NULL;
         318                 :          0 :     return PyFloat_FromDouble(x);
         319                 :            : }
         320                 :            :
         321                 :            : static PyObject *
         322                 :          0 : unpack_double(const char *p,  /* start of 8-byte string */
         323                 :            :           int le)         /* true for little-endian, false for big-endian */
         324                 :            : {
         325                 :            :     double x;
         326                 :            :
         327                 :          0 :     x = PyFloat_Unpack8(p, le);
         328   [ #  #  #  # ]:          0 :     if (x == -1.0 && PyErr_Occurred())
         329                 :          0 :         return NULL;
         330                 :          0 :     return PyFloat_FromDouble(x);
         331                 :            : }
         332                 :            :
         333                 :            : /* Helper to format the range error exceptions */
         334                 :            : static int
         335                 :          0 : _range_error(_structmodulestate *state, const formatdef *f, int is_unsigned)
         336                 :            : {
         337                 :            :     /* ulargest is the largest unsigned value with f->size bytes.
         338                 :            :      * Note that the simpler:
         339                 :            :      *     ((size_t)1 << (f->size * 8)) - 1
         340                 :            :      * doesn't work when f->size == sizeof(size_t) because C doesn't
         341                 :            :      * define what happens when a left shift count is >= the number of
         342                 :            :      * bits in the integer being shifted; e.g., on some boxes it doesn't
         343                 :            :      * shift at all when they're equal.
         344                 :            :      */
         345                 :          0 :     const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
         346                 :            :     assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
         347         [ #  # ]:          0 :     if (is_unsigned)
         348                 :          0 :         PyErr_Format(state->StructError,
         349                 :            :             "'%c' format requires 0 <= number <= %zu",
         350                 :          0 :             f->format,
         351                 :            :             ulargest);
         352                 :            :     else {
         353                 :          0 :         const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
         354                 :          0 :         PyErr_Format(state->StructError,
         355                 :            :             "'%c' format requires %zd <= number <= %zd",
         356                 :          0 :             f->format,
         357                 :            :             ~ largest,
         358                 :            :             largest);
         359                 :            :     }
         360                 :            :
         361                 :          0 :     return -1;
         362                 :            : }
         363                 :            :
         364                 :            :
         365                 :            :
         366                 :            : /* A large number of small routines follow, with names of the form
         367                 :            :
         368                 :            :    [bln][up]_TYPE
         369                 :            :
         370                 :            :    [bln] distinguishes among big-endian, little-endian and native.
         371                 :            :    [pu] distinguishes between pack (to struct) and unpack (from struct).
         372                 :            :    TYPE is one of char, byte, ubyte, etc.
         373                 :            : */
         374                 :            :
         375                 :            : /* Native mode routines. ****************************************************/
         376                 :            : /* NOTE:
         377                 :            :    In all n[up]_<type> routines handling types larger than 1 byte, there is
         378                 :            :    *no* guarantee that the p pointer is properly aligned for each type,
         379                 :            :    therefore memcpy is called.  An intermediate variable is used to
         380                 :            :    compensate for big-endian architectures.
         381                 :            :    Normally both the intermediate variable and the memcpy call will be
         382                 :            :    skipped by C optimisation in little-endian architectures (gcc >= 2.91
         383                 :            :    does this). */
         384                 :            :
         385                 :            : static PyObject *
         386                 :          0 : nu_char(_structmodulestate *state, const char *p, const formatdef *f)
         387                 :            : {
         388                 :          0 :     return PyBytes_FromStringAndSize(p, 1);
         389                 :            : }
         390                 :            :
         391                 :            : static PyObject *
         392                 :          0 : nu_byte(_structmodulestate *state, const char *p, const formatdef *f)
         393                 :            : {
         394                 :          0 :     return PyLong_FromLong((long) *(signed char *)p);
         395                 :            : }
         396                 :            :
         397                 :            : static PyObject *
         398                 :          0 : nu_ubyte(_structmodulestate *state, const char *p, const formatdef *f)
         399                 :            : {
         400                 :          0 :     return PyLong_FromLong((long) *(unsigned char *)p);
         401                 :            : }
         402                 :            :
         403                 :            : static PyObject *
         404                 :          0 : nu_short(_structmodulestate *state, const char *p, const formatdef *f)
         405                 :            : {
         406                 :            :     short x;
         407                 :          0 :     memcpy((char *)&x, p, sizeof x);
         408                 :          0 :     return PyLong_FromLong((long)x);
         409                 :            : }
         410                 :            :
         411                 :            : static PyObject *
         412                 :          0 : nu_ushort(_structmodulestate *state, const char *p, const formatdef *f)
         413                 :            : {
         414                 :            :     unsigned short x;
         415                 :          0 :     memcpy((char *)&x, p, sizeof x);
         416                 :          0 :     return PyLong_FromLong((long)x);
         417                 :            : }
         418                 :            :
         419                 :            : static PyObject *
         420                 :          0 : nu_int(_structmodulestate *state, const char *p, const formatdef *f)
         421                 :            : {
         422                 :            :     int x;
         423                 :          0 :     memcpy((char *)&x, p, sizeof x);
         424                 :          0 :     return PyLong_FromLong((long)x);
         425                 :            : }
         426                 :            :
         427                 :            : static PyObject *
         428                 :          0 : nu_uint(_structmodulestate *state, const char *p, const formatdef *f)
         429                 :            : {
         430                 :            :     unsigned int x;
         431                 :          0 :     memcpy((char *)&x, p, sizeof x);
         432                 :          0 :     return PyLong_FromUnsignedLong((unsigned long)x);
         433                 :            : }
         434                 :            :
         435                 :            : static PyObject *
         436                 :          0 : nu_long(_structmodulestate *state, const char *p, const formatdef *f)
         437                 :            : {
         438                 :            :     long x;
         439                 :          0 :     memcpy((char *)&x, p, sizeof x);
         440                 :          0 :     return PyLong_FromLong(x);
         441                 :            : }
         442                 :            :
         443                 :            : static PyObject *
         444                 :          0 : nu_ulong(_structmodulestate *state, const char *p, const formatdef *f)
         445                 :            : {
         446                 :            :     unsigned long x;
         447                 :          0 :     memcpy((char *)&x, p, sizeof x);
         448                 :          0 :     return PyLong_FromUnsignedLong(x);
         449                 :            : }
         450                 :            :
         451                 :            : static PyObject *
         452                 :          0 : nu_ssize_t(_structmodulestate *state, const char *p, const formatdef *f)
         453                 :            : {
         454                 :            :     Py_ssize_t x;
         455                 :          0 :     memcpy((char *)&x, p, sizeof x);
         456                 :          0 :     return PyLong_FromSsize_t(x);
         457                 :            : }
         458                 :            :
         459                 :            : static PyObject *
         460                 :          0 : nu_size_t(_structmodulestate *state, const char *p, const formatdef *f)
         461                 :            : {
         462                 :            :     size_t x;
         463                 :          0 :     memcpy((char *)&x, p, sizeof x);
         464                 :          0 :     return PyLong_FromSize_t(x);
         465                 :            : }
         466                 :            :
         467                 :            : static PyObject *
         468                 :        198 : nu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
         469                 :            : {
         470                 :            :     long long x;
         471                 :        198 :     memcpy((char *)&x, p, sizeof x);
         472                 :        198 :     return PyLong_FromLongLong(x);
         473                 :            : }
         474                 :            :
         475                 :            : static PyObject *
         476                 :          0 : nu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
         477                 :            : {
         478                 :            :     unsigned long long x;
         479                 :          0 :     memcpy((char *)&x, p, sizeof x);
         480                 :          0 :     return PyLong_FromUnsignedLongLong(x);
         481                 :            : }
         482                 :            :
         483                 :            : static PyObject *
         484                 :          0 : nu_bool(_structmodulestate *state, const char *p, const formatdef *f)
         485                 :            : {
         486                 :            :     _Bool x;
         487                 :          0 :     memcpy((char *)&x, p, sizeof x);
         488                 :          0 :     return PyBool_FromLong(x != 0);
         489                 :            : }
         490                 :            :
         491                 :            :
         492                 :            : static PyObject *
         493                 :          0 : nu_halffloat(_structmodulestate *state, const char *p, const formatdef *f)
         494                 :            : {
         495                 :            : #if PY_LITTLE_ENDIAN
         496                 :          0 :     return unpack_halffloat(p, 1);
         497                 :            : #else
         498                 :            :     return unpack_halffloat(p, 0);
         499                 :            : #endif
         500                 :            : }
         501                 :            :
         502                 :            : static PyObject *
         503                 :          0 : nu_float(_structmodulestate *state, const char *p, const formatdef *f)
         504                 :            : {
         505                 :            :     float x;
         506                 :          0 :     memcpy((char *)&x, p, sizeof x);
         507                 :          0 :     return PyFloat_FromDouble((double)x);
         508                 :            : }
         509                 :            :
         510                 :            : static PyObject *
         511                 :          0 : nu_double(_structmodulestate *state, const char *p, const formatdef *f)
         512                 :            : {
         513                 :            :     double x;
         514                 :          0 :     memcpy((char *)&x, p, sizeof x);
         515                 :          0 :     return PyFloat_FromDouble(x);
         516                 :            : }
         517                 :            :
         518                 :            : static PyObject *
         519                 :          0 : nu_void_p(_structmodulestate *state, const char *p, const formatdef *f)
         520                 :            : {
         521                 :            :     void *x;
         522                 :          0 :     memcpy((char *)&x, p, sizeof x);
         523                 :          0 :     return PyLong_FromVoidPtr(x);
         524                 :            : }
         525                 :            :
         526                 :            : static int
         527                 :          0 : np_byte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         528                 :            : {
         529                 :            :     long x;
         530         [ #  # ]:          0 :     if (get_long(state, v, &x) < 0) {
         531         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         532                 :          0 :             RANGE_ERROR(state, f, 0);
         533                 :            :         }
         534                 :          0 :         return -1;
         535                 :            :     }
         536   [ #  #  #  # ]:          0 :     if (x < -128 || x > 127) {
         537                 :          0 :         RANGE_ERROR(state, f, 0);
         538                 :            :     }
         539                 :          0 :     *p = (char)x;
         540                 :          0 :     return 0;
         541                 :            : }
         542                 :            :
         543                 :            : static int
         544                 :          0 : np_ubyte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         545                 :            : {
         546                 :            :     long x;
         547         [ #  # ]:          0 :     if (get_long(state, v, &x) < 0) {
         548         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         549                 :          0 :             RANGE_ERROR(state, f, 1);
         550                 :            :         }
         551                 :          0 :         return -1;
         552                 :            :     }
         553   [ #  #  #  # ]:          0 :     if (x < 0 || x > 255) {
         554                 :          0 :         RANGE_ERROR(state, f, 1);
         555                 :            :     }
         556                 :          0 :     *(unsigned char *)p = (unsigned char)x;
         557                 :          0 :     return 0;
         558                 :            : }
         559                 :            :
         560                 :            : static int
         561                 :          0 : np_char(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         562                 :            : {
         563   [ #  #  #  # ]:          0 :     if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) {
         564                 :          0 :         PyErr_SetString(state->StructError,
         565                 :            :                         "char format requires a bytes object of length 1");
         566                 :          0 :         return -1;
         567                 :            :     }
         568                 :          0 :     *p = *PyBytes_AS_STRING(v);
         569                 :          0 :     return 0;
         570                 :            : }
         571                 :            :
         572                 :            : static int
         573                 :          0 : np_short(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         574                 :            : {
         575                 :            :     long x;
         576                 :            :     short y;
         577         [ #  # ]:          0 :     if (get_long(state, v, &x) < 0) {
         578         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         579                 :          0 :             RANGE_ERROR(state, f, 0);
         580                 :            :         }
         581                 :          0 :         return -1;
         582                 :            :     }
         583   [ #  #  #  # ]:          0 :     if (x < SHRT_MIN || x > SHRT_MAX) {
         584                 :          0 :         RANGE_ERROR(state, f, 0);
         585                 :            :     }
         586                 :          0 :     y = (short)x;
         587                 :          0 :     memcpy(p, (char *)&y, sizeof y);
         588                 :          0 :     return 0;
         589                 :            : }
         590                 :            :
         591                 :            : static int
         592                 :          0 : np_ushort(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         593                 :            : {
         594                 :            :     long x;
         595                 :            :     unsigned short y;
         596         [ #  # ]:          0 :     if (get_long(state, v, &x) < 0) {
         597         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         598                 :          0 :             RANGE_ERROR(state, f, 1);
         599                 :            :         }
         600                 :          0 :         return -1;
         601                 :            :     }
         602   [ #  #  #  # ]:          0 :     if (x < 0 || x > USHRT_MAX) {
         603                 :          0 :         RANGE_ERROR(state, f, 1);
         604                 :            :     }
         605                 :          0 :     y = (unsigned short)x;
         606                 :          0 :     memcpy(p, (char *)&y, sizeof y);
         607                 :          0 :     return 0;
         608                 :            : }
         609                 :            :
         610                 :            : static int
         611                 :          0 : np_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         612                 :            : {
         613                 :            :     long x;
         614                 :            :     int y;
         615         [ #  # ]:          0 :     if (get_long(state, v, &x) < 0) {
         616         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         617                 :          0 :             RANGE_ERROR(state, f, 0);
         618                 :            :         }
         619                 :          0 :         return -1;
         620                 :            :     }
         621                 :            : #if (SIZEOF_LONG > SIZEOF_INT)
         622   [ #  #  #  # ]:          0 :     if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
         623                 :          0 :         RANGE_ERROR(state, f, 0);
         624                 :            : #endif
         625                 :          0 :     y = (int)x;
         626                 :          0 :     memcpy(p, (char *)&y, sizeof y);
         627                 :          0 :     return 0;
         628                 :            : }
         629                 :            :
         630                 :            : static int
         631                 :          0 : np_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         632                 :            : {
         633                 :            :     unsigned long x;
         634                 :            :     unsigned int y;
         635         [ #  # ]:          0 :     if (get_ulong(state, v, &x) < 0) {
         636         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         637                 :          0 :             RANGE_ERROR(state, f, 1);
         638                 :            :         }
         639                 :          0 :         return -1;
         640                 :            :     }
         641                 :          0 :     y = (unsigned int)x;
         642                 :            : #if (SIZEOF_LONG > SIZEOF_INT)
         643         [ #  # ]:          0 :     if (x > ((unsigned long)UINT_MAX))
         644                 :          0 :         RANGE_ERROR(state, f, 1);
         645                 :            : #endif
         646                 :          0 :     memcpy(p, (char *)&y, sizeof y);
         647                 :          0 :     return 0;
         648                 :            : }
         649                 :            :
         650                 :            : static int
         651                 :          0 : np_long(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         652                 :            : {
         653                 :            :     long x;
         654         [ #  # ]:          0 :     if (get_long(state, v, &x) < 0) {
         655         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         656                 :          0 :             RANGE_ERROR(state, f, 0);
         657                 :            :         }
         658                 :          0 :         return -1;
         659                 :            :     }
         660                 :          0 :     memcpy(p, (char *)&x, sizeof x);
         661                 :          0 :     return 0;
         662                 :            : }
         663                 :            :
         664                 :            : static int
         665                 :          0 : np_ulong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         666                 :            : {
         667                 :            :     unsigned long x;
         668         [ #  # ]:          0 :     if (get_ulong(state, v, &x) < 0) {
         669         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         670                 :          0 :             RANGE_ERROR(state, f, 1);
         671                 :            :         }
         672                 :          0 :         return -1;
         673                 :            :     }
         674                 :          0 :     memcpy(p, (char *)&x, sizeof x);
         675                 :          0 :     return 0;
         676                 :            : }
         677                 :            :
         678                 :            : static int
         679                 :          0 : np_ssize_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         680                 :            : {
         681                 :            :     Py_ssize_t x;
         682         [ #  # ]:          0 :     if (get_ssize_t(state, v, &x) < 0) {
         683         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         684                 :          0 :             RANGE_ERROR(state, f, 0);
         685                 :            :         }
         686                 :          0 :         return -1;
         687                 :            :     }
         688                 :          0 :     memcpy(p, (char *)&x, sizeof x);
         689                 :          0 :     return 0;
         690                 :            : }
         691                 :            :
         692                 :            : static int
         693                 :          0 : np_size_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         694                 :            : {
         695                 :            :     size_t x;
         696         [ #  # ]:          0 :     if (get_size_t(state, v, &x) < 0) {
         697         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         698                 :          0 :             RANGE_ERROR(state, f, 1);
         699                 :            :         }
         700                 :          0 :         return -1;
         701                 :            :     }
         702                 :          0 :     memcpy(p, (char *)&x, sizeof x);
         703                 :          0 :     return 0;
         704                 :            : }
         705                 :            :
         706                 :            : static int
         707                 :          0 : np_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         708                 :            : {
         709                 :            :     long long x;
         710         [ #  # ]:          0 :     if (get_longlong(state, v, &x) < 0) {
         711         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         712                 :          0 :             PyErr_Format(state->StructError,
         713                 :            :                          "'%c' format requires %lld <= number <= %lld",
         714                 :          0 :                          f->format,
         715                 :            :                          LLONG_MIN,
         716                 :            :                          LLONG_MAX);
         717                 :            :         }
         718                 :          0 :         return -1;
         719                 :            :     }
         720                 :          0 :     memcpy(p, (char *)&x, sizeof x);
         721                 :          0 :     return 0;
         722                 :            : }
         723                 :            :
         724                 :            : static int
         725                 :          0 : np_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         726                 :            : {
         727                 :            :     unsigned long long x;
         728         [ #  # ]:          0 :     if (get_ulonglong(state, v, &x) < 0) {
         729         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         730                 :          0 :             PyErr_Format(state->StructError,
         731                 :            :                          "'%c' format requires 0 <= number <= %llu",
         732                 :          0 :                          f->format,
         733                 :            :                          ULLONG_MAX);
         734                 :            :         }
         735                 :          0 :         return -1;
         736                 :            :     }
         737                 :          0 :     memcpy(p, (char *)&x, sizeof x);
         738                 :          0 :     return 0;
         739                 :            : }
         740                 :            :
         741                 :            :
         742                 :            : static int
         743                 :          0 : np_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         744                 :            : {
         745                 :            :     int y;
         746                 :            :     _Bool x;
         747                 :          0 :     y = PyObject_IsTrue(v);
         748         [ #  # ]:          0 :     if (y < 0)
         749                 :          0 :         return -1;
         750                 :          0 :     x = y;
         751                 :          0 :     memcpy(p, (char *)&x, sizeof x);
         752                 :          0 :     return 0;
         753                 :            : }
         754                 :            :
         755                 :            : static int
         756                 :          0 : np_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         757                 :            : {
         758                 :            : #if PY_LITTLE_ENDIAN
         759                 :          0 :     return pack_halffloat(state, p, v, 1);
         760                 :            : #else
         761                 :            :     return pack_halffloat(state, p, v, 0);
         762                 :            : #endif
         763                 :            : }
         764                 :            :
         765                 :            : static int
         766                 :          0 : np_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         767                 :            : {
         768                 :          0 :     float x = (float)PyFloat_AsDouble(v);
         769   [ #  #  #  # ]:          0 :     if (x == -1 && PyErr_Occurred()) {
         770                 :          0 :         PyErr_SetString(state->StructError,
         771                 :            :                         "required argument is not a float");
         772                 :          0 :         return -1;
         773                 :            :     }
         774                 :          0 :     memcpy(p, (char *)&x, sizeof x);
         775                 :          0 :     return 0;
         776                 :            : }
         777                 :            :
         778                 :            : static int
         779                 :          0 : np_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         780                 :            : {
         781                 :          0 :     double x = PyFloat_AsDouble(v);
         782   [ #  #  #  # ]:          0 :     if (x == -1 && PyErr_Occurred()) {
         783                 :          0 :         PyErr_SetString(state->StructError,
         784                 :            :                         "required argument is not a float");
         785                 :          0 :         return -1;
         786                 :            :     }
         787                 :          0 :     memcpy(p, (char *)&x, sizeof(double));
         788                 :          0 :     return 0;
         789                 :            : }
         790                 :            :
         791                 :            : static int
         792                 :          0 : np_void_p(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         793                 :            : {
         794                 :            :     void *x;
         795                 :            :
         796                 :          0 :     v = get_pylong(state, v);
         797         [ #  # ]:          0 :     if (v == NULL)
         798                 :          0 :         return -1;
         799                 :            :     assert(PyLong_Check(v));
         800                 :          0 :     x = PyLong_AsVoidPtr(v);
         801                 :          0 :     Py_DECREF(v);
         802   [ #  #  #  # ]:          0 :     if (x == NULL && PyErr_Occurred())
         803                 :          0 :         return -1;
         804                 :          0 :     memcpy(p, (char *)&x, sizeof x);
         805                 :          0 :     return 0;
         806                 :            : }
         807                 :            :
         808                 :            : static const formatdef native_table[] = {
         809                 :            :     {'x',       sizeof(char),   0,              NULL},
         810                 :            :     {'b',       sizeof(char),   0,              nu_byte,        np_byte},
         811                 :            :     {'B',       sizeof(char),   0,              nu_ubyte,       np_ubyte},
         812                 :            :     {'c',       sizeof(char),   0,              nu_char,        np_char},
         813                 :            :     {'s',       sizeof(char),   0,              NULL},
         814                 :            :     {'p',       sizeof(char),   0,              NULL},
         815                 :            :     {'h',       sizeof(short),  SHORT_ALIGN,    nu_short,       np_short},
         816                 :            :     {'H',       sizeof(short),  SHORT_ALIGN,    nu_ushort,      np_ushort},
         817                 :            :     {'i',       sizeof(int),    INT_ALIGN,      nu_int,         np_int},
         818                 :            :     {'I',       sizeof(int),    INT_ALIGN,      nu_uint,        np_uint},
         819                 :            :     {'l',       sizeof(long),   LONG_ALIGN,     nu_long,        np_long},
         820                 :            :     {'L',       sizeof(long),   LONG_ALIGN,     nu_ulong,       np_ulong},
         821                 :            :     {'n',       sizeof(size_t), SIZE_T_ALIGN,   nu_ssize_t,     np_ssize_t},
         822                 :            :     {'N',       sizeof(size_t), SIZE_T_ALIGN,   nu_size_t,      np_size_t},
         823                 :            :     {'q',       sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong},
         824                 :            :     {'Q',       sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
         825                 :            :     {'?',       sizeof(_Bool),      BOOL_ALIGN,     nu_bool,        np_bool},
         826                 :            :     {'e',       sizeof(short),  SHORT_ALIGN,    nu_halffloat,   np_halffloat},
         827                 :            :     {'f',       sizeof(float),  FLOAT_ALIGN,    nu_float,       np_float},
         828                 :            :     {'d',       sizeof(double), DOUBLE_ALIGN,   nu_double,      np_double},
         829                 :            :     {'P',       sizeof(void *), VOID_P_ALIGN,   nu_void_p,      np_void_p},
         830                 :            :     {0}
         831                 :            : };
         832                 :            :
         833                 :            : /* Big-endian routines. *****************************************************/
         834                 :            :
         835                 :            : static PyObject *
         836                 :          0 : bu_short(_structmodulestate *state, const char *p, const formatdef *f)
         837                 :            : {
         838                 :          0 :     unsigned long x = 0;
         839                 :            :
         840                 :            :     /* This function is only ever used in the case f->size == 2. */
         841                 :            :     assert(f->size == 2);
         842                 :          0 :     Py_ssize_t i = 2;
         843                 :          0 :     const unsigned char *bytes = (const unsigned char *)p;
         844                 :            :     do {
         845                 :          0 :         x = (x<<8) | *bytes++;
         846         [ #  # ]:          0 :     } while (--i > 0);
         847                 :            :     /* Extend sign, avoiding implementation-defined or undefined behaviour. */
         848                 :          0 :     x = (x ^ 0x8000U) - 0x8000U;
         849         [ #  # ]:          0 :     return PyLong_FromLong(x & 0x8000U ? -1 - (long)(~x) : (long)x);
         850                 :            : }
         851                 :            :
         852                 :            : static PyObject *
         853                 :          0 : bu_int(_structmodulestate *state, const char *p, const formatdef *f)
         854                 :            : {
         855                 :          0 :     unsigned long x = 0;
         856                 :            :
         857                 :            :     /* This function is only ever used in the case f->size == 4. */
         858                 :            :     assert(f->size == 4);
         859                 :          0 :     Py_ssize_t i = 4;
         860                 :          0 :     const unsigned char *bytes = (const unsigned char *)p;
         861                 :            :     do {
         862                 :          0 :         x = (x<<8) | *bytes++;
         863         [ #  # ]:          0 :     } while (--i > 0);
         864                 :            :     /* Extend sign, avoiding implementation-defined or undefined behaviour. */
         865                 :          0 :     x = (x ^ 0x80000000U) - 0x80000000U;
         866         [ #  # ]:          0 :     return PyLong_FromLong(x & 0x80000000U ? -1 - (long)(~x) : (long)x);
         867                 :            : }
         868                 :            :
         869                 :            : static PyObject *
         870                 :          0 : bu_uint(_structmodulestate *state, const char *p, const formatdef *f)
         871                 :            : {
         872                 :          0 :     unsigned long x = 0;
         873                 :          0 :     Py_ssize_t i = f->size;
         874                 :          0 :     const unsigned char *bytes = (const unsigned char *)p;
         875                 :            :     do {
         876                 :          0 :         x = (x<<8) | *bytes++;
         877         [ #  # ]:          0 :     } while (--i > 0);
         878                 :          0 :     return PyLong_FromUnsignedLong(x);
         879                 :            : }
         880                 :            :
         881                 :            : static PyObject *
         882                 :          0 : bu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
         883                 :            : {
         884                 :          0 :     unsigned long long x = 0;
         885                 :            :
         886                 :            :     /* This function is only ever used in the case f->size == 8. */
         887                 :            :     assert(f->size == 8);
         888                 :          0 :     Py_ssize_t i = 8;
         889                 :          0 :     const unsigned char *bytes = (const unsigned char *)p;
         890                 :            :     do {
         891                 :          0 :         x = (x<<8) | *bytes++;
         892         [ #  # ]:          0 :     } while (--i > 0);
         893                 :            :     /* Extend sign, avoiding implementation-defined or undefined behaviour. */
         894                 :          0 :     x = (x ^ 0x8000000000000000U) - 0x8000000000000000U;
         895                 :          0 :     return PyLong_FromLongLong(
         896         [ #  # ]:          0 :         x & 0x8000000000000000U ? -1 - (long long)(~x) : (long long)x);
         897                 :            : }
         898                 :            :
         899                 :            : static PyObject *
         900                 :          0 : bu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
         901                 :            : {
         902                 :          0 :     unsigned long long x = 0;
         903                 :          0 :     Py_ssize_t i = f->size;
         904                 :          0 :     const unsigned char *bytes = (const unsigned char *)p;
         905                 :            :     do {
         906                 :          0 :         x = (x<<8) | *bytes++;
         907         [ #  # ]:          0 :     } while (--i > 0);
         908                 :          0 :     return PyLong_FromUnsignedLongLong(x);
         909                 :            : }
         910                 :            :
         911                 :            : static PyObject *
         912                 :          0 : bu_halffloat(_structmodulestate *state, const char *p, const formatdef *f)
         913                 :            : {
         914                 :          0 :     return unpack_halffloat(p, 0);
         915                 :            : }
         916                 :            :
         917                 :            : static PyObject *
         918                 :          0 : bu_float(_structmodulestate *state, const char *p, const formatdef *f)
         919                 :            : {
         920                 :          0 :     return unpack_float(p, 0);
         921                 :            : }
         922                 :            :
         923                 :            : static PyObject *
         924                 :          0 : bu_double(_structmodulestate *state, const char *p, const formatdef *f)
         925                 :            : {
         926                 :          0 :     return unpack_double(p, 0);
         927                 :            : }
         928                 :            :
         929                 :            : static PyObject *
         930                 :          0 : bu_bool(_structmodulestate *state, const char *p, const formatdef *f)
         931                 :            : {
         932                 :          0 :     return PyBool_FromLong(*p != 0);
         933                 :            : }
         934                 :            :
         935                 :            : static int
         936                 :          0 : bp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         937                 :            : {
         938                 :            :     long x;
         939                 :            :     Py_ssize_t i;
         940                 :          0 :     unsigned char *q = (unsigned char *)p;
         941         [ #  # ]:          0 :     if (get_long(state, v, &x) < 0) {
         942         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         943                 :          0 :             RANGE_ERROR(state, f, 0);
         944                 :            :         }
         945                 :          0 :         return -1;
         946                 :            :     }
         947                 :          0 :     i = f->size;
         948         [ #  # ]:          0 :     if (i != SIZEOF_LONG) {
         949   [ #  #  #  #  :          0 :         if ((i == 2) && (x < -32768 || x > 32767))
                       #  # ]
         950                 :          0 :             RANGE_ERROR(state, f, 0);
         951                 :            : #if (SIZEOF_LONG != 4)
         952   [ #  #  #  #  :          0 :         else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
                       #  # ]
         953                 :          0 :             RANGE_ERROR(state, f, 0);
         954                 :            : #endif
         955                 :            :     }
         956                 :            :     do {
         957                 :          0 :         q[--i] = (unsigned char)(x & 0xffL);
         958                 :          0 :         x >>= 8;
         959         [ #  # ]:          0 :     } while (i > 0);
         960                 :          0 :     return 0;
         961                 :            : }
         962                 :            :
         963                 :            : static int
         964                 :          0 : bp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         965                 :            : {
         966                 :            :     unsigned long x;
         967                 :            :     Py_ssize_t i;
         968                 :          0 :     unsigned char *q = (unsigned char *)p;
         969         [ #  # ]:          0 :     if (get_ulong(state, v, &x) < 0) {
         970         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
         971                 :          0 :             RANGE_ERROR(state, f, 1);
         972                 :            :         }
         973                 :          0 :         return -1;
         974                 :            :     }
         975                 :          0 :     i = f->size;
         976         [ #  # ]:          0 :     if (i != SIZEOF_LONG) {
         977                 :          0 :         unsigned long maxint = 1;
         978                 :          0 :         maxint <<= (unsigned long)(i * 8);
         979         [ #  # ]:          0 :         if (x >= maxint)
         980                 :          0 :             RANGE_ERROR(state, f, 1);
         981                 :            :     }
         982                 :            :     do {
         983                 :          0 :         q[--i] = (unsigned char)(x & 0xffUL);
         984                 :          0 :         x >>= 8;
         985         [ #  # ]:          0 :     } while (i > 0);
         986                 :          0 :     return 0;
         987                 :            : }
         988                 :            :
         989                 :            : static int
         990                 :          0 : bp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
         991                 :            : {
         992                 :            :     int res;
         993                 :          0 :     v = get_pylong(state, v);
         994         [ #  # ]:          0 :     if (v == NULL)
         995                 :          0 :         return -1;
         996                 :          0 :     res = _PyLong_AsByteArray((PyLongObject *)v,
         997                 :            :                               (unsigned char *)p,
         998                 :            :                               8,
         999                 :            :                               0, /* little_endian */
        1000                 :            :                               1  /* signed */);
        1001                 :          0 :     Py_DECREF(v);
        1002   [ #  #  #  # ]:          0 :     if (res == -1 && PyErr_Occurred()) {
        1003                 :          0 :         PyErr_Format(state->StructError,
        1004                 :            :                      "'%c' format requires %lld <= number <= %lld",
        1005                 :          0 :                      f->format,
        1006                 :            :                      LLONG_MIN,
        1007                 :            :                      LLONG_MAX);
        1008                 :          0 :         return -1;
        1009                 :            :     }
        1010                 :          0 :     return res;
        1011                 :            : }
        1012                 :            :
        1013                 :            : static int
        1014                 :          0 : bp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
        1015                 :            : {
        1016                 :            :     int res;
        1017                 :          0 :     v = get_pylong(state, v);
        1018         [ #  # ]:          0 :     if (v == NULL)
        1019                 :          0 :         return -1;
        1020                 :          0 :     res = _PyLong_AsByteArray((PyLongObject *)v,
        1021                 :            :                               (unsigned char *)p,
        1022                 :            :                               8,
        1023                 :            :                               0, /* little_endian */
        1024                 :            :                               0  /* signed */);
        1025                 :          0 :     Py_DECREF(v);
        1026   [ #  #  #  # ]:          0 :     if (res == -1 && PyErr_Occurred()) {
        1027                 :          0 :         PyErr_Format(state->StructError,
        1028                 :            :                      "'%c' format requires 0 <= number <= %llu",
        1029                 :          0 :                      f->format,
        1030                 :            :                      ULLONG_MAX);
        1031                 :          0 :         return -1;
        1032                 :            :     }
        1033                 :          0 :     return res;
        1034                 :            : }
        1035                 :            :
        1036                 :            : static int
        1037                 :          0 : bp_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
        1038                 :            : {
        1039                 :          0 :     return pack_halffloat(state, p, v, 0);
        1040                 :            : }
        1041                 :            :
        1042                 :            : static int
        1043                 :          0 : bp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
        1044                 :            : {
        1045                 :          0 :     double x = PyFloat_AsDouble(v);
        1046   [ #  #  #  # ]:          0 :     if (x == -1 && PyErr_Occurred()) {
        1047                 :          0 :         PyErr_SetString(state->StructError,
        1048                 :            :                         "required argument is not a float");
        1049                 :          0 :         return -1;
        1050                 :            :     }
        1051                 :          0 :     return PyFloat_Pack4(x, p, 0);
        1052                 :            : }
        1053                 :            :
        1054                 :            : static int
        1055                 :          0 : bp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
        1056                 :            : {
        1057                 :          0 :     double x = PyFloat_AsDouble(v);
        1058   [ #  #  #  # ]:          0 :     if (x == -1 && PyErr_Occurred()) {
        1059                 :          0 :         PyErr_SetString(state->StructError,
        1060                 :            :                         "required argument is not a float");
        1061                 :          0 :         return -1;
        1062                 :            :     }
        1063                 :          0 :     return PyFloat_Pack8(x, p, 0);
        1064                 :            : }
        1065                 :            :
        1066                 :            : static int
        1067                 :          0 : bp_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
        1068                 :            : {
        1069                 :            :     int y;
        1070                 :          0 :     y = PyObject_IsTrue(v);
        1071         [ #  # ]:          0 :     if (y < 0)
        1072                 :          0 :         return -1;
        1073                 :          0 :     *p = (char)y;
        1074                 :          0 :     return 0;
        1075                 :            : }
        1076                 :            :
        1077                 :            : static formatdef bigendian_table[] = {
        1078                 :            :     {'x',       1,              0,              NULL},
        1079                 :            :     {'b',       1,              0,              nu_byte,        np_byte},
        1080                 :            :     {'B',       1,              0,              nu_ubyte,       np_ubyte},
        1081                 :            :     {'c',       1,              0,              nu_char,        np_char},
        1082                 :            :     {'s',       1,              0,              NULL},
        1083                 :            :     {'p',       1,              0,              NULL},
        1084                 :            :     {'h',       2,              0,              bu_short,       bp_int},
        1085                 :            :     {'H',       2,              0,              bu_uint,        bp_uint},
        1086                 :            :     {'i',       4,              0,              bu_int,         bp_int},
        1087                 :            :     {'I',       4,              0,              bu_uint,        bp_uint},
        1088                 :            :     {'l',       4,              0,              bu_int,         bp_int},
        1089                 :            :     {'L',       4,              0,              bu_uint,        bp_uint},
        1090                 :            :     {'q',       8,              0,              bu_longlong,    bp_longlong},
        1091                 :            :     {'Q',       8,              0,              bu_ulonglong,   bp_ulonglong},
        1092                 :            :     {'?',       1,              0,              bu_bool,        bp_bool},
        1093                 :            :     {'e',       2,              0,              bu_halffloat,   bp_halffloat},
        1094                 :            :     {'f',       4,              0,              bu_float,       bp_float},
        1095                 :            :     {'d',       8,              0,              bu_double,      bp_double},
        1096                 :            :     {0}
        1097                 :            : };
        1098                 :            :
        1099                 :            : /* Little-endian routines. *****************************************************/
        1100                 :            :
        1101                 :            : static PyObject *
        1102                 :          0 : lu_short(_structmodulestate *state, const char *p, const formatdef *f)
        1103                 :            : {
        1104                 :          0 :     unsigned long x = 0;
        1105                 :            :
        1106                 :            :     /* This function is only ever used in the case f->size == 2. */
        1107                 :            :     assert(f->size == 2);
        1108                 :          0 :     Py_ssize_t i = 2;
        1109                 :          0 :     const unsigned char *bytes = (const unsigned char *)p;
        1110                 :            :     do {
        1111                 :          0 :         x = (x<<8) | bytes[--i];
        1112         [ #  # ]:          0 :     } while (i > 0);
        1113                 :            :     /* Extend sign, avoiding implementation-defined or undefined behaviour. */
        1114                 :          0 :     x = (x ^ 0x8000U) - 0x8000U;
        1115         [ #  # ]:          0 :     return PyLong_FromLong(x & 0x8000U ? -1 - (long)(~x) : (long)x);
        1116                 :            : }
        1117                 :            :
        1118                 :            : static PyObject *
        1119                 :          0 : lu_int(_structmodulestate *state, const char *p, const formatdef *f)
        1120                 :            : {
        1121                 :          0 :     unsigned long x = 0;
        1122                 :            :
        1123                 :            :     /* This function is only ever used in the case f->size == 4. */
        1124                 :            :     assert(f->size == 4);
        1125                 :          0 :     Py_ssize_t i = 4;
        1126                 :          0 :     const unsigned char *bytes = (const unsigned char *)p;
        1127                 :            :     do {
        1128                 :          0 :         x = (x<<8) | bytes[--i];
        1129         [ #  # ]:          0 :     } while (i > 0);
        1130                 :            :     /* Extend sign, avoiding implementation-defined or undefined behaviour. */
        1131                 :          0 :     x = (x ^ 0x80000000U) - 0x80000000U;
        1132         [ #  # ]:          0 :     return PyLong_FromLong(x & 0x80000000U ? -1 - (long)(~x) : (long)x);
        1133                 :            : }
        1134                 :            :
        1135                 :            : static PyObject *
        1136                 :          0 : lu_uint(_structmodulestate *state, const char *p, const formatdef *f)
        1137                 :            : {
        1138                 :          0 :     unsigned long x = 0;
        1139                 :          0 :     Py_ssize_t i = f->size;
        1140                 :          0 :     const unsigned char *bytes = (const unsigned char *)p;
        1141                 :            :     do {
        1142                 :          0 :         x = (x<<8) | bytes[--i];
        1143         [ #  # ]:          0 :     } while (i > 0);
        1144                 :          0 :     return PyLong_FromUnsignedLong(x);
        1145                 :            : }
        1146                 :            :
        1147                 :            : static PyObject *
        1148                 :          0 : lu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
        1149                 :            : {
        1150                 :          0 :     unsigned long long x = 0;
        1151                 :            :
        1152                 :            :     /* This function is only ever used in the case f->size == 8. */
        1153                 :            :     assert(f->size == 8);
        1154                 :          0 :     Py_ssize_t i = 8;
        1155                 :          0 :     const unsigned char *bytes = (const unsigned char *)p;
        1156                 :            :     do {
        1157                 :          0 :         x = (x<<8) | bytes[--i];
        1158         [ #  # ]:          0 :     } while (i > 0);
        1159                 :            :     /* Extend sign, avoiding implementation-defined or undefined behaviour. */
        1160                 :          0 :     x = (x ^ 0x8000000000000000U) - 0x8000000000000000U;
        1161                 :          0 :     return PyLong_FromLongLong(
        1162         [ #  # ]:          0 :         x & 0x8000000000000000U ? -1 - (long long)(~x) : (long long)x);
        1163                 :            : }
        1164                 :            :
        1165                 :            : static PyObject *
        1166                 :          0 : lu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
        1167                 :            : {
        1168                 :          0 :     unsigned long long x = 0;
        1169                 :          0 :     Py_ssize_t i = f->size;
        1170                 :          0 :     const unsigned char *bytes = (const unsigned char *)p;
        1171                 :            :     do {
        1172                 :          0 :         x = (x<<8) | bytes[--i];
        1173         [ #  # ]:          0 :     } while (i > 0);
        1174                 :          0 :     return PyLong_FromUnsignedLongLong(x);
        1175                 :            : }
        1176                 :            :
        1177                 :            : static PyObject *
        1178                 :          0 : lu_halffloat(_structmodulestate *state, const char *p, const formatdef *f)
        1179                 :            : {
        1180                 :          0 :     return unpack_halffloat(p, 1);
        1181                 :            : }
        1182                 :            :
        1183                 :            : static PyObject *
        1184                 :          0 : lu_float(_structmodulestate *state, const char *p, const formatdef *f)
        1185                 :            : {
        1186                 :          0 :     return unpack_float(p, 1);
        1187                 :            : }
        1188                 :            :
        1189                 :            : static PyObject *
        1190                 :          0 : lu_double(_structmodulestate *state, const char *p, const formatdef *f)
        1191                 :            : {
        1192                 :          0 :     return unpack_double(p, 1);
        1193                 :            : }
        1194                 :            :
        1195                 :            : static int
        1196                 :          0 : lp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
        1197                 :            : {
        1198                 :            :     long x;
        1199                 :            :     Py_ssize_t i;
        1200                 :          0 :     unsigned char *q = (unsigned char *)p;
        1201         [ #  # ]:          0 :     if (get_long(state, v, &x) < 0) {
        1202         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
        1203                 :          0 :             RANGE_ERROR(state, f, 0);
        1204                 :            :         }
        1205                 :          0 :         return -1;
        1206                 :            :     }
        1207                 :          0 :     i = f->size;
        1208         [ #  # ]:          0 :     if (i != SIZEOF_LONG) {
        1209   [ #  #  #  #  :          0 :         if ((i == 2) && (x < -32768 || x > 32767))
                       #  # ]
        1210                 :          0 :             RANGE_ERROR(state, f, 0);
        1211                 :            : #if (SIZEOF_LONG != 4)
        1212   [ #  #  #  #  :          0 :         else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
                       #  # ]
        1213                 :          0 :             RANGE_ERROR(state, f, 0);
        1214                 :            : #endif
        1215                 :            :     }
        1216                 :            :     do {
        1217                 :          0 :         *q++ = (unsigned char)(x & 0xffL);
        1218                 :          0 :         x >>= 8;
        1219         [ #  # ]:          0 :     } while (--i > 0);
        1220                 :          0 :     return 0;
        1221                 :            : }
        1222                 :            :
        1223                 :            : static int
        1224                 :          0 : lp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
        1225                 :            : {
        1226                 :            :     unsigned long x;
        1227                 :            :     Py_ssize_t i;
        1228                 :          0 :     unsigned char *q = (unsigned char *)p;
        1229         [ #  # ]:          0 :     if (get_ulong(state, v, &x) < 0) {
        1230         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
        1231                 :          0 :             RANGE_ERROR(state, f, 1);
        1232                 :            :         }
        1233                 :          0 :         return -1;
        1234                 :            :     }
        1235                 :          0 :     i = f->size;
        1236         [ #  # ]:          0 :     if (i != SIZEOF_LONG) {
        1237                 :          0 :         unsigned long maxint = 1;
        1238                 :          0 :         maxint <<= (unsigned long)(i * 8);
        1239         [ #  # ]:          0 :         if (x >= maxint)
        1240                 :          0 :             RANGE_ERROR(state, f, 1);
        1241                 :            :     }
        1242                 :            :     do {
        1243                 :          0 :         *q++ = (unsigned char)(x & 0xffUL);
        1244                 :          0 :         x >>= 8;
        1245         [ #  # ]:          0 :     } while (--i > 0);
        1246                 :          0 :     return 0;
        1247                 :            : }
        1248                 :            :
        1249                 :            : static int
        1250                 :          0 : lp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
        1251                 :            : {
        1252                 :            :     int res;
        1253                 :          0 :     v = get_pylong(state, v);
        1254         [ #  # ]:          0 :     if (v == NULL)
        1255                 :          0 :         return -1;
        1256                 :          0 :     res = _PyLong_AsByteArray((PyLongObject*)v,
        1257                 :            :                               (unsigned char *)p,
        1258                 :            :                               8,
        1259                 :            :                               1, /* little_endian */
        1260                 :            :                               1  /* signed */);
        1261                 :          0 :     Py_DECREF(v);
        1262   [ #  #  #  # ]:          0 :     if (res == -1 && PyErr_Occurred()) {
        1263                 :          0 :         PyErr_Format(state->StructError,
        1264                 :            :                      "'%c' format requires %lld <= number <= %lld",
        1265                 :          0 :                      f->format,
        1266                 :            :                      LLONG_MIN,
        1267                 :            :                      LLONG_MAX);
        1268                 :          0 :         return -1;
        1269                 :            :     }
        1270                 :          0 :     return res;
        1271                 :            : }
        1272                 :            :
        1273                 :            : static int
        1274                 :          0 : lp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
        1275                 :            : {
        1276                 :            :     int res;
        1277                 :          0 :     v = get_pylong(state, v);
        1278         [ #  # ]:          0 :     if (v == NULL)
        1279                 :          0 :         return -1;
        1280                 :          0 :     res = _PyLong_AsByteArray((PyLongObject*)v,
        1281                 :            :                               (unsigned char *)p,
        1282                 :            :                               8,
        1283                 :            :                               1, /* little_endian */
        1284                 :            :                               0  /* signed */);
        1285                 :          0 :     Py_DECREF(v);
        1286   [ #  #  #  # ]:          0 :     if (res == -1 && PyErr_Occurred()) {
        1287                 :          0 :         PyErr_Format(state->StructError,
        1288                 :            :                      "'%c' format requires 0 <= number <= %llu",
        1289                 :          0 :                      f->format,
        1290                 :            :                      ULLONG_MAX);
        1291                 :          0 :         return -1;
        1292                 :            :     }
        1293                 :          0 :     return res;
        1294                 :            : }
        1295                 :            :
        1296                 :            : static int
        1297                 :          0 : lp_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
        1298                 :            : {
        1299                 :          0 :     return pack_halffloat(state, p, v, 1);
        1300                 :            : }
        1301                 :            :
        1302                 :            : static int
        1303                 :          0 : lp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
        1304                 :            : {
        1305                 :          0 :     double x = PyFloat_AsDouble(v);
        1306   [ #  #  #  # ]:          0 :     if (x == -1 && PyErr_Occurred()) {
        1307                 :          0 :         PyErr_SetString(state->StructError,
        1308                 :            :                         "required argument is not a float");
        1309                 :          0 :         return -1;
        1310                 :            :     }
        1311                 :          0 :     return PyFloat_Pack4(x, p, 1);
        1312                 :            : }
        1313                 :            :
        1314                 :            : static int
        1315                 :        198 : lp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
        1316                 :            : {
        1317                 :        198 :     double x = PyFloat_AsDouble(v);
        1318   [ +  +  -  + ]:        198 :     if (x == -1 && PyErr_Occurred()) {
        1319                 :          0 :         PyErr_SetString(state->StructError,
        1320                 :            :                         "required argument is not a float");
        1321                 :          0 :         return -1;
        1322                 :            :     }
        1323                 :        198 :     return PyFloat_Pack8(x, p, 1);
        1324                 :            : }
        1325                 :            :
        1326                 :            : static formatdef lilendian_table[] = {
        1327                 :            :     {'x',       1,              0,              NULL},
        1328                 :            :     {'b',       1,              0,              nu_byte,        np_byte},
        1329                 :            :     {'B',       1,              0,              nu_ubyte,       np_ubyte},
        1330                 :            :     {'c',       1,              0,              nu_char,        np_char},
        1331                 :            :     {'s',       1,              0,              NULL},
        1332                 :            :     {'p',       1,              0,              NULL},
        1333                 :            :     {'h',       2,              0,              lu_short,       lp_int},
        1334                 :            :     {'H',       2,              0,              lu_uint,        lp_uint},
        1335                 :            :     {'i',       4,              0,              lu_int,         lp_int},
        1336                 :            :     {'I',       4,              0,              lu_uint,        lp_uint},
        1337                 :            :     {'l',       4,              0,              lu_int,         lp_int},
        1338                 :            :     {'L',       4,              0,              lu_uint,        lp_uint},
        1339                 :            :     {'q',       8,              0,              lu_longlong,    lp_longlong},
        1340                 :            :     {'Q',       8,              0,              lu_ulonglong,   lp_ulonglong},
        1341                 :            :     {'?',       1,              0,              bu_bool,        bp_bool}, /* Std rep not endian dep,
        1342                 :            :         but potentially different from native rep -- reuse bx_bool funcs. */
        1343                 :            :     {'e',       2,              0,              lu_halffloat,   lp_halffloat},
        1344                 :            :     {'f',       4,              0,              lu_float,       lp_float},
        1345                 :            :     {'d',       8,              0,              lu_double,      lp_double},
        1346                 :            :     {0}
        1347                 :            : };
        1348                 :            :
        1349                 :            :
        1350                 :            : static const formatdef *
        1351                 :         15 : whichtable(const char **pfmt)
        1352                 :            : {
        1353                 :         15 :     const char *fmt = (*pfmt)++; /* May be backed out of later */
        1354   [ +  -  -  +  :         15 :     switch (*fmt) {
                          - ]
        1355                 :          2 :     case '<':
        1356                 :          2 :         return lilendian_table;
        1357                 :          0 :     case '>':
        1358                 :            :     case '!': /* Network byte order is big-endian */
        1359                 :          0 :         return bigendian_table;
        1360                 :          0 :     case '=': { /* Host byte order -- different from native in alignment! */
        1361                 :            : #if PY_LITTLE_ENDIAN
        1362                 :          0 :         return lilendian_table;
        1363                 :            : #else
        1364                 :            :         return bigendian_table;
        1365                 :            : #endif
        1366                 :            :     }
        1367                 :         13 :     default:
        1368                 :         13 :         --*pfmt; /* Back out of pointer increment */
        1369                 :            :         /* Fall through */
        1370                 :         13 :     case '@':
        1371                 :         13 :         return native_table;
        1372                 :            :     }
        1373                 :            : }
        1374                 :            :
        1375                 :            :
        1376                 :            : /* Get the table entry for a format code */
        1377                 :            :
        1378                 :            : static const formatdef *
        1379                 :         30 : getentry(_structmodulestate *state, int c, const formatdef *f)
        1380                 :            : {
        1381         [ +  - ]:        344 :     for (; f->format != '\0'; f++) {
        1382         [ +  + ]:        344 :         if (f->format == c) {
        1383                 :         30 :             return f;
        1384                 :            :         }
        1385                 :            :     }
        1386                 :          0 :     PyErr_SetString(state->StructError, "bad char in struct format");
        1387                 :          0 :     return NULL;
        1388                 :            : }
        1389                 :            :
        1390                 :            :
        1391                 :            : /* Align a size according to a format code.  Return -1 on overflow. */
        1392                 :            :
        1393                 :            : static Py_ssize_t
        1394                 :         30 : align(Py_ssize_t size, char c, const formatdef *e)
        1395                 :            : {
        1396                 :            :     Py_ssize_t extra;
        1397                 :            :
        1398         [ +  - ]:         30 :     if (e->format == c) {
        1399   [ +  +  -  + ]:         30 :         if (e->alignment && size > 0) {
        1400                 :          0 :             extra = (e->alignment - 1) - (size - 1) % (e->alignment);
        1401         [ #  # ]:          0 :             if (extra > PY_SSIZE_T_MAX - size)
        1402                 :          0 :                 return -1;
        1403                 :          0 :             size += extra;
        1404                 :            :         }
        1405                 :            :     }
        1406                 :         30 :     return size;
        1407                 :            : }
        1408                 :            :
        1409                 :            : /*
        1410                 :            :  * Struct object implementation.
        1411                 :            :  */
        1412                 :            :
        1413                 :            : /* calculate the size of a format string */
        1414                 :            :
        1415                 :            : static int
        1416                 :         15 : prepare_s(PyStructObject *self)
        1417                 :            : {
        1418                 :            :     const formatdef *f;
        1419                 :            :     const formatdef *e;
        1420                 :            :     formatcode *codes;
        1421                 :            :
        1422                 :            :     const char *s;
        1423                 :            :     const char *fmt;
        1424                 :            :     char c;
        1425                 :            :     Py_ssize_t size, len, num, itemsize;
        1426                 :            :     size_t ncodes;
        1427                 :            :
        1428                 :         15 :     _structmodulestate *state = get_struct_state_structinst(self);
        1429                 :            :
        1430                 :         15 :     fmt = PyBytes_AS_STRING(self->s_format);
        1431         [ -  + ]:         15 :     if (strlen(fmt) != (size_t)PyBytes_GET_SIZE(self->s_format)) {
        1432                 :          0 :         PyErr_SetString(state->StructError,
        1433                 :            :                         "embedded null character");
        1434                 :          0 :         return -1;
        1435                 :            :     }
        1436                 :            :
        1437                 :         15 :     f = whichtable(&fmt);
        1438                 :            :
        1439                 :         15 :     s = fmt;
        1440                 :         15 :     size = 0;
        1441                 :         15 :     len = 0;
        1442                 :         15 :     ncodes = 0;
        1443         [ +  + ]:         30 :     while ((c = *s++) != '\0') {
        1444         [ -  + ]:         15 :         if (Py_ISSPACE(c))
        1445                 :          0 :             continue;
        1446   [ +  -  -  + ]:         15 :         if ('0' <= c && c <= '9') {
        1447                 :          0 :             num = c - '0';
        1448   [ #  #  #  # ]:          0 :             while ('0' <= (c = *s++) && c <= '9') {
        1449                 :            :                 /* overflow-safe version of
        1450                 :            :                    if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
        1451   [ #  #  #  # ]:          0 :                 if (num >= PY_SSIZE_T_MAX / 10 && (
        1452                 :          0 :                         num > PY_SSIZE_T_MAX / 10 ||
        1453         [ #  # ]:          0 :                         (c - '0') > PY_SSIZE_T_MAX % 10))
        1454                 :          0 :                     goto overflow;
        1455                 :          0 :                 num = num*10 + (c - '0');
        1456                 :            :             }
        1457         [ #  # ]:          0 :             if (c == '\0') {
        1458                 :          0 :                 PyErr_SetString(state->StructError,
        1459                 :            :                                 "repeat count given without format specifier");
        1460                 :          0 :                 return -1;
        1461                 :            :             }
        1462                 :            :         }
        1463                 :            :         else
        1464                 :         15 :             num = 1;
        1465                 :            :
        1466                 :         15 :         e = getentry(state, c, f);
        1467         [ -  + ]:         15 :         if (e == NULL)
        1468                 :          0 :             return -1;
        1469                 :            :
        1470      [ -  -  + ]:         15 :         switch (c) {
        1471                 :          0 :             case 's': /* fall through */
        1472                 :          0 :             case 'p': len++; ncodes++; break;
        1473                 :          0 :             case 'x': break;
        1474         [ +  - ]:         15 :             default: len += num; if (num) ncodes++; break;
        1475                 :            :         }
        1476                 :            :
        1477                 :         15 :         itemsize = e->size;
        1478                 :         15 :         size = align(size, c, e);
        1479         [ -  + ]:         15 :         if (size == -1)
        1480                 :          0 :             goto overflow;
        1481                 :            :
        1482                 :            :         /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
        1483         [ -  + ]:         15 :         if (num > (PY_SSIZE_T_MAX - size) / itemsize)
        1484                 :          0 :             goto overflow;
        1485                 :         15 :         size += num * itemsize;
        1486                 :            :     }
        1487                 :            :
        1488                 :            :     /* check for overflow */
        1489         [ -  + ]:         15 :     if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) {
        1490                 :          0 :         PyErr_NoMemory();
        1491                 :          0 :         return -1;
        1492                 :            :     }
        1493                 :            :
        1494                 :         15 :     self->s_size = size;
        1495                 :         15 :     self->s_len = len;
        1496                 :         15 :     codes = PyMem_Malloc((ncodes + 1) * sizeof(formatcode));
        1497         [ -  + ]:         15 :     if (codes == NULL) {
        1498                 :          0 :         PyErr_NoMemory();
        1499                 :          0 :         return -1;
        1500                 :            :     }
        1501                 :            :     /* Free any s_codes value left over from a previous initialization. */
        1502         [ -  + ]:         15 :     if (self->s_codes != NULL)
        1503                 :          0 :         PyMem_Free(self->s_codes);
        1504                 :         15 :     self->s_codes = codes;
        1505                 :            :
        1506                 :         15 :     s = fmt;
        1507                 :         15 :     size = 0;
        1508         [ +  + ]:         30 :     while ((c = *s++) != '\0') {
        1509         [ -  + ]:         15 :         if (Py_ISSPACE(c))
        1510                 :          0 :             continue;
        1511   [ +  -  -  + ]:         15 :         if ('0' <= c && c <= '9') {
        1512                 :          0 :             num = c - '0';
        1513   [ #  #  #  # ]:          0 :             while ('0' <= (c = *s++) && c <= '9')
        1514                 :          0 :                 num = num*10 + (c - '0');
        1515                 :            :         }
        1516                 :            :         else
        1517                 :         15 :             num = 1;
        1518                 :            :
        1519                 :         15 :         e = getentry(state, c, f);
        1520                 :            :
        1521                 :         15 :         size = align(size, c, e);
        1522   [ +  -  -  + ]:         15 :         if (c == 's' || c == 'p') {
        1523                 :          0 :             codes->offset = size;
        1524                 :          0 :             codes->size = num;
        1525                 :          0 :             codes->fmtdef = e;
        1526                 :          0 :             codes->repeat = 1;
        1527                 :          0 :             codes++;
        1528                 :          0 :             size += num;
        1529         [ -  + ]:         15 :         } else if (c == 'x') {
        1530                 :          0 :             size += num;
        1531         [ +  - ]:         15 :         } else if (num) {
        1532                 :         15 :             codes->offset = size;
        1533                 :         15 :             codes->size = e->size;
        1534                 :         15 :             codes->fmtdef = e;
        1535                 :         15 :             codes->repeat = num;
        1536                 :         15 :             codes++;
        1537                 :         15 :             size += e->size * num;
        1538                 :            :         }
        1539                 :            :     }
        1540                 :         15 :     codes->fmtdef = NULL;
        1541                 :         15 :     codes->offset = size;
        1542                 :         15 :     codes->size = 0;
        1543                 :         15 :     codes->repeat = 0;
        1544                 :            :
        1545                 :         15 :     return 0;
        1546                 :            :
        1547                 :          0 :   overflow:
        1548                 :          0 :     PyErr_SetString(state->StructError,
        1549                 :            :                     "total struct size too long");
        1550                 :          0 :     return -1;
        1551                 :            : }
        1552                 :            :
        1553                 :            : /*[clinic input]
        1554                 :            : @classmethod
        1555                 :            : Struct.__new__
        1556                 :            :
        1557                 :            :     format: object
        1558                 :            :
        1559                 :            : Create a compiled struct object.
        1560                 :            :
        1561                 :            : Return a new Struct object which writes and reads binary data according to
        1562                 :            : the format string.
        1563                 :            :
        1564                 :            : See help(struct) for more on format strings.
        1565                 :            : [clinic start generated code]*/
        1566                 :            :
        1567                 :            : static PyObject *
        1568                 :         15 : Struct_impl(PyTypeObject *type, PyObject *format)
        1569                 :            : /*[clinic end generated code: output=49468b044e334308 input=8b91868eb1df0e28]*/
        1570                 :            : {
        1571                 :         15 :     allocfunc alloc = PyType_GetSlot(type, Py_tp_alloc);
        1572                 :            :     assert(alloc != NULL);
        1573                 :         15 :     PyStructObject *self = (PyStructObject *)alloc(type, 0);
        1574                 :            :
        1575         [ -  + ]:         15 :     if (self == NULL) {
        1576                 :          0 :         return NULL;
        1577                 :            :     }
        1578                 :            :
        1579         [ +  - ]:         15 :     if (PyUnicode_Check(format)) {
        1580                 :         15 :         format = PyUnicode_AsASCIIString(format);
        1581         [ -  + ]:         15 :         if (format == NULL) {
        1582                 :          0 :             Py_DECREF(self);
        1583                 :          0 :             return NULL;
        1584                 :            :         }
        1585                 :            :     }
        1586                 :            :     else {
        1587                 :          0 :         Py_INCREF(format);
        1588                 :            :     }
        1589                 :            :
        1590         [ -  + ]:         15 :     if (!PyBytes_Check(format)) {
        1591                 :          0 :         Py_DECREF(format);
        1592                 :          0 :         Py_DECREF(self);
        1593                 :          0 :         PyErr_Format(PyExc_TypeError,
        1594                 :            :                      "Struct() argument 1 must be a str or bytes object, "
        1595                 :            :                      "not %.200s",
        1596                 :            :                      _PyType_Name(Py_TYPE(format)));
        1597                 :          0 :         return NULL;
        1598                 :            :     }
        1599                 :            :
        1600                 :         15 :     self->s_format = format;
        1601                 :            :
        1602         [ -  + ]:         15 :     if (prepare_s(self) < 0) {
        1603                 :          0 :         Py_DECREF(self);
        1604                 :          0 :         return NULL;
        1605                 :            :     }
        1606                 :         15 :     return (PyObject *)self;
        1607                 :            : }
        1608                 :            :
        1609                 :            :
        1610                 :            : static int
        1611                 :          0 : s_clear(PyStructObject *s)
        1612                 :            : {
        1613         [ #  # ]:          0 :     Py_CLEAR(s->s_format);
        1614                 :          0 :     return 0;
        1615                 :            : }
        1616                 :            :
        1617                 :            : static int
        1618                 :        108 : s_traverse(PyStructObject *s, visitproc visit, void *arg)
        1619                 :            : {
        1620   [ +  -  -  + ]:        108 :     Py_VISIT(Py_TYPE(s));
        1621   [ +  -  -  + ]:        108 :     Py_VISIT(s->s_format);
        1622                 :        108 :     return 0;
        1623                 :            : }
        1624                 :            :
        1625                 :            : static void
        1626                 :         13 : s_dealloc(PyStructObject *s)
        1627                 :            : {
        1628                 :         13 :     PyTypeObject *tp = Py_TYPE(s);
        1629                 :         13 :     PyObject_GC_UnTrack(s);
        1630         [ -  + ]:         13 :     if (s->weakreflist != NULL)
        1631                 :          0 :         PyObject_ClearWeakRefs((PyObject *)s);
        1632         [ +  - ]:         13 :     if (s->s_codes != NULL) {
        1633                 :         13 :         PyMem_Free(s->s_codes);
        1634                 :            :     }
        1635                 :         13 :     Py_XDECREF(s->s_format);
        1636                 :         13 :     freefunc free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free);
        1637                 :         13 :     free_func(s);
        1638                 :         13 :     Py_DECREF(tp);
        1639                 :         13 : }
        1640                 :            :
        1641                 :            : static PyObject *
        1642                 :        198 : s_unpack_internal(PyStructObject *soself, const char *startfrom,
        1643                 :            :                   _structmodulestate *state) {
        1644                 :            :     formatcode *code;
        1645                 :        198 :     Py_ssize_t i = 0;
        1646                 :        198 :     PyObject *result = PyTuple_New(soself->s_len);
        1647         [ -  + ]:        198 :     if (result == NULL)
        1648                 :          0 :         return NULL;
        1649                 :            :
        1650         [ +  + ]:        396 :     for (code = soself->s_codes; code->fmtdef != NULL; code++) {
        1651                 :        198 :         const formatdef *e = code->fmtdef;
        1652                 :        198 :         const char *res = startfrom + code->offset;
        1653                 :        198 :         Py_ssize_t j = code->repeat;
        1654         [ +  + ]:        396 :         while (j--) {
        1655                 :            :             PyObject *v;
        1656         [ -  + ]:        198 :             if (e->format == 's') {
        1657                 :          0 :                 v = PyBytes_FromStringAndSize(res, code->size);
        1658         [ -  + ]:        198 :             } else if (e->format == 'p') {
        1659                 :          0 :                 Py_ssize_t n = *(unsigned char*)res;
        1660         [ #  # ]:          0 :                 if (n >= code->size)
        1661                 :          0 :                     n = code->size - 1;
        1662                 :          0 :                 v = PyBytes_FromStringAndSize(res + 1, n);
        1663                 :            :             } else {
        1664                 :        198 :                 v = e->unpack(state, res, e);
        1665                 :            :             }
        1666         [ -  + ]:        198 :             if (v == NULL)
        1667                 :          0 :                 goto fail;
        1668                 :        198 :             PyTuple_SET_ITEM(result, i++, v);
        1669                 :        198 :             res += code->size;
        1670                 :            :         }
        1671                 :            :     }
        1672                 :            :
        1673                 :        198 :     return result;
        1674                 :          0 : fail:
        1675                 :          0 :     Py_DECREF(result);
        1676                 :          0 :     return NULL;
        1677                 :            : }
        1678                 :            :
        1679                 :            :
        1680                 :            : /*[clinic input]
        1681                 :            : Struct.unpack
        1682                 :            :
        1683                 :            :     buffer: Py_buffer
        1684                 :            :     /
        1685                 :            :
        1686                 :            : Return a tuple containing unpacked values.
        1687                 :            :
        1688                 :            : Unpack according to the format string Struct.format. The buffer's size
        1689                 :            : in bytes must be Struct.size.
        1690                 :            :
        1691                 :            : See help(struct) for more on format strings.
        1692                 :            : [clinic start generated code]*/
        1693                 :            :
        1694                 :            : static PyObject *
        1695                 :        198 : Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
        1696                 :            : /*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
        1697                 :            : {
        1698                 :        198 :     _structmodulestate *state = get_struct_state_structinst(self);
        1699                 :            :     assert(self->s_codes != NULL);
        1700         [ -  + ]:        198 :     if (buffer->len != self->s_size) {
        1701                 :          0 :         PyErr_Format(state->StructError,
        1702                 :            :                      "unpack requires a buffer of %zd bytes",
        1703                 :            :                      self->s_size);
        1704                 :          0 :         return NULL;
        1705                 :            :     }
        1706                 :        198 :     return s_unpack_internal(self, buffer->buf, state);
        1707                 :            : }
        1708                 :            :
        1709                 :            : /*[clinic input]
        1710                 :            : Struct.unpack_from
        1711                 :            :
        1712                 :            :     buffer: Py_buffer
        1713                 :            :     offset: Py_ssize_t = 0
        1714                 :            :
        1715                 :            : Return a tuple containing unpacked values.
        1716                 :            :
        1717                 :            : Values are unpacked according to the format string Struct.format.
        1718                 :            :
        1719                 :            : The buffer's size in bytes, starting at position offset, must be
        1720                 :            : at least Struct.size.
        1721                 :            :
        1722                 :            : See help(struct) for more on format strings.
        1723                 :            : [clinic start generated code]*/
        1724                 :            :
        1725                 :            : static PyObject *
        1726                 :          0 : Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
        1727                 :            :                         Py_ssize_t offset)
        1728                 :            : /*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/
        1729                 :            : {
        1730                 :          0 :     _structmodulestate *state = get_struct_state_structinst(self);
        1731                 :            :     assert(self->s_codes != NULL);
        1732                 :            :
        1733         [ #  # ]:          0 :     if (offset < 0) {
        1734         [ #  # ]:          0 :         if (offset + self->s_size > 0) {
        1735                 :          0 :             PyErr_Format(state->StructError,
        1736                 :            :                          "not enough data to unpack %zd bytes at offset %zd",
        1737                 :            :                          self->s_size,
        1738                 :            :                          offset);
        1739                 :          0 :             return NULL;
        1740                 :            :         }
        1741                 :            :
        1742         [ #  # ]:          0 :         if (offset + buffer->len < 0) {
        1743                 :          0 :             PyErr_Format(state->StructError,
        1744                 :            :                          "offset %zd out of range for %zd-byte buffer",
        1745                 :            :                          offset,
        1746                 :            :                          buffer->len);
        1747                 :          0 :             return NULL;
        1748                 :            :         }
        1749                 :          0 :         offset += buffer->len;
        1750                 :            :     }
        1751                 :            :
        1752         [ #  # ]:          0 :     if ((buffer->len - offset) < self->s_size) {
        1753                 :          0 :         PyErr_Format(state->StructError,
        1754                 :            :                      "unpack_from requires a buffer of at least %zu bytes for "
        1755                 :            :                      "unpacking %zd bytes at offset %zd "
        1756                 :            :                      "(actual buffer size is %zd)",
        1757                 :          0 :                      (size_t)self->s_size + (size_t)offset,
        1758                 :            :                      self->s_size,
        1759                 :            :                      offset,
        1760                 :            :                      buffer->len);
        1761                 :          0 :         return NULL;
        1762                 :            :     }
        1763                 :          0 :     return s_unpack_internal(self, (char*)buffer->buf + offset, state);
        1764                 :            : }
        1765                 :            :
        1766                 :            :
        1767                 :            :
        1768                 :            : /* Unpack iterator type */
        1769                 :            :
        1770                 :            : typedef struct {
        1771                 :            :     PyObject_HEAD
        1772                 :            :     PyStructObject *so;
        1773                 :            :     Py_buffer buf;
        1774                 :            :     Py_ssize_t index;
        1775                 :            : } unpackiterobject;
        1776                 :            :
        1777                 :            : static void
        1778                 :          0 : unpackiter_dealloc(unpackiterobject *self)
        1779                 :            : {
        1780                 :            :     /* bpo-31095: UnTrack is needed before calling any callbacks */
        1781                 :          0 :     PyTypeObject *tp = Py_TYPE(self);
        1782                 :          0 :     PyObject_GC_UnTrack(self);
        1783                 :          0 :     Py_XDECREF(self->so);
        1784                 :          0 :     PyBuffer_Release(&self->buf);
        1785                 :          0 :     PyObject_GC_Del(self);
        1786                 :          0 :     Py_DECREF(tp);
        1787                 :          0 : }
        1788                 :            :
        1789                 :            : static int
        1790                 :          0 : unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
        1791                 :            : {
        1792   [ #  #  #  # ]:          0 :     Py_VISIT(Py_TYPE(self));
        1793   [ #  #  #  # ]:          0 :     Py_VISIT(self->so);
        1794   [ #  #  #  # ]:          0 :     Py_VISIT(self->buf.obj);
        1795                 :          0 :     return 0;
        1796                 :            : }
        1797                 :            :
        1798                 :            : static PyObject *
        1799                 :          0 : unpackiter_len(unpackiterobject *self, PyObject *Py_UNUSED(ignored))
        1800                 :            : {
        1801                 :            :     Py_ssize_t len;
        1802         [ #  # ]:          0 :     if (self->so == NULL)
        1803                 :          0 :         len = 0;
        1804                 :            :     else
        1805                 :          0 :         len = (self->buf.len - self->index) / self->so->s_size;
        1806                 :          0 :     return PyLong_FromSsize_t(len);
        1807                 :            : }
        1808                 :            :
        1809                 :            : static PyMethodDef unpackiter_methods[] = {
        1810                 :            :     {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
        1811                 :            :     {NULL,              NULL}           /* sentinel */
        1812                 :            : };
        1813                 :            :
        1814                 :            : static PyObject *
        1815                 :          0 : unpackiter_iternext(unpackiterobject *self)
        1816                 :            : {
        1817                 :          0 :     _structmodulestate *state = get_struct_state_iterinst(self);
        1818                 :            :     PyObject *result;
        1819         [ #  # ]:          0 :     if (self->so == NULL)
        1820                 :          0 :         return NULL;
        1821         [ #  # ]:          0 :     if (self->index >= self->buf.len) {
        1822                 :            :         /* Iterator exhausted */
        1823         [ #  # ]:          0 :         Py_CLEAR(self->so);
        1824                 :          0 :         PyBuffer_Release(&self->buf);
        1825                 :          0 :         return NULL;
        1826                 :            :     }
        1827                 :            :     assert(self->index + self->so->s_size <= self->buf.len);
        1828                 :          0 :     result = s_unpack_internal(self->so,
        1829                 :          0 :                                (char*) self->buf.buf + self->index,
        1830                 :            :                                state);
        1831                 :          0 :     self->index += self->so->s_size;
        1832                 :          0 :     return result;
        1833                 :            : }
        1834                 :            :
        1835                 :          0 : PyObject *unpackiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
        1836                 :          0 :     PyErr_Format(PyExc_TypeError, "Cannot create '%.200s objects", _PyType_Name(type));
        1837                 :          0 :     return NULL;
        1838                 :            : }
        1839                 :            :
        1840                 :            : static PyType_Slot unpackiter_type_slots[] = {
        1841                 :            :     {Py_tp_dealloc, unpackiter_dealloc},
        1842                 :            :     {Py_tp_getattro, PyObject_GenericGetAttr},
        1843                 :            :     {Py_tp_traverse, unpackiter_traverse},
        1844                 :            :     {Py_tp_iter, PyObject_SelfIter},
        1845                 :            :     {Py_tp_iternext, unpackiter_iternext},
        1846                 :            :     {Py_tp_methods, unpackiter_methods},
        1847                 :            :     {Py_tp_new, unpackiter_new},
        1848                 :            :     {0, 0},
        1849                 :            : };
        1850                 :            :
        1851                 :            : static PyType_Spec unpackiter_type_spec = {
        1852                 :            :     "_struct.unpack_iterator",
        1853                 :            :     sizeof(unpackiterobject),
        1854                 :            :     0,
        1855                 :            :     (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        1856                 :            :      Py_TPFLAGS_IMMUTABLETYPE),
        1857                 :            :     unpackiter_type_slots
        1858                 :            : };
        1859                 :            :
        1860                 :            : /*[clinic input]
        1861                 :            : Struct.iter_unpack
        1862                 :            :
        1863                 :            :     buffer: object
        1864                 :            :     /
        1865                 :            :
        1866                 :            : Return an iterator yielding tuples.
        1867                 :            :
        1868                 :            : Tuples are unpacked from the given bytes source, like a repeated
        1869                 :            : invocation of unpack_from().
        1870                 :            :
        1871                 :            : Requires that the bytes length be a multiple of the struct size.
        1872                 :            : [clinic start generated code]*/
        1873                 :            :
        1874                 :            : static PyObject *
        1875                 :          0 : Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
        1876                 :            : /*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
        1877                 :            : {
        1878                 :          0 :     _structmodulestate *state = get_struct_state_structinst(self);
        1879                 :            :     unpackiterobject *iter;
        1880                 :            :
        1881                 :            :     assert(self->s_codes != NULL);
        1882                 :            :
        1883         [ #  # ]:          0 :     if (self->s_size == 0) {
        1884                 :          0 :         PyErr_Format(state->StructError,
        1885                 :            :                      "cannot iteratively unpack with a struct of length 0");
        1886                 :          0 :         return NULL;
        1887                 :            :     }
        1888                 :            :
        1889                 :          0 :     iter = (unpackiterobject *) PyType_GenericAlloc((PyTypeObject *)state->unpackiter_type, 0);
        1890         [ #  # ]:          0 :     if (iter == NULL)
        1891                 :          0 :         return NULL;
        1892                 :            :
        1893         [ #  # ]:          0 :     if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
        1894                 :          0 :         Py_DECREF(iter);
        1895                 :          0 :         return NULL;
        1896                 :            :     }
        1897         [ #  # ]:          0 :     if (iter->buf.len % self->s_size != 0) {
        1898                 :          0 :         PyErr_Format(state->StructError,
        1899                 :            :                      "iterative unpacking requires a buffer of "
        1900                 :            :                      "a multiple of %zd bytes",
        1901                 :            :                      self->s_size);
        1902                 :          0 :         Py_DECREF(iter);
        1903                 :          0 :         return NULL;
        1904                 :            :     }
        1905                 :          0 :     iter->so = (PyStructObject*)Py_NewRef(self);
        1906                 :          0 :     iter->index = 0;
        1907                 :          0 :     return (PyObject *)iter;
        1908                 :            : }
        1909                 :            :
        1910                 :            :
        1911                 :            : /*
        1912                 :            :  * Guts of the pack function.
        1913                 :            :  *
        1914                 :            :  * Takes a struct object, a tuple of arguments, and offset in that tuple of
        1915                 :            :  * argument for where to start processing the arguments for packing, and a
        1916                 :            :  * character buffer for writing the packed string.  The caller must insure
        1917                 :            :  * that the buffer may contain the required length for packing the arguments.
        1918                 :            :  * 0 is returned on success, 1 is returned if there is an error.
        1919                 :            :  *
        1920                 :            :  */
        1921                 :            : static int
        1922                 :        198 : s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset,
        1923                 :            :                 char* buf, _structmodulestate *state)
        1924                 :            : {
        1925                 :            :     formatcode *code;
        1926                 :            :     /* XXX(nnorwitz): why does i need to be a local?  can we use
        1927                 :            :        the offset parameter or do we need the wider width? */
        1928                 :            :     Py_ssize_t i;
        1929                 :            :
        1930                 :        198 :     memset(buf, '\0', soself->s_size);
        1931                 :        198 :     i = offset;
        1932         [ +  + ]:        396 :     for (code = soself->s_codes; code->fmtdef != NULL; code++) {
        1933                 :        198 :         const formatdef *e = code->fmtdef;
        1934                 :        198 :         char *res = buf + code->offset;
        1935                 :        198 :         Py_ssize_t j = code->repeat;
        1936         [ +  + ]:        396 :         while (j--) {
        1937                 :        198 :             PyObject *v = args[i++];
        1938         [ -  + ]:        198 :             if (e->format == 's') {
        1939                 :            :                 Py_ssize_t n;
        1940                 :            :                 int isstring;
        1941                 :            :                 const void *p;
        1942                 :          0 :                 isstring = PyBytes_Check(v);
        1943   [ #  #  #  # ]:          0 :                 if (!isstring && !PyByteArray_Check(v)) {
        1944                 :          0 :                     PyErr_SetString(state->StructError,
        1945                 :            :                                     "argument for 's' must be a bytes object");
        1946                 :          0 :                     return -1;
        1947                 :            :                 }
        1948         [ #  # ]:          0 :                 if (isstring) {
        1949                 :          0 :                     n = PyBytes_GET_SIZE(v);
        1950                 :          0 :                     p = PyBytes_AS_STRING(v);
        1951                 :            :                 }
        1952                 :            :                 else {
        1953                 :          0 :                     n = PyByteArray_GET_SIZE(v);
        1954                 :          0 :                     p = PyByteArray_AS_STRING(v);
        1955                 :            :                 }
        1956         [ #  # ]:          0 :                 if (n > code->size)
        1957                 :          0 :                     n = code->size;
        1958         [ #  # ]:          0 :                 if (n > 0)
        1959                 :          0 :                     memcpy(res, p, n);
        1960         [ -  + ]:        198 :             } else if (e->format == 'p') {
        1961                 :            :                 Py_ssize_t n;
        1962                 :            :                 int isstring;
        1963                 :            :                 const void *p;
        1964                 :          0 :                 isstring = PyBytes_Check(v);
        1965   [ #  #  #  # ]:          0 :                 if (!isstring && !PyByteArray_Check(v)) {
        1966                 :          0 :                     PyErr_SetString(state->StructError,
        1967                 :            :                                     "argument for 'p' must be a bytes object");
        1968                 :          0 :                     return -1;
        1969                 :            :                 }
        1970         [ #  # ]:          0 :                 if (isstring) {
        1971                 :          0 :                     n = PyBytes_GET_SIZE(v);
        1972                 :          0 :                     p = PyBytes_AS_STRING(v);
        1973                 :            :                 }
        1974                 :            :                 else {
        1975                 :          0 :                     n = PyByteArray_GET_SIZE(v);
        1976                 :          0 :                     p = PyByteArray_AS_STRING(v);
        1977                 :            :                 }
        1978         [ #  # ]:          0 :                 if (n > (code->size - 1))
        1979                 :          0 :                     n = code->size - 1;
        1980         [ #  # ]:          0 :                 if (n > 0)
        1981                 :          0 :                     memcpy(res + 1, p, n);
        1982         [ #  # ]:          0 :                 if (n > 255)
        1983                 :          0 :                     n = 255;
        1984                 :          0 :                 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
        1985                 :            :             } else {
        1986         [ -  + ]:        198 :                 if (e->pack(state, res, v, e) < 0) {
        1987   [ #  #  #  # ]:          0 :                     if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
        1988                 :          0 :                         PyErr_SetString(state->StructError,
        1989                 :            :                                         "int too large to convert");
        1990                 :          0 :                     return -1;
        1991                 :            :                 }
        1992                 :            :             }
        1993                 :        198 :             res += code->size;
        1994                 :            :         }
        1995                 :            :     }
        1996                 :            :
        1997                 :            :     /* Success */
        1998                 :        198 :     return 0;
        1999                 :            : }
        2000                 :            :
        2001                 :            :
        2002                 :            : PyDoc_STRVAR(s_pack__doc__,
        2003                 :            : "S.pack(v1, v2, ...) -> bytes\n\
        2004                 :            : \n\
        2005                 :            : Return a bytes object containing values v1, v2, ... packed according\n\
        2006                 :            : to the format string S.format.  See help(struct) for more on format\n\
        2007                 :            : strings.");
        2008                 :            :
        2009                 :            : static PyObject *
        2010                 :        198 : s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
        2011                 :            : {
        2012                 :            :     char *buf;
        2013                 :            :     PyStructObject *soself;
        2014                 :        198 :     _structmodulestate *state = get_struct_state_structinst(self);
        2015                 :            :
        2016                 :            :     /* Validate arguments. */
        2017                 :        198 :     soself = (PyStructObject *)self;
        2018                 :            :     assert(PyStruct_Check(self, state));
        2019                 :            :     assert(soself->s_codes != NULL);
        2020         [ -  + ]:        198 :     if (nargs != soself->s_len)
        2021                 :            :     {
        2022                 :          0 :         PyErr_Format(state->StructError,
        2023                 :            :             "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
        2024                 :          0 :         return NULL;
        2025                 :            :     }
        2026                 :            :
        2027                 :            :     /* Allocate a new string */
        2028                 :            :     _PyBytesWriter writer;
        2029                 :        198 :     _PyBytesWriter_Init(&writer);
        2030                 :        198 :     buf = _PyBytesWriter_Alloc(&writer, soself->s_size);
        2031         [ -  + ]:        198 :     if (buf == NULL) {
        2032                 :          0 :         _PyBytesWriter_Dealloc(&writer);
        2033                 :          0 :         return NULL;
        2034                 :            :     }
        2035                 :            :
        2036                 :            :     /* Call the guts */
        2037         [ -  + ]:        198 :     if ( s_pack_internal(soself, args, 0, buf, state) != 0 ) {
        2038                 :          0 :         _PyBytesWriter_Dealloc(&writer);
        2039                 :          0 :         return NULL;
        2040                 :            :     }
        2041                 :            :
        2042                 :        198 :     return _PyBytesWriter_Finish(&writer, buf + soself->s_size);
        2043                 :            : }
        2044                 :            :
        2045                 :            : PyDoc_STRVAR(s_pack_into__doc__,
        2046                 :            : "S.pack_into(buffer, offset, v1, v2, ...)\n\
        2047                 :            : \n\
        2048                 :            : Pack the values v1, v2, ... according to the format string S.format\n\
        2049                 :            : and write the packed bytes into the writable buffer buf starting at\n\
        2050                 :            : offset.  Note that the offset is a required argument.  See\n\
        2051                 :            : help(struct) for more on format strings.");
        2052                 :            :
        2053                 :            : static PyObject *
        2054                 :          0 : s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
        2055                 :            : {
        2056                 :            :     PyStructObject *soself;
        2057                 :            :     Py_buffer buffer;
        2058                 :            :     Py_ssize_t offset;
        2059                 :          0 :     _structmodulestate *state = get_struct_state_structinst(self);
        2060                 :            :
        2061                 :            :     /* Validate arguments.  +1 is for the first arg as buffer. */
        2062                 :          0 :     soself = (PyStructObject *)self;
        2063                 :            :     assert(PyStruct_Check(self, state));
        2064                 :            :     assert(soself->s_codes != NULL);
        2065         [ #  # ]:          0 :     if (nargs != (soself->s_len + 2))
        2066                 :            :     {
        2067         [ #  # ]:          0 :         if (nargs == 0) {
        2068                 :          0 :             PyErr_Format(state->StructError,
        2069                 :            :                         "pack_into expected buffer argument");
        2070                 :            :         }
        2071         [ #  # ]:          0 :         else if (nargs == 1) {
        2072                 :          0 :             PyErr_Format(state->StructError,
        2073                 :            :                         "pack_into expected offset argument");
        2074                 :            :         }
        2075                 :            :         else {
        2076                 :          0 :             PyErr_Format(state->StructError,
        2077                 :            :                         "pack_into expected %zd items for packing (got %zd)",
        2078                 :            :                         soself->s_len, (nargs - 2));
        2079                 :            :         }
        2080                 :          0 :         return NULL;
        2081                 :            :     }
        2082                 :            :
        2083                 :            :     /* Extract a writable memory buffer from the first argument */
        2084         [ #  # ]:          0 :     if (!PyArg_Parse(args[0], "w*", &buffer))
        2085                 :          0 :         return NULL;
        2086                 :            :     assert(buffer.len >= 0);
        2087                 :            :
        2088                 :            :     /* Extract the offset from the first argument */
        2089                 :          0 :     offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
        2090   [ #  #  #  # ]:          0 :     if (offset == -1 && PyErr_Occurred()) {
        2091                 :          0 :         PyBuffer_Release(&buffer);
        2092                 :          0 :         return NULL;
        2093                 :            :     }
        2094                 :            :
        2095                 :            :     /* Support negative offsets. */
        2096         [ #  # ]:          0 :     if (offset < 0) {
        2097                 :            :          /* Check that negative offset is low enough to fit data */
        2098         [ #  # ]:          0 :         if (offset + soself->s_size > 0) {
        2099                 :          0 :             PyErr_Format(state->StructError,
        2100                 :            :                          "no space to pack %zd bytes at offset %zd",
        2101                 :            :                          soself->s_size,
        2102                 :            :                          offset);
        2103                 :          0 :             PyBuffer_Release(&buffer);
        2104                 :          0 :             return NULL;
        2105                 :            :         }
        2106                 :            :
        2107                 :            :         /* Check that negative offset is not crossing buffer boundary */
        2108         [ #  # ]:          0 :         if (offset + buffer.len < 0) {
        2109                 :          0 :             PyErr_Format(state->StructError,
        2110                 :            :                          "offset %zd out of range for %zd-byte buffer",
        2111                 :            :                          offset,
        2112                 :            :                          buffer.len);
        2113                 :          0 :             PyBuffer_Release(&buffer);
        2114                 :          0 :             return NULL;
        2115                 :            :         }
        2116                 :            :
        2117                 :          0 :         offset += buffer.len;
        2118                 :            :     }
        2119                 :            :
        2120                 :            :     /* Check boundaries */
        2121         [ #  # ]:          0 :     if ((buffer.len - offset) < soself->s_size) {
        2122                 :            :         assert(offset >= 0);
        2123                 :            :         assert(soself->s_size >= 0);
        2124                 :            :
        2125                 :          0 :         PyErr_Format(state->StructError,
        2126                 :            :                      "pack_into requires a buffer of at least %zu bytes for "
        2127                 :            :                      "packing %zd bytes at offset %zd "
        2128                 :            :                      "(actual buffer size is %zd)",
        2129                 :          0 :                      (size_t)soself->s_size + (size_t)offset,
        2130                 :            :                      soself->s_size,
        2131                 :            :                      offset,
        2132                 :            :                      buffer.len);
        2133                 :          0 :         PyBuffer_Release(&buffer);
        2134                 :          0 :         return NULL;
        2135                 :            :     }
        2136                 :            :
        2137                 :            :     /* Call the guts */
        2138         [ #  # ]:          0 :     if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset, state) != 0) {
        2139                 :          0 :         PyBuffer_Release(&buffer);
        2140                 :          0 :         return NULL;
        2141                 :            :     }
        2142                 :            :
        2143                 :          0 :     PyBuffer_Release(&buffer);
        2144                 :          0 :     Py_RETURN_NONE;
        2145                 :            : }
        2146                 :            :
        2147                 :            : static PyObject *
        2148                 :          0 : s_get_format(PyStructObject *self, void *unused)
        2149                 :            : {
        2150                 :          0 :     return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
        2151                 :            :                                        PyBytes_GET_SIZE(self->s_format));
        2152                 :            : }
        2153                 :            :
        2154                 :            : static PyObject *
        2155                 :          0 : s_get_size(PyStructObject *self, void *unused)
        2156                 :            : {
        2157                 :          0 :     return PyLong_FromSsize_t(self->s_size);
        2158                 :            : }
        2159                 :            :
        2160                 :            : PyDoc_STRVAR(s_sizeof__doc__,
        2161                 :            : "S.__sizeof__() -> size of S in memory, in bytes");
        2162                 :            :
        2163                 :            : static PyObject *
        2164                 :          0 : s_sizeof(PyStructObject *self, void *unused)
        2165                 :            : {
        2166                 :          0 :     size_t size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
        2167         [ #  # ]:          0 :     for (formatcode *code = self->s_codes; code->fmtdef != NULL; code++) {
        2168                 :          0 :         size += sizeof(formatcode);
        2169                 :            :     }
        2170                 :          0 :     return PyLong_FromSize_t(size);
        2171                 :            : }
        2172                 :            :
        2173                 :            : /* List of functions */
        2174                 :            :
        2175                 :            : static struct PyMethodDef s_methods[] = {
        2176                 :            :     STRUCT_ITER_UNPACK_METHODDEF
        2177                 :            :     {"pack",            _PyCFunction_CAST(s_pack), METH_FASTCALL, s_pack__doc__},
        2178                 :            :     {"pack_into",       _PyCFunction_CAST(s_pack_into), METH_FASTCALL, s_pack_into__doc__},
        2179                 :            :     STRUCT_UNPACK_METHODDEF
        2180                 :            :     STRUCT_UNPACK_FROM_METHODDEF
        2181                 :            :     {"__sizeof__",      (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
        2182                 :            :     {NULL,       NULL}          /* sentinel */
        2183                 :            : };
        2184                 :            :
        2185                 :            : static PyMemberDef s_members[] = {
        2186                 :            :     {"__weaklistoffset__", T_PYSSIZET, offsetof(PyStructObject, weakreflist), READONLY},
        2187                 :            :     {NULL}  /* sentinel */
        2188                 :            : };
        2189                 :            :
        2190                 :            : static PyGetSetDef s_getsetlist[] = {
        2191                 :            :     {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
        2192                 :            :     {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
        2193                 :            :     {NULL} /* sentinel */
        2194                 :            : };
        2195                 :            :
        2196                 :            : PyDoc_STRVAR(s__doc__,
        2197                 :            : "Struct(fmt) --> compiled struct object\n"
        2198                 :            : "\n"
        2199                 :            : );
        2200                 :            :
        2201                 :            : static PyType_Slot PyStructType_slots[] = {
        2202                 :            :     {Py_tp_dealloc, s_dealloc},
        2203                 :            :     {Py_tp_getattro, PyObject_GenericGetAttr},
        2204                 :            :     {Py_tp_setattro, PyObject_GenericSetAttr},
        2205                 :            :     {Py_tp_doc, (void*)s__doc__},
        2206                 :            :     {Py_tp_traverse, s_traverse},
        2207                 :            :     {Py_tp_clear, s_clear},
        2208                 :            :     {Py_tp_methods, s_methods},
        2209                 :            :     {Py_tp_members, s_members},
        2210                 :            :     {Py_tp_getset, s_getsetlist},
        2211                 :            :     {Py_tp_new, Struct},
        2212                 :            :     {Py_tp_alloc, PyType_GenericAlloc},
        2213                 :            :     {Py_tp_free, PyObject_GC_Del},
        2214                 :            :     {0, 0},
        2215                 :            : };
        2216                 :            :
        2217                 :            : static PyType_Spec PyStructType_spec = {
        2218                 :            :     "_struct.Struct",
        2219                 :            :     sizeof(PyStructObject),
        2220                 :            :     0,
        2221                 :            :     (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
        2222                 :            :      Py_TPFLAGS_BASETYPE | Py_TPFLAGS_IMMUTABLETYPE),
        2223                 :            :     PyStructType_slots
        2224                 :            : };
        2225                 :            :
        2226                 :            :
        2227                 :            : /* ---- Standalone functions  ---- */
        2228                 :            :
        2229                 :            : #define MAXCACHE 100
        2230                 :            :
        2231                 :            : static int
        2232                 :        414 : cache_struct_converter(PyObject *module, PyObject *fmt, PyStructObject **ptr)
        2233                 :            : {
        2234                 :            :     PyObject * s_object;
        2235                 :        414 :     _structmodulestate *state = get_struct_state(module);
        2236                 :            :
        2237         [ -  + ]:        414 :     if (fmt == NULL) {
        2238                 :          0 :         Py_SETREF(*ptr, NULL);
        2239                 :          0 :         return 1;
        2240                 :            :     }
        2241                 :            :
        2242         [ +  + ]:        414 :     if (state->cache == NULL) {
        2243                 :          2 :         state->cache = PyDict_New();
        2244         [ -  + ]:          2 :         if (state->cache == NULL)
        2245                 :          0 :             return 0;
        2246                 :            :     }
        2247                 :            :
        2248                 :        414 :     s_object = PyDict_GetItemWithError(state->cache, fmt);
        2249         [ +  + ]:        414 :     if (s_object != NULL) {
        2250                 :        399 :         *ptr = (PyStructObject *)Py_NewRef(s_object);
        2251                 :        399 :         return Py_CLEANUP_SUPPORTED;
        2252                 :            :     }
        2253         [ -  + ]:         15 :     else if (PyErr_Occurred()) {
        2254                 :          0 :         return 0;
        2255                 :            :     }
        2256                 :            :
        2257                 :         15 :     s_object = PyObject_CallOneArg(state->PyStructType, fmt);
        2258         [ +  - ]:         15 :     if (s_object != NULL) {
        2259         [ -  + ]:         15 :         if (PyDict_GET_SIZE(state->cache) >= MAXCACHE)
        2260                 :          0 :             PyDict_Clear(state->cache);
        2261                 :            :         /* Attempt to cache the result */
        2262         [ -  + ]:         15 :         if (PyDict_SetItem(state->cache, fmt, s_object) == -1)
        2263                 :          0 :             PyErr_Clear();
        2264                 :         15 :         *ptr = (PyStructObject *)s_object;
        2265                 :         15 :         return Py_CLEANUP_SUPPORTED;
        2266                 :            :     }
        2267                 :          0 :     return 0;
        2268                 :            : }
        2269                 :            :
        2270                 :            : /*[clinic input]
        2271                 :            : _clearcache
        2272                 :            :
        2273                 :            : Clear the internal cache.
        2274                 :            : [clinic start generated code]*/
        2275                 :            :
        2276                 :            : static PyObject *
        2277                 :          1 : _clearcache_impl(PyObject *module)
        2278                 :            : /*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
        2279                 :            : {
        2280         [ +  - ]:          1 :     Py_CLEAR(get_struct_state(module)->cache);
        2281                 :          1 :     Py_RETURN_NONE;
        2282                 :            : }
        2283                 :            :
        2284                 :            :
        2285                 :            : /*[clinic input]
        2286                 :            : calcsize -> Py_ssize_t
        2287                 :            :
        2288                 :            :     format as s_object: cache_struct
        2289                 :            :     /
        2290                 :            :
        2291                 :            : Return size in bytes of the struct described by the format string.
        2292                 :            : [clinic start generated code]*/
        2293                 :            :
        2294                 :            : static Py_ssize_t
        2295                 :         18 : calcsize_impl(PyObject *module, PyStructObject *s_object)
        2296                 :            : /*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
        2297                 :            : {
        2298                 :         18 :     return s_object->s_size;
        2299                 :            : }
        2300                 :            :
        2301                 :            : PyDoc_STRVAR(pack_doc,
        2302                 :            : "pack(format, v1, v2, ...) -> bytes\n\
        2303                 :            : \n\
        2304                 :            : Return a bytes object containing the values v1, v2, ... packed according\n\
        2305                 :            : to the format string.  See help(struct) for more on format strings.");
        2306                 :            :
        2307                 :            : static PyObject *
        2308                 :        198 : pack(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
        2309                 :            : {
        2310                 :        198 :     PyObject *s_object = NULL;
        2311                 :            :     PyObject *format, *result;
        2312                 :            :
        2313         [ -  + ]:        198 :     if (nargs == 0) {
        2314                 :          0 :         PyErr_SetString(PyExc_TypeError, "missing format argument");
        2315                 :          0 :         return NULL;
        2316                 :            :     }
        2317                 :        198 :     format = args[0];
        2318                 :            :
        2319         [ -  + ]:        198 :     if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) {
        2320                 :          0 :         return NULL;
        2321                 :            :     }
        2322                 :        198 :     result = s_pack(s_object, args + 1, nargs - 1);
        2323                 :        198 :     Py_DECREF(s_object);
        2324                 :        198 :     return result;
        2325                 :            : }
        2326                 :            :
        2327                 :            : PyDoc_STRVAR(pack_into_doc,
        2328                 :            : "pack_into(format, buffer, offset, v1, v2, ...)\n\
        2329                 :            : \n\
        2330                 :            : Pack the values v1, v2, ... according to the format string and write\n\
        2331                 :            : the packed bytes into the writable buffer buf starting at offset.  Note\n\
        2332                 :            : that the offset is a required argument.  See help(struct) for more\n\
        2333                 :            : on format strings.");
        2334                 :            :
        2335                 :            : static PyObject *
        2336                 :          0 : pack_into(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
        2337                 :            : {
        2338                 :          0 :     PyObject *s_object = NULL;
        2339                 :            :     PyObject *format, *result;
        2340                 :            :
        2341         [ #  # ]:          0 :     if (nargs == 0) {
        2342                 :          0 :         PyErr_SetString(PyExc_TypeError, "missing format argument");
        2343                 :          0 :         return NULL;
        2344                 :            :     }
        2345                 :          0 :     format = args[0];
        2346                 :            :
        2347         [ #  # ]:          0 :     if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) {
        2348                 :          0 :         return NULL;
        2349                 :            :     }
        2350                 :          0 :     result = s_pack_into(s_object, args + 1, nargs - 1);
        2351                 :          0 :     Py_DECREF(s_object);
        2352                 :          0 :     return result;
        2353                 :            : }
        2354                 :            :
        2355                 :            : /*[clinic input]
        2356                 :            : unpack
        2357                 :            :
        2358                 :            :     format as s_object: cache_struct
        2359                 :            :     buffer: Py_buffer
        2360                 :            :     /
        2361                 :            :
        2362                 :            : Return a tuple containing values unpacked according to the format string.
        2363                 :            :
        2364                 :            : The buffer's size in bytes must be calcsize(format).
        2365                 :            :
        2366                 :            : See help(struct) for more on format strings.
        2367                 :            : [clinic start generated code]*/
        2368                 :            :
        2369                 :            : static PyObject *
        2370                 :        198 : unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
        2371                 :            : /*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
        2372                 :            : {
        2373                 :        198 :     return Struct_unpack_impl(s_object, buffer);
        2374                 :            : }
        2375                 :            :
        2376                 :            : /*[clinic input]
        2377                 :            : unpack_from
        2378                 :            :
        2379                 :            :     format as s_object: cache_struct
        2380                 :            :     /
        2381                 :            :     buffer: Py_buffer
        2382                 :            :     offset: Py_ssize_t = 0
        2383                 :            :
        2384                 :            : Return a tuple containing values unpacked according to the format string.
        2385                 :            :
        2386                 :            : The buffer's size, minus offset, must be at least calcsize(format).
        2387                 :            :
        2388                 :            : See help(struct) for more on format strings.
        2389                 :            : [clinic start generated code]*/
        2390                 :            :
        2391                 :            : static PyObject *
        2392                 :          0 : unpack_from_impl(PyObject *module, PyStructObject *s_object,
        2393                 :            :                  Py_buffer *buffer, Py_ssize_t offset)
        2394                 :            : /*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
        2395                 :            : {
        2396                 :          0 :     return Struct_unpack_from_impl(s_object, buffer, offset);
        2397                 :            : }
        2398                 :            :
        2399                 :            : /*[clinic input]
        2400                 :            : iter_unpack
        2401                 :            :
        2402                 :            :     format as s_object: cache_struct
        2403                 :            :     buffer: object
        2404                 :            :     /
        2405                 :            :
        2406                 :            : Return an iterator yielding tuples unpacked from the given bytes.
        2407                 :            :
        2408                 :            : The bytes are unpacked according to the format string, like
        2409                 :            : a repeated invocation of unpack_from().
        2410                 :            :
        2411                 :            : Requires that the bytes length be a multiple of the format struct size.
        2412                 :            : [clinic start generated code]*/
        2413                 :            :
        2414                 :            : static PyObject *
        2415                 :          0 : iter_unpack_impl(PyObject *module, PyStructObject *s_object,
        2416                 :            :                  PyObject *buffer)
        2417                 :            : /*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
        2418                 :            : {
        2419                 :          0 :     return Struct_iter_unpack(s_object, buffer);
        2420                 :            : }
        2421                 :            :
        2422                 :            : static struct PyMethodDef module_functions[] = {
        2423                 :            :     _CLEARCACHE_METHODDEF
        2424                 :            :     CALCSIZE_METHODDEF
        2425                 :            :     ITER_UNPACK_METHODDEF
        2426                 :            :     {"pack",            _PyCFunction_CAST(pack), METH_FASTCALL,   pack_doc},
        2427                 :            :     {"pack_into",       _PyCFunction_CAST(pack_into), METH_FASTCALL,   pack_into_doc},
        2428                 :            :     UNPACK_METHODDEF
        2429                 :            :     UNPACK_FROM_METHODDEF
        2430                 :            :     {NULL,       NULL}          /* sentinel */
        2431                 :            : };
        2432                 :            :
        2433                 :            :
        2434                 :            : /* Module initialization */
        2435                 :            :
        2436                 :            : PyDoc_STRVAR(module_doc,
        2437                 :            : "Functions to convert between Python values and C structs.\n\
        2438                 :            : Python bytes objects are used to hold the data representing the C struct\n\
        2439                 :            : and also as format strings (explained below) to describe the layout of data\n\
        2440                 :            : in the C struct.\n\
        2441                 :            : \n\
        2442                 :            : The optional first format char indicates byte order, size and alignment:\n\
        2443                 :            :   @: native order, size & alignment (default)\n\
        2444                 :            :   =: native order, std. size & alignment\n\
        2445                 :            :   <: little-endian, std. size & alignment\n\
        2446                 :            :   >: big-endian, std. size & alignment\n\
        2447                 :            :   !: same as >\n\
        2448                 :            : \n\
        2449                 :            : The remaining chars indicate types of args and must match exactly;\n\
        2450                 :            : these can be preceded by a decimal repeat count:\n\
        2451                 :            :   x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
        2452                 :            :   ?: _Bool (requires C99; if not available, char is used instead)\n\
        2453                 :            :   h:short; H:unsigned short; i:int; I:unsigned int;\n\
        2454                 :            :   l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
        2455                 :            : Special cases (preceding decimal count indicates length):\n\
        2456                 :            :   s:string (array of char); p: pascal string (with count byte).\n\
        2457                 :            : Special cases (only available in native format):\n\
        2458                 :            :   n:ssize_t; N:size_t;\n\
        2459                 :            :   P:an integer type that is wide enough to hold a pointer.\n\
        2460                 :            : Special case (not in native mode unless 'long long' in platform C):\n\
        2461                 :            :   q:long long; Q:unsigned long long\n\
        2462                 :            : Whitespace between formats is ignored.\n\
        2463                 :            : \n\
        2464                 :            : The variable struct.error is an exception raised on errors.\n");
        2465                 :            :
        2466                 :            :
        2467                 :            : static int
        2468                 :         54 : _structmodule_traverse(PyObject *module, visitproc visit, void *arg)
        2469                 :            : {
        2470                 :         54 :     _structmodulestate *state = get_struct_state(module);
        2471         [ +  - ]:         54 :     if (state) {
        2472   [ +  +  -  + ]:         54 :         Py_VISIT(state->cache);
        2473   [ +  -  -  + ]:         54 :         Py_VISIT(state->PyStructType);
        2474   [ +  -  -  + ]:         54 :         Py_VISIT(state->unpackiter_type);
        2475   [ +  -  -  + ]:         54 :         Py_VISIT(state->StructError);
        2476                 :            :     }
        2477                 :         54 :     return 0;
        2478                 :            : }
        2479                 :            :
        2480                 :            : static int
        2481                 :          2 : _structmodule_clear(PyObject *module)
        2482                 :            : {
        2483                 :          2 :     _structmodulestate *state = get_struct_state(module);
        2484         [ +  - ]:          2 :     if (state) {
        2485         [ -  + ]:          2 :         Py_CLEAR(state->cache);
        2486         [ +  + ]:          2 :         Py_CLEAR(state->PyStructType);
        2487         [ +  + ]:          2 :         Py_CLEAR(state->unpackiter_type);
        2488         [ +  + ]:          2 :         Py_CLEAR(state->StructError);
        2489                 :            :     }
        2490                 :          2 :     return 0;
        2491                 :            : }
        2492                 :            :
        2493                 :            : static void
        2494                 :          1 : _structmodule_free(void *module)
        2495                 :            : {
        2496                 :          1 :     _structmodule_clear((PyObject *)module);
        2497                 :          1 : }
        2498                 :            :
        2499                 :            : static int
        2500                 :          3 : _structmodule_exec(PyObject *m)
        2501                 :            : {
        2502                 :          3 :     _structmodulestate *state = get_struct_state(m);
        2503                 :            :
        2504                 :          3 :     state->PyStructType = PyType_FromModuleAndSpec(
        2505                 :            :         m, &PyStructType_spec, NULL);
        2506         [ -  + ]:          3 :     if (state->PyStructType == NULL) {
        2507                 :          0 :         return -1;
        2508                 :            :     }
        2509         [ -  + ]:          3 :     if (PyModule_AddType(m, (PyTypeObject *)state->PyStructType) < 0) {
        2510                 :          0 :         return -1;
        2511                 :            :     }
        2512                 :            :
        2513                 :          3 :     state->unpackiter_type = PyType_FromModuleAndSpec(
        2514                 :            :         m, &unpackiter_type_spec, NULL);
        2515         [ -  + ]:          3 :     if (state->unpackiter_type == NULL) {
        2516                 :          0 :         return -1;
        2517                 :            :     }
        2518                 :            :
        2519                 :            :     /* Check endian and swap in faster functions */
        2520                 :            :     {
        2521                 :          3 :         const formatdef *native = native_table;
        2522                 :            :         formatdef *other, *ptr;
        2523                 :            : #if PY_LITTLE_ENDIAN
        2524                 :          3 :         other = lilendian_table;
        2525                 :            : #else
        2526                 :            :         other = bigendian_table;
        2527                 :            : #endif
        2528                 :            :         /* Scan through the native table, find a matching
        2529                 :            :            entry in the endian table and swap in the
        2530                 :            :            native implementations whenever possible
        2531                 :            :            (64-bit platforms may not have "standard" sizes) */
        2532   [ +  -  +  + ]:         63 :         while (native->format != '\0' && other->format != '\0') {
        2533                 :         60 :             ptr = other;
        2534         [ +  + ]:         96 :             while (ptr->format != '\0') {
        2535         [ +  + ]:         90 :                 if (ptr->format == native->format) {
        2536                 :            :                     /* Match faster when formats are
        2537                 :            :                        listed in the same order */
        2538         [ +  - ]:         54 :                     if (ptr == other)
        2539                 :         54 :                         other++;
        2540                 :            :                     /* Only use the trick if the
        2541                 :            :                        size matches */
        2542         [ +  + ]:         54 :                     if (ptr->size != native->size)
        2543                 :          6 :                         break;
        2544                 :            :                     /* Skip float and double, could be
        2545                 :            :                        "unknown" float format */
        2546   [ +  +  +  + ]:         48 :                     if (ptr->format == 'd' || ptr->format == 'f')
        2547                 :            :                         break;
        2548                 :            :                     /* Skip _Bool, semantics are different for standard size */
        2549         [ +  + ]:         42 :                     if (ptr->format == '?')
        2550                 :          3 :                         break;
        2551                 :         39 :                     ptr->pack = native->pack;
        2552                 :         39 :                     ptr->unpack = native->unpack;
        2553                 :         39 :                     break;
        2554                 :            :                 }
        2555                 :         36 :                 ptr++;
        2556                 :            :             }
        2557                 :         60 :             native++;
        2558                 :            :         }
        2559                 :            :     }
        2560                 :            :
        2561                 :            :     /* Add some symbolic constants to the module */
        2562                 :          3 :     state->StructError = PyErr_NewException("struct.error", NULL, NULL);
        2563         [ -  + ]:          3 :     if (state->StructError == NULL) {
        2564                 :          0 :         return -1;
        2565                 :            :     }
        2566         [ -  + ]:          3 :     if (PyModule_AddObjectRef(m, "error", state->StructError) < 0) {
        2567                 :          0 :         return -1;
        2568                 :            :     }
        2569                 :            :
        2570                 :          3 :     return 0;
        2571                 :            : }
        2572                 :            :
        2573                 :            : static PyModuleDef_Slot _structmodule_slots[] = {
        2574                 :            :     {Py_mod_exec, _structmodule_exec},
        2575                 :            :     {0, NULL}
        2576                 :            : };
        2577                 :            :
        2578                 :            : static struct PyModuleDef _structmodule = {
        2579                 :            :     PyModuleDef_HEAD_INIT,
        2580                 :            :     .m_name = "_struct",
        2581                 :            :     .m_doc = module_doc,
        2582                 :            :     .m_size = sizeof(_structmodulestate),
        2583                 :            :     .m_methods = module_functions,
        2584                 :            :     .m_slots = _structmodule_slots,
        2585                 :            :     .m_traverse = _structmodule_traverse,
        2586                 :            :     .m_clear = _structmodule_clear,
        2587                 :            :     .m_free = _structmodule_free,
        2588                 :            : };
        2589                 :            :
        2590                 :            : PyMODINIT_FUNC
        2591                 :          3 : PyInit__struct(void)
        2592                 :            : {
        2593                 :          3 :     return PyModuleDef_Init(&_structmodule);
        2594                 :            : }

Generated by: LCOV version 1.14