<commit_before>/*  =========================================================================
    zstr - sending and receiving strings

    Copyright (c) the Contributors as noted in the AUTHORS file.
    This file is part of CZMQ, the high-level C binding for 0MQ:
    http://czmq.zeromq.org.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.
    =========================================================================
*/

/*
@header
    The zstr class provides utility functions for sending and receiving C
    strings across 0MQ sockets. It sends strings without a terminating null,
    and appends a null byte on received strings. This class is for simple
    message sending.
@discuss
           Memory                       Wire
           +-------------+---+          +---+-------------+
    Send   | S t r i n g | 0 |  ---->   | 6 | S t r i n g |
           +-------------+---+          +---+-------------+

           Wire                         Heap
           +---+-------------+          +-------------+---+
    Recv   | 6 | S t r i n g |  ---->   | S t r i n g | 0 |
           +---+-------------+          +-------------+---+
@end
*/

#include "czmq_classes.h"
#ifdef HAVE_LIBLZ4
#include <lz4.h>

static void
s_free_compress (void *data, void *hint)
{
    free (data);
}
#endif

static int
s_send_string (void *dest, bool more, char *string, bool compress)
{
    assert (dest);
    void *handle = zsock_resolve (dest);

    size_t len = strlen (string);
    zmq_msg_t message;

    if (compress) {
#ifdef HAVE_LIBLZ4
        size_t compressed_len = LZ4_compressBound (len);
        if (compressed_len == 0)
            return -1;

        char *buffer = (char *)malloc (compressed_len );
        if (!buffer)
            return -1;

        //  LZ4_compress has been deprecated in newer versions, but
        //  the new APIs are not available for older distros
#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
        int rc = LZ4_compress_default (string, buffer, len, compressed_len);
#else
        int rc = LZ4_compress (string, buffer, len);
#endif
        if (rc == 0) {
            free (buffer);
            return -1;
        }

        zmq_msg_t size_frame;
        zmq_msg_init_size (&size_frame, sizeof (size_t));
        memcpy (zmq_msg_data (&size_frame), &len, sizeof (size_t));

#if defined (ZMQ_SERVER)
        //  Set routing ID if we're sending to a SERVER socket (ZMQ 4.2 and later)
        if (zsock_is (dest) && zsock_type (dest) == ZMQ_SERVER)
            zmq_msg_set_routing_id (&size_frame, zsock_routing_id ((zsock_t *) dest));
#endif
        if (zmq_sendmsg (handle, &size_frame, ZMQ_SNDMORE) == -1) {
            free (buffer);
            zmq_msg_close (&size_frame);
            return -1;
        }

        //  Optimisation: use zero-copy send. The common use case for
        //  compressed data is large buffers, so avoiding an extra malloc + copy
        //  is worth the extra few lines of code
        rc = zmq_msg_init_data (&message, buffer, rc, s_free_compress, NULL);
        //  Assert on OOM
        assert (rc != -1);
#else
        return -1;
#endif
    } else {
        zmq_msg_init_size (&message, len);
        memcpy (zmq_msg_data (&message), string, len);
    }

#if defined (ZMQ_SERVER)
    //  Set routing ID if we're sending to a SERVER socket (ZMQ 4.2 and later)
    if (zsock_is (dest) && zsock_type (dest) == ZMQ_SERVER)
        zmq_msg_set_routing_id (&message, zsock_routing_id ((zsock_t *) dest));
#endif
    if (zmq_sendmsg (handle, &message, more? ZMQ_SNDMORE: 0) == -1) {
        zmq_msg_close (&message);
        return -1;
    }
    else
        return 0;
}


//  --------------------------------------------------------------------------
//  Receive C string from socket. Caller must free returned string using
//  zstr_free(). Returns NULL if the context is being terminated or the
//  process was interrupted.

