<commit_before>/*
 * waysome - wayland based window manager
 *
 * Copyright in alphabetical order:
 *
 * Copyright (C) 2014-2015 <NAME>
 * Copyright (C) 2014-2015 <NAME>
 * Copyright (C) 2014-2015 <NAME>
 * Copyright (C) 2014-2015 <NAME>
 * Copyright (C) 2014-2015 <NAME>
 *
 * This file is part of waysome.
 *
 * waysome is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * waysome is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with waysome. If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unicode/ustring.h>

#include "objects/string.h"

#include "objects/object.h"

/*
 *
 *
 * forward declarations
 *
 *
 */

static bool
deinit_callback(
    struct ws_object* const
);

/*
 *
 *
 * v-table
 *
 *
 */

ws_object_type_id WS_OBJECT_TYPE_ID_STRING = {
    .supertype = &WS_OBJECT_TYPE_ID_OBJECT,
    .typestr = "ws_string",

    .deinit_callback = deinit_callback,
    .hash_callback = NULL,
    .cmp_callback = (int (*) (struct ws_object const*, struct ws_object const*))
                    ws_string_cmp,
    .uuid_callback = NULL,

    .attribute_table = NULL,
    .function_table = NULL,
};

bool
ws_string_init(
    struct ws_string* self
) {
    if (!self) {
        return false;
    }

    self->str = calloc(1, sizeof(*self->str)); //initialize as empty string
    if (!self->str) {
        return false;
    }

    ws_object_init(&self->obj);
    self->obj.id = &WS_OBJECT_TYPE_ID_STRING;

    return true;
}

bool
ws_string_set_from_str(
    struct ws_string* self,
    struct ws_string* other
) {
    if (!self || !other) {
        return false;
    }

    ws_object_lock_write(&self->obj);
    ws_object_lock_read(&other->obj);

    size_t charcount = u_strlen(other->str);

    UChar* temp = realloc(self->str, (charcount + 1) * sizeof(*self->str));
    if (!temp) {
        ws_object_unlock(&other->obj);
        ws_object_unlock(&self->obj);
        return false;
    }
    self->str = temp;

    self->str = u_strcpy(self->str, other->str);

    ws_object_unlock(&other->obj);
    ws_object_unlock(&self->obj);

    return !!self->str;
}

struct ws_string*
ws_string_new(void)
{
    struct ws_string* wss = calloc(1, sizeof(*wss));

    if (wss) {
        ws_string_init(wss);
        wss->obj.settings |= WS_OBJECT_HEAPALLOCED;
    }

    return wss;
}

size_t
ws_string_len(
    struct ws_string* self
){
    if (self) {
        size_t len;
        ws_object_lock_read(&self->obj);
        len = u_strlen(self->str);
        ws_object_unlock(&self->obj);
        return len;
    }

    return 0;
}

struct ws_string*
ws_string_cat(
    struct ws_string* self,
    struct ws_string* other
){
    ws_object_lock_write(&self->obj);
    ws_object_lock_read(&other->obj); //!< @todo Thread-safeness!

    size_t new_len = u_strlen(self->str) + u_strlen(other->str) + 1;
    UChar* temp = realloc(self->str, new_len * sizeof(*self->str));
    if (!temp) {
        ws_object_unlock(&other->obj);
        ws_object_unlock(&self->obj);
        return NULL;
    }
    self->str = temp;

    u_strcat(self->str, other->str);

    ws_object_unlock(&other->obj);
    ws_object_unlock(&self->obj);

    return self;
}

struct ws_string*
ws_string_dupl(
    struct ws_string* self
){
    struct ws_string* nstr = ws_string_new();

    if (nstr) {
        bool res;
        res = ws_string_set_from_str(nstr, self);

        if (res) {
            return nstr;
        }
    }

    return NULL;
}

