/* struct module -- pack values into and (out of) bytes objects */

/* New version supporting byte order, alignment and size options,
   character strings, and unsigned numbers */

#ifndef Py_BUILD_CORE_BUILTIN
#  define Py_BUILD_CORE_MODULE 1
#endif

#include "Python.h"
#include "pycore_bytesobject.h"   // _PyBytesWriter
#include "pycore_lock.h"          // _PyOnceFlag_CallOnce()
#include "pycore_long.h"          // _PyLong_AsByteArray()
#include "pycore_moduleobject.h"  // _PyModule_GetState()
#include "pycore_weakref.h"       // FT_CLEAR_WEAKREFS()

#include <stddef.h>               // offsetof()

/*[clinic input]
class Struct "PyStructObject *" "&PyStructType"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b032058a83ed7c3]*/

typedef struct {
    PyObject *cache;
    PyObject *PyStructType;
    PyObject *unpackiter_type;
    PyObject *StructError;
} _structmodulestate;

static inline _structmodulestate*
get_struct_state(PyObject *module)
{
    void *state = _PyModule_GetState(module);
    assert(state != NULL);
    return (_structmodulestate *)state;
}

static struct PyModuleDef _structmodule;

#define get_struct_state_structinst(self) \
    (get_struct_state(PyType_GetModuleByDef(Py_TYPE(self), &_structmodule)))
#define get_struct_state_iterinst(self) \
    (get_struct_state(PyType_GetModule(Py_TYPE(self))))

/* The translation function for each format character is table driven */
typedef struct _formatdef {
    char format;
    Py_ssize_t size;
    Py_ssize_t alignment;
    PyObject* (*unpack)(_structmodulestate *, const char *,
                        const struct _formatdef *);
    int (*pack)(_structmodulestate *, char *, PyObject *,
                const struct _formatdef *);
} formatdef;

typedef struct _formatcode {
    const struct _formatdef *fmtdef;
    Py_ssize_t offset;
    Py_ssize_t size;
    Py_ssize_t repeat;
} formatcode;

/* Struct object interface */

typedef struct {
    PyObject_HEAD
    Py_ssize_t s_size;
    Py_ssize_t s_len;
    formatcode *s_codes;
    PyObject *s_format;
    PyObject *weakreflist; /* List of weak references */
    bool init_called;
} PyStructObject;

#define PyStructObject_CAST(op)     ((PyStructObject *)(op))
#define PyStruct_Check(op, state)   PyObject_TypeCheck(op, (PyTypeObject *)(state)->PyStructType)

#ifdef __powerc
#pragma options align=reset
#endif

/*[python input]
class cache_struct_converter(CConverter):
    type = 'PyStructObject *'
    converter = 'cache_struct_converter'
    c_default = "NULL"
    broken_limited_capi = True

    def parse_arg(self, argname, displayname, *, limited_capi):
        assert not limited_capi
        return self.format_code("""
            if (!{converter}(module, {argname}, &{paramname})) {{{{
                goto exit;
            }}}}
            """,
            argname=argname,
            converter=self.converter)

    def cleanup(self):
        return "Py_XDECREF(%s);\n" % self.name
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=c33b27d6b06006c6]*/

static int cache_struct_converter(PyObject *, PyObject *, PyStructObject **);

#include "clinic/_struct.c.h"

/* Helper for integer format codes: converts an arbitrary Python object to a
   PyLongObject if possible, otherwise fails.  Caller should decref. */

static PyObject *
get_pylong(_structmodulestate *state, PyObject *v)
{
    assert(v != NULL);
    if (!PyLong_Check(v)) {
        /* Not an integer;  try to use __index__ to convert. */
        if (PyIndex_Check(v)) {
            v = _PyNumber_Index(v);
            if (v == NULL)
                return NULL;
        }
        else {
            PyErr_SetString(state->StructError,
                            "required argument is not an integer");
            return NULL;
        }
    }
    else
        Py_INCREF(v);

    assert(PyLong_Check(v));
    return v;
}

/* Helper routine to get a C long and raise the appropriate error if it isn't
   one */

static int
get_long(_structmodulestate *state, PyObject *v, long *p)
{
    long x;

    v = get_pylong(state, v);
    if (v == NULL)
        return -1;
    assert(PyLong_Check(v));
    x = PyLong_AsLong(v);
    Py_DECREF(v);
    if (x == (long)-1 && PyErr_Occurred()) {
        return -1;
    }
    *p = x;
    return 0;
}


/* Same, but handling unsigned long */

static int
get_ulong(_structmodulestate *state, PyObject *v, unsigned long *p)
{
    unsigned long x;

    v = get_pylong(state, v);
    if (v == NULL)
        return -1;
    assert(PyLong_Check(v));
    x = PyLong_AsUnsignedLong(v);
    Py_DECREF(v);
    if (x == (unsigned long)-1 && PyErr_Occurred()) {
        return -1;
    }
    *p = x;
    return 0;
}

/* Same, but handling native long long. */

static int
get_longlong(_structmodulestate *state, PyObject *v, long long *p)
{
    long long x;

    v = get_pylong(state, v);
    if (v == NULL)
        return -1;
    assert(PyLong_Check(v));
    x = PyLong_AsLongLong(v);
    Py_DECREF(v);
    if (x == (long long)-1 && PyErr_Occurred()) {
        return -1;
    }
    *p = x;
    return 0;
}

/* Same, but handling native unsigned long long. */

static int
get_ulonglong(_structmodulestate *state, PyObject *v, unsigned long long *p)
{
    unsigned long long x;

    v = get_pylong(state, v);
    if (v == NULL)
        return -1;
    assert(PyLong_Check(v));
    x = PyLong_AsUnsignedLongLong(v);
    Py_DECREF(v);
    if (x == (unsigned long long)-1 && PyErr_Occurred()) {
        return -1;
    }
    *p = x;
    return 0;
}

/* Same, but handling Py_ssize_t */

static int
get_ssize_t(_structmodulestate *state, PyObject *v, Py_ssize_t *p)
{
    Py_ssize_t x;

    v = get_pylong(state, v);
    if (v == NULL)
        return -1;
    assert(PyLong_Check(v));
    x = PyLong_AsSsize_t(v);
    Py_DECREF(v);
    if (x == (Py_ssize_t)-1 && PyErr_Occurred()) {
        return -1;
    }
    *p = x;
    return 0;
}

/* Same, but handling size_t */

static int
get_size_t(_structmodulestate *state, PyObject *v, size_t *p)
{
    size_t x;

    v = get_pylong(state, v);
    if (v == NULL)
        return -1;
    assert(PyLong_Check(v));
    x = PyLong_AsSize_t(v);
    Py_DECREF(v);
    if (x == (size_t)-1 && PyErr_Occurred()) {
        return -1;
    }
    *p = x;
    return 0;
}


#define RANGE_ERROR(state, f, flag) return _range_error(state, f, flag)


/* Floating-point helpers */

static PyObject *
unpack_halffloat(const char *p,  /* start of 2-byte string */
                 int le)         /* true for little-endian, false for big-endian */
{
    double x = PyFloat_Unpack2(p, le);
    if (x == -1.0 && PyErr_Occurred()) {
        return NULL;
    }
    return PyFloat_FromDouble(x);
}

static int
pack_halffloat(_structmodulestate *state,
               char *p,      /* start of 2-byte string */
               PyObject *v,  /* value to pack */
               int le)       /* true for little-endian, false for big-endian */
{
    double x = PyFloat_AsDouble(v);
    if (x == -1.0 && PyErr_Occurred()) {
        PyErr_SetString(state->StructError,
                        "required argument is not a float");
        return -1;
    }
    return PyFloat_Pack2(x, p, le);
}

static PyObject *
unpack_float(const char *p,  /* start of 4-byte string */
         int le)             /* true for little-endian, false for big-endian */
{
    double x;

    x = PyFloat_Unpack4(p, le);
    if (x == -1.0 && PyErr_Occurred())
        return NULL;
    return PyFloat_FromDouble(x);
}

static PyObject *
unpack_double(const char *p,  /* start of 8-byte string */
          int le)         /* true for little-endian, false for big-endian */
{
    double x;

    x = PyFloat_Unpack8(p, le);
    if (x == -1.0 && PyErr_Occurred())
        return NULL;
    return PyFloat_FromDouble(x);
}

/* Helper to format the range error exceptions */
static int
_range_error(_structmodulestate *state, const formatdef *f, int is_unsigned)
{
    /* ulargest is the largest unsigned value with f->size bytes.
     * Note that the simpler:
     *     ((size_t)1 << (f->size * 8)) - 1
     * doesn't work when f->size == sizeof(size_t) because C doesn't
     * define what happens when a left shift count is >= the number of
     * bits in the integer being shifted; e.g., on some boxes it doesn't
     * shift at all when they're equal.
     */
    const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
    assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
    if (is_unsigned)
        PyErr_Format(state->StructError,
            "'%c' format requires 0 <= number <= %zu",
            f->format,
            ulargest);
    else {
        const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
        PyErr_Format(state->StructError,
            "'%c' format requires %zd <= number <= %zd",
            f->format,
            ~ largest,
            largest);
    }

    return -1;
}



/* A large number of small routines follow, with names of the form

   [bln][up]_TYPE

   [bln] distinguishes among big-endian, little-endian and native.
   [pu] distinguishes between pack (to struct) and unpack (from struct).
   TYPE is one of char, byte, ubyte, etc.
*/

/* Native mode routines. ****************************************************/
/* NOTE:
   In all n[up]_<type> routines handling types larger than 1 byte, there is
   *no* guarantee that the p pointer is properly aligned for each type,
   therefore memcpy is called.  An intermediate variable is used to
   compensate for big-endian architectures.
   Normally both the intermediate variable and the memcpy call will be
   skipped by C optimisation in little-endian architectures (gcc >= 2.91
   does this). */

