]>
jfr.im git - irc/quakenet/newserv.git/blob - lib/sstring.c
f77921a7cd9e86176a6e9d207ce4a871a8005121
1 /* sstring.h - Declaration of "static strings" functions */
3 #define COMPILING_SSTRING
6 #include "../core/hooks.h"
15 /* List of free stuff */
16 sstring
*freelist
[SSTRING_MAXLEN
+1];
18 /* Global variables to track allocated memory */
24 /* Statistics counters */
30 /* Internal function */
31 void sstringstats(int hooknum
, void *arg
);
35 for(i
=0;i
<=SSTRING_MAXLEN
;i
++)
43 /* Initialise statistics counters */
49 registerhook(HOOK_CORE_STATSREQUEST
,&sstringstats
);
52 sstring
*getsstring(const char *inputstr
, int maxlen
) {
58 /* getsstring() on a NULL pointer returns a NULL sstring.. */
63 if (inputstr
[0]=='\0') {
67 /* Only count calls that actually did something */
70 length
=strlen(inputstr
)+1;
74 assert(length
<=SSTRING_MAXLEN
);
76 /* Check to see if an approximately correct
77 * sized string is available */
78 for(i
=0;i
<SSTRING_SLACK
;i
++) {
79 if (length
+i
>SSTRING_MAXLEN
)
82 if (freelist
[length
+i
]!=NULL
) {
83 retval
=freelist
[length
+i
];
84 freelist
[length
+i
]=retval
->u
.next
;
85 retval
->u
.l
.alloc
=(length
+i
);
90 /* None found, allocate a new one */
93 if (structfree
< sizeof(sstring
)) {
94 /* We always allocate an exact multiple of these.
95 * Therefore, if there is enough for a partial structure we broke something */
96 assert(structfree
==0);
98 /* Allocate more RAM */
100 structmem
=(sstring
*)malloc(SSTRING_STRUCTALLOC
);
101 assert(structmem
!=NULL
);
102 structfree
=SSTRING_STRUCTALLOC
;
107 structfree
-=sizeof(sstring
);
109 if (stringfree
< length
) {
110 /* Not enough left for what we want.
111 * Allocate the remainder of our chunk (if any)
112 * to something and immediately free it.
113 * Decrement the freecalls counter to fix the stats */
114 if (stringfree
> 0) {
115 retval
->content
=stringmem
;
116 retval
->u
.l
.alloc
=stringfree
;
121 /* GOTO GOTO GOTO: We need to allocate
122 * another new struct here. Goto is the cleanest
126 /* Grab some more string space */
128 stringmem
=(char *)malloc(SSTRING_DATAALLOC
);
129 assert(stringmem
!=NULL
);
130 stringfree
=SSTRING_DATAALLOC
;
134 retval
->content
=stringmem
;
135 retval
->u
.l
.alloc
=length
;
141 * At this point, retval points to a valid structure which is at
142 * least the right size and has the "alloc" value set correctly
145 retval
->u
.l
.length
=(length
-1);
146 strncpy(retval
->content
,inputstr
,(length
-1));
147 retval
->content
[length
-1]='\0';
152 void freesstring(sstring
*inval
) {
156 /* Allow people to call this with a NULL value */
160 /* Only count calls that actually did something */
163 alloc
=inval
->u
.l
.alloc
;
164 assert(alloc
<=SSTRING_MAXLEN
);
165 inval
->u
.next
=freelist
[alloc
];
166 freelist
[alloc
]=inval
;
169 void sstringstats(int hooknum
, void *arg
) {
173 long statslev
=(long)arg
;
176 for(i
=0,j
=0;i
<=SSTRING_MAXLEN
;i
++) {
177 for(ssp
=freelist
[i
];ssp
;ssp
=ssp
->u
.next
)
181 snprintf(buf
,512,"SString : %7d get calls, %7d free calls, %7d struct allocs, %7d string allocs, %7d strings free",getcalls
,freecalls
,allocstruct
,allocstring
,j
);
182 triggerhook(HOOK_CORE_STATSREPLY
,(void *)buf
);
186 int sstringcompare(sstring
*ss1
, sstring
*ss2
) {
187 if (ss1
->u
.l
.length
!= ss2
->u
.l
.length
)
190 return strncmp(ss1
->content
, ss2
->content
, ss1
->u
.l
.length
);