cdef int _encode_unicode_impl(WriterRef writer, UCSString data, Py_ssize_t length) except -1:
    cdef char buf[32]
    cdef uint32_t c
    cdef uint32_t s1, s2
    cdef const char *escaped_string
    cdef Py_ssize_t escaped_length
    cdef size_t unescaped_length, index
    cdef Py_ssize_t sublength

    if length > 0:
        writer.reserve(writer, 2 + length)
        writer.append_c(writer, <char> PyUnicode_1BYTE_DATA((<Options> writer.options).quotationmark)[0])
        while True:
            if UCSString is UCS1String:
                sublength = length
            else:
                sublength = min(length, <Py_ssize_t> sizeof(buf))

            unescaped_length = ESCAPE_DCT.find_unescaped_range(data, sublength)
            if unescaped_length > 0:
                if UCSString is UCS1String:
                    writer.append_s(writer, <const char*> data, unescaped_length)
                else:
                    for index in range(unescaped_length):
                        buf[index] = <const char> data[index]
                    writer.append_s(writer, buf, unescaped_length)

                data += unescaped_length
                length -= unescaped_length
                if length <= 0:
                    break

                if UCSString is not UCS1String:
                    continue

            c = data[0]
            if (UCSString is UCS1String) or (c < 0x100):
                escaped_length = ESCAPE_DCT.items[c][0]
                escaped_string = &ESCAPE_DCT.items[c][1]
                writer.append_s(writer, escaped_string, escaped_length)
            elif (UCSString is UCS2String) or (c <= 0xffff):
                buf[0] = b'\\';
                buf[1] = b'u';
                buf[2] = HEX[(c >> (4*3)) & 0xf];
                buf[3] = HEX[(c >> (4*2)) & 0xf];
                buf[4] = HEX[(c >> (4*1)) & 0xf];
                buf[5] = HEX[(c >> (4*0)) & 0xf];
                buf[6] = 0;

                writer.append_s(writer, buf, 6);
            else:
                # surrogate pair
                c -= 0x10000
                s1 = 0xd800 | ((c >> 10) & 0x3ff)
                s2 = 0xdc00 | (c & 0x3ff)

                buf[0x0] = b'\\';
                buf[0x1] = b'u';
                buf[0x2] = HEX[(s1 >> (4*3)) & 0xf];
                buf[0x3] = HEX[(s1 >> (4*2)) & 0xf];
                buf[0x4] = HEX[(s1 >> (4*1)) & 0xf];
                buf[0x5] = HEX[(s1 >> (4*0)) & 0xf];

                buf[0x6] = b'\\';
                buf[0x7] = b'u';
                buf[0x8] = HEX[(s2 >> (4*3)) & 0xf];
                buf[0x9] = HEX[(s2 >> (4*2)) & 0xf];
                buf[0xa] = HEX[(s2 >> (4*1)) & 0xf];
                buf[0xb] = HEX[(s2 >> (4*0)) & 0xf];

                buf[0xc] = 0;

                writer.append_s(writer, buf, 12);

            data += 1
            length -= 1
            if length <= 0:
                break
        writer.append_c(writer, <char> PyUnicode_1BYTE_DATA((<Options> writer.options).quotationmark)[0])
    else:
        writer.append_s(writer, b'""', 2)

    return True


cdef int _encode_unicode(WriterRef writer, object data) except -1:
    cdef Py_ssize_t length
    cdef int kind

    PyUnicode_READY(data)

    length = PyUnicode_GET_LENGTH(data)
    kind = PyUnicode_KIND(data)

    if kind == PyUnicode_1BYTE_KIND:
        _encode_unicode_impl(writer, PyUnicode_1BYTE_DATA(data), length)
    elif kind == PyUnicode_2BYTE_KIND:
        _encode_unicode_impl(writer, PyUnicode_2BYTE_DATA(data), length)
    elif kind == PyUnicode_4BYTE_KIND:
        _encode_unicode_impl(writer, PyUnicode_4BYTE_DATA(data), length)
    else:
        pass  # impossible

    return True


cdef int _encode_nested_key(WriterRef writer, object data) except -1:
    cdef const char *string
    cdef char c
    cdef Py_ssize_t index, length
    cdef int result

    cdef WriterReallocatable sub_writer = WriterReallocatable(
        Writer(
            _WriterReallocatable_reserve,
            _WriterReallocatable_append_c,
            _WriterReallocatable_append_s,
            writer.options,
        ),
        0, 0, NULL,
    )
    try:
        result = _encode(sub_writer.base, data)
        if expect(result < 0, False):
            return result

        length = sub_writer.position
        string = <char*> sub_writer.obj

        writer.reserve(writer, 2 + length)
        writer.append_c(writer, <char> PyUnicode_1BYTE_DATA((<Options> writer.options).quotationmark)[0])
        for index in range(length):
            c = string[index]
            if c in b'\\"':
                writer.append_c(writer, b'\\')
            writer.append_c(writer, c)
        writer.append_c(writer, <char> PyUnicode_1BYTE_DATA((<Options> writer.options).quotationmark)[0])
    finally:
        if sub_writer.obj is not NULL:
            ObjectFree(sub_writer.obj)

    return True


cdef int _append_ascii(WriterRef writer, object data) except -1:
    cdef Py_buffer view
    cdef const char *buf
    cdef Py_ssize_t index
    cdef unsigned char c

    if PyUnicode_Check(data):
        PyUnicode_READY(data)
        if not PyUnicode_IS_ASCII(data):
            raise TypeError('Expected ASCII data')
        writer.append_s(writer, <const char*> PyUnicode_1BYTE_DATA(data), PyUnicode_GET_LENGTH(data))
    else:
        PyObject_GetBuffer(data, &view, PyBUF_CONTIG_RO)
        try:
            buf = <const char*> view.buf
            for index in range(view.len):
                c = <unsigned char> buf[index]
                if c & ~0x7f:
                    raise TypeError('Expected ASCII data')

            writer.append_s(writer, buf, view.len)
        finally:
            PyBuffer_Release(&view)

    return True


cdef int _encode_tojson(WriterRef writer, object data) except -1:
    cdef object value = getattr(data, (<Options> writer.options).tojson, None)
    if value is None:
        return False

    if callable(value):
        Py_EnterRecursiveCall(' while encoding nested JSON5 object')
        try:
            value = value()
        finally:
            Py_LeaveRecursiveCall()

    _append_ascii(writer, value)
    return True


cdef int _encode_sequence(WriterRef writer, object data) except -1:
    cdef boolean first
    cdef object iterator
    cdef object value
    cdef int result

    try:
        iterator = PyObject_GetIter(data)
    except TypeError:
        return False

    Py_EnterRecursiveCall(' while encoding nested JSON5 object')
    try:
        writer.append_c(writer, <char> b'[')
        first = True
        value = None
        while iter_next(iterator, &<PyObject*&> value):
            if not first:
                writer.append_c(writer, <char> b',')
            else:
                first = False

            result = _encode(writer, value)
            if expect(result < 0, False):
                return result
        writer.append_c(writer, <char> b']')
    finally:
        Py_LeaveRecursiveCall()

    return True


cdef int _encode_mapping(WriterRef writer, object data) except -1:
    cdef boolean first
    cdef object iterator, key, value
    cdef int result

    if not isinstance(data, (<Options> writer.options).mappingtypes):
        return False

    iterator = PyObject_GetIter(data)

    Py_EnterRecursiveCall(' while encoding nested JSON5 object')
    try:
        writer.append_c(writer, <char> b'{')
        first = True
        key = None
        while iter_next(iterator, &<PyObject*&> key):
            if not first:
                writer.append_c(writer, <char> b',')
            else:
                first = False
            value = data[key]

            if PyUnicode_Check(key):
                _encode_unicode(writer, key)
            else:
                _encode_nested_key(writer, key)

            writer.append_c(writer, <char> b':')

            result = _encode(writer, value)
            if expect(result < 0, False):
                return result
        writer.append_c(writer, <char> b'}')
    finally:
        Py_LeaveRecursiveCall()

    return True


cdef int _encode_none(WriterRef writer, object data) except -1:
    writer.append_s(writer, b'null', 4)
    return True


cdef int _encode_bytes(WriterRef writer, object data) except -1:
    _encode_unicode(writer, PyUnicode_FromEncodedObject(data, 'UTF-8', 'strict'))
    return True


cdef int _encode_datetime(WriterRef writer, object data) except -1:
    cdef object stringified
    cdef Py_ssize_t length
    cdef const char *string

    if not isinstance(data, DATETIME_CLASSES):
        return False

    stringified = data.isoformat()
    length = 0
    string = PyUnicode_AsUTF8AndSize(stringified, &length)

    writer.reserve(writer, 2 + length)
    writer.append_c(writer, <char> PyUnicode_1BYTE_DATA((<Options> writer.options).quotationmark)[0])
    writer.append_s(writer, string, length)
    writer.append_c(writer, <char> PyUnicode_1BYTE_DATA((<Options> writer.options).quotationmark)[0])

    return True