static PyObject *
nu_char(_structmodulestate *state, const char *p, const formatdef *f)
{
    return PyBytes_FromStringAndSize(p, 1);
}

static PyObject *
nu_byte(_structmodulestate *state, const char *p, const formatdef *f)
{
    return PyLong_FromLong((long) *(signed char *)p);
}

static PyObject *
nu_ubyte(_structmodulestate *state, const char *p, const formatdef *f)
{
    return PyLong_FromLong((long) *(unsigned char *)p);
}

static PyObject *
nu_short(_structmodulestate *state, const char *p, const formatdef *f)
{
    short x;
    memcpy(&x, p, sizeof x);
    return PyLong_FromLong((long)x);
}

static PyObject *
nu_ushort(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned short x;
    memcpy(&x, p, sizeof x);
    return PyLong_FromLong((long)x);
}

static PyObject *
nu_int(_structmodulestate *state, const char *p, const formatdef *f)
{
    int x;
    memcpy(&x, p, sizeof x);
    return PyLong_FromLong((long)x);
}

static PyObject *
nu_uint(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned int x;
    memcpy(&x, p, sizeof x);
    return PyLong_FromUnsignedLong((unsigned long)x);
}

static PyObject *
nu_long(_structmodulestate *state, const char *p, const formatdef *f)
{
    long x;
    memcpy(&x, p, sizeof x);
    return PyLong_FromLong(x);
}

static PyObject *
nu_ulong(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned long x;
    memcpy(&x, p, sizeof x);
    return PyLong_FromUnsignedLong(x);
}

static PyObject *
nu_ssize_t(_structmodulestate *state, const char *p, const formatdef *f)
{
    Py_ssize_t x;
    memcpy(&x, p, sizeof x);
    return PyLong_FromSsize_t(x);
}

static PyObject *
nu_size_t(_structmodulestate *state, const char *p, const formatdef *f)
{
    size_t x;
    memcpy(&x, p, sizeof x);
    return PyLong_FromSize_t(x);
}

static PyObject *
nu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
{
    long long x;
    memcpy(&x, p, sizeof x);
    return PyLong_FromLongLong(x);
}

static PyObject *
nu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned long long x;
    memcpy(&x, p, sizeof x);
    return PyLong_FromUnsignedLongLong(x);
}

static PyObject *
nu_bool(_structmodulestate *state, const char *p, const formatdef *f)
{
    const _Bool bool_false = 0;
    return PyBool_FromLong(memcmp(p, &bool_false, sizeof(_Bool)));
}


static PyObject *
nu_halffloat(_structmodulestate *state, const char *p, const formatdef *f)
{
#if PY_LITTLE_ENDIAN
    return unpack_halffloat(p, 1);
#else
    return unpack_halffloat(p, 0);
#endif
}

static PyObject *
nu_float(_structmodulestate *state, const char *p, const formatdef *f)
{
    float x;
    memcpy(&x, p, sizeof x);
    return PyFloat_FromDouble((double)x);
}

static PyObject *
nu_double(_structmodulestate *state, const char *p, const formatdef *f)
{
    double x;
    memcpy(&x, p, sizeof x);
    return PyFloat_FromDouble(x);
}

static PyObject *
nu_float_complex(_structmodulestate *state, const char *p, const formatdef *f)
{
    float x[2];

    memcpy(&x, p, sizeof(x));
    return PyComplex_FromDoubles(x[0], x[1]);
}

static PyObject *
nu_double_complex(_structmodulestate *state, const char *p, const formatdef *f)
{
    double x[2];

    memcpy(&x, p, sizeof(x));
    return PyComplex_FromDoubles(x[0], x[1]);
}

static PyObject *
nu_void_p(_structmodulestate *state, const char *p, const formatdef *f)
{
    void *x;
    memcpy(&x, p, sizeof x);
    return PyLong_FromVoidPtr(x);
}

static int
np_byte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    long x;
    if (get_long(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 0);
        }
        return -1;
    }
    if (x < -128 || x > 127) {
        RANGE_ERROR(state, f, 0);
    }
    *p = (char)x;
    return 0;
}

static int
np_ubyte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    long x;
    if (get_long(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 1);
        }
        return -1;
    }
    if (x < 0 || x > 255) {
        RANGE_ERROR(state, f, 1);
    }
    *(unsigned char *)p = (unsigned char)x;
    return 0;
}

static int
np_char(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) {
        PyErr_SetString(state->StructError,
                        "char format requires a bytes object of length 1");
        return -1;
    }
    *p = *PyBytes_AS_STRING(v);
    return 0;
}

static int
np_short(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    long x;
    short y;
    if (get_long(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 0);
        }
        return -1;
    }
    if (x < SHRT_MIN || x > SHRT_MAX) {
        RANGE_ERROR(state, f, 0);
    }
    y = (short)x;
    memcpy(p, &y, sizeof y);
    return 0;
}

static int
np_ushort(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    long x;
    unsigned short y;
    if (get_long(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 1);
        }
        return -1;
    }
    if (x < 0 || x > USHRT_MAX) {
        RANGE_ERROR(state, f, 1);
    }
    y = (unsigned short)x;
    memcpy(p, &y, sizeof y);
    return 0;
}

static int
np_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    long x;
    int y;
    if (get_long(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 0);
        }
        return -1;
    }
#if (SIZEOF_LONG > SIZEOF_INT)
    if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
        RANGE_ERROR(state, f, 0);
#endif
    y = (int)x;
    memcpy(p, &y, sizeof y);
    return 0;
}

static int
np_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    unsigned long x;
    unsigned int y;
    if (get_ulong(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 1);
        }
        return -1;
    }
    y = (unsigned int)x;
#if (SIZEOF_LONG > SIZEOF_INT)
    if (x > ((unsigned long)UINT_MAX))
        RANGE_ERROR(state, f, 1);
#endif
    memcpy(p, &y, sizeof y);
    return 0;
}

static int
np_long(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    long x;
    if (get_long(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 0);
        }
        return -1;
    }
    memcpy(p, &x, sizeof x);
    return 0;
}

static int
np_ulong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    unsigned long x;
    if (get_ulong(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 1);
        }
        return -1;
    }
    memcpy(p, &x, sizeof x);
    return 0;
}

static int
np_ssize_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    Py_ssize_t x;
    if (get_ssize_t(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 0);
        }
        return -1;
    }
    memcpy(p, &x, sizeof x);
    return 0;
}

static int
np_size_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    size_t x;
    if (get_size_t(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 1);
        }
        return -1;
    }
    memcpy(p, &x, sizeof x);
    return 0;
}

static int
np_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    long long x;
    if (get_longlong(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            PyErr_Format(state->StructError,
                         "'%c' format requires %lld <= number <= %lld",
                         f->format,
                         LLONG_MIN,
                         LLONG_MAX);
        }
        return -1;
    }
    memcpy(p, &x, sizeof x);
    return 0;
}

static int
np_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    unsigned long long x;
    if (get_ulonglong(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            PyErr_Format(state->StructError,
                         "'%c' format requires 0 <= number <= %llu",
                         f->format,
                         ULLONG_MAX);
        }
        return -1;
    }
    memcpy(p, &x, sizeof x);
    return 0;
}


static int
np_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    int y;
    _Bool x;
    y = PyObject_IsTrue(v);
    if (y < 0)
        return -1;
    x = y;
    memcpy(p, &x, sizeof x);
    return 0;
}

static int
np_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
#if PY_LITTLE_ENDIAN
    return pack_halffloat(state, p, v, 1);
#else
    return pack_halffloat(state, p, v, 0);
#endif
}

static int
np_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    double x = PyFloat_AsDouble(v);
    if (x == -1 && PyErr_Occurred()) {
        PyErr_SetString(state->StructError,
                        "required argument is not a float");
        return -1;
    }
    return PyFloat_Pack4(x, p, PY_LITTLE_ENDIAN);
}

static int
np_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    double x = PyFloat_AsDouble(v);
    if (x == -1 && PyErr_Occurred()) {
        PyErr_SetString(state->StructError,
                        "required argument is not a float");
        return -1;
    }
    memcpy(p, &x, sizeof(double));
    return 0;
}

static int
np_float_complex(_structmodulestate *state, char *p, PyObject *v,
                 const formatdef *f)
{
    Py_complex c = PyComplex_AsCComplex(v);
    float x[2] = {(float)c.real, (float)c.imag};

    if (c.real == -1 && PyErr_Occurred()) {
        PyErr_SetString(state->StructError,
                        "required argument is not a complex");
        return -1;
    }
    memcpy(p, &x, sizeof(x));
    return 0;
}

static int
np_double_complex(_structmodulestate *state, char *p, PyObject *v,
                  const formatdef *f)
{
    Py_complex c = PyComplex_AsCComplex(v);
    double x[2] = {c.real, c.imag};

    if (c.real == -1 && PyErr_Occurred()) {
        PyErr_SetString(state->StructError,
                        "required argument is not a complex");
        return -1;
    }
    memcpy(p, &x, sizeof(x));
    return 0;
}

static int
np_void_p(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    void *x;

    v = get_pylong(state, v);
    if (v == NULL)
        return -1;
    assert(PyLong_Check(v));
    x = PyLong_AsVoidPtr(v);
    Py_DECREF(v);
    if (x == NULL && PyErr_Occurred())
        return -1;
    memcpy(p, &x, sizeof x);
    return 0;
}

