src/chain.h
author Tero Marttila <terom@fixme.fi>
Mon, 04 May 2009 20:55:04 +0300
branchnew-transport
changeset 168 a58ad50911fc
parent 87 f0db6ebf18b9
child 171 b54f393c3df0
permissions -rw-r--r--
refactor test.c into tests/*
#ifndef CHAIN_H
#define CHAIN_H

/**
 * @file
 * 
 * Defines a semi-generalized "chain of things" behaviour.
 *
 * The structure of this is a chain_list, which contains a number of chain_head items, which then contain a number of
 * induvidual items.
 */
#include "error.h"
#include <sys/queue.h>

/**
 * The chain header.
 */
struct chain_head {
    /** The list of items */
    const void *chain;
    
    /** The context arg */
    void *arg;
    
    /** Our position in the chain_list */
    STAILQ_ENTRY(chain_head) node;
};

/**
 * @struct chain_list
 *
 * The chain list
 */
STAILQ_HEAD(chain_list, chain_head);

/**
 * Initialize a `struct chain_list`
 */
#define CHAIN_INIT(list_ptr) STAILQ_INIT(list_ptr)

/**
 * Add an item onto the end of a chain_list
 */
err_t chain_add (struct chain_list *list, const void *chain, void *arg);

/**
 * Iterate over the contents of a chain_list
 *
 * struct chain_list *list = ...;
 * struct chain_head *head;
 * struct foo *foo;
 *
 *  CHAIN_FOREACH(list, head) {
 *      for (foo = head->chain; foo->bar; foo++) {
 *          foo->bar(foo, head->arg);
 *      }
 *  }
 */
#define CHAIN_FOREACH(list_ptr, head_ptr) STAILQ_FOREACH(head_ptr, list_ptr, node)

/**
 * Remove an item added with chain_add from a chain_list, matching against the given chain/arg.
 *
 * If no item matches, nothing is done.
 */
void chain_remove (struct chain_list *list, const void *chain, void *arg);

/**
 * Free a chain_list
 */
void chain_free (struct chain_list *list);

#endif