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 27 struct dictentry { 28 SPLAY_ENTRY(dictentry) entry; 29 char key[MAX_DICTKEY_SIZE + 1]; 30 void *data; 31 }; 32 33 static int dictentry_cmp(struct dictentry *, struct dictentry *); 34 35 SPLAY_PROTOTYPE(dict, dictentry, entry, dictentry_cmp); 36 37 int 38 dict_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 48 void * 49 dict_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 69 void * 70 dict_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 82 void * 83 dict_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 100 static int 101 dictentry_cmp(struct dictentry *a, struct dictentry *b) 102 { 103 return strcmp(a->key, b->key); 104 } 105 106 SPLAY_GENERATE(dict, dictentry, entry, dictentry_cmp); 107