static const formatdef native_table[] = {
    {'x',       sizeof(char),   0,              NULL},
    {'b',       sizeof(char),   0,              nu_byte,        np_byte},
    {'B',       sizeof(char),   0,              nu_ubyte,       np_ubyte},
    {'c',       sizeof(char),   0,              nu_char,        np_char},
    {'s',       sizeof(char),   0,              NULL},
    {'p',       sizeof(char),   0,              NULL},
    {'h',       sizeof(short),  _Alignof(short),    nu_short,       np_short},
    {'H',       sizeof(short),  _Alignof(short),    nu_ushort,      np_ushort},
    {'i',       sizeof(int),    _Alignof(int),      nu_int,         np_int},
    {'I',       sizeof(int),    _Alignof(int),      nu_uint,        np_uint},
    {'l',       sizeof(long),   _Alignof(long),     nu_long,        np_long},
    {'L',       sizeof(long),   _Alignof(long),     nu_ulong,       np_ulong},
    {'n',       sizeof(size_t), _Alignof(size_t),   nu_ssize_t,     np_ssize_t},
    {'N',       sizeof(size_t), _Alignof(size_t),   nu_size_t,      np_size_t},
    {'q',       sizeof(long long), _Alignof(long long), nu_longlong, np_longlong},
    {'Q',       sizeof(long long), _Alignof(long long), nu_ulonglong,np_ulonglong},
    {'?',       sizeof(_Bool),      _Alignof(_Bool),     nu_bool,        np_bool},
    {'e',       sizeof(short),  _Alignof(short),    nu_halffloat,   np_halffloat},
    {'f',       sizeof(float),  _Alignof(float),    nu_float,       np_float},
    {'d',       sizeof(double), _Alignof(double),   nu_double,      np_double},
    {'F',       2*sizeof(float), _Alignof(float), nu_float_complex, np_float_complex},
    {'D',       2*sizeof(double), _Alignof(double), nu_double_complex, np_double_complex},
    {'P',       sizeof(void *), _Alignof(void *),   nu_void_p,      np_void_p},
    {0}
};

/* Big-endian routines. *****************************************************/

static PyObject *
bu_short(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned long x = 0;

    /* This function is only ever used in the case f->size == 2. */
    assert(f->size == 2);
    Py_ssize_t i = 2;
    const unsigned char *bytes = (const unsigned char *)p;
    do {
        x = (x<<8) | *bytes++;
    } while (--i > 0);
    /* Extend sign, avoiding implementation-defined or undefined behaviour. */
    x = (x ^ 0x8000U) - 0x8000U;
    return PyLong_FromLong(x & 0x8000U ? -1 - (long)(~x) : (long)x);
}

static PyObject *
bu_int(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned long x = 0;

    /* This function is only ever used in the case f->size == 4. */
    assert(f->size == 4);
    Py_ssize_t i = 4;
    const unsigned char *bytes = (const unsigned char *)p;
    do {
        x = (x<<8) | *bytes++;
    } while (--i > 0);
    /* Extend sign, avoiding implementation-defined or undefined behaviour. */
    x = (x ^ 0x80000000U) - 0x80000000U;
    return PyLong_FromLong(x & 0x80000000U ? -1 - (long)(~x) : (long)x);
}

static PyObject *
bu_uint(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned long x = 0;
    Py_ssize_t i = f->size;
    const unsigned char *bytes = (const unsigned char *)p;
    do {
        x = (x<<8) | *bytes++;
    } while (--i > 0);
    return PyLong_FromUnsignedLong(x);
}

static PyObject *
bu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned long long x = 0;

    /* This function is only ever used in the case f->size == 8. */
    assert(f->size == 8);
    Py_ssize_t i = 8;
    const unsigned char *bytes = (const unsigned char *)p;
    do {
        x = (x<<8) | *bytes++;
    } while (--i > 0);
    /* Extend sign, avoiding implementation-defined or undefined behaviour. */
    x = (x ^ 0x8000000000000000U) - 0x8000000000000000U;
    return PyLong_FromLongLong(
        x & 0x8000000000000000U ? -1 - (long long)(~x) : (long long)x);
}

static PyObject *
bu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned long long x = 0;
    Py_ssize_t i = f->size;
    const unsigned char *bytes = (const unsigned char *)p;
    do {
        x = (x<<8) | *bytes++;
    } while (--i > 0);
    return PyLong_FromUnsignedLongLong(x);
}

static PyObject *
bu_halffloat(_structmodulestate *state, const char *p, const formatdef *f)
{
    return unpack_halffloat(p, 0);
}

static PyObject *
bu_float(_structmodulestate *state, const char *p, const formatdef *f)
{
    return unpack_float(p, 0);
}

static PyObject *
bu_double(_structmodulestate *state, const char *p, const formatdef *f)
{
    return unpack_double(p, 0);
}

static PyObject *
bu_float_complex(_structmodulestate *state, const char *p, const formatdef *f)
{
    double x = PyFloat_Unpack4(p, 0);
    if (x == -1.0 && PyErr_Occurred()) {
        return NULL;
    }
    double y = PyFloat_Unpack4(p + 4, 0);
    if (y == -1.0 && PyErr_Occurred()) {
        return NULL;
    }
    return PyComplex_FromDoubles(x, y);
}

static PyObject *
bu_double_complex(_structmodulestate *state, const char *p, const formatdef *f)
{
    double x, y;

    x = PyFloat_Unpack8(p, 0);
    if (x == -1.0 && PyErr_Occurred()) {
        return NULL;
    }
    y = PyFloat_Unpack8(p + 8, 0);
    if (y == -1.0 && PyErr_Occurred()) {
        return NULL;
    }
    return PyComplex_FromDoubles(x, y);
}

static PyObject *
bu_bool(_structmodulestate *state, const char *p, const formatdef *f)
{
    return PyBool_FromLong(*p != 0);
}

static int
bp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    long x;
    Py_ssize_t i;
    unsigned char *q = (unsigned char *)p;
    if (get_long(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 0);
        }
        return -1;
    }
    i = f->size;
    if (i != SIZEOF_LONG) {
        if ((i == 2) && (x < -32768 || x > 32767))
            RANGE_ERROR(state, f, 0);
#if (SIZEOF_LONG != 4)
        else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
            RANGE_ERROR(state, f, 0);
#endif
    }
    do {
        q[--i] = (unsigned char)(x & 0xffL);
        x >>= 8;
    } while (i > 0);
    return 0;
}

static int
bp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    unsigned long x;
    Py_ssize_t i;
    unsigned char *q = (unsigned char *)p;
    if (get_ulong(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 1);
        }
        return -1;
    }
    i = f->size;
    if (i != SIZEOF_LONG) {
        unsigned long maxint = 1;
        maxint <<= (unsigned long)(i * 8);
        if (x >= maxint)
            RANGE_ERROR(state, f, 1);
    }
    do {
        q[--i] = (unsigned char)(x & 0xffUL);
        x >>= 8;
    } while (i > 0);
    return 0;
}

static int
bp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    int res;
    v = get_pylong(state, v);
    if (v == NULL)
        return -1;
    res = _PyLong_AsByteArray((PyLongObject *)v,
                              (unsigned char *)p,
                              8,
                              0, /* little_endian */
                              1, /* signed */
                              0  /* !with_exceptions */);
    Py_DECREF(v);
    if (res < 0) {
        PyErr_Format(state->StructError,
                     "'%c' format requires %lld <= number <= %lld",
                     f->format,
                     LLONG_MIN,
                     LLONG_MAX);
        return -1;
    }
    return res;
}

static int
bp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    int res;
    v = get_pylong(state, v);
    if (v == NULL)
        return -1;
    res = _PyLong_AsByteArray((PyLongObject *)v,
                              (unsigned char *)p,
                              8,
                              0, /* little_endian */
                              0, /* signed */
                              0  /* !with_exceptions */);
    Py_DECREF(v);
    if (res < 0) {
        PyErr_Format(state->StructError,
                     "'%c' format requires 0 <= number <= %llu",
                     f->format,
                     ULLONG_MAX);
        return -1;
    }
    return res;
}

static int
bp_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    return pack_halffloat(state, p, v, 0);
}

static int
bp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    double x = PyFloat_AsDouble(v);
    if (x == -1 && PyErr_Occurred()) {
        PyErr_SetString(state->StructError,
                        "required argument is not a float");
        return -1;
    }
    return PyFloat_Pack4(x, p, 0);
}

static int
bp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    double x = PyFloat_AsDouble(v);
    if (x == -1 && PyErr_Occurred()) {
        PyErr_SetString(state->StructError,
                        "required argument is not a float");
        return -1;
    }
    return PyFloat_Pack8(x, p, 0);
}

static int
bp_float_complex(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    Py_complex x = PyComplex_AsCComplex(v);
    if (x.real == -1 && PyErr_Occurred()) {
        PyErr_SetString(state->StructError,
                        "required argument is not a complex");
        return -1;
    }
    if (PyFloat_Pack4(x.real, p, 0)) {
        return -1;
    }
    return PyFloat_Pack4(x.imag, p + 4, 0);
}

static int
bp_double_complex(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    Py_complex x = PyComplex_AsCComplex(v);
    if (x.real == -1 && PyErr_Occurred()) {
        PyErr_SetString(state->StructError,
                        "required argument is not a complex");
        return -1;
    }
    if (PyFloat_Pack8(x.real, p, 0)) {
        return -1;
    }
    return PyFloat_Pack8(x.imag, p + 8, 0);
}

static int
bp_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    int y;
    y = PyObject_IsTrue(v);
    if (y < 0)
        return -1;
    *p = (char)y;
    return 0;
}

