<commit_before>/**
 Copyright 2017 <NAME>

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/
#include "vmslh.h"

static vmslh_callback_t * vmslh_by_addr(gru_list_t *list, vmslh_callback_fn callback) {
	gru_node_t *node = list->root;

	while (node) {
		vmslh_callback_t *vmslh_callback = (vmslh_callback_t *) node->data;
		if (vmslh_callback && vmslh_callback->call == callback) {
			return vmslh_callback;
		}

		node = node->next;
	}

	return NULL;
}

bool vmslh_add(gru_list_t *list, vmslh_callback_fn callback, void *payload, gru_status_t *status) {
	vmslh_callback_t *wrapper = NULL;

	wrapper = vmslh_by_addr(list, callback);
	if (!wrapper) {
		gru_alloc(sizeof(vmslh_callback_t), status);
		gru_alloc_check(wrapper, false);
	}

	wrapper->call = callback;
	wrapper->payload = payload;

	if (!gru_list_append(list, wrapper)) {
		gru_dealloc((void **)&wrapper);
		gru_status_set(status, GRU_FAILURE, "Unable to append VMSL handler wrapper");

		return false;
	}

	return true;
}

void vmslh_run(gru_list_t *list, void *ctxt, void *msg) {
	if (!list) {
		return;
	}

	gru_node_t *node = list->root;

	while (node) {
		vmslh_callback_t *callback = (vmslh_callback_t *) node->data;

		callback->call(ctxt, msg, callback->payload);

		node = node->next;
	}
}

static void vmslh_callback_cleanup(void **ptr) {
	vmslh_callback_t *cb = *ptr;

	if (!cb) {
		return;
	}

	gru_dealloc((void **) &cb);
}

vmslh_handlers_t vmslh_new(gru_status_t *status) {
	vmslh_handlers_t handlers = {0};

	handlers.before_connect = gru_list_new(status);
	handlers.after_connect = gru_list_new(status);
	handlers.before_send = gru_list_new(status);
	handlers.after_send = gru_list_new(status);
	handlers.before_receive = gru_list_new(status);
	handlers.after_receive = gru_list_new(status);
	handlers.finalize_receive = gru_list_new(status);

	return handlers;
}

void vmslh_cleanup(vmslh_handlers_t *handlers) {
	if (!handlers) {
		return;
	}

	gru_list_clean(handlers->before_connect, vmslh_callback_cleanup);<commit_msg>FIX: to add the callback wrapper to the list<commit_after>/**
 Copyright 2017 <NAME>

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/
#include "vmslh.h"

static vmslh_callback_t * vmslh_by_addr(gru_list_t *list, vmslh_callback_fn callback, gru_status_t *status) {
	gru_node_t *node = list->root;

	while (node) {
		vmslh_callback_t *vmslh_callback = (vmslh_callback_t *) node->data;
		if (vmslh_callback && vmslh_callback->call == callback) {
			return vmslh_callback;
		}

		node = node->next;
	}

	vmslh_callback_t *ret = gru_alloc(sizeof(vmslh_callback_t), status);
	if (!gru_list_append(list, ret)) {
		gru_dealloc((void **)&ret);
		gru_status_set(status, GRU_FAILURE, "Unable to append VMSL handler wrapper");

		return NULL;
	}

	return ret;
}

bool vmslh_add(gru_list_t *list, vmslh_callback_fn callback, void *payload, gru_status_t *status) {
	vmslh_callback_t *wrapper = NULL;

	wrapper = vmslh_by_addr(list, callback, status);
	if (!wrapper) {
		return false;
	}

	wrapper->call = callback;
	wrapper->payload = payload;

	return true;
}

void vmslh_run(gru_list_t *list, void *ctxt, void *msg) {
	if (!list) {
		return;
	}

	gru_node_t *node = list->root;

	while (node) {
		vmslh_callback_t *callback = (vmslh_callback_t *) node->data;

		callback->call(ctxt, msg, callback->payload);

		node = node->next;
	}
}

static void vmslh_callback_cleanup(void **ptr) {
	vmslh_callback_t *cb = *ptr;

	if (!cb) {
		return;
	}

	gru_dealloc((void **) &cb);
}

vmslh_handlers_t vmslh_new(gru_status_t *status) {
	vmslh_handlers_t handlers = {0};

	handlers.before_connect = gru_list_new(status);
	handlers.after_connect = gru_list_new(status);
	handlers.before_send = gru_list_new(status);
	handlers.after_send = gru_list_new(status);
	handlers.before_receive = gru_list_new(status);
	handlers.after_receive = gru_list_new(status);
	handlers.finalize_receive = gru_list_new(status);
	return handlers;
}

void vmslh_cleanup(vmslh_handlers_t *handlers) {
	if (!handlers) {
		return;
	}

	gru_list_clean(handlers->before_connect, vmslh_callback_cleanup);
{'fraction_non_alphanumeric': 0.10980470306895178, 'fraction_numerical': 0.0035870864886408927, 'mean_word_length': 5.083636363636364, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 29, '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': '7086247', 'n_tokens_mistral': 1914, 'n_tokens_neox': 1827, 'n_words': 446}