int aws_event_stream_message_init()

in source/event_stream.c [286:345]


int aws_event_stream_message_init(
    struct aws_event_stream_message *message,
    struct aws_allocator *alloc,
    struct aws_array_list *headers,
    struct aws_byte_buf *payload) {

    size_t payload_len = payload ? payload->len : 0;

    uint32_t headers_length = aws_event_stream_compute_headers_required_buffer_len(headers);

    if (AWS_UNLIKELY(headers_length > AWS_EVENT_STREAM_MAX_HEADERS_SIZE)) {
        return aws_raise_error(AWS_ERROR_EVENT_STREAM_MESSAGE_FIELD_SIZE_EXCEEDED);
    }

    uint32_t total_length =
        (uint32_t)(AWS_EVENT_STREAM_PRELUDE_LENGTH + headers_length + payload_len + AWS_EVENT_STREAM_TRAILER_LENGTH);

    if (AWS_UNLIKELY(total_length < headers_length || total_length < payload_len)) {
        return aws_raise_error(AWS_ERROR_OVERFLOW_DETECTED);
    }

    if (AWS_UNLIKELY(total_length > AWS_EVENT_STREAM_MAX_MESSAGE_SIZE)) {
        return aws_raise_error(AWS_ERROR_EVENT_STREAM_MESSAGE_FIELD_SIZE_EXCEEDED);
    }

    message->alloc = alloc;
    message->message_buffer = aws_mem_acquire(message->alloc, total_length);

    if (message->message_buffer) {
        message->owns_buffer = 1;
        aws_write_u32(total_length, message->message_buffer);
        uint8_t *buffer_offset = message->message_buffer + sizeof(total_length);
        aws_write_u32(headers_length, buffer_offset);
        buffer_offset += sizeof(headers_length);

        uint32_t running_crc =
            aws_checksums_crc32(message->message_buffer, (int)(buffer_offset - message->message_buffer), 0);

        const uint8_t *message_crc_boundary_start = buffer_offset;
        aws_write_u32(running_crc, buffer_offset);
        buffer_offset += sizeof(running_crc);

        if (headers_length) {
            buffer_offset += aws_event_stream_write_headers_to_buffer(headers, buffer_offset);
        }

        if (payload) {
            memcpy(buffer_offset, payload->buffer, payload->len);
            buffer_offset += payload->len;
        }

        running_crc = aws_checksums_crc32(
            message_crc_boundary_start, (int)(buffer_offset - message_crc_boundary_start), running_crc);
        aws_write_u32(running_crc, buffer_offset);

        return AWS_OP_SUCCESS;
    }

    return aws_raise_error(AWS_ERROR_OOM);
}