<commit_before>//
//  CFunc::Pointer class
// 
//  See Copyright Notice in cfunc.h
//

#include "cfunc_pointer.h"
#include "cfunc_type.h"
#include "cfunc_call.h"

#include "mruby/class.h"
#include "mruby/data.h"
#include "mruby/string.h"
#include "mruby/variable.h"

#include "ffi.h"

#include <stdio.h>
#include <string.h>
#include <stdbool.h>



static void
cfunc_pointer_destructor(mrb_state *mrb, void *p)
{
    struct cfunc_type_data *data = (struct cfunc_type_data *)p;
    if(data->autofree) {
        free(get_cfunc_pointer_data(data));
    }
    free(p);
}


static struct mrb_data_type cfunc_pointer_data_type = {
    "cfunc_pointer", cfunc_pointer_destructor,
};


void* get_cfunc_pointer_data(struct cfunc_type_data *data)
{
    if(data->refer) {
        return *(void**)data->value._pointer;
    }
    else {
        return data->value._pointer;
    }
}


void set_cfunc_pointer_data(struct cfunc_type_data *data, void *p)
{
    if(data->refer) {
        *(void**)data->value._pointer = p;
    }
    else {
        data->value._pointer = p;
    }
}


mrb_value
cfunc_pointer_class_malloc(mrb_state *mrb, mrb_value klass)
{
    struct cfunc_type_data *data = malloc(sizeof(struct cfunc_type_data));
    data->refer = false;
    data->autofree = false;

    mrb_int alloc_size;
    mrb_get_args(mrb, "i", &alloc_size);
    
    set_cfunc_pointer_data(data, malloc(alloc_size));
    
    return mrb_obj_value(Data_Wrap_Struct(mrb, mrb_class_ptr(klass), &cfunc_pointer_data_type, data));
}


mrb_value
cfunc_pointer_new_with_pointer(mrb_state *mrb, void *p, bool autofree)
{
    struct cfunc_type_data *data = malloc(sizeof(struct cfunc_type_data));
    data->refer = false;
    data->autofree = autofree;

    set_cfunc_pointer_data(data, p);

    struct cfunc_state *state = cfunc_state(mrb, NULL);
    return mrb_obj_value(Data_Wrap_Struct(mrb, state->pointer_class, &cfunc_pointer_data_type, data));
}


mrb_value
cfunc_pointer_refer(mrb_state *mrb, mrb_value klass)
{
    struct RClass *c = mrb_class_ptr(klass);
    struct cfunc_type_data *data = malloc(sizeof(struct cfunc_type_data));
    data->refer = true;
    data->autofree = false;

    mrb_value pointer;
    mrb_get_args(mrb, "o", &pointer);

    data->value._pointer = cfunc_pointer_ptr(pointer);

    struct RObject *obj = (struct RObject *)Data_Wrap_Struct(mrb, c, &cfunc_pointer_data_type, data);
    mrb_obj_iv_set(mrb, obj, mrb_intern(mrb, "parent_pointer"), pointer); // keep for GC
    return mrb_obj_value(obj);
}


mrb_value
cfunc_pointer_initialize(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data;
    data = mrb_get_datatype(mrb, self, &cfunc_pointer_data_type);
    if (!data) {
        data = malloc(sizeof(struct cfunc_type_data));
        DATA_PTR(self) = data;
        DATA_TYPE(self) = &cfunc_pointer_data_type;   
    }
    data->refer = false;
    data->autofree = false;

    mrb_value ptr;
    int argc = mrb_get_args(mrb, "|o", &ptr);
    if(argc == 0) {
        set_cfunc_pointer_data(data, NULL);
    }
    else {
        set_cfunc_pointer_data(data, cfunc_pointer_ptr(ptr));
    }

    return self;
}


mrb_value
cfunc_pointer_realloc(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data = DATA_PTR(self);
    
    mrb_int alloc_size;
    mrb_get_args(mrb, "i", &alloc_size);
    set_cfunc_pointer_data(data, realloc(get_cfunc_pointer_data(data), alloc_size));
    
    return self;
}


mrb_value
cfunc_pointer_free(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data = DATA_PTR(self);
    
    free(get_cfunc_pointer_data(data));
    data->autofree = false;
    set_cfunc_pointer_data(data, NULL);
    
    return self;
}


mrb_value
cfunc_pointer_inspect(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data = DATA_PTR(self);
    
    mrb_value type = mrb_funcall(mrb, mrb_obj_value(mrb_class(mrb, self)), "type", 0);
    const char* classname = mrb_class_name(mrb, (struct RClass*)mrb_object(type));
    if(!classname) {
        classname = "Unknown pointer";
    }

    char cstr[256];
    snprintf(cstr, sizeof(cstr), "<%s pointer=%p>", classname, get_cfunc_pointer_data(data));
    
    return mrb_str_new2(mrb, cstr);
}


mrb_value
cfunc_pointer_is_null(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data = DATA_PTR(self);
    return (get_cfunc_pointer_data(data) == NULL) ? mrb_true_value() : mrb_false_value();
}


mrb_value
cfunc_pointer_autofree(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data = DATA_PTR(self);
    data->autofree = true;
    return self;
}


