<commit_before>/*
 * Copyright 2014-2022 Real Logic Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <exception>
#include <functional>
#include <string>
#include <limits>

#include <gtest/gtest.h>

#include "aeron_client_test_utils.h"

extern "C"
{
#include "aeron_image.h"
}

#define FILE_PAGE_SIZE (4 * 1024)

#define SUB_URI "aeron:udp?endpoint=localhost:24567"
#define STREAM_ID (101)
#define SESSION_ID (110)
#define REGISTRATION_ID (27)
#define SUBSCRIBER_POSITION_ID (49)

#define INITIAL_TERM_ID (1234)

using namespace aeron::test;

class ImageTest : public testing::Test
{
public:
    ImageTest() = default;

    ~ImageTest() override
    {
        if (!m_filename.empty())
        {
            aeron_log_buffer_delete(m_image->log_buffer);
            aeron_image_delete(m_image);

            ::unlink(m_filename.c_str());
        }
    }

    int64_t createImage()
    {
        aeron_image_t *image = nullptr;
        aeron_log_buffer_t *log_buffer = nullptr;
        std::string filename = tempFileName();

        createLogFile(filename);

        if (aeron_log_buffer_create(&log_buffer, filename.c_str(), m_correlationId, false) < 0)
        {
            throw std::runtime_error("could not create log_buffer: " + std::string(aeron_errmsg()));
        }

        if (aeron_image_create(
            &image,
            nullptr,
            nullptr,
            log_buffer,
            SUBSCRIBER_POSITION_ID,
            &m_sub_pos,
            m_correlationId,
            (int32_t)m_correlationId,
            "none",
            strlen("none")) < 0)
        {
            throw std::runtime_error("could not create image: " + std::string(aeron_errmsg()));
        }

        auto *metadata = (aeron_logbuffer_metadata_t *)log_buffer->mapped_raw_log.log_meta_data.addr;

        m_image = image;
        m_filename = filename;

        m_term_length = metadata->term_length;
        m_initial_term_id = metadata->initial_term_id;
        m_position_bits_to_shift = (size_t)aeron_number_of_trailing_zeroes(metadata->term_length);

        return m_correlationId++;
    }

    void appendMessage(int64_t position, size_t length)
    {
        auto *metadata = (aeron_logbuffer_metadata_t *)m_image->log_buffer->mapped_raw_log.log_meta_data.addr;
        const size_t index = aeron_logbuffer_index_by_position(position, m_position_bits_to_shift);
        aeron_mapped_buffer_t *term_buffer = &m_image->log_buffer->mapped_raw_log.term_buffers[index];
        uint8_t buffer[1024] = { 0 };
        int32_t term_id = aeron_logbuffer_compute_term_id_from_position(
            position, m_position_bits_to_shift, m_initial_term_id);
        int32_t tail_offset = (int32_t)position & (m_term_length - 1);

        metadata->term_tail_counters[index] = static_cast<int64_t>(term_id) << 32 | tail_offset;

        const size_t frame_length = length + AERON_DATA_HEADER_LENGTH;
        const auto aligned_frame_length = (int32_t)AERON_ALIGN(frame_length, AERON_LOGBUFFER_FRAME_ALIGNMENT);

        int32_t resulting_offset = tail_offset + aligned_frame_length;
        metadata->term_tail_counters[index] = static_cast<int64_t>(term_id) << 32 | resulting_offset;

        size_t term_length = term_buffer->length;
        auto *header = (aeron_data_header_t *)(term_buffer->addr + tail_offset);

        if (resulting_offset > term_length)
        {
            if (tail_offset < term_length)
            {
                const int32_t padding_length = (int32_t)term_length - tail_offset;

                header->frame_header.version = AERON_FRAME_HEADER_VERSION;
                header->frame_header.flags = AERON_DATA_HEADER_BEGIN_FLAG | AERON_DATA_HEADER_END_FLAG;
                header->frame_header.type = AERON_HDR_TYPE_PAD;
                header->term_offset = tail_offset;
                header->session_id = SESSION_ID;
                header->stream_id = STREAM_ID;
                header->term_id = term_id;

                AERON_PUT_ORDERED(header->frame_header.frame_length, padding_length);
            }
        }
        else
        {
            header->frame_header.version = AERON_FRAME_HEADER_VERSION;
            header->frame_header.flags = AERON_DATA_HEADER_BEGIN_FLAG | AERON_DATA_HEADER_END_FLAG;
            header->frame_header.type = AERON_HDR_TYPE_DATA;
            header->term_offset = tail_offset;
            header->session_id = SESSION_ID;
            header->stream_id = STREAM_ID;
            header->term_id = term_id;

            memcpy(term_buffer->addr + tail_offset + AERON_DATA_HEADER_LENGTH, buffer, length);

            AERON_PUT_ORDERED(header->frame_header.frame_length, (int32_t)frame_length);
        }
    }

    static void fragment_handler(void *clientd, const uint8_t *buffer, size_t length, aeron_header_t *header)
    {<commit_msg>[C] Fix comparison of different signed types.<commit_after>/*
 * Copyright 2014-2022 Real Logic Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <exception>
#include <functional>
#include <string>
#include <limits>

#include <gtest/gtest.h>

#include "aeron_client_test_utils.h"

extern "C"
{
#include "aeron_image.h"
}

#define FILE_PAGE_SIZE (4 * 1024)

#define SUB_URI "aeron:udp?endpoint=localhost:24567"
#define STREAM_ID (101)
#define SESSION_ID (110)
#define REGISTRATION_ID (27)
#define SUBSCRIBER_POSITION_ID (49)

#define INITIAL_TERM_ID (1234)

using namespace aeron::test;

class ImageTest : public testing::Test
{
public:
    ImageTest() = default;

    ~ImageTest() override
    {
        if (!m_filename.empty())
        {
            aeron_log_buffer_delete(m_image->log_buffer);
            aeron_image_delete(m_image);

            ::unlink(m_filename.c_str());
        }
    }

    int64_t createImage()
    {
        aeron_image_t *image = nullptr;
        aeron_log_buffer_t *log_buffer = nullptr;
        std::string filename = tempFileName();

        createLogFile(filename);

        if (aeron_log_buffer_create(&log_buffer, filename.c_str(), m_correlationId, false) < 0)
        {
            throw std::runtime_error("could not create log_buffer: " + std::string(aeron_errmsg()));
        }

        if (aeron_image_create(
            &image,
            nullptr,
            nullptr,
            log_buffer,
            SUBSCRIBER_POSITION_ID,
            &m_sub_pos,
            m_correlationId,
            (int32_t)m_correlationId,
            "none",
            strlen("none")) < 0)
        {
            throw std::runtime_error("could not create image: " + std::string(aeron_errmsg()));
        }

        auto *metadata = (aeron_logbuffer_metadata_t *)log_buffer->mapped_raw_log.log_meta_data.addr;

        m_image = image;
        m_filename = filename;

        m_term_length = metadata->term_length;
        m_initial_term_id = metadata->initial_term_id;
        m_position_bits_to_shift = (size_t)aeron_number_of_trailing_zeroes(metadata->term_length);

        return m_correlationId++;
    }

    void appendMessage(int64_t position, size_t length)
    {
        auto *metadata = (aeron_logbuffer_metadata_t *)m_image->log_buffer->mapped_raw_log.log_meta_data.addr;
        const size_t index = aeron_logbuffer_index_by_position(position, m_position_bits_to_shift);
        aeron_mapped_buffer_t *term_buffer = &m_image->log_buffer->mapped_raw_log.term_buffers[index];
        uint8_t buffer[1024] = { 0 };
        int32_t term_id = aeron_logbuffer_compute_term_id_from_position(
            position, m_position_bits_to_shift, m_initial_term_id);
        int32_t tail_offset = (int32_t)position & (m_term_length - 1);

        metadata->term_tail_counters[index] = static_cast<int64_t>(term_id) << 32 | tail_offset;

        const size_t frame_length = length + AERON_DATA_HEADER_LENGTH;
        const auto aligned_frame_length = (int32_t)AERON_ALIGN(frame_length, AERON_LOGBUFFER_FRAME_ALIGNMENT);

        int32_t resulting_offset = tail_offset + aligned_frame_length;
        metadata->term_tail_counters[index] = static_cast<int64_t>(term_id) << 32 | resulting_offset;

        auto term_length = static_cast<int32_t>(term_buffer->length);
        auto *header = (aeron_data_header_t *)(term_buffer->addr + tail_offset);

        if (resulting_offset > term_length)
        {
            if (tail_offset < term_length)
            {
                const int32_t padding_length = term_length - tail_offset;

                header->frame_header.version = AERON_FRAME_HEADER_VERSION;
                header->frame_header.flags = AERON_DATA_HEADER_BEGIN_FLAG | AERON_DATA_HEADER_END_FLAG;
                header->frame_header.type = AERON_HDR_TYPE_PAD;
                header->term_offset = tail_offset;
                header->session_id = SESSION_ID;
                header->stream_id = STREAM_ID;
                header->term_id = term_id;

                AERON_PUT_ORDERED(header->frame_header.frame_length, padding_length);
            }
        }
        else
        {
            header->frame_header.version = AERON_FRAME_HEADER_VERSION;
            header->frame_header.flags = AERON_DATA_HEADER_BEGIN_FLAG | AERON_DATA_HEADER_END_FLAG;
            header->frame_header.type = AERON_HDR_TYPE_DATA;
            header->term_offset = tail_offset;
            header->session_id = SESSION_ID;
            header->stream_id = STREAM_ID;
            header->term_id = term_id;

            memcpy(term_buffer->addr + tail_offset + AERON_DATA_HEADER_LENGTH, buffer, length);

            AERON_PUT_ORDERED(header->frame_header.frame_length, (int32_t)frame_length);
        }
    }

    static void fragment_handler(void *clientd, const uint8_t *buffer, size_t length, aeron_header_t *header)
    {
{'fraction_non_alphanumeric': 0.09119761037991225, 'fraction_numerical': 0.014188369270979185, 'mean_word_length': 2.8931686046511627, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 80, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4813597', 'n_tokens_mistral': 3512, 'n_tokens_neox': 3350, 'n_words': 648}