char *
zstr_recv (void *source)
{
    assert (source);
    void *handle = zsock_resolve (source);<commit_msg>Problem: zstr_send* do not check malloc result<commit_after>/*  =========================================================================
    zstr - sending and receiving strings

    Copyright (c) the Contributors as noted in the AUTHORS file.
    This file is part of CZMQ, the high-level C binding for 0MQ:
    http://czmq.zeromq.org.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.
    =========================================================================
*/

/*
@header
    The zstr class provides utility functions for sending and receiving C
    strings across 0MQ sockets. It sends strings without a terminating null,
    and appends a null byte on received strings. This class is for simple
    message sending.
@discuss
           Memory                       Wire
           +-------------+---+          +---+-------------+
    Send   | S t r i n g | 0 |  ---->   | 6 | S t r i n g |
           +-------------+---+          +---+-------------+

           Wire                         Heap
           +---+-------------+          +-------------+---+
    Recv   | 6 | S t r i n g |  ---->   | S t r i n g | 0 |
           +---+-------------+          +-------------+---+
@end
*/

#include "czmq_classes.h"
#ifdef HAVE_LIBLZ4
#include <lz4.h>

static void
s_free_compress (void *data, void *hint)
{
    free (data);
}
#endif

static int
s_send_string (void *dest, bool more, char *string, bool compress)
{
    assert (dest);
    void *handle = zsock_resolve (dest);

    size_t len = strlen (string);
    zmq_msg_t message;

    if (compress) {
#ifdef HAVE_LIBLZ4
        size_t compressed_len = LZ4_compressBound (len);
        if (compressed_len == 0)
            return -1;

        char *buffer = (char *)malloc (compressed_len );
        if (!buffer)
            return -1;

        //  LZ4_compress has been deprecated in newer versions, but
        //  the new APIs are not available for older distros
#if LZ4_VERSION_MAJOR >= 1 && LZ4_VERSION_MINOR >= 7
        int rc = LZ4_compress_default (string, buffer, len, compressed_len);
#else
        int rc = LZ4_compress (string, buffer, len);
#endif
        if (rc == 0) {
            free (buffer);
            return -1;
        }

        zmq_msg_t size_frame;
        zmq_msg_init_size (&size_frame, sizeof (size_t));
        memcpy (zmq_msg_data (&size_frame), &len, sizeof (size_t));

#if defined (ZMQ_SERVER)
        //  Set routing ID if we're sending to a SERVER socket (ZMQ 4.2 and later)
        if (zsock_is (dest) && zsock_type (dest) == ZMQ_SERVER)
            zmq_msg_set_routing_id (&size_frame, zsock_routing_id ((zsock_t *) dest));
#endif
        if (zmq_sendmsg (handle, &size_frame, ZMQ_SNDMORE) == -1) {
            free (buffer);
            zmq_msg_close (&size_frame);
            return -1;
        }

        //  Optimisation: use zero-copy send. The common use case for
        //  compressed data is large buffers, so avoiding an extra malloc + copy
        //  is worth the extra few lines of code
        rc = zmq_msg_init_data (&message, buffer, rc, s_free_compress, NULL);
        //  Assert on OOM
        assert (rc != -1);
#else
        return -1;
#endif
    } else {
        int rc = zmq_msg_init_size (&message, len);
        assert (rc == 0);
        memcpy (zmq_msg_data (&message), string, len);
    }

#if defined (ZMQ_SERVER)
    //  Set routing ID if we're sending to a SERVER socket (ZMQ 4.2 and later)
    if (zsock_is (dest) && zsock_type (dest) == ZMQ_SERVER)
        zmq_msg_set_routing_id (&message, zsock_routing_id ((zsock_t *) dest));
#endif
    if (zmq_sendmsg (handle, &message, more? ZMQ_SNDMORE: 0) == -1) {
        zmq_msg_close (&message);
        return -1;
    }
    else
        return 0;
}


//  --------------------------------------------------------------------------
//  Receive C string from socket. Caller must free returned string using
//  zstr_free(). Returns NULL if the context is being terminated or the
//  process was interrupted.

char *
zstr_recv (void *source)
{
    assert (source);
    void *handle = zsock_resolve (source);
{'fraction_non_alphanumeric': 0.17750774362639982, 'fraction_numerical': 0.009173218965928044, 'mean_word_length': 1.9189847009735743, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5339465', 'n_tokens_mistral': 2638, 'n_tokens_neox': 2506, 'n_words': 866}