static formatdef bigendian_table[] = {
    {'x',       1,              0,              NULL},
    {'b',       1,              0,              nu_byte,        np_byte},
    {'B',       1,              0,              nu_ubyte,       np_ubyte},
    {'c',       1,              0,              nu_char,        np_char},
    {'s',       1,              0,              NULL},
    {'p',       1,              0,              NULL},
    {'h',       2,              0,              bu_short,       bp_int},
    {'H',       2,              0,              bu_uint,        bp_uint},
    {'i',       4,              0,              bu_int,         bp_int},
    {'I',       4,              0,              bu_uint,        bp_uint},
    {'l',       4,              0,              bu_int,         bp_int},
    {'L',       4,              0,              bu_uint,        bp_uint},
    {'q',       8,              0,              bu_longlong,    bp_longlong},
    {'Q',       8,              0,              bu_ulonglong,   bp_ulonglong},
    {'?',       1,              0,              bu_bool,        bp_bool},
    {'e',       2,              0,              bu_halffloat,   bp_halffloat},
    {'f',       4,              0,              bu_float,       bp_float},
    {'d',       8,              0,              bu_double,      bp_double},
    {'F',       8,              0,              bu_float_complex, bp_float_complex},
    {'D',       16,             0,              bu_double_complex, bp_double_complex},
    {0}
};

/* Little-endian routines. *****************************************************/

static PyObject *
lu_short(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned long x = 0;

    /* This function is only ever used in the case f->size == 2. */
    assert(f->size == 2);
    Py_ssize_t i = 2;
    const unsigned char *bytes = (const unsigned char *)p;
    do {
        x = (x<<8) | bytes[--i];
    } while (i > 0);
    /* Extend sign, avoiding implementation-defined or undefined behaviour. */
    x = (x ^ 0x8000U) - 0x8000U;
    return PyLong_FromLong(x & 0x8000U ? -1 - (long)(~x) : (long)x);
}

static PyObject *
lu_int(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned long x = 0;

    /* This function is only ever used in the case f->size == 4. */
    assert(f->size == 4);
    Py_ssize_t i = 4;
    const unsigned char *bytes = (const unsigned char *)p;
    do {
        x = (x<<8) | bytes[--i];
    } while (i > 0);
    /* Extend sign, avoiding implementation-defined or undefined behaviour. */
    x = (x ^ 0x80000000U) - 0x80000000U;
    return PyLong_FromLong(x & 0x80000000U ? -1 - (long)(~x) : (long)x);
}

static PyObject *
lu_uint(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned long x = 0;
    Py_ssize_t i = f->size;
    const unsigned char *bytes = (const unsigned char *)p;
    do {
        x = (x<<8) | bytes[--i];
    } while (i > 0);
    return PyLong_FromUnsignedLong(x);
}

static PyObject *
lu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned long long x = 0;

    /* This function is only ever used in the case f->size == 8. */
    assert(f->size == 8);
    Py_ssize_t i = 8;
    const unsigned char *bytes = (const unsigned char *)p;
    do {
        x = (x<<8) | bytes[--i];
    } while (i > 0);
    /* Extend sign, avoiding implementation-defined or undefined behaviour. */
    x = (x ^ 0x8000000000000000U) - 0x8000000000000000U;
    return PyLong_FromLongLong(
        x & 0x8000000000000000U ? -1 - (long long)(~x) : (long long)x);
}

static PyObject *
lu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
{
    unsigned long long x = 0;
    Py_ssize_t i = f->size;
    const unsigned char *bytes = (const unsigned char *)p;
    do {
        x = (x<<8) | bytes[--i];
    } while (i > 0);
    return PyLong_FromUnsignedLongLong(x);
}

static PyObject *
lu_halffloat(_structmodulestate *state, const char *p, const formatdef *f)
{
    return unpack_halffloat(p, 1);
}

static PyObject *
lu_float(_structmodulestate *state, const char *p, const formatdef *f)
{
    return unpack_float(p, 1);
}

static PyObject *
lu_double(_structmodulestate *state, const char *p, const formatdef *f)
{
    return unpack_double(p, 1);
}

static PyObject *
lu_float_complex(_structmodulestate *state, const char *p, const formatdef *f)
{
    double x = PyFloat_Unpack4(p, 1);
    if (x == -1.0 && PyErr_Occurred()) {
        return NULL;
    }
    double y = PyFloat_Unpack4(p + 4, 1);
    if (y == -1.0 && PyErr_Occurred()) {
        return NULL;
    }
    return PyComplex_FromDoubles(x, y);
}

static PyObject *
lu_double_complex(_structmodulestate *state, const char *p, const formatdef *f)
{
    double x, y;

    x = PyFloat_Unpack8(p, 1);
    if (x == -1.0 && PyErr_Occurred()) {
        return NULL;
    }
    y = PyFloat_Unpack8(p + 8, 1);
    if (y == -1.0 && PyErr_Occurred()) {
        return NULL;
    }
    return PyComplex_FromDoubles(x, y);
}

static int
lp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    long x;
    Py_ssize_t i;
    unsigned char *q = (unsigned char *)p;
    if (get_long(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 0);
        }
        return -1;
    }
    i = f->size;
    if (i != SIZEOF_LONG) {
        if ((i == 2) && (x < -32768 || x > 32767))
            RANGE_ERROR(state, f, 0);
#if (SIZEOF_LONG != 4)
        else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
            RANGE_ERROR(state, f, 0);
#endif
    }
    do {
        *q++ = (unsigned char)(x & 0xffL);
        x >>= 8;
    } while (--i > 0);
    return 0;
}

static int
lp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    unsigned long x;
    Py_ssize_t i;
    unsigned char *q = (unsigned char *)p;
    if (get_ulong(state, v, &x) < 0) {
        if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
            RANGE_ERROR(state, f, 1);
        }
        return -1;
    }
    i = f->size;
    if (i != SIZEOF_LONG) {
        unsigned long maxint = 1;
        maxint <<= (unsigned long)(i * 8);
        if (x >= maxint)
            RANGE_ERROR(state, f, 1);
    }
    do {
        *q++ = (unsigned char)(x & 0xffUL);
        x >>= 8;
    } while (--i > 0);
    return 0;
}

static int
lp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    int res;
    v = get_pylong(state, v);
    if (v == NULL)
        return -1;
    res = _PyLong_AsByteArray((PyLongObject*)v,
                              (unsigned char *)p,
                              8,
                              1, /* little_endian */
                              1, /* signed */
                              0  /* !with_exceptions */);
    Py_DECREF(v);
    if (res < 0) {
        PyErr_Format(state->StructError,
                     "'%c' format requires %lld <= number <= %lld",
                     f->format,
                     LLONG_MIN,
                     LLONG_MAX);
        return -1;
    }
    return res;
}

static int
lp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    int res;
    v = get_pylong(state, v);
    if (v == NULL)
        return -1;
    res = _PyLong_AsByteArray((PyLongObject*)v,
                              (unsigned char *)p,
                              8,
                              1, /* little_endian */
                              0, /* signed */
                              0  /* !with_exceptions */);
    Py_DECREF(v);
    if (res < 0) {
        PyErr_Format(state->StructError,
                     "'%c' format requires 0 <= number <= %llu",
                     f->format,
                     ULLONG_MAX);
        return -1;
    }
    return res;
}

static int
lp_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    return pack_halffloat(state, p, v, 1);
}

static int
lp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    double x = PyFloat_AsDouble(v);
    if (x == -1 && PyErr_Occurred()) {
        PyErr_SetString(state->StructError,
                        "required argument is not a float");
        return -1;
    }
    return PyFloat_Pack4(x, p, 1);
}

static int
lp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    double x = PyFloat_AsDouble(v);
    if (x == -1 && PyErr_Occurred()) {
        PyErr_SetString(state->StructError,
                        "required argument is not a float");
        return -1;
    }
    return PyFloat_Pack8(x, p, 1);
}

static int
lp_float_complex(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    Py_complex x = PyComplex_AsCComplex(v);
    if (x.real == -1 && PyErr_Occurred()) {
        PyErr_SetString(state->StructError,
                        "required argument is not a complex");
        return -1;
    }
    if (PyFloat_Pack4(x.real, p, 1)) {
        return -1;
    }
    return PyFloat_Pack4(x.imag, p + 4, 1);

}

