in source/event_stream_headers.c [10:157]
static bool s_add_native_header(struct aws_array_list *native_headers, PyObject *src_tuple_py) {
bool success = false;
/* For reading bytes-like values. Needs to be released at end of function */
Py_buffer value_buf_py = {.obj = NULL};
const char *name;
size_t name_len;
PyObject *value_py; /* Borrowed reference, don't need to decref */
int type;
if (!PyArg_ParseTuple(src_tuple_py, "s#Oi", &name, (Py_ssize_t *)&name_len, &value_py, &type)) {
goto done;
}
const size_t name_len_max = sizeof(((struct aws_event_stream_header_value_pair *)0)->header_name) - 1;
if (name_len > name_len_max) {
PyErr_SetString(PyExc_ValueError, "Header.name exceeds max length");
goto done;
}
switch (type) {
case AWS_EVENT_STREAM_HEADER_BOOL_TRUE: {
if (aws_event_stream_add_bool_header(native_headers, name, name_len, true)) {
PyErr_SetAwsLastError();
goto done;
}
} break;
case AWS_EVENT_STREAM_HEADER_BOOL_FALSE: {
if (aws_event_stream_add_bool_header(native_headers, name, name_len, false)) {
PyErr_SetAwsLastError();
goto done;
}
} break;
case AWS_EVENT_STREAM_HEADER_BYTE: {
int32_t value = PyLong_AsLong(value_py);
if (PyErr_Occurred()) {
goto done;
}
/* simply casting to 8 bits, we already checked bounds when setting value in python */
if (aws_event_stream_add_byte_header(native_headers, name, name_len, (int8_t)value)) {
PyErr_SetAwsLastError();
goto done;
}
} break;
case AWS_EVENT_STREAM_HEADER_INT16: {
int32_t value = PyLong_AsLong(value_py);
if (PyErr_Occurred()) {
goto done;
}
/* simply casting to 16 bits, we already checked bounds when setting value in python */
if (aws_event_stream_add_int16_header(native_headers, name, name_len, (int16_t)value)) {
PyErr_SetAwsLastError();
goto done;
}
} break;
case AWS_EVENT_STREAM_HEADER_INT32: {
int32_t value = PyLong_AsLong(value_py);
if (PyErr_Occurred()) {
goto done;
}
if (aws_event_stream_add_int32_header(native_headers, name, name_len, value)) {
PyErr_SetAwsLastError();
goto done;
}
} break;
case AWS_EVENT_STREAM_HEADER_INT64: {
int64_t value = PyLong_AsLongLong(value_py);
if (PyErr_Occurred()) {
goto done;
}
if (aws_event_stream_add_int64_header(native_headers, name, name_len, value)) {
PyErr_SetAwsLastError();
goto done;
}
} break;
case AWS_EVENT_STREAM_HEADER_BYTE_BUF: {
if (PyObject_GetBuffer(value_py, &value_buf_py, PyBUF_SIMPLE) == -1) { /* New reference */
goto done;
}
if (aws_event_stream_add_bytebuf_header(
native_headers, name, name_len, value_buf_py.buf, value_buf_py.len, true /*copy*/)) {
PyErr_SetAwsLastError();
goto done;
}
} break;
case AWS_EVENT_STREAM_HEADER_STRING: {
size_t value_len;
const char *value = PyUnicode_AsUTF8AndSize(value_py, (Py_ssize_t *)&value_len);
if (!value) {
goto done;
}
if (value_len > UINT16_MAX) {
PyErr_SetString(PyExc_ValueError, "Header STRING value exceeds max length");
goto done;
}
if (aws_event_stream_add_string_header(
native_headers, name, name_len, value, (uint16_t)value_len, true /*copy*/)) {
PyErr_SetAwsLastError();
goto done;
}
} break;
case AWS_EVENT_STREAM_HEADER_TIMESTAMP: {
int64_t value = PyLong_AsLongLong(value_py);
if (PyErr_Occurred()) {
goto done;
}
if (aws_event_stream_add_timestamp_header(native_headers, name, name_len, value)) {
PyErr_SetAwsLastError();
goto done;
}
} break;
case AWS_EVENT_STREAM_HEADER_UUID: {
/* UUID.bytes was passed in */
if (PyObject_GetBuffer(value_py, &value_buf_py, PyBUF_SIMPLE) == -1) { /* New reference */
goto done;
}
if (value_buf_py.len != 16) {
PyErr_SetString(PyExc_ValueError, "UUID.bytes must be length 16");
goto done;
}
if (aws_event_stream_add_uuid_header(native_headers, name, name_len, (const uint8_t *)value_buf_py.buf)) {
PyErr_SetAwsLastError();
goto done;
}
} break;
default: {
PyErr_SetString(PyExc_ValueError, "Header.type has invalid value");
goto done;
} break;
}
success = true;
done:
if (value_buf_py.obj) {
PyBuffer_Release(&value_buf_py);
}
return success;
}