| | from cpython cimport PyBytes_AsString |
| |
|
| |
|
| | |
| | cdef extern from "Python.h": |
| | char* PyByteArray_AsString(bytearray ba) except NULL |
| |
|
| | from libc.stdint cimport uint32_t, uint64_t, uintmax_t |
| |
|
| |
|
| | cpdef void _websocket_mask_cython(bytes mask, bytearray data): |
| | """Note, this function mutates its `data` argument |
| | """ |
| | cdef: |
| | Py_ssize_t data_len, i |
| | |
| | unsigned char * in_buf |
| | const unsigned char * mask_buf |
| | uint32_t uint32_msk |
| | uint64_t uint64_msk |
| |
|
| | assert len(mask) == 4 |
| |
|
| | data_len = len(data) |
| | in_buf = <unsigned char*>PyByteArray_AsString(data) |
| | mask_buf = <const unsigned char*>PyBytes_AsString(mask) |
| | uint32_msk = (<uint32_t*>mask_buf)[0] |
| |
|
| | |
| | |
| |
|
| | if sizeof(size_t) >= 8: |
| | uint64_msk = uint32_msk |
| | uint64_msk = (uint64_msk << 32) | uint32_msk |
| |
|
| | while data_len >= 8: |
| | (<uint64_t*>in_buf)[0] ^= uint64_msk |
| | in_buf += 8 |
| | data_len -= 8 |
| |
|
| |
|
| | while data_len >= 4: |
| | (<uint32_t*>in_buf)[0] ^= uint32_msk |
| | in_buf += 4 |
| | data_len -= 4 |
| |
|
| | for i in range(0, data_len): |
| | in_buf[i] ^= mask_buf[i] |
| |
|