]>
jfr.im git - irc/quakenet/newserv.git/blob - lib/sstring.c
1 /* sstring.h - Declaration of "static strings" functions */
3 #define COMPILING_SSTRING
6 #include "../core/hooks.h"
7 #include "../core/nsmalloc.h"
18 /* List of free stuff */
19 sstring
*freelist
[SSTRING_MAXLEN
+1];
21 /* Global variables to track allocated memory */
27 /* Statistics counters */
33 /* Internal function */
34 void sstringstats(int hooknum
, void *arg
);
38 for(i
=0;i
<=SSTRING_MAXLEN
;i
++)
46 /* Initialise statistics counters */
52 registerhook(HOOK_CORE_STATSREQUEST
,&sstringstats
);
55 sstring
*getsstring(const char *inputstr
, int maxlen
) {
61 /* getsstring() on a NULL pointer returns a NULL sstring.. */
66 if (inputstr
[0]=='\0') {
70 /* Only count calls that actually did something */
73 length
=strlen(inputstr
)+1;
77 assert(length
<=SSTRING_MAXLEN
);
79 /* Check to see if an approximately correct
80 * sized string is available */
81 for(i
=0;i
<SSTRING_SLACK
;i
++) {
82 if (length
+i
>SSTRING_MAXLEN
)
85 if (freelist
[length
+i
]!=NULL
) {
86 retval
=freelist
[length
+i
];
87 freelist
[length
+i
]=retval
->u
.next
;
88 retval
->u
.l
.alloc
=(length
+i
);
93 /* None found, allocate a new one */
96 if (structfree
< sizeof(sstring
)) {
97 /* We always allocate an exact multiple of these.
98 * Therefore, if there is enough for a partial structure we broke something */
99 assert(structfree
==0);
101 /* Allocate more RAM */
103 structmem
=(sstring
*)nsmalloc(POOL_SSTRING
,SSTRING_STRUCTALLOC
);
104 assert(structmem
!=NULL
);
105 structfree
=SSTRING_STRUCTALLOC
;
110 structfree
-=sizeof(sstring
);
112 if (stringfree
< length
) {
113 /* Not enough left for what we want.
114 * Allocate the remainder of our chunk (if any)
115 * to something and immediately free it.
116 * Decrement the freecalls counter to fix the stats */
117 if (stringfree
> 0) {
118 retval
->content
=stringmem
;
119 retval
->u
.l
.alloc
=stringfree
;
124 /* GOTO GOTO GOTO: We need to allocate
125 * another new struct here. Goto is the cleanest
129 /* Grab some more string space */
131 stringmem
=(char *)nsmalloc(POOL_SSTRING
,SSTRING_DATAALLOC
);
132 assert(stringmem
!=NULL
);
133 stringfree
=SSTRING_DATAALLOC
;
137 retval
->content
=stringmem
;
138 retval
->u
.l
.alloc
=length
;
144 * At this point, retval points to a valid structure which is at
145 * least the right size and has the "alloc" value set correctly
148 retval
->u
.l
.length
=(length
-1);
149 strncpy(retval
->content
,inputstr
,(length
-1));
150 retval
->content
[length
-1]='\0';
155 void freesstring(sstring
*inval
) {
159 /* Allow people to call this with a NULL value */
163 /* Only count calls that actually did something */
166 alloc
=inval
->u
.l
.alloc
;
167 assert(alloc
<=SSTRING_MAXLEN
);
168 inval
->u
.next
=freelist
[alloc
];
169 freelist
[alloc
]=inval
;
172 void sstringstats(int hooknum
, void *arg
) {
176 long statslev
=(long)arg
;
179 for(i
=0,j
=0;i
<=SSTRING_MAXLEN
;i
++) {
180 for(ssp
=freelist
[i
];ssp
;ssp
=ssp
->u
.next
)
184 snprintf(buf
,512,"SString : %7d get calls, %7d free calls, %7d struct allocs, %7d string allocs, %7d strings free",getcalls
,freecalls
,allocstruct
,allocstring
,j
);
185 triggerhook(HOOK_CORE_STATSREPLY
,(void *)buf
);
189 #else /* USE_VALGRIND */
193 sstring
*getsstring(const char *inputstr
, int maxlen
) {
194 size_t len
= strlen(inputstr
);
197 s
=(sstring
*)nsmalloc(POOL_SSTRING
,sizeof(sstring
));
198 s
->u
.l
.length
= strlen(inputstr
);
199 s
->content
=(char *)nsmalloc(POOL_SSTRING
,s
->u
.l
.length
+ 1);
201 memcpy(s
->content
, inputstr
, len
+ 1);
206 void freesstring(sstring
*inval
) {
210 nsfree(POOL_SSTRING
,inval
->content
);
211 nsfree(POOL_SSTRING
,inval
);
215 int sstringcompare(sstring
*ss1
, sstring
*ss2
) {
216 if (ss1
->u
.l
.length
!= ss2
->u
.l
.length
)
219 return strncmp(ss1
->content
, ss2
->content
, ss1
->u
.l
.length
);