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