cdef int _encode_format_string(WriterRef writer, object data, object fmt) except -1:
    cdef object formatted
    cdef const char *string
    cdef Py_ssize_t length = 0  # silence warning

    formatted = PyUnicode_Format(fmt, data)
    string = PyUnicode_AsUTF8AndSize(formatted, &length)
    writer.append_s(writer, string, length)

    return True


cdef int _encode_float(WriterRef writer, object data) except -1:
    cdef double value = PyFloat_AsDouble(data)
    cdef int classification = fpclassify(value)
    cdef char buf[64]
    cdef char *end
    cdef char *string
    cdef Py_ssize_t length

    if classification == FP_NORMAL:
        end = Dtoa(buf, PyFloat_AsDouble(data))
        length = end - buf
        string = buf
    elif classification in (FP_SUBNORMAL, FP_ZERO):
        string = b'0.0'
        length = 3
    elif classification == FP_NAN:
        string = b'NaN'
        length = 3
    else:
        # classification == FP_INFINITE
        if value > 0.0:
            string = b'Infinity'
            length = 8
        else:
            string = b'-Infinity'
            length = 9

    writer.append_s(writer, string, length)
    return True


cdef int _encode_long(WriterRef writer, object data) except -1:
    if PyBool_Check(data):
        if data is True:
            writer.append_s(writer, 'true', 4)
        else:
            writer.append_s(writer, 'false', 5)
    else:
        _encode_format_string(writer, data, DEFAULT_INTFORMAT)
    return True


cdef int _encode_decimal(WriterRef writer, object data) except -1:
    if not isinstance(data, Decimal):
        return False

    _encode_format_string(writer, data, DEFAULT_DECIMALFORMAT)
    return True


cdef int _encode_unstringifiable(WriterRef writer, object data) except -1:
    if expect(not data, True):
        writer.append_s(writer, b'none', 4)
    else:
        _raise_unstringifiable(data)
    return True


cdef int _encode_other(WriterRef writer, object data):
    cdef int result = 0

    while True:
        if (<Options> writer.options).tojson is not None:
            result = (<int(*)(WriterRef, object)> _encode_tojson)(writer, data)
            if result != 0:
                break

        if obj_has_iter(data):
            result = (<int(*)(WriterRef, object)> _encode_mapping)(writer, data)
            if result != 0:
                break

            result = (<int(*)(WriterRef, object)> _encode_sequence)(writer, data)
            if result != 0:
                break

        result = (<int(*)(WriterRef, object)> _encode_decimal)(writer, data)
        if result != 0:
            break

        result = (<int(*)(WriterRef, object)> _encode_datetime)(writer, data)
        if result != 0:
            break

        result = (<int(*)(WriterRef, object)> _encode_unstringifiable)(writer, data)
        if result != 0:
            break

        break

    return result


cdef int _encode(WriterRef writer, object data):
    cdef int (*encoder)(WriterRef, object)

    if data is None:
        encoder = <int(*)(WriterRef, object)> _encode_none
    elif PyUnicode_Check(data):
        encoder = <int(*)(WriterRef, object)> _encode_unicode
    elif PyLong_Check(data):
        encoder = <int(*)(WriterRef, object)> _encode_long
    elif PyFloat_Check(data):
        encoder = <int(*)(WriterRef, object)> _encode_float
    elif PyBytes_Check(data):
        encoder = <int(*)(WriterRef, object)> _encode_bytes
    else:
        encoder = <int(*)(WriterRef, object)> _encode_other

    return encoder(writer, data)


cdef int _encode_callback_bytes(object data, object cb, object options) except -1:
    cdef WriterCallback writer = WriterCallback(
        Writer(
            _WriterNoop_reserve,
            _WriterCbBytes_append_c,
            _WriterCbBytes_append_s,
            <PyObject*> options,
        ),
        <PyObject*> cb,
    )

    if expect(not callable(cb), False):
        raise TypeError(f'type(cb)=={type(cb)!r} is not callable')

    return _encode(writer.base, data)


cdef int _encode_callback_str(object data, object cb, object options) except -1:
    cdef WriterCallback writer = WriterCallback(
        Writer(
            _WriterNoop_reserve,
            _WriterCbStr_append_c,
            _WriterCbStr_append_s,
            <PyObject*> options,
        ),
        <PyObject*> cb,
    )

    if expect(not callable(cb), False):
        raise TypeError(f'type(cb)=={type(cb)!r} is not callable')

    return _encode(writer.base, data)
