ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/shstr.C
Revision: 1.17
Committed: Tue Sep 12 19:20:06 2006 UTC (17 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.16: +11 -5 lines
Log Message:
- improve assign to prepend "..."
- make more use of assign
- implement op->debug_desc() and make some more use of it

File Contents

# User Rev Content
1 root 1.13
2 elmex 1.1 /*
3 root 1.3 * shstr.C
4 elmex 1.1 */
5    
6 root 1.3 #include <cstring>
7     #include <cstdlib>
8    
9 root 1.10 #include <glib.h>
10    
11 root 1.3 #include <tr1/unordered_set>
12 elmex 1.1
13 root 1.16 #include "global.h"
14 elmex 1.1
15 root 1.16 typedef std::tr1::unordered_set<const char *, str_hash, str_equal> HT;
16 elmex 1.1
17 root 1.16 static HT ht;
18 elmex 1.1
19 root 1.13 static const char *
20     makevec (const char *s)
21 root 1.7 {
22 root 1.17 int len = strlen (s);
23 root 1.7
24 root 1.17 const char *v = (const char *) (2 + (int *) g_slice_alloc (sizeof (int) * 2 + len + 1));
25 root 1.7
26     shstr::length (v) = len;
27     shstr::refcnt (v) = 1;
28    
29 root 1.13 memcpy ((char *) v, s, len + 1);
30 root 1.7
31 root 1.8 return v;
32 root 1.7 }
33    
34 root 1.17 static const char *
35     makenull ()
36     {
37     const char *s = makevec ("(null)");
38     shstr::length (s) = 0;
39     return s;
40     }
41    
42     const char *shstr::null = makenull ();
43 root 1.15
44 elmex 1.1 const char *
45 root 1.3 shstr::find (const char *s)
46     {
47 root 1.4 if (!s)
48     return s;
49    
50 root 1.3 HT::iterator i = ht.find (s);
51 elmex 1.1
52 root 1.13 return i != ht.end ()? *i : 0;
53 elmex 1.1 }
54    
55     const char *
56 root 1.3 shstr::intern (const char *s)
57     {
58 root 1.4 if (!s)
59 root 1.7 return null;
60 elmex 1.1
61 root 1.4 if (const char *found = find (s))
62 root 1.5 {
63     ++refcnt (found);
64     return found;
65     }
66 elmex 1.1
67 root 1.7 s = makevec (s);
68     ht.insert (s);
69     return s;
70 elmex 1.1 }
71    
72 root 1.5 // periodically test refcounts == 0 for a few strings
73     // this is the ONLY thing that erases stuff from ht. keep it that way.
74 elmex 1.1 void
75 root 1.3 shstr::gc ()
76     {
77 root 1.14 return; //D
78     //D currently disabled: some datastructures might still store them
79     //D but their pointers will become invalidated
80 root 1.5 static const char *curpos;
81    
82     HT::iterator i = curpos ? ht.find (curpos) : ht.begin ();
83    
84     if (i == ht.end ())
85     i = ht.begin ();
86    
87     // go through all strings roughly once every 4 minutes
88 root 1.11 int n = ht.size () / 256 + 16;
89 root 1.6
90     for (;;)
91 root 1.5 {
92     if (i == ht.end ())
93     {
94     curpos = 0;
95     return;
96     }
97 root 1.6 else if (!--n)
98     break;
99     else if (!refcnt (*i))
100 root 1.5 {
101     HT::iterator o = i++;
102     const char *s = *o;
103 root 1.13
104 root 1.5 ht.erase (o);
105    
106     //printf ("GC %4d %3d %d >%s<%d\n", (int)ht.size (), n, shstr::refcnt (s), s, shstr::length (s));
107 root 1.13 g_slice_free1 (sizeof (int) * 2 + length (s) + 1, -2 + (int *) s);
108 root 1.5 }
109     else
110     ++i;
111     }
112    
113     curpos = *i;
114 elmex 1.1 }
115    
116 root 1.16 shstr skill_names[NUM_SKILLS];
117    
118     // what weird misoptimisation is this again?
119     const shstr undead_name ("undead");
120    
121 root 1.5 //TODO: this should of course not be here
122 root 1.13
123 elmex 1.1 /* buf_overflow() - we don't want to exceed the buffer size of
124     * buf1 by adding on buf2! Returns true if overflow will occur.
125     */
126    
127 root 1.13 int
128 elmex 1.1 buf_overflow (const char *buf1, const char *buf2, int bufsize)
129     {
130 root 1.13 int len1 = 0, len2 = 0;
131 elmex 1.1
132 root 1.13 if (buf1)
133     len1 = strlen (buf1);
134     if (buf2)
135     len2 = strlen (buf2);
136     if ((len1 + len2) >= bufsize)
137     return 1;
138     return 0;
139 elmex 1.1 }