mrb_value
cfunc_pointer_to_s(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data = DATA_PTR(self);
    size_t len;
    mrb_value str;
    struct RString *s;
    const char* p = (const char*)get_cfunc_pointer_data(data);
        
    len = strlen(p);<commit_msg>replace removed mrb_str_new2 with mrb_str_new_cstr<commit_after>//
//  CFunc::Pointer class
// 
//  See Copyright Notice in cfunc.h
//

#include "cfunc_pointer.h"
#include "cfunc_type.h"
#include "cfunc_call.h"

#include "mruby/class.h"
#include "mruby/data.h"
#include "mruby/string.h"
#include "mruby/variable.h"

#include "ffi.h"

#include <stdio.h>
#include <string.h>
#include <stdbool.h>



static void
cfunc_pointer_destructor(mrb_state *mrb, void *p)
{
    struct cfunc_type_data *data = (struct cfunc_type_data *)p;
    if(data->autofree) {
        free(get_cfunc_pointer_data(data));
    }
    free(p);
}


static struct mrb_data_type cfunc_pointer_data_type = {
    "cfunc_pointer", cfunc_pointer_destructor,
};


void* get_cfunc_pointer_data(struct cfunc_type_data *data)
{
    if(data->refer) {
        return *(void**)data->value._pointer;
    }
    else {
        return data->value._pointer;
    }
}


void set_cfunc_pointer_data(struct cfunc_type_data *data, void *p)
{
    if(data->refer) {
        *(void**)data->value._pointer = p;
    }
    else {
        data->value._pointer = p;
    }
}


mrb_value
cfunc_pointer_class_malloc(mrb_state *mrb, mrb_value klass)
{
    struct cfunc_type_data *data = malloc(sizeof(struct cfunc_type_data));
    data->refer = false;
    data->autofree = false;

    mrb_int alloc_size;
    mrb_get_args(mrb, "i", &alloc_size);
    
    set_cfunc_pointer_data(data, malloc(alloc_size));
    
    return mrb_obj_value(Data_Wrap_Struct(mrb, mrb_class_ptr(klass), &cfunc_pointer_data_type, data));
}


mrb_value
cfunc_pointer_new_with_pointer(mrb_state *mrb, void *p, bool autofree)
{
    struct cfunc_type_data *data = malloc(sizeof(struct cfunc_type_data));
    data->refer = false;
    data->autofree = autofree;

    set_cfunc_pointer_data(data, p);

    struct cfunc_state *state = cfunc_state(mrb, NULL);
    return mrb_obj_value(Data_Wrap_Struct(mrb, state->pointer_class, &cfunc_pointer_data_type, data));
}


mrb_value
cfunc_pointer_refer(mrb_state *mrb, mrb_value klass)
{
    struct RClass *c = mrb_class_ptr(klass);
    struct cfunc_type_data *data = malloc(sizeof(struct cfunc_type_data));
    data->refer = true;
    data->autofree = false;

    mrb_value pointer;
    mrb_get_args(mrb, "o", &pointer);

    data->value._pointer = cfunc_pointer_ptr(pointer);

    struct RObject *obj = (struct RObject *)Data_Wrap_Struct(mrb, c, &cfunc_pointer_data_type, data);
    mrb_obj_iv_set(mrb, obj, mrb_intern(mrb, "parent_pointer"), pointer); // keep for GC
    return mrb_obj_value(obj);
}


mrb_value
cfunc_pointer_initialize(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data;
    data = mrb_get_datatype(mrb, self, &cfunc_pointer_data_type);
    if (!data) {
        data = malloc(sizeof(struct cfunc_type_data));
        DATA_PTR(self) = data;
        DATA_TYPE(self) = &cfunc_pointer_data_type;   
    }
    data->refer = false;
    data->autofree = false;

    mrb_value ptr;
    int argc = mrb_get_args(mrb, "|o", &ptr);
    if(argc == 0) {
        set_cfunc_pointer_data(data, NULL);
    }
    else {
        set_cfunc_pointer_data(data, cfunc_pointer_ptr(ptr));
    }

    return self;
}


mrb_value
cfunc_pointer_realloc(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data = DATA_PTR(self);
    
    mrb_int alloc_size;
    mrb_get_args(mrb, "i", &alloc_size);
    set_cfunc_pointer_data(data, realloc(get_cfunc_pointer_data(data), alloc_size));
    
    return self;
}


mrb_value
cfunc_pointer_free(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data = DATA_PTR(self);
    
    free(get_cfunc_pointer_data(data));
    data->autofree = false;
    set_cfunc_pointer_data(data, NULL);
    
    return self;
}


mrb_value
cfunc_pointer_inspect(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data = DATA_PTR(self);
    
    mrb_value type = mrb_funcall(mrb, mrb_obj_value(mrb_class(mrb, self)), "type", 0);
    const char* classname = mrb_class_name(mrb, (struct RClass*)mrb_object(type));
    if(!classname) {
        classname = "Unknown pointer";
    }

    char cstr[256];
    snprintf(cstr, sizeof(cstr), "<%s pointer=%p>", classname, get_cfunc_pointer_data(data));
    
    return mrb_str_new_cstr(mrb, cstr);
}


mrb_value
cfunc_pointer_is_null(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data = DATA_PTR(self);
    return (get_cfunc_pointer_data(data) == NULL) ? mrb_true_value() : mrb_false_value();
}


mrb_value
cfunc_pointer_autofree(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data = DATA_PTR(self);
    data->autofree = true;
    return self;
}


mrb_value
cfunc_pointer_to_s(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data = DATA_PTR(self);
    size_t len;
    mrb_value str;
    struct RString *s;
    const char* p = (const char*)get_cfunc_pointer_data(data);
        
    len = strlen(p);
{'fraction_non_alphanumeric': 0.11943673553294275, 'fraction_numerical': 0.0012334258402713536, 'mean_word_length': 3.9871860584315737, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 49, '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': '7206591', 'n_tokens_mistral': 3845, 'n_tokens_neox': 3788, 'n_words': 671}