source: trunk/include/range_list.h @ 213

Last change on this file since 213 was 201, checked in by tim, 14 years ago

changed symbol visibility to hidden by default and explicitly exported API functions

  • Property svn:keywords set to Id
File size: 5.5 KB
RevLine 
[169]1/*
2 * Copyright (C) 2008-2010 Timothy D. Morgan
[168]3 *
[98]4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
16 *
[122]17 * $Id: range_list.h 201 2010-06-05 04:45:05Z tim $
[98]18 */
19
[169]20/**
21 * @file
22 *
23 * A data structure which stores a list of address ranges.
24 *
25 * range_lists support basic in-place modifications and maintain the address
26 * space in sorted order.  Looking up a range_list_element is implemented
27 * through binary search.
28 */
29
[148]30#ifndef _RANGE_LIST_H
31#define _RANGE_LIST_H
32
[98]33#include <stdlib.h>
34#include <stdbool.h>
35#include <stdint.h>
36#include <string.h>
[148]37#include <math.h>
[201]38#include <talloc.h>
[98]39
[201]40/* GCC-specific macro for library exports */
41#ifdef _EXPORT
42#undef _EXPORT
43#endif
44#define _EXPORT __attribute__((visibility("default")))
45
[98]46typedef struct _range_list_element
47{
48  uint32_t offset;
49  uint32_t length;
50  void* data;
51} range_list_element;
52
53
[169]54/** XXX: document this. */
[98]55typedef struct _range_list
56{
57  range_list_element** elements;
58  uint32_t elem_alloced;
59  uint32_t size;
60} range_list;
61
62
[169]63/** Allocates a new range_list.
[98]64 *
[169]65 * @return A newly allocated range_list, or NULL if an error occurred.
[98]66 */
[201]67_EXPORT
[98]68range_list* range_list_new();
69
70
[169]71/** Frees the memory associated with a range_list, including the elements, but
72 *  not any data parameters referenced by those elements. 
[98]73 *
[169]74 * If rl is NULL, does nothing.
75 *
76 * @param rl the range_list to be free()d.
[98]77 */
[201]78_EXPORT
[98]79void range_list_free(range_list* rl);
80
81
[169]82/** Query the current number of elements on a range_list
[98]83 *
[169]84 * @param rl the range_list to query
[98]85 *
[169]86 * @return The number of elements currently in the list.
[98]87 */
[201]88_EXPORT
[98]89uint32_t range_list_size(const range_list* rl);
90
91
[169]92/** Adds an element to the range_list. 
[98]93 *
[169]94 * The new element must not overlap with others.
95 * NOTE: this is a slow operation.
96 *
97 * @param rl     the range list to update
98 * @param offset the starting point for the range
99 * @param length the length of the range
100 * @param data   misc data associated with this range element
101 *
102 * @return  true on success, false on failure.
103 *
104 * Failures can occur due to memory limitations, max_size limitations,
105 * or if the submitted range overlaps with an existing element.  Other
106 * errors may also be possible.
[98]107 */
[201]108_EXPORT
[98]109bool range_list_add(range_list* rl, uint32_t offset, uint32_t length, void* data);
110
111
[169]112/** Removes an element from the list. 
[98]113 *
[169]114 * The element data structure will be freed, but the data property will not be.
[98]115 *
[169]116 * @param rl    the range_list to modify
117 * @param index the element index to remove
118 *
119 * @return true if the element was successfully removed, false otherwise.
[98]120 */
[201]121_EXPORT
[98]122bool range_list_remove(range_list* rl, uint32_t index);
123
124
[169]125/** Retrieves the element for a given index.
[98]126 *
[169]127 * @param rl    the range_list being queried.
128 * @param index the element index desired.
[98]129 *
[169]130 * @return The element for a given index, or NULL if the element is not
131 *         available.
[98]132 */
[201]133_EXPORT
[98]134const range_list_element* range_list_get(const range_list* rl, uint32_t index);
135
136
[169]137/** Attempts to find the unique element whose range encompasses offset.
[98]138 *
[169]139 * @param rl     the range_list being queried.
140 * @param offset the location for which an element is desired.
[98]141 *
[169]142 * @return A matching element index or a negative value if none could be found.
[98]143 */
[201]144_EXPORT
[98]145int32_t range_list_find(const range_list* rl, uint32_t offset);
146
147
[169]148/** Same as range_list_find(), but returns the data associated with an element.
[98]149 *
[169]150 * @param rl     the range_list being queried.
151 * @param offset the address to search for in the ranges
[98]152 *
[169]153 * @return The data element of the matching element index or NULL if none could
154 *         be found.
[98]155 *
[169]156 *  NOTE: May also return NULL if an element matched but the data
[98]157 *        element was never set.
158 */
[201]159_EXPORT
[98]160void* range_list_find_data(const range_list* rl, uint32_t offset);
161
162
[169]163/**  Splits an existing element into two elements in place.
[98]164 *
[169]165 * The resulting list will contain an additional element whose offset
166 * is the one provided and whose length extends to the end of the old element
167 * (the one identified by the index).  The original element's offset will
168 * remain the same while it's length is shortened such that it is contiguous
169 * with the newly created element.  The newly created element will have an index
170 * of one more than the current element.
[98]171 *
[169]172 * Both the original element and the newly created element will reference the
173 * original element's data.
[98]174 *
[169]175 * @param rl     the range_list to modify
176 * @param index  the index of the element to be split
177 * @param offset the at which the element will be split
[98]178 *
[169]179 * @return true if the element was successfully split, false otherwise.
[98]180 */
[201]181_EXPORT
[98]182bool range_list_split_element(range_list* rl, uint32_t index, uint32_t offset);
183
[113]184
[169]185/** Determines whether or not a specified range exists contiguously within the
[113]186 *  range_list.
187 *
[169]188 * @param rl     the range_list to search
189 * @param start  the offset at the beginning of the range
190 * @param length the length of the range
[113]191 *
[169]192 * @return true if the specified range exists and is complete, false otherwise.
[113]193 */
[201]194_EXPORT
[113]195bool range_list_has_range(range_list* rl, uint32_t start, uint32_t length);
196
[98]197#endif
Note: See TracBrowser for help on using the repository browser.