static int
lp_double_complex(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
{
    Py_complex x = PyComplex_AsCComplex(v);
    if (x.real == -1 && PyErr_Occurred()) {
        PyErr_SetString(state->StructError,
                        "required argument is not a complex");
        return -1;
    }
    if (PyFloat_Pack8(x.real, p, 1)) {
        return -1;
    }
    return PyFloat_Pack8(x.imag, p + 8, 1);
}

static formatdef lilendian_table[] = {
    {'x',       1,              0,              NULL},
    {'b',       1,              0,              nu_byte,        np_byte},
    {'B',       1,              0,              nu_ubyte,       np_ubyte},
    {'c',       1,              0,              nu_char,        np_char},
    {'s',       1,              0,              NULL},
    {'p',       1,              0,              NULL},
    {'h',       2,              0,              lu_short,       lp_int},
    {'H',       2,              0,              lu_uint,        lp_uint},
    {'i',       4,              0,              lu_int,         lp_int},
    {'I',       4,              0,              lu_uint,        lp_uint},
    {'l',       4,              0,              lu_int,         lp_int},
    {'L',       4,              0,              lu_uint,        lp_uint},
    {'q',       8,              0,              lu_longlong,    lp_longlong},
    {'Q',       8,              0,              lu_ulonglong,   lp_ulonglong},
    {'?',       1,              0,              bu_bool,        bp_bool}, /* Std rep not endian dep,
        but potentially different from native rep -- reuse bx_bool funcs. */
    {'e',       2,              0,              lu_halffloat,   lp_halffloat},
    {'f',       4,              0,              lu_float,       lp_float},
    {'d',       8,              0,              lu_double,      lp_double},
    {'F',       8,              0,              lu_float_complex, lp_float_complex},
    {'D',       16,             0,              lu_double_complex, lp_double_complex},
    {0}
};

/* Ensure endian table optimization happens exactly once across all interpreters */
static _PyOnceFlag endian_tables_init_once = {0};

static int
init_endian_tables(void *Py_UNUSED(arg))
{
    const formatdef *native = native_table;
    formatdef *other, *ptr;
#if PY_LITTLE_ENDIAN
    other = lilendian_table;
#else
    other = bigendian_table;
#endif
    /* Scan through the native table, find a matching
        entry in the endian table and swap in the
        native implementations whenever possible
        (64-bit platforms may not have "standard" sizes) */
    while (native->format != '\0' && other->format != '\0') {
        ptr = other;
        while (ptr->format != '\0') {
            if (ptr->format == native->format) {
                /* Match faster when formats are
                    listed in the same order */
                if (ptr == other)
                    other++;
                /* Only use the trick if the
                    size matches */
                if (ptr->size != native->size)
                    break;
                /* Skip _Bool, semantics are different for standard size */
                if (ptr->format == '?')
                    break;
                ptr->pack = native->pack;
                ptr->unpack = native->unpack;
                break;
            }
            ptr++;
        }
        native++;
    }
    return 0;
}


static const formatdef *
whichtable(const char **pfmt)
{
    const char *fmt = (*pfmt)++; /* May be backed out of later */
    switch (*fmt) {
    case '<':
        return lilendian_table;
    case '>':
    case '!': /* Network byte order is big-endian */
        return bigendian_table;
    case '=': { /* Host byte order -- different from native in alignment! */
#if PY_LITTLE_ENDIAN
        return lilendian_table;
#else
        return bigendian_table;
#endif
    }
    default:
        --*pfmt; /* Back out of pointer increment */
        _Py_FALLTHROUGH;
    case '@':
        return native_table;
    }
}


/* Get the table entry for a format code */

static const formatdef *
getentry(_structmodulestate *state, int c, const formatdef *f)
{
    for (; f->format != '\0'; f++) {
        if (f->format == c) {
            return f;
        }
    }
    PyErr_SetString(state->StructError, "bad char in struct format");
    return NULL;
}


/* Align a size according to a format code.  Return -1 on overflow. */

static Py_ssize_t
align(Py_ssize_t size, char c, const formatdef *e)
{
    Py_ssize_t extra;

    if (e->format == c) {
        if (e->alignment && size > 0) {
            extra = (e->alignment - 1) - (size - 1) % (e->alignment);
            if (extra > PY_SSIZE_T_MAX - size)
                return -1;
            size += extra;
        }
    }
    return size;
}

/*
 * Struct object implementation.
 */

/* calculate the size of a format string */

static int
prepare_s(PyStructObject *self, PyObject *format)
{
    const formatdef *f;
    const formatdef *e;
    formatcode *codes, *codes0;

    const char *s;
    const char *fmt;
    char c;
    Py_ssize_t size, len, num, itemsize;
    size_t ncodes;

    _structmodulestate *state = get_struct_state_structinst(self);

    if (!PyUnicode_IS_ASCII(format)) {
        PyErr_SetString(PyExc_ValueError, "non-ASCII character in struct format");
        return -1;
    }
    fmt = (const char *)PyUnicode_1BYTE_DATA(format);
    if (strlen(fmt) != (size_t)PyUnicode_GET_LENGTH(format)) {
        PyErr_SetString(state->StructError,
                        "embedded null character");
        return -1;
    }

    f = whichtable(&fmt);

    s = fmt;
    size = 0;
    len = 0;
    ncodes = 0;
    while ((c = *s++) != '\0') {
        if (Py_ISSPACE(c))
            continue;
        if ('0' <= c && c <= '9') {
            num = c - '0';
            while ('0' <= (c = *s++) && c <= '9') {
                /* overflow-safe version of
                   if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
                if (num >= PY_SSIZE_T_MAX / 10 && (
                        num > PY_SSIZE_T_MAX / 10 ||
                        (c - '0') > PY_SSIZE_T_MAX % 10))
                    goto overflow;
                num = num*10 + (c - '0');
            }
            if (c == '\0') {
                PyErr_SetString(state->StructError,
                                "repeat count given without format specifier");
                return -1;
            }
        }
        else
            num = 1;

        e = getentry(state, c, f);
        if (e == NULL)
            return -1;

        switch (c) {
            case 's': _Py_FALLTHROUGH;
            case 'p':
                if (len == PY_SSIZE_T_MAX) {
                    goto overflow;
                }
                len++;
                ncodes++;
                break;
            case 'x': break;
            default:
                if (num > PY_SSIZE_T_MAX - len) {
                    goto overflow;
                }
                len += num;
                if (num) {
                    ncodes++;
                }
                break;
        }

        itemsize = e->size;
        size = align(size, c, e);
        if (size == -1)
            goto overflow;

        /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
        if (num > (PY_SSIZE_T_MAX - size) / itemsize)
            goto overflow;
        size += num * itemsize;
    }

    /* check for overflow */
    if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) {
        PyErr_NoMemory();
        return -1;
    }

    codes = PyMem_Malloc((ncodes + 1) * sizeof(formatcode));
    if (codes == NULL) {
        PyErr_NoMemory();
        return -1;
    }
    codes0 = codes;
    s = fmt;
    size = 0;
    while ((c = *s++) != '\0') {
        if (Py_ISSPACE(c))
            continue;
        if ('0' <= c && c <= '9') {
            num = c - '0';
            while ('0' <= (c = *s++) && c <= '9')
                num = num*10 + (c - '0');
        }
        else
            num = 1;

        e = getentry(state, c, f);

        size = align(size, c, e);
        if (c == 's' || c == 'p') {
            codes->offset = size;
            codes->size = num;
            codes->fmtdef = e;
            codes->repeat = 1;
            codes++;
            size += num;
        } else if (c == 'x') {
            size += num;
        } else if (num) {
            codes->offset = size;
            codes->size = e->size;
            codes->fmtdef = e;
            codes->repeat = num;
            codes++;
            size += e->size * num;
        }
    }
    codes->fmtdef = NULL;
    codes->offset = size;
    codes->size = 0;
    codes->repeat = 0;

    /* Free any s_codes value left over from a previous initialization. */
    if (self->s_codes != NULL)
        PyMem_Free(self->s_codes);
    self->s_codes = codes0;
    self->s_size = size;
    self->s_len = len;
    Py_XSETREF(self->s_format, Py_NewRef(format));

    return 0;

  overflow:
    PyErr_SetString(state->StructError,
                    "total struct size too long");
    return -1;
}

/* This should be moved to Struct_impl() when Struct___init__() and
 * s_new() will be removed (see gh-143715 and gh-94532). */
static int
set_format(PyStructObject *self, PyObject *format)
{
    if (PyUnicode_Check(format)) {
        format = PyUnicode_FromObject(format);
    }
    else if (PyBytes_Check(format)) {
        format = PyUnicode_DecodeASCII(PyBytes_AS_STRING(format),
                                       PyBytes_GET_SIZE(format), "surrogateescape");
    }
    else  {
        PyErr_Format(PyExc_TypeError,
                     "Struct() argument 1 must be a str or bytes object, "
                     "not %T", format);
        return -1;
    }
    if (format == NULL) {
        return -1;
    }
    if (prepare_s(self, format)) {
        Py_DECREF(format);
        return -1;
    }
    Py_DECREF(format);
    return 0;
}

/*[clinic input]
@classmethod
Struct.__new__

   format: object

Create a compiled struct object.

Return a new Struct object which writes and reads binary data according
to the format string.  See help(struct) for more on format strings.
[clinic start generated code]*/

static PyObject *
Struct_impl(PyTypeObject *type, PyObject *format)
/*[clinic end generated code: output=49468b044e334308 input=8381a9796f20f24e]*/
{
    PyStructObject *self = (PyStructObject *)type->tp_alloc(type, 0);
    if (self == NULL) {
        return NULL;
    }
    self->s_format = NULL;
    self->s_codes = NULL;
    self->s_size = -1;
    self->s_len = -1;
    self->init_called = false;
    if (set_format(self, format) < 0) {
        Py_DECREF(self);
        return NULL;
    }
    return (PyObject *)self;
}


static int
s_init(PyObject *self, PyObject *args, PyObject *kwargs);

static PyObject *
s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    if (type->tp_new != s_new) {
        /* Struct.__new__() was called explicitly in a subclass' __new__(). */
        return Struct(type, args, kwds);
    }

    PyObject *format = NULL;
    if (PyTuple_GET_SIZE(args) == 1 && (kwds == NULL || PyDict_GET_SIZE(kwds) == 0)) {
        format = Py_NewRef(PyTuple_GET_ITEM(args, 0));
    }
    else if (PyTuple_GET_SIZE(args) == 0 && kwds != NULL && PyDict_GET_SIZE(kwds) == 1) {
        if (PyDict_GetItemStringRef(kwds, "format", &format) < 0) {
            return NULL;
        }
    }
    if (format == NULL && type->tp_init != s_init) {
        Py_ssize_t nargs = PyTuple_GET_SIZE(args) + (kwds ? PyDict_GET_SIZE(kwds) : 0);
        if (nargs > 1) {
            if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
                "Struct() takes at most 1 argument (%zd given)", nargs))
            {
                Py_XDECREF(format);
                return NULL;
            }
        }
        else {
            if (PyErr_WarnEx(PyExc_DeprecationWarning,
                "Struct() missing required argument 'format' (pos 1)", 1))
            {
                Py_XDECREF(format);
                return NULL;
            }
        }
    }

    PyStructObject *self = (PyStructObject *)type->tp_alloc(type, 0);
    if (self == NULL) {
        return NULL;
    }
    self->s_format = NULL;
    self->s_codes = NULL;
    self->s_size = -1;
    self->s_len = -1;
    self->init_called = false;
    if (format && set_format(self, format) < 0) {
        if (type->tp_init == s_init) {
            /* No custom __init__() method, so __new__() should do
             * all the work. */
            Py_DECREF(format);
            Py_DECREF(self);
            return NULL;
        }
        PyObject *exc = PyErr_GetRaisedException();
        Py_CLEAR(self->s_format);
        if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
            "Invalid 'format' argument for Struct.__new__(): %S", exc))
        {
            Py_DECREF(exc);
            Py_DECREF(format);
            Py_DECREF(self);
            return NULL;
        }
        Py_DECREF(exc);
    }
    Py_XDECREF(format);
    return (PyObject *)self;
}

