<commit_before>/* 
 * Copyright (c) 2005-2008 by KoanLogic s.r.l. - All rights reserved.  
 */

#include <u/libu_conf.h>
#include <u/libu.h>
#include <toolbox/array.h>

typedef struct __slot_s { int set; void *data; } __slot_t;

struct u_array_s
{
    __slot_t *base;
    size_t nslot;               /* total number of slots (0..n) */
    size_t nelem;               /* number of busy slots (0..n)  */
    size_t type_sz;             /* size of the hosted type */
    void (*cb_free)(void *);    /* optional free function for hosted elements */
};

/**
 *  \defgroup array Dynamic Arrays
 *  \{
 */

/**
 *  \brief  Create a new array object
 *
 *  \param type_sz  the size of the hosted type in bytes
 *  \param nslot    the initial number of slots to be created  (set it to \c 0 
 *                  if you don't want to specify an initial array size)
 *  \param pa       the newly created array object as a result argument
 *
 *  \return \c 0 on success, \c ~0 on error
 */
int u_array_create (size_t type_sz, size_t nslot, u_array_t **pa)
{
    u_array_t *a = NULL;

    dbg_return_if (pa == NULL, ~0);
    dbg_return_if (type_sz == 0, ~0);

    a = u_zalloc(sizeof(u_array_t));
    warn_err_sif (a == NULL);

    /* if we've been requested to allocate some slot, do it now */
    if ((a->nslot = nslot) != 0)
        warn_err_sif ((a->base = u_zalloc(nslot * sizeof(__slot_t))) == NULL);

    a->nelem = 0;
    a->type_sz = type_sz;
    a->cb_free = NULL;
 
    *pa = a;
    
    return 0;
err:
    return ~0;
}

/**
 *  \brief  Set an element at a given slot
 *
 *  \param a    the array object
 *  \param idx  the index at which \p elem is to be inserted
 *  \param elem the element that shall be inserted
 *
 *  \return \c 0 on success, \c ~0 on error
 */
int u_array_set_n (u_array_t *a, size_t idx, const void *elem, void **oelem)
{
    __slot_t *s;

    dbg_return_if (a == NULL, ~0);

    if (idx > a->nslot)
        warn_err_if (u_array_grow(a, U_ARRAY_GROW_AUTO));

    /* get slot location and copy elem there */
    s = a->base + idx;

    if (s->set)
    {
        warn("overriding an already set slot");
        if (oelem)
            *oelem = s->data;
    }
    else
        warn_err_sif ((s->data = u_zalloc(a->type_sz)) == NULL);

    memcpy(s->data, elem, a->type_sz);
    s->set = 1;

    a->nelem += 1;

    return 0;
err:
    return ~0;
}

/**
 *  \brief  Add the supplied number of slots to the array
 *
 *  \param a    the array object
 *  \param more the number of elements that shall be added. 
 *              If \c U_ARRAY_GROW_AUTO is supplied, the default resize
 *              strategy is used (i.e. size is doubled)
 *
 *  \return \c 0 on success, \c ~0 on error
 */
int u_array_grow (u_array_t *a, size_t more)
{
    size_t new_nslot;
    void *new_base;

    dbg_return_if (a == NULL, ~0);<commit_msg>[libu] s/memcpy/assignement/ in u_array_put_n<commit_after>/* 
 * Copyright (c) 2005-2008 by KoanLogic s.r.l. - All rights reserved.  
 */

#include <u/libu_conf.h>
#include <u/libu.h>
#include <toolbox/array.h>

typedef struct __slot_s { int set; void *data; } __slot_t;

struct u_array_s
{
    __slot_t *base;
    size_t nslot;               /* total number of slots (0..n) */
    size_t nelem;               /* number of busy slots (0..n)  */
    size_t type_sz;             /* size of the hosted type */
    void (*cb_free)(void *);    /* optional free function for hosted elements */
};

/**
 *  \defgroup array Dynamic Arrays
 *  \{
 */

/**
 *  \brief  Create a new array object
 *
 *  \param type_sz  the size of the hosted type in bytes
 *  \param nslot    the initial number of slots to be created  (set it to \c 0 
 *                  if you don't want to specify an initial array size)
 *  \param pa       the newly created array object as a result argument
 *
 *  \return \c 0 on success, \c ~0 on error
 */
int u_array_create (size_t type_sz, size_t nslot, u_array_t **pa)
{
    u_array_t *a = NULL;

    dbg_return_if (pa == NULL, ~0);
    dbg_return_if (type_sz == 0, ~0);

    a = u_zalloc(sizeof(u_array_t));
    warn_err_sif (a == NULL);

    /* if we've been requested to allocate some slot, do it now */
    if ((a->nslot = nslot) != 0)
        warn_err_sif ((a->base = u_zalloc(nslot * sizeof(__slot_t))) == NULL);

    a->nelem = 0;
    a->type_sz = type_sz;
    a->cb_free = NULL;
 
    *pa = a;
    
    return 0;
err:
    return ~0;
}

/**
 *  \brief  Set an element at a given slot
 *
 *  \param a    the array object
 *  \param idx  the index at which \p elem is to be inserted
 *  \param elem the element that shall be inserted
 *
 *  \return \c 0 on success, \c ~0 on error
 */
int u_array_set_n (u_array_t *a, size_t idx, const void *elem, void **oelem)
{
    __slot_t *s;

    dbg_return_if (a == NULL, ~0);

    if (idx > a->nslot)
        warn_err_if (u_array_grow(a, U_ARRAY_GROW_AUTO));

    /* get slot location and copy elem there */
    s = a->base + idx;

    if (s->set)
    {
        warn("overriding an already set slot");
        if (oelem)
            *oelem = s->data;
    }
    else
        warn_err_sif ((s->data = u_zalloc(a->type_sz)) == NULL);

    /* copyin data */
    s->data = elem;
    s->set = 1;

    a->nelem += 1;

    return 0;
err:
    return ~0;
}

/**
 *  \brief  Add the supplied number of slots to the array
 *
 *  \param a    the array object
 *  \param more the number of elements that shall be added. 
 *              If \c U_ARRAY_GROW_AUTO is supplied, the default resize
 *              strategy is used (i.e. size is doubled)
 *
 *  \return \c 0 on success, \c ~0 on error
 */
int u_array_grow (u_array_t *a, size_t more)
{
    __slot_t *new_base;
    size_t new_nslot;

    dbg_return_if (a == NULL, ~0);
{'fraction_non_alphanumeric': 0.12524051075739023, 'fraction_numerical': 0.010495014867937729, 'mean_word_length': 2.1908482142857144, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '3266221', 'n_tokens_mistral': 2153, 'n_tokens_neox': 2061, 'n_words': 693}