int
ws_string_cmp(
    struct ws_string* self,<commit_msg>Minify ws_string_dupl()<commit_after>/*
 * waysome - wayland based window manager
 *
 * Copyright in alphabetical order:
 *
 * Copyright (C) 2014-2015 <NAME>
 * Copyright (C) 2014-2015 <NAME>
 * Copyright (C) 2014-2015 <NAME>
 * Copyright (C) 2014-2015 <NAME>
 * Copyright (C) 2014-2015 <NAME>
 *
 * This file is part of waysome.
 *
 * waysome is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation, either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * waysome is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with waysome. If not, see <http://www.gnu.org/licenses/>.
 */

#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unicode/ustring.h>

#include "objects/string.h"

#include "objects/object.h"

/*
 *
 *
 * forward declarations
 *
 *
 */

static bool
deinit_callback(
    struct ws_object* const
);

/*
 *
 *
 * v-table
 *
 *
 */

ws_object_type_id WS_OBJECT_TYPE_ID_STRING = {
    .supertype = &WS_OBJECT_TYPE_ID_OBJECT,
    .typestr = "ws_string",

    .deinit_callback = deinit_callback,
    .hash_callback = NULL,
    .cmp_callback = (int (*) (struct ws_object const*, struct ws_object const*))
                    ws_string_cmp,
    .uuid_callback = NULL,

    .attribute_table = NULL,
    .function_table = NULL,
};

bool
ws_string_init(
    struct ws_string* self
) {
    if (!self) {
        return false;
    }

    self->str = calloc(1, sizeof(*self->str)); //initialize as empty string
    if (!self->str) {
        return false;
    }

    ws_object_init(&self->obj);
    self->obj.id = &WS_OBJECT_TYPE_ID_STRING;

    return true;
}

bool
ws_string_set_from_str(
    struct ws_string* self,
    struct ws_string* other
) {
    if (!self || !other) {
        return false;
    }

    ws_object_lock_write(&self->obj);
    ws_object_lock_read(&other->obj);

    size_t charcount = u_strlen(other->str);

    UChar* temp = realloc(self->str, (charcount + 1) * sizeof(*self->str));
    if (!temp) {
        ws_object_unlock(&other->obj);
        ws_object_unlock(&self->obj);
        return false;
    }
    self->str = temp;

    self->str = u_strcpy(self->str, other->str);

    ws_object_unlock(&other->obj);
    ws_object_unlock(&self->obj);

    return !!self->str;
}

struct ws_string*
ws_string_new(void)
{
    struct ws_string* wss = calloc(1, sizeof(*wss));

    if (wss) {
        ws_string_init(wss);
        wss->obj.settings |= WS_OBJECT_HEAPALLOCED;
    }

    return wss;
}

size_t
ws_string_len(
    struct ws_string* self
){
    if (self) {
        size_t len;
        ws_object_lock_read(&self->obj);
        len = u_strlen(self->str);
        ws_object_unlock(&self->obj);
        return len;
    }

    return 0;
}

struct ws_string*
ws_string_cat(
    struct ws_string* self,
    struct ws_string* other
){
    ws_object_lock_write(&self->obj);
    ws_object_lock_read(&other->obj); //!< @todo Thread-safeness!

    size_t new_len = u_strlen(self->str) + u_strlen(other->str) + 1;
    UChar* temp = realloc(self->str, new_len * sizeof(*self->str));
    if (!temp) {
        ws_object_unlock(&other->obj);
        ws_object_unlock(&self->obj);
        return NULL;
    }
    self->str = temp;

    u_strcat(self->str, other->str);

    ws_object_unlock(&other->obj);
    ws_object_unlock(&self->obj);

    return self;
}

struct ws_string*
ws_string_dupl(
    struct ws_string* self
){
    struct ws_string* nstr = ws_string_new();
    if (!nstr || !ws_string_set_from_str(nstr, self)) {
        return NULL;
    }

    return nstr;
}

int
ws_string_cmp(
    struct ws_string* self,
{'fraction_non_alphanumeric': 0.12671103855330906, 'fraction_numerical': 0.011804596257691825, 'mean_word_length': 2.9173635022134774, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 95, 'https://': 0, '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': '2317809', 'n_tokens_mistral': 2901, 'n_tokens_neox': 2708, 'n_words': 679}