1 /*
2 * atheme-services: A collection of minimalist IRC services
3 * strshare.c: Shared strings.
4 *
5 * Copyright (c) 2008 Atheme Project (http://www.atheme.org)
6 *
7 * Permission to use, copy, modify, and/or 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 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
12 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
13 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
14 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
15 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
17 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
19 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
20 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
21 * POSSIBILITY OF SUCH DAMAGE.
22 */
23
24 #include "atheme.h"
25
26 mowgli_patricia_t *strshare_dict;
27
28 typedef struct
29 {
30 int refcount;
31 } strshare_t;
32
strshare_init(void)33 void strshare_init(void)
34 {
35 strshare_dict = mowgli_patricia_create(noopcanon);
36 }
37
strshare_get(const char * str)38 stringref strshare_get(const char *str)
39 {
40 strshare_t *ss;
41
42 if (str == NULL)
43 return NULL;
44
45 ss = mowgli_patricia_retrieve(strshare_dict, str);
46 if (ss != NULL)
47 ss->refcount++;
48 else
49 {
50 ss = smalloc(sizeof(strshare_t) + strlen(str) + 1);
51 ss->refcount = 1;
52 strcpy((char *)(ss + 1), str);
53 mowgli_patricia_add(strshare_dict, (char *)(ss + 1), ss);
54 }
55 return (char *)(ss + 1);
56 }
57
strshare_ref(stringref str)58 stringref strshare_ref(stringref str)
59 {
60 strshare_t *ss;
61
62 if (str == NULL)
63 return NULL;
64
65 /* intermediate cast to suppress gcc -Wcast-qual */
66 ss = (strshare_t *)(uintptr_t)str - 1;
67 ss->refcount++;
68
69 return str;
70 }
71
strshare_unref(stringref str)72 void strshare_unref(stringref str)
73 {
74 strshare_t *ss;
75
76 if (str == NULL)
77 return;
78
79 /* intermediate cast to suppress gcc -Wcast-qual */
80 ss = (strshare_t *)(uintptr_t)str - 1;
81 ss->refcount--;
82 if (ss->refcount == 0)
83 {
84 mowgli_patricia_delete(strshare_dict, str);
85 free(ss);
86 }
87 }
88
89 /* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs
90 * vim:ts=8
91 * vim:sw=8
92 * vim:noexpandtab
93 */
94