Removed some less useful comments.
/*
* The contents of this file are subject to the AOLserver Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://aolserver.com/.
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is AOLserver Code and related documentation
* distributed by AOL.
*
* The Initial Developer of the Original Code is America Online,
* Inc. Portions created by AOL are Copyright (C) 1999 America Online,
* Inc. All Rights Reserved.
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License (the "GPL"), in which case the
* provisions of GPL are applicable instead of those above. If you wish
* to allow use of your version of this file only under the terms of the
* GPL and not to allow others to use your version of this file under the
* License, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the GPL.
* If you do not delete the provisions above, a recipient may use your
* version of this file under either the License or the GPL.
*/
/*
* set.c --
*
* Implements the Ns_Set data type.
*/
static const char *RCSID = "@(#) $Header: /cvsroot/aolserver/aolserver/nsd/set.c,v 1.4 2000/08/25 13:49:57 jgdavidson Exp $, compiled: " __DATE__ " " __TIME__;
#include "nsd.h"
/*
*----------------------------------------------------------------------
*
* Ns_SetUpdate --
*
* Remove a tuple and re-add it.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
Ns_SetUpdate(Ns_Set *set, char *key, char *value)
{
Ns_SetDeleteKey(set, key);
Ns_SetPut(set, key, value);
}
/*
*----------------------------------------------------------------------
*
* Ns_SetCreate --
*
* Initialize a new set.
*
* Results:
* A pointer to a new set.
*
* Side effects:
* Memory is allocated; free with Ns_SetFree.
*
*----------------------------------------------------------------------
*/
Ns_Set *
Ns_SetCreate(char *name)
{
Ns_Set *setPtr;
setPtr = ns_malloc(sizeof(Ns_Set));
setPtr->size = 0;
setPtr->maxSize = 10;
setPtr->name = ns_strcopy(name);
setPtr->fields = ns_malloc(sizeof(Ns_SetField) * setPtr->maxSize);
return setPtr;
}
/*
*----------------------------------------------------------------------
*
* Ns_SetFree --
*
* Free a set and its associated data with ns_free.
*
* Results:
* None.
*
* Side effects:
* Will free both the Ns_Set structure AND its tuples.
*
*----------------------------------------------------------------------
*/
void
Ns_SetFree(Ns_Set *set)
{
int i;
if (set != NULL) {
for (i = 0; i < set->size; ++i) {
ns_free(set->fields[i].name);
ns_free(set->fields[i].value);
}
ns_free(set->fields);
ns_free(set->name);
ns_free(set);
}
}
/*
*----------------------------------------------------------------------
*
* Ns_SetPut --
*
* Insert a tuple into an existing set.
*
* Results:
* The index number of the new tuple.
*
* Side effects:
* The key/value will be strdup'ed.
*
*----------------------------------------------------------------------
*/
int
Ns_SetPut(Ns_Set *set, char *key, char *value)
{
int index;
index = set->size;
set->size++;
if (set->size > set->maxSize) {
set->maxSize = set->size * 2;
set->fields = ns_realloc(set->fields,
sizeof(Ns_SetField) * set->maxSize);
}
set->fields[index].name = ns_strcopy(key);
set->fields[index].value = ns_strcopy(value);
return index;
}
/*
*----------------------------------------------------------------------
*
* Ns_SetUniqueCmp --
*
* Using the comparison function, see if multiple keys match
* key.
*
* Results:
* NS_FALSE: multiple keys match key
* NS_TRUE: 0 or 1 keys match key.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
Ns_SetUniqueCmp(Ns_Set *set, char *key, int (*cmp) (char *s1, char *s2))
{
int i;
char *name;
int found;
found = 0;
for (i = 0; i < set->size; ++i) {
name = set->fields[i].name;
if ((key == NULL && name == NULL) ||
(key != NULL && name != NULL && ((*cmp) (key, name)) == 0)) {
if (found) {
return NS_FALSE;
}
found = 1;
}
}
return NS_TRUE;
}
/*
*----------------------------------------------------------------------
*
* Ns_SetFindCmp --
*
* Returns the index of a tuple matching key, using a comparison
* function callback.
*
* Results:
* A tuple index or -1 if no matches.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
Ns_SetFindCmp(Ns_Set *set, char *key, int (*cmp) (char *s1, char *s2))
{
int i;
char *name;
for (i = 0; i < set->size; ++i) {
name = set->fields[i].name;
if ((key == NULL && name == NULL) ||
(key != NULL && name != NULL && ((*cmp) (key, name)) == 0)) {
return i;
}
}
return -1;
}
/*
*----------------------------------------------------------------------
*
* Ns_SetGetCmp --
*
* Returns the value of a tuple matching key, using a comparison
* function callback.
*
* Results:
* A value or NULL if no matches.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
char *
Ns_SetGetCmp(Ns_Set *set, char *key, int (*cmp) (char *s1, char *s2))
{
int i;
i = Ns_SetFindCmp(set, key, cmp);
if (i == -1) {
return NULL;
}
return set->fields[i].value;
}
/*
*----------------------------------------------------------------------
*
* Ns_SetUnique --
*
* Check if a key in a set is unique (case sensitive).
*
* Results:
* NS_TRUE if unique, NS_FALSE if not.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
Ns_SetUnique(Ns_Set *set, char *key)
{
return Ns_SetUniqueCmp(set, key, (int (*) (char *, char *)) strcmp);
}
/*
*----------------------------------------------------------------------
*
* Ns_SetIUnique --
*
* Check if a key in a set is unique (case insensitive).
*
* Results:
* NS_TRUE if unique, NS_FALSE if not.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
Ns_SetIUnique(Ns_Set *set, char *key)
{
return Ns_SetUniqueCmp(set, key, (int (*) (char *, char *)) strcasecmp);
}
/*
*----------------------------------------------------------------------
*
* Ns_SetFind --
*
* Locate the index of a field in a set (case sensitive)
*
* Results:
* A field index or -1 if not found.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
Ns_SetFind(Ns_Set *set, char *key)
{
return Ns_SetFindCmp(set, key, (int (*) (char *, char *)) strcmp);
}
/*
*----------------------------------------------------------------------
*
* Ns_SetIFind --
*
* Locate the index of a field in a set (case insensitive)
*
* Results:
* A field index or -1 if not found.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
Ns_SetIFind(Ns_Set *set, char *key)
{
return Ns_SetFindCmp(set, key, (int (*) (char *, char *)) strcasecmp);
}
/*
*----------------------------------------------------------------------
*
* Ns_SetGet --
*
* Return the value associated with a key, case sensitive.
*
* Results:
* A value or NULL if key not found.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
char *
Ns_SetGet(Ns_Set *set, char *key)
{
return Ns_SetGetCmp(set, key, (int (*) (char *, char *)) strcmp);
}
/*
*----------------------------------------------------------------------
*
* Ns_SetIGet --
*
* Return the value associated with a key, case insensitive.
*
* Results:
* A value or NULL if key not found.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
char *
Ns_SetIGet(Ns_Set *set, char *key)
{
return Ns_SetGetCmp(set, key, (int (*) (char *, char *)) strcasecmp);
}
/*
*----------------------------------------------------------------------
*
* Ns_SetTrunc --
*
* Remove all tuples after 'size'
*
* Results:
* None.
*
* Side effects:
* Will free tuple memory.
*
*----------------------------------------------------------------------
*/
void
Ns_SetTrunc(Ns_Set *set, int size)
{
if (size < set->size) {
int index;
for (index = size; index < set->size; index++) {
ns_free(set->fields[index].name);
ns_free(set->fields[index].value);
}
set->size = size;
}
}
/*
*----------------------------------------------------------------------
*
* Ns_SetDelete --
*
* Delete a tuple from a set.
*
* Results:
* None.
*
* Side effects:
* Will free tuple memory.
*
*----------------------------------------------------------------------
*/
void
Ns_SetDelete(Ns_Set *set, int index)
{
if ((index != -1) && (index < set->size)) {
int i;
ns_free(set->fields[index].name);
ns_free(set->fields[index].value);
for (i = index; i < set->size; ++i) {
set->fields[i].name = set->fields[i + 1].name;
set->fields[i].value = set->fields[i + 1].value;
}
--set->size;
}
}
/*
*----------------------------------------------------------------------
*
* Ns_SetPutValue --
*
* Set the value for a given tuple.
*
* Results:
* None.
*
* Side effects:
* Will free the old value dup the new value.
*
*----------------------------------------------------------------------
*/
void
Ns_SetPutValue(Ns_Set *set, int index, char *value)
{
if ((index != -1) && (index < set->size)) {
ns_free(set->fields[index].value);
set->fields[index].value = ns_strcopy(value);
}
}
/*
*----------------------------------------------------------------------
*
* Ns_SetDeleteKey --
*
* Delete a tuple from the set (case sensitive).
*
* Results:
* None.
*
* Side effects:
* Will free tuple memory.
*
*----------------------------------------------------------------------
*/
void
Ns_SetDeleteKey(Ns_Set *set, char *key)
{
Ns_SetDelete(set, Ns_SetFind(set, key));
}
/*
*----------------------------------------------------------------------
*
* Ns_SetIDeleteKey --
*
* Delete a tuple from the set (case insensitive).
*
* Results:
* None.
*
* Side effects:
* Will free tuple memory.
*
*----------------------------------------------------------------------
*/
void
Ns_SetIDeleteKey(Ns_Set *set, char *key)
{
Ns_SetDelete(set, Ns_SetIFind(set, key));
}
/*
*----------------------------------------------------------------------
*
* Ns_SetListFind --
*
* In a null-terminated array of sets, find the set with the
* given name.
*
* Results:
* A set, or NULL.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
Ns_Set *
Ns_SetListFind(Ns_Set **sets, char *name)
{
while (*sets != NULL) {
if (name == NULL) {
if ((*sets)->name == NULL) {
return (*sets);
}
} else {
if ((*sets)->name != NULL &&
STREQ((*sets)->name, name)) {
return (*sets);
}
}
++sets;
}
return NULL;
}
/*
*----------------------------------------------------------------------
*
* Ns_SetSplit --
*
* Split a set into an array of new sets. This assumes that each
* key name in the fields of a set contains a separating
* character. The fields of the set are partitioned into new
* sets whose set names are the characters before the separator
* and whose field key names are the characters after the
* separator.
*
* Results:
* A new set.
*
* Side effects:
* Will allocate a new set and tuples.
*
*----------------------------------------------------------------------
*/
Ns_Set **
Ns_SetSplit(Ns_Set *set, char sep)
{
int i;
Ns_DString ds;
Ns_Set *end = NULL;
Ns_DStringInit(&ds);
Ns_DStringNAppend(&ds, (char *) &end, sizeof(Ns_Set *));
for (i = 0; i < set->size; ++i) {
Ns_Set *next;
char *name;
char *key;
key = strchr(set->fields[i].name, sep);
if (key != NULL) {
*key++ = '\0';
name = set->fields[i].name;
} else {
key = set->fields[i].name;
name = NULL;
}
next = Ns_SetListFind((Ns_Set **) ds.string, name);
if (next == NULL) {
Ns_Set **sp;
next = Ns_SetCreate(name);
sp = (Ns_Set **) (ds.string + ds.length - sizeof(Ns_Set *));
*sp = next;
Ns_DStringNAppend(&ds, (char *) &end, sizeof(Ns_Set *));
}
Ns_SetPut(next, key, set->fields[i].value);
if (name != NULL) {
*--key = sep;
}
}
return (Ns_Set **) Ns_DStringExport(&ds);
}
/*
*----------------------------------------------------------------------
*
* Ns_SetListFree --
*
* Free a null-terminated array of sets.
*
* Results:
* None.
*
* Side effects:
* Will free all sets in the array and their tuples.
*
*----------------------------------------------------------------------
*/
void
Ns_SetListFree(Ns_Set **sets)
{
Ns_Set **s;
s = sets;
while (*s != NULL) {
Ns_SetFree(*s);
++s;
}
ns_free(sets);
}
/*
*----------------------------------------------------------------------
*
* Ns_SetMerge --
*
* Combine the 'low' set into the 'high' set.
*
* Results:
* None.
*
* Side effects:
* Will add tuples to 'high'.
*
*----------------------------------------------------------------------
*/
void
Ns_SetMerge(Ns_Set *high, Ns_Set *low)
{
int i,j;
for (i = 0; i < low->size; ++i) {
j = Ns_SetFind(high, low->fields[i].name);
if (j == -1) {
Ns_SetPut(high, low->fields[i].name, low->fields[i].value);
}
}
}
/*
*----------------------------------------------------------------------
*
* Ns_SetCopy --
*
* Make a duplicate of a set.
*
* Results:
* A new set.
*
* Side effects:
* Will copy tuples and alloc new memory for them, too.
*
*----------------------------------------------------------------------
*/
Ns_Set *
Ns_SetCopy(Ns_Set *old)
{
int i;
Ns_Set *new;
if (old == NULL) {
return NULL;
}
new = Ns_SetCreate(old->name);
for (i = 0; i < old->size; ++i) {
Ns_SetPut(new, old->fields[i].name, old->fields[i].value);
}
return new;
}
/*
*----------------------------------------------------------------------
*
* Ns_SetMove --
*
* Moves the data from one set to another, truncating the "from"
* set.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
Ns_SetMove(Ns_Set *to, Ns_Set *from)
{
int i;
for (i = 0; i < from->size; i++) {
Ns_SetPut(to, from->fields[i].name, from->fields[i].value);
}
Ns_SetTrunc(from, 0);
}
/*
*----------------------------------------------------------------------
*
* Ns_SetPrint --
*
* Dump the contents of a set to stderr.
*
* Results:
* None.
*
* Side effects:
* Will write to stderr.
*
*----------------------------------------------------------------------
*/
void
Ns_SetPrint(Ns_Set *set)
{
int i;
fprintf(stderr, "%s:\n", set->name ? set->name : "<Unamed set>");
for (i = 0; i < set->size; ++i) {
if (set->fields[i].name == NULL) {
fprintf(stderr, "\t(null) = ");
} else {
fprintf(stderr, "\t%s = ", set->fields[i].name);
}
if (set->fields[i].value == NULL) {
fprintf(stderr, "(null)\n");
} else {
fprintf(stderr, "%s\n", set->fields[i].value);
}
}
}
|
Back to SourceForge.net Powered by ViewCVS 1.0-dev |