static bool
same_format(PyStructObject *s, PyObject *format)
{
    Py_ssize_t size = PyUnicode_GET_LENGTH(s->s_format);
    const void *data = PyUnicode_1BYTE_DATA(s->s_format);
    if (PyUnicode_Check(format) && PyUnicode_IS_ASCII(format)) {
        return PyUnicode_GET_LENGTH(format) == size
            && memcmp(PyUnicode_1BYTE_DATA(format), data, size) == 0;
    }
    if (PyBytes_Check(format)) {
        return PyBytes_GET_SIZE(format) == size
            && memcmp(PyBytes_AS_STRING(format), data, size) == 0;
    }
    return false;
}

/*[clinic input]
Struct.__init__

    format: object

Create a compiled struct object.

Return a new Struct object which writes and reads binary data according
to the format string.  See help(struct) for more on format strings.
[clinic start generated code]*/

static int
Struct___init___impl(PyStructObject *self, PyObject *format)
/*[clinic end generated code: output=b8e80862444e92d0 input=1af78a5f57d82cec]*/
{
    if (self->s_format == NULL) {
        if (set_format(self, format) < 0) {
            return -1;
        }
    }
    else if (!same_format(self, format)) {
        const char *msg = self->init_called
            ? "Re-initialization of Struct by calling the __init__() method "
              "will not work in future Python versions"
            : "Different format arguments for __new__() and __init__() "
              "methods of Struct";
        if (PyErr_WarnEx(PyExc_FutureWarning, msg, 1)) {
            return -1;
        }
        if (set_format(self, format) < 0) {
            return -1;
        }
    }
    self->init_called = true;
    return 0;
}

static int
s_init(PyObject *self, PyObject *args, PyObject *kwargs)
{
    if (!((PyStructObject *)self)->init_called
            && Py_TYPE(self)->tp_init == s_init
            && ((PyStructObject *)self)->s_format != NULL)
    {
        /* Struct.__init__() was called implicitly.
         * __new__() already did all the work. */
        ((PyStructObject *)self)->init_called = true;
        return 0;
    }
    /* Struct.__init__() was called explicitly. */
    return Struct___init__(self, args, kwargs);
}

static int
s_clear(PyObject *op)
{
    PyStructObject *s = PyStructObject_CAST(op);
    Py_CLEAR(s->s_format);
    return 0;
}

static int
s_traverse(PyObject *op, visitproc visit, void *arg)
{
    PyStructObject *s = PyStructObject_CAST(op);
    Py_VISIT(Py_TYPE(s));
    Py_VISIT(s->s_format);
    return 0;
}

static void
s_dealloc(PyObject *op)
{
    PyStructObject *s = PyStructObject_CAST(op);
    PyTypeObject *tp = Py_TYPE(s);
    PyObject_GC_UnTrack(s);
    FT_CLEAR_WEAKREFS(op, s->weakreflist);
    if (s->s_codes != NULL) {
        PyMem_Free(s->s_codes);
    }
    Py_XDECREF(s->s_format);
    tp->tp_free(s);
    Py_DECREF(tp);
}

static PyObject *
s_unpack_internal(PyStructObject *soself, const char *startfrom,
                  _structmodulestate *state) {
    formatcode *code;
    Py_ssize_t i = 0;
    PyObject *result = PyTuple_New(soself->s_len);
    if (result == NULL)
        return NULL;

    for (code = soself->s_codes; code->fmtdef != NULL; code++) {
        const formatdef *e = code->fmtdef;
        const char *res = startfrom + code->offset;
        Py_ssize_t j = code->repeat;
        while (j--) {
            PyObject *v;
            if (e->format == 's') {
                v = PyBytes_FromStringAndSize(res, code->size);
            } else if (e->format == 'p') {
                Py_ssize_t n;
                if (code->size == 0) {
                    n = 0;
                }
                else {
                    n = *(unsigned char*)res;
                    if (n >= code->size) {
                        n = code->size - 1;
                    }
                }
                v = PyBytes_FromStringAndSize(res + 1, n);
            } else {
                v = e->unpack(state, res, e);
            }
            if (v == NULL)
                goto fail;
            PyTuple_SET_ITEM(result, i++, v);
            res += code->size;
        }
    }

    return result;
fail:
    Py_DECREF(result);
    return NULL;
}

#define ENSURE_STRUCT_IS_READY(self)                             \
    do {                                                         \
        if (!(self)->s_codes) {                                  \
            PyErr_SetString(PyExc_RuntimeError,                  \
                            "Struct object is not initialized"); \
            return NULL;                                         \
        }                                                        \
    } while (0);

/*[clinic input]
Struct.unpack

    buffer: Py_buffer
    /

Return a tuple containing unpacked values.

Unpack according to the struct format string.  The buffer's
size in bytes must be the struct size.  See help(struct) for more on
format strings.
[clinic start generated code]*/

static PyObject *
Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
/*[clinic end generated code: output=873a24faf02e848a input=488843a57c47065a]*/
{
    _structmodulestate *state = get_struct_state_structinst(self);
    ENSURE_STRUCT_IS_READY(self);
    if (buffer->len != self->s_size) {
        PyErr_Format(state->StructError,
                     "unpack requires a buffer of %zd bytes",
                     self->s_size);
        return NULL;
    }
    return s_unpack_internal(self, buffer->buf, state);
}

/*[clinic input]
Struct.unpack_from

    buffer: Py_buffer
    offset: Py_ssize_t = 0

Return a tuple containing unpacked values.

Values are unpacked according to the struct format string.  The
buffer's size in bytes, starting at position offset, must be at
least the struct size.  See help(struct) for more on format
strings.
[clinic start generated code]*/

static PyObject *
Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
                        Py_ssize_t offset)
/*[clinic end generated code: output=57fac875e0977316 input=57cfcf84c088faa4]*/
{
    _structmodulestate *state = get_struct_state_structinst(self);
    ENSURE_STRUCT_IS_READY(self);

    if (offset < 0) {
        if (offset + self->s_size > 0) {
            PyErr_Format(state->StructError,
                         "not enough data to unpack %zd bytes at offset %zd",
                         self->s_size,
                         offset);
            return NULL;
        }

        if (offset + buffer->len < 0) {
            PyErr_Format(state->StructError,
                         "offset %zd out of range for %zd-byte buffer",
                         offset,
                         buffer->len);
            return NULL;
        }
        offset += buffer->len;
    }

    if ((buffer->len - offset) < self->s_size) {
        PyErr_Format(state->StructError,
                     "unpack_from requires a buffer of at least %zu bytes for "
                     "unpacking %zd bytes at offset %zd "
                     "(actual buffer size is %zd)",
                     (size_t)self->s_size + (size_t)offset,
                     self->s_size,
                     offset,
                     buffer->len);
        return NULL;
    }
    return s_unpack_internal(self, (char*)buffer->buf + offset, state);
}



/* Unpack iterator type */

typedef struct {
    PyObject_HEAD
    PyStructObject *so;
    Py_buffer buf;
    Py_ssize_t index;
} unpackiterobject;

#define unpackiterobject_CAST(op)   ((unpackiterobject *)(op))

static void
unpackiter_dealloc(PyObject *op)
{
    unpackiterobject *self = unpackiterobject_CAST(op);
    /* bpo-31095: UnTrack is needed before calling any callbacks */
    PyTypeObject *tp = Py_TYPE(self);
    PyObject_GC_UnTrack(self);
    Py_XDECREF(self->so);
    PyBuffer_Release(&self->buf);
    PyObject_GC_Del(self);
    Py_DECREF(tp);
}

static int
unpackiter_traverse(PyObject *op, visitproc visit, void *arg)
{
    unpackiterobject *self = unpackiterobject_CAST(op);
    Py_VISIT(Py_TYPE(self));
    Py_VISIT(self->so);
    Py_VISIT(self->buf.obj);
    return 0;
}

static PyObject *
unpackiter_len(PyObject *op, PyObject *Py_UNUSED(dummy))
{
    Py_ssize_t len;
    unpackiterobject *self = unpackiterobject_CAST(op);
    if (self->so == NULL) {
        len = 0;
    }
    else {
        len = (self->buf.len - self->index) / self->so->s_size;
    }
    return PyLong_FromSsize_t(len);
}

static PyMethodDef unpackiter_methods[] = {
    {"__length_hint__", unpackiter_len, METH_NOARGS, NULL},
    {NULL,              NULL}           /* sentinel */
};

static PyObject *
unpackiter_iternext(PyObject *op)
{
    unpackiterobject *self = unpackiterobject_CAST(op);
    _structmodulestate *state = get_struct_state_iterinst(self);
    PyObject *result;
    if (self->so == NULL) {
        return NULL;
    }
    if (self->index >= self->buf.len) {
        /* Iterator exhausted */
        Py_CLEAR(self->so);
        PyBuffer_Release(&self->buf);
        return NULL;
    }
    assert(self->index + self->so->s_size <= self->buf.len);
    result = s_unpack_internal(self->so,
                               (char*)self->buf.buf + self->index,
                               state);
    self->index += self->so->s_size;
    return result;
}

static PyType_Slot unpackiter_type_slots[] = {
    {Py_tp_dealloc, unpackiter_dealloc},
    {Py_tp_getattro, PyObject_GenericGetAttr},
    {Py_tp_traverse, unpackiter_traverse},
    {Py_tp_iter, PyObject_SelfIter},
    {Py_tp_iternext, unpackiter_iternext},
    {Py_tp_methods, unpackiter_methods},
    {0, 0},
};

