Skip to content

Destructor callback for reference  #38

@nokute78

Description

@nokute78

Background

cfl_variant_destroy destroys if a variant is string, bytes, array or kvlist.
It doesn't if the type is reference.

cfl_array and cfl_kvlist supports reference.
It means that user needs to release before destroying them.

e.g.

        for (index = 0 ; index < array->entry_count ; index++) {
            if(array->entries[index] != NULL && array->entries[index].type == CFL_VARIANT_REFERENCE) {
                free(array->entries[index].data.as_reference);
            }
        }
        cfl_array_destroy(array);

We need to save keys to fetch references.

        for (index = 0 ; index < keys_size ; index++) {
              var = cfl_kvlist_fetch(kvlist, keys[index]);
              if (var != NULL && var.type == CFL_VARIANT_REFERENCE ) {
                   free(var.data.as_reference)
              }
        }
        cfl_kvlist_destroy(kvlist);

I think it is messy.

Proposal

I propose to add a function pointer to struct cfl_variant and add a new function cfl_variant_set_destructor(funcptr).

cfl_variant_destroy calls funcptr if it is not NULL.
It allows user to register destructor callback.

cfl_kvlist_insert_reference and cfl_array_append_reference will be extracted to pass funcptr.

Note: Do not set callback on creating

We can extract like cfl_variant_create_from_reference(value, funcptr).
However it causes issue following case.
The reference will be released when cfl_array_append is failed.

int cfl_array_append_reference(struct cfl_array *array, void *value, void (*funcptr) (void *))
{
    struct cfl_variant *value_instance;
    int                 result;

    value_instance = cfl_variant_create_from_reference(value, funcptr); // set callback on create

    if (value_instance == NULL) {
        return -1;
    }

    result = cfl_array_append(array, value_instance);

    if (result) {
        cfl_variant_destroy(value_instance); // reference is released !

        return -2;
    }

    return 0;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions