Releasing version 3-2014010504
[notion/jeffpc.git] / libtu / stringstore.c
blob3c5b7a1ec238d615fb8e71f8786b71c9bf765a8b
1 /*
2 * libtu/stringstore.c
4 * Copyright (c) Tuomo Valkonen 2004-2007.
6 * You may distribute and modify this library under the terms of either
7 * the Clarified Artistic License or the GNU LGPL, version 2.1 or later.
8 */
10 #include <stdlib.h>
11 #include <string.h>
13 #include "misc.h"
14 #include "output.h"
15 #include "rb.h"
16 #include "stringstore.h"
19 static Rb_node stringstore=NULL;
22 const char *stringstore_get(StringId id)
24 return (id==STRINGID_NONE
25 ? NULL
26 : (const char*)(((Rb_node)id)->k.key));
30 typedef struct{
31 const char *key;
32 uint len;
33 } D;
35 static int cmp(const void *d_, const char *nodekey)
37 D *d=(D*)d_;
39 int res=strncmp(d->key, nodekey, d->len);
41 return (res!=0
42 ? res
43 : (nodekey[d->len]=='\0' ? 0 : -1));
47 StringId stringstore_find_n(const char *str, uint l)
49 Rb_node node;
50 int found=0;
51 D d;
53 if(stringstore==NULL)
54 return STRINGID_NONE;
56 d.key=str;
57 d.len=l;
59 node=rb_find_gkey_n(stringstore, &d, (Rb_compfn*)cmp, &found);
61 if(!found)
62 return STRINGID_NONE;
64 return (StringId)node;
68 StringId stringstore_find(const char *str)
70 return stringstore_find_n(str, strlen(str));
74 StringId stringstore_alloc_n(const char *str, uint l)
76 Rb_node node=(Rb_node)stringstore_find_n(str, l);
77 char *s;
79 if(node!=NULL){
80 node->v.ival++;
81 return node;
84 if(stringstore==NULL){
85 stringstore=make_rb();
86 if(stringstore==NULL)
87 return STRINGID_NONE;
90 s=scopyn(str, l);
92 if(s==NULL)
93 return STRINGID_NONE;
95 node=rb_insert(stringstore, s, NULL);
97 if(node==NULL)
98 return STRINGID_NONE;
100 node->v.ival=1;
102 return (StringId)node;
106 StringId stringstore_alloc(const char *str)
108 if(str==NULL)
109 return STRINGID_NONE;
111 return stringstore_alloc_n(str, strlen(str));
115 void stringstore_free(StringId id)
117 Rb_node node=(Rb_node)id;
119 if(node==NULL)
120 return;
122 if(node->v.ival<=0){
123 warn("Stringstore reference count corrupted.");
124 return;
127 node->v.ival--;
129 if(node->v.ival==0){
130 char *s=(char*)(node->k.key);
131 rb_delete_node(node);
132 free(s);
137 void stringstore_ref(StringId id)
139 Rb_node node=(Rb_node)id;
141 if(node!=NULL)
142 node->v.ival++;