]>
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"
16 /* List of free stuff */
17 sstring
*freelist
[SSTRING_MAXLEN
+1];
19 /* Global variables to track allocated memory */
25 /* Statistics counters */
31 /* Internal function */
32 void sstringstats(int hooknum
, void *arg
);
36 for(i
=0;i
<=SSTRING_MAXLEN
;i
++)
44 /* Initialise statistics counters */
50 registerhook(HOOK_CORE_STATSREQUEST
,&sstringstats
);
53 sstring
*getsstring(const char *inputstr
, int maxlen
) {
59 /* getsstring() on a NULL pointer returns a NULL sstring.. */
64 if (inputstr
[0]=='\0') {
68 /* Only count calls that actually did something */
71 length
=strlen(inputstr
)+1;
75 assert(length
<=SSTRING_MAXLEN
);
77 /* Check to see if an approximately correct
78 * sized string is available */
79 for(i
=0;i
<SSTRING_SLACK
;i
++) {
80 if (length
+i
>SSTRING_MAXLEN
)
83 if (freelist
[length
+i
]!=NULL
) {
84 retval
=freelist
[length
+i
];
85 freelist
[length
+i
]=retval
->u
.next
;
86 retval
->u
.l
.alloc
=(length
+i
);
91 /* None found, allocate a new one */
94 if (structfree
< sizeof(sstring
)) {
95 /* We always allocate an exact multiple of these.
96 * Therefore, if there is enough for a partial structure we broke something */
97 assert(structfree
==0);
99 /* Allocate more RAM */
101 structmem
=(sstring
*)nsmalloc(POOL_SSTRING
,SSTRING_STRUCTALLOC
);
102 assert(structmem
!=NULL
);
103 structfree
=SSTRING_STRUCTALLOC
;
108 structfree
-=sizeof(sstring
);
110 if (stringfree
< length
) {
111 /* Not enough left for what we want.
112 * Allocate the remainder of our chunk (if any)
113 * to something and immediately free it.
114 * Decrement the freecalls counter to fix the stats */
115 if (stringfree
> 0) {
116 retval
->content
=stringmem
;
117 retval
->u
.l
.alloc
=stringfree
;
122 /* GOTO GOTO GOTO: We need to allocate
123 * another new struct here. Goto is the cleanest
127 /* Grab some more string space */
129 stringmem
=(char *)nsmalloc(POOL_SSTRING
,SSTRING_DATAALLOC
);
130 assert(stringmem
!=NULL
);
131 stringfree
=SSTRING_DATAALLOC
;
135 retval
->content
=stringmem
;
136 retval
->u
.l
.alloc
=length
;
142 * At this point, retval points to a valid structure which is at
143 * least the right size and has the "alloc" value set correctly
146 retval
->u
.l
.length
=(length
-1);
147 strncpy(retval
->content
,inputstr
,(length
-1));
148 retval
->content
[length
-1]='\0';
153 void freesstring(sstring
*inval
) {
157 /* Allow people to call this with a NULL value */
161 /* Only count calls that actually did something */
164 alloc
=inval
->u
.l
.alloc
;
165 assert(alloc
<=SSTRING_MAXLEN
);
166 inval
->u
.next
=freelist
[alloc
];
167 freelist
[alloc
]=inval
;
170 void sstringstats(int hooknum
, void *arg
) {
174 long statslev
=(long)arg
;
177 for(i
=0,j
=0;i
<=SSTRING_MAXLEN
;i
++) {
178 for(ssp
=freelist
[i
];ssp
;ssp
=ssp
->u
.next
)
182 snprintf(buf
,512,"SString : %7d get calls, %7d free calls, %7d struct allocs, %7d string allocs, %7d strings free",getcalls
,freecalls
,allocstruct
,allocstring
,j
);
183 triggerhook(HOOK_CORE_STATSREPLY
,(void *)buf
);
187 int sstringcompare(sstring
*ss1
, sstring
*ss2
) {
188 if (ss1
->u
.l
.length
!= ss2
->u
.l
.length
)
191 return strncmp(ss1
->content
, ss2
->content
, ss1
->u
.l
.length
);