1/* $OpenBSD: dict.c,v 1.2 2014/04/28 13:08:34 syl Exp $ */ 2 3/* 4 * Copyright (c) 2012 Gilles Chehade <gilles@poolp.org> 5 * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20#include <err.h> 21#include <stdlib.h> 22#include <string.h> 23 24#include "fuse_private.h" 25 26#define MAX_DICTKEY_SIZE NAME_MAX 27struct dictentry { 28 SPLAY_ENTRY(dictentry) entry; 29 char key[MAX_DICTKEY_SIZE + 1]; 30 void *data; 31}; 32 33static int dictentry_cmp(struct dictentry *, struct dictentry *); 34 35SPLAY_PROTOTYPE(dict, dictentry, entry, dictentry_cmp); 36 37int 38dict_check(struct dict *d, const char *k) 39{ 40 struct dictentry key; 41 42 if (strlcpy(key.key, k, sizeof key.key) >= sizeof key.key) 43 errx(1, "dict_check(%p, %s): key too large", d, k); 44 45 return (SPLAY_FIND(dict, d, &key) != NULL); 46} 47 48void * 49dict_set(struct dict *d, const char *k, void *data) 50{ 51 struct dictentry *entry, key; 52 53 if (strlcpy(key.key, k, sizeof key.key) >= sizeof key.key) 54 errx(1, "dict_set(%p, %s): key too large", d, k); 55 if ((entry = SPLAY_FIND(dict, d, &key)) == NULL) { 56 entry = malloc(sizeof *entry); 57 if (entry == NULL) 58 return (NULL); 59 60 strlcpy(entry->key, k, sizeof entry->key); 61 SPLAY_INSERT(dict, d, entry); 62 } 63 64 entry->data = data; 65 66 return (entry); 67} 68 69void * 70dict_get(struct dict *d, const char *k) 71{ 72 struct dictentry key, *entry; 73 74 if (strlcpy(key.key, k, sizeof key.key) >= sizeof key.key) 75 errx(1, "dict_get(%p, %s): key too large", d, k); 76 if ((entry = SPLAY_FIND(dict, d, &key)) == NULL) 77 return (NULL); 78 79 return (entry->data); 80} 81 82void * 83dict_pop(struct dict *d, const char *k) 84{ 85 struct dictentry key, *entry; 86 void *data; 87 88 if (strlcpy(key.key, k, sizeof key.key) >= sizeof key.key) 89 errx(1, "dict_pop(%p, %s): key too large", d, k); 90 if ((entry = SPLAY_FIND(dict, d, &key)) == NULL) 91 return (NULL); 92 93 data = entry->data; 94 SPLAY_REMOVE(dict, d, entry); 95 free(entry); 96 97 return (data); 98} 99 100static int 101dictentry_cmp(struct dictentry *a, struct dictentry *b) 102{ 103 return strcmp(a->key, b->key); 104} 105 106SPLAY_GENERATE(dict, dictentry, entry, dictentry_cmp); 107