int aws_event_stream_message_from_buffer()

in source/event_stream.c [348:397]


int aws_event_stream_message_from_buffer(
    struct aws_event_stream_message *message,
    struct aws_allocator *alloc,
    struct aws_byte_buf *buffer) {
    AWS_ASSERT(buffer);

    message->alloc = alloc;
    message->owns_buffer = 0;

    if (AWS_UNLIKELY(buffer->len < AWS_EVENT_STREAM_PRELUDE_LENGTH + AWS_EVENT_STREAM_TRAILER_LENGTH)) {
        return aws_raise_error(AWS_ERROR_EVENT_STREAM_BUFFER_LENGTH_MISMATCH);
    }

    uint32_t message_length = aws_read_u32(buffer->buffer + TOTAL_LEN_OFFSET);

    if (AWS_UNLIKELY(message_length != buffer->len)) {
        return aws_raise_error(AWS_ERROR_EVENT_STREAM_BUFFER_LENGTH_MISMATCH);
    }

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

    uint32_t running_crc = aws_checksums_crc32(buffer->buffer, (int)PRELUDE_CRC_OFFSET, 0);
    uint32_t prelude_crc = aws_read_u32(buffer->buffer + PRELUDE_CRC_OFFSET);

    if (running_crc != prelude_crc) {
        return aws_raise_error(AWS_ERROR_EVENT_STREAM_PRELUDE_CHECKSUM_FAILURE);
    }

    running_crc = aws_checksums_crc32(
        buffer->buffer + PRELUDE_CRC_OFFSET,
        (int)(message_length - PRELUDE_CRC_OFFSET - AWS_EVENT_STREAM_TRAILER_LENGTH),
        running_crc);
    uint32_t message_crc = aws_read_u32(buffer->buffer + message_length - AWS_EVENT_STREAM_TRAILER_LENGTH);

    if (running_crc != message_crc) {
        return aws_raise_error(AWS_ERROR_EVENT_STREAM_MESSAGE_CHECKSUM_FAILURE);
    }

    message->message_buffer = buffer->buffer;

    if (aws_event_stream_message_headers_len(message) >
        message_length - AWS_EVENT_STREAM_PRELUDE_LENGTH - AWS_EVENT_STREAM_TRAILER_LENGTH) {
        message->message_buffer = 0;
        return aws_raise_error(AWS_ERROR_EVENT_STREAM_MESSAGE_INVALID_HEADERS_LEN);
    }

    return AWS_OP_SUCCESS;
}