static PyType_Spec unpackiter_type_spec = {
    "_struct.unpack_iterator",
    sizeof(unpackiterobject),
    0,
    (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
     Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION),
    unpackiter_type_slots
};

/*[clinic input]
Struct.iter_unpack

    buffer: object
    /

Return an iterator yielding tuples.

Tuples are unpacked from the given bytes source, like a repeated
invocation of unpack_from().  Requires that the bytes length be
a multiple of the struct size.
[clinic start generated code]*/

static PyObject *
Struct_iter_unpack_impl(PyStructObject *self, PyObject *buffer)
/*[clinic end generated code: output=818f89ad4afa8d64 input=9555d2d29d1d9cd2]*/
{
    _structmodulestate *state = get_struct_state_structinst(self);
    unpackiterobject *iter;
    ENSURE_STRUCT_IS_READY(self);

    if (self->s_size == 0) {
        PyErr_Format(state->StructError,
                     "cannot iteratively unpack with a struct of length 0");
        return NULL;
    }

    iter = (unpackiterobject *) PyType_GenericAlloc((PyTypeObject *)state->unpackiter_type, 0);
    if (iter == NULL)
        return NULL;

    if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
        Py_DECREF(iter);
        return NULL;
    }
    if (iter->buf.len % self->s_size != 0) {
        PyErr_Format(state->StructError,
                     "iterative unpacking requires a buffer of "
                     "a multiple of %zd bytes",
                     self->s_size);
        Py_DECREF(iter);
        return NULL;
    }
    iter->so = (PyStructObject*)Py_NewRef(self);
    iter->index = 0;
    return (PyObject *)iter;
}


/*
 * Guts of the pack function.
 *
 * Takes a struct object, a tuple of arguments, and offset in that tuple of
 * argument for where to start processing the arguments for packing, and a
 * character buffer for writing the packed string.  The caller must insure
 * that the buffer may contain the required length for packing the arguments.
 * 0 is returned on success, 1 is returned if there is an error.
 *
 */
static int
s_pack_internal(PyStructObject *soself, PyObject *const *args,
                char* buf, _structmodulestate *state)
{
    formatcode *code;
    /* XXX(nnorwitz): why does i need to be a local?  can we use
       the offset parameter or do we need the wider width? */
    Py_ssize_t i;

    memset(buf, '\0', soself->s_size);
    i = 0;
    for (code = soself->s_codes; code->fmtdef != NULL; code++) {
        const formatdef *e = code->fmtdef;
        char *res = buf + code->offset;
        Py_ssize_t j = code->repeat;
        while (j--) {
            PyObject *v = args[i++];
            if (e->format == 's') {
                Py_ssize_t n;
                int isstring;
                const void *p;
                isstring = PyBytes_Check(v);
                if (!isstring && !PyByteArray_Check(v)) {
                    PyErr_SetString(state->StructError,
                                    "argument for 's' must be a bytes object");
                    return -1;
                }
                if (isstring) {
                    n = PyBytes_GET_SIZE(v);
                    p = PyBytes_AS_STRING(v);
                }
                else {
                    n = PyByteArray_GET_SIZE(v);
                    p = PyByteArray_AS_STRING(v);
                }
                if (n > code->size)
                    n = code->size;
                if (n > 0)
                    memcpy(res, p, n);
            } else if (e->format == 'p') {
                Py_ssize_t n;
                int isstring;
                const void *p;
                isstring = PyBytes_Check(v);
                if (!isstring && !PyByteArray_Check(v)) {
                    PyErr_SetString(state->StructError,
                                    "argument for 'p' must be a bytes object");
                    return -1;
                }
                if (isstring) {
                    n = PyBytes_GET_SIZE(v);
                    p = PyBytes_AS_STRING(v);
                }
                else {
                    n = PyByteArray_GET_SIZE(v);
                    p = PyByteArray_AS_STRING(v);
                }
                if (code->size == 0) {
                    n = 0;
                }
                else if (n > (code->size - 1)) {
                    n = code->size - 1;
                }
                if (n > 0)
                    memcpy(res + 1, p, n);
                if (n > 255)
                    n = 255;
                *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
            } else {
                if (e->pack(state, res, v, e) < 0) {
                    if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
                        PyErr_SetString(state->StructError,
                                        "int too large to convert");
                    return -1;
                }
            }
            res += code->size;
        }
    }

    /* Success */
    return 0;
}


/*[clinic input]
Struct.pack

    *values: array

Pack values and return the packed bytes.

Return a bytes object containing the provided values packed
according to the struct format string.  See help(struct) for more on
format strings.
[clinic start generated code]*/

static PyObject *
Struct_pack_impl(PyStructObject *self, PyObject * const *values,
                 Py_ssize_t values_length)
/*[clinic end generated code: output=5766e18f596cae9e input=295f4b1a97747458]*/
{
    _structmodulestate *state = get_struct_state_structinst(self);

    /* Validate arguments. */
    ENSURE_STRUCT_IS_READY(self);
    if (values_length != self->s_len) {
        PyErr_Format(state->StructError,
                     "pack expected %zd items for packing (got %zd)",
                     self->s_len, values_length);
        return NULL;
    }

    PyBytesWriter *writer = PyBytesWriter_Create(self->s_size);
    if (writer == NULL) {
        return NULL;
    }
    char *buf = PyBytesWriter_GetData(writer);

    /* Call the guts */
    if (s_pack_internal(self, values, buf, state) != 0) {
        PyBytesWriter_Discard(writer);
        return NULL;
    }

    return PyBytesWriter_FinishWithSize(writer, self->s_size);
}

/*[clinic input]
Struct.pack_into

    buffer: Py_buffer(accept={rwbuffer})
    offset: Py_ssize_t
    /
    *values: array

Pack values and write the packed bytes into the buffer.

Pack the provided values according to the struct format string
and write the packed bytes into the writable buffer starting at
offset.  Note that the offset is a required argument.  See
help(struct) for more on format strings.
[clinic start generated code]*/

static PyObject *
Struct_pack_into_impl(PyStructObject *self, Py_buffer *buffer,
                      Py_ssize_t offset, PyObject * const *values,
                      Py_ssize_t values_length)
/*[clinic end generated code: output=aa9d9a93f5f8f77b input=9d842a368ee14245]*/
{
    _structmodulestate *state = get_struct_state_structinst(self);

    ENSURE_STRUCT_IS_READY(self);
    if (values_length != self->s_len) {
        PyErr_Format(state->StructError,
                     "pack_into expected %zd items for packing (got %zd)",
                     self->s_len, values_length);
        return NULL;
    }

    /* Support negative offsets. */
    if (offset < 0) {
         /* Check that negative offset is low enough to fit data */
        if (offset + self->s_size > 0) {
            PyErr_Format(state->StructError,
                         "no space to pack %zd bytes at offset %zd",
                         self->s_size,
                         offset);
            return NULL;
        }

        /* Check that negative offset is not crossing buffer boundary */
        if (offset + buffer->len < 0) {
            PyErr_Format(state->StructError,
                         "offset %zd out of range for %zd-byte buffer",
                         offset,
                         buffer->len);
            return NULL;
        }

        offset += buffer->len;
    }

    /* Check boundaries */
    if ((buffer->len - offset) < self->s_size) {
        assert(offset >= 0);
        assert(self->s_size >= 0);

        PyErr_Format(state->StructError,
                     "pack_into requires a buffer of at least %zu bytes for "
                     "packing %zd bytes at offset %zd "
                     "(actual buffer size is %zd)",
                     (size_t)self->s_size + (size_t)offset,
                     self->s_size,
                     offset,
                     buffer->len);
        return NULL;
    }

    /* Call the guts */
    if (s_pack_internal(self, values, (char*)buffer->buf + offset, state) != 0) {
        return NULL;
    }

    Py_RETURN_NONE;
}

/*[clinic input]
Struct.__sizeof__
[clinic start generated code]*/

static PyObject *
Struct___sizeof___impl(PyStructObject *self)
/*[clinic end generated code: output=2d0d78900b4cdb4e input=faca5925c1f1ffd0]*/
{
    ENSURE_STRUCT_IS_READY(self);
    size_t size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
    for (formatcode *code = self->s_codes; code->fmtdef != NULL; code++) {
        size += sizeof(formatcode);
    }
    return PyLong_FromSize_t(size);
}

static PyObject *
s_repr(PyObject *op)
{
    PyStructObject *self = PyStructObject_CAST(op);
    ENSURE_STRUCT_IS_READY(self);
    return PyUnicode_FromFormat("%s(%R)", _PyType_Name(Py_TYPE(self)), self->s_format);
}

/* List of functions */

static struct PyMethodDef s_methods[] = {
    STRUCT_ITER_UNPACK_METHODDEF
    STRUCT_PACK_METHODDEF
    STRUCT_PACK_INTO_METHODDEF
    STRUCT_UNPACK_METHODDEF
    STRUCT_UNPACK_FROM_METHODDEF
    STRUCT___SIZEOF___METHODDEF
    {NULL,       NULL}          /* sentinel */
};

static PyMemberDef s_members[] = {
    {"__weaklistoffset__", Py_T_PYSSIZET, offsetof(PyStructObject, weakreflist), Py_READONLY},
    {"format", Py_T_OBJECT_EX, offsetof(PyStructObject, s_format),
        Py_READONLY, PyDoc_STR("struct format string")},
    {"size", Py_T_PYSSIZET, offsetof(PyStructObject, s_size), Py_READONLY,
        PyDoc_STR("struct size in bytes")},
    {NULL}  /* sentinel */
};

static PyType_Slot PyStructType_slots[] = {
    {Py_tp_dealloc, s_dealloc},
    {Py_tp_getattro, PyObject_GenericGetAttr},
    {Py_tp_setattro, PyObject_GenericSetAttr},
    {Py_tp_repr, s_repr},
    {Py_tp_doc, (void*)Struct___init____doc__},
    {Py_tp_traverse, s_traverse},
    {Py_tp_clear, s_clear},
    {Py_tp_methods, s_methods},
    {Py_tp_members, s_members},
    {Py_tp_init, s_init},
    {Py_tp_new, s_new},
    {0, 0},
};

static PyType_Spec PyStructType_spec = {
    "_struct.Struct",
    sizeof(PyStructObject),
    0,
    (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
     Py_TPFLAGS_BASETYPE | Py_TPFLAGS_IMMUTABLETYPE),
    PyStructType_slots
};


/* ---- Standalone functions  ---- */

#define MAXCACHE 100

static int
cache_struct_converter(PyObject *module, PyObject *fmt, PyStructObject **ptr)
{
    PyObject * s_object;
    _structmodulestate *state = get_struct_state(module);

    if (fmt == NULL) {
        Py_SETREF(*ptr, NULL);
        return 1;
    }

    if (PyDict_GetItemRef(state->cache, fmt, &s_object) < 0) {
        return 0;
    }
    if (s_object != NULL) {
        *ptr = PyStructObject_CAST(s_object);
        return Py_CLEANUP_SUPPORTED;
    }

    s_object = PyObject_CallOneArg(state->PyStructType, fmt);
    if (s_object != NULL) {
        if (PyDict_GET_SIZE(state->cache) >= MAXCACHE)
            PyDict_Clear(state->cache);
        /* Attempt to cache the result */
        if (PyDict_SetItem(state->cache, fmt, s_object) == -1)
            PyErr_Clear();
        *ptr = (PyStructObject *)s_object;
        return Py_CLEANUP_SUPPORTED;
    }
    return 0;
}

/*[clinic input]
_clearcache

Clear the internal cache.
[clinic start generated code]*/

static PyObject *
_clearcache_impl(PyObject *module)
/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
{
    PyDict_Clear(get_struct_state(module)->cache);
    Py_RETURN_NONE;
}


/*[clinic input]
calcsize -> Py_ssize_t

    format as s_object: cache_struct
    /

Return size in bytes of the struct described by the format string.
[clinic start generated code]*/

static Py_ssize_t
calcsize_impl(PyObject *module, PyStructObject *s_object)
/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
{
    return s_object->s_size;
}

/*[clinic input]
pack

    format as s_object: cache_struct
    /
    *values: array

Pack values and return the packed bytes.

Return a bytes object containing the provided values packed according
to the format string.  See help(struct) for more on format strings.
[clinic start generated code]*/

static PyObject *
pack_impl(PyObject *module, PyStructObject *s_object,
          PyObject * const *values, Py_ssize_t values_length)
/*[clinic end generated code: output=2f874191ddecdec0 input=8144972342391de1]*/
{
    return Struct_pack_impl(s_object, values, values_length);
}

/*[clinic input]
pack_into

    format as s_object: cache_struct
    buffer: Py_buffer(accept={rwbuffer})
    offset: Py_ssize_t
    /
    *values: array

Pack values and write the packed bytes into the buffer.

Pack the provided values according to the format string and write the
packed bytes into the writable buffer starting at offset.  Note that the
offset is a required argument.  See help(struct) for more on format
strings.
[clinic start generated code]*/

static PyObject *
pack_into_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer,
               Py_ssize_t offset, PyObject * const *values,
               Py_ssize_t values_length)
/*[clinic end generated code: output=e8bf7d422b2088ef input=086867c0f5d8a8e4]*/
{
    return Struct_pack_into_impl(s_object, buffer, offset,
                                 values, values_length);
}

/*[clinic input]
unpack

    format as s_object: cache_struct
    buffer: Py_buffer
    /

Return a tuple containing values unpacked according to the format string.

The buffer's size in bytes must be calcsize(format).  See help(struct)
for more on format strings.
[clinic start generated code]*/

static PyObject *
unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
/*[clinic end generated code: output=48ddd4d88eca8551 input=7df28c5d0b5b6f4e]*/
{
    return Struct_unpack_impl(s_object, buffer);
}

/*[clinic input]
unpack_from

    format as s_object: cache_struct
    /
    buffer: Py_buffer
    offset: Py_ssize_t = 0

Return a tuple containing values unpacked according to the format string.

The buffer's size, minus offset, must be at least calcsize(format).  See
help(struct) for more on format strings.
[clinic start generated code]*/

static PyObject *
unpack_from_impl(PyObject *module, PyStructObject *s_object,
                 Py_buffer *buffer, Py_ssize_t offset)
/*[clinic end generated code: output=1042631674c6e0d3 input=599262b23559f6c5]*/
{
    return Struct_unpack_from_impl(s_object, buffer, offset);
}

/*[clinic input]
iter_unpack

    format as s_object: cache_struct
    buffer: object
    /

Return an iterator yielding tuples unpacked from the given bytes.

The bytes are unpacked according to the format string, like a repeated
invocation of unpack_from().  Requires that the bytes length be
a multiple of calcsize(format).
[clinic start generated code]*/

static PyObject *
iter_unpack_impl(PyObject *module, PyStructObject *s_object,
                 PyObject *buffer)
/*[clinic end generated code: output=0ae50e250d20e74d input=ac5086c5c4ed68bb]*/
{
    return Struct_iter_unpack_impl(s_object, buffer);
}

static struct PyMethodDef module_functions[] = {
    _CLEARCACHE_METHODDEF
    CALCSIZE_METHODDEF
    ITER_UNPACK_METHODDEF
    PACK_METHODDEF
    PACK_INTO_METHODDEF
    UNPACK_METHODDEF
    UNPACK_FROM_METHODDEF
    {NULL,       NULL}          /* sentinel */
};


/* Module initialization */

PyDoc_STRVAR(module_doc,
"Functions to convert between Python values and C structs.\n\
Python bytes objects are used to hold the data representing the C struct\n\
and also as format strings (explained below) to describe the layout of data\n\
in the C struct.\n\
\n\
The optional first format char indicates byte order, size and alignment:\n\
  @: native order, size & alignment (default)\n\
  =: native order, std. size & alignment\n\
  <: little-endian, std. size & alignment\n\
  >: big-endian, std. size & alignment\n\
  !: same as >\n\
\n\
The remaining chars indicate types of args and must match exactly;\n\
these can be preceded by a decimal repeat count:\n\
  x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
  ?:_Bool; h:short; H:unsigned short; i:int; I:unsigned int;\n\
  l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
  F:float complex; D:double complex.\n\
Special cases (preceding decimal count indicates length):\n\
  s:string (array of char); p: pascal string (with count byte).\n\
Special cases (only available in native format):\n\
  n:ssize_t; N:size_t;\n\
  P:an integer type that is wide enough to hold a pointer.\n\
Special case (not in native mode unless 'long long' in platform C):\n\
  q:long long; Q:unsigned long long\n\
Whitespace between formats is ignored.\n\
\n\
The variable struct.error is an exception raised on errors.\n");


static int
_structmodule_traverse(PyObject *module, visitproc visit, void *arg)
{
    _structmodulestate *state = get_struct_state(module);
    if (state) {
        Py_VISIT(state->cache);
        Py_VISIT(state->PyStructType);
        Py_VISIT(state->unpackiter_type);
        Py_VISIT(state->StructError);
    }
    return 0;
}

static int
_structmodule_clear(PyObject *module)
{
    _structmodulestate *state = get_struct_state(module);
    if (state) {
        Py_CLEAR(state->cache);
        Py_CLEAR(state->PyStructType);
        Py_CLEAR(state->unpackiter_type);
        Py_CLEAR(state->StructError);
    }
    return 0;
}

static void
_structmodule_free(void *module)
{
    (void)_structmodule_clear((PyObject *)module);
}

static int
_structmodule_exec(PyObject *m)
{
    _structmodulestate *state = get_struct_state(m);

    state->cache = PyDict_New();
    if (state->cache == NULL) {
        return -1;
    }

    state->PyStructType = PyType_FromModuleAndSpec(
        m, &PyStructType_spec, NULL);
    if (state->PyStructType == NULL) {
        return -1;
    }
    if (PyModule_AddType(m, (PyTypeObject *)state->PyStructType) < 0) {
        return -1;
    }

    state->unpackiter_type = PyType_FromModuleAndSpec(
        m, &unpackiter_type_spec, NULL);
    if (state->unpackiter_type == NULL) {
        return -1;
    }

    /* init cannot fail */
    (void)_PyOnceFlag_CallOnce(&endian_tables_init_once, init_endian_tables, NULL);

    /* Add some symbolic constants to the module */
    state->StructError = PyErr_NewException("struct.error", NULL, NULL);
    if (state->StructError == NULL) {
        return -1;
    }
    if (PyModule_AddObjectRef(m, "error", state->StructError) < 0) {
        return -1;
    }

    return 0;
}

static PyModuleDef_Slot _structmodule_slots[] = {
    _Py_ABI_SLOT,
    {Py_mod_exec, _structmodule_exec},
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
    {0, NULL}
};

static struct PyModuleDef _structmodule = {
    PyModuleDef_HEAD_INIT,
    .m_name = "_struct",
    .m_doc = module_doc,
    .m_size = sizeof(_structmodulestate),
    .m_methods = module_functions,
    .m_slots = _structmodule_slots,
    .m_traverse = _structmodule_traverse,
    .m_clear = _structmodule_clear,
    .m_free = _structmodule_free,
};

PyMODINIT_FUNC
PyInit__struct(void)
{
    return PyModuleDef_Init(&_structmodule);
}
