00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <assert.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038
00039 #include "abyss_mallocvar.h"
00040 #include "abyss_xmlrpc_int.h"
00041
00042 #include <xmlrpc-c/abyss.h>
00043
00044 #include "abyss_token.h"
00045
00046 #include "abyss_data.h"
00047
00048
00049
00050
00051
00052 void ListInit(TList *sl)
00053 {
00054 sl->item=NULL;
00055 sl->size=sl->maxsize=0;
00056 sl->autofree=FALSE;
00057 }
00058
00059 void ListInitAutoFree(TList *sl)
00060 {
00061 sl->item=NULL;
00062 sl->size=sl->maxsize=0;
00063 sl->autofree=TRUE;
00064 }
00065
00066
00067
00068 void
00069 ListFree(TList * const sl) {
00070
00071 if (sl->item) {
00072 if (sl->autofree) {
00073 unsigned int i;
00074 for (i = sl->size; i > 0; --i)
00075 free(sl->item[i-1]);
00076
00077 }
00078 free(sl->item);
00079 }
00080 sl->item = NULL;
00081 sl->size = 0;
00082 sl->maxsize = 0;
00083 }
00084
00085
00086
00087 void
00088 ListFreeItems(TList * const sl) {
00089
00090 if (sl->item) {
00091 unsigned int i;
00092 for (i = sl->size; i > 0; --i)
00093 free(sl->item[i-1]);
00094 }
00095 }
00096
00097
00098
00099 abyss_bool
00100 ListAdd(TList * const sl,
00101 void * const str) {
00102
00103
00104
00105 abyss_bool success;
00106
00107 if (sl->size >= sl->maxsize) {
00108 uint16_t newSize = sl->maxsize + 16;
00109 void **newitem;
00110
00111 newitem = realloc(sl->item, newSize * sizeof(void *));
00112 if (newitem) {
00113 sl->item = newitem;
00114 sl->maxsize = newSize;
00115 }
00116 }
00117
00118 if (sl->size >= sl->maxsize)
00119 success = FALSE;
00120 else {
00121 success = TRUE;
00122 sl->item[sl->size++] = str;
00123 }
00124 return success;
00125 }
00126
00127
00128
00129 void
00130 ListRemove(TList * const sl) {
00131
00132
00133
00134
00135 assert(sl->size > 0);
00136
00137 --sl->size;
00138 }
00139
00140
00141
00142 abyss_bool
00143 ListAddFromString(TList * const list,
00144 const char * const stringArg) {
00145
00146 abyss_bool retval;
00147
00148 if (!stringArg)
00149 retval = TRUE;
00150 else {
00151 char * buffer;
00152
00153 buffer = strdup(stringArg);
00154 if (!buffer)
00155 retval = FALSE;
00156 else {
00157 abyss_bool endOfString;
00158 abyss_bool error;
00159 char * c;
00160
00161 for (c = &buffer[0], endOfString = FALSE, error = FALSE;
00162 !endOfString && !error;
00163 ) {
00164 const char * t;
00165 NextToken((const char **)&c);
00166
00167 while (*c == ',')
00168 ++c;
00169
00170 t = GetToken(&c);
00171 if (!t)
00172 endOfString = TRUE;
00173 else {
00174 char * p;
00175
00176 for (p = c - 2; *p == ','; --p)
00177 *p = '\0';
00178
00179 if (t[0] != '\0') {
00180 abyss_bool added;
00181 added = ListAdd(list, (void*)t);
00182
00183 if (!added)
00184 error = TRUE;
00185 }
00186 }
00187 }
00188 retval = !error;
00189 xmlrpc_strfree(buffer);
00190 }
00191 }
00192 return retval;
00193 }
00194
00195
00196
00197 abyss_bool
00198 ListFindString(TList * const sl,
00199 const char * const str,
00200 uint16_t * const indexP)
00201 {
00202 uint16_t i;
00203
00204 if (sl->item && str)
00205 for (i=0;i<sl->size;i++)
00206 if (strcmp(str,(char *)(sl->item[i]))==0)
00207 {
00208 *indexP=i;
00209 return TRUE;
00210 };
00211
00212 return FALSE;
00213 }
00214
00215
00216
00217
00218
00219 abyss_bool BufferAlloc(TBuffer *buf,uint32_t memsize)
00220 {
00221
00222 buf->staticid=0;
00223 buf->data=(void *)malloc(memsize);
00224 if (buf->data)
00225 {
00226 buf->size=memsize;
00227 return TRUE;
00228 }
00229 else
00230 {
00231 buf->size=0;
00232 return FALSE;
00233 };
00234 }
00235
00236 void BufferFree(TBuffer *buf)
00237 {
00238 if (buf->staticid)
00239 {
00240
00241 }
00242 else
00243 free(buf->data);
00244
00245 buf->size=0;
00246 buf->staticid=0;
00247 }
00248
00249 abyss_bool BufferRealloc(TBuffer *buf,uint32_t memsize)
00250 {
00251 if (buf->staticid)
00252 {
00253 TBuffer b;
00254
00255 if (memsize<=buf->size)
00256 return TRUE;
00257
00258 if (BufferAlloc(&b,memsize))
00259 {
00260 memcpy(b.data,buf->data,buf->size);
00261 BufferFree(buf);
00262 *buf=b;
00263 return TRUE;
00264 }
00265 }
00266 else
00267 {
00268 void *d;
00269
00270 d=realloc(buf->data,memsize);
00271 if (d)
00272 {
00273 buf->data=d;
00274 buf->size=memsize;
00275 return TRUE;
00276 }
00277 }
00278
00279 return FALSE;
00280 }
00281
00282
00283
00284
00285
00286
00287 abyss_bool StringAlloc(TString *s)
00288 {
00289 s->size=0;
00290 if (BufferAlloc(&(s->buffer),256))
00291 {
00292 *(char *)(s->buffer.data)='\0';
00293 return TRUE;
00294 }
00295 else
00296 return FALSE;
00297 }
00298
00299 abyss_bool StringConcat(TString *s,char *s2)
00300 {
00301 uint32_t len=strlen(s2);
00302
00303 if (len+s->size+1>s->buffer.size)
00304 if (!BufferRealloc(&(s->buffer),((len+s->size+1+256)/256)*256))
00305 return FALSE;
00306
00307 strcat((char *)(s->buffer.data),s2);
00308 s->size+=len;
00309 return TRUE;
00310 }
00311
00312 abyss_bool StringBlockConcat(TString *s,char *s2,char **ref)
00313 {
00314 uint32_t len=strlen(s2)+1;
00315
00316 if (len+s->size>s->buffer.size)
00317 if (!BufferRealloc(&(s->buffer),((len+s->size+1+256)/256)*256))
00318 return FALSE;
00319
00320 *ref=(char *)(s->buffer.data)+s->size;
00321 memcpy(*ref,s2,len);
00322 s->size+=len;
00323 return TRUE;
00324 }
00325
00326 void StringFree(TString *s)
00327 {
00328 s->size=0;
00329 BufferFree(&(s->buffer));
00330 }
00331
00332 char *StringData(TString *s)
00333 {
00334 return (char *)(s->buffer.data);
00335 }
00336
00337
00338
00339
00340
00341 static uint16_t
00342 Hash16(const char * const start) {
00343
00344 const char * s;
00345
00346 uint16_t i;
00347
00348 s = start;
00349 i = 0;
00350
00351 while(*s)
00352 i = i * 37 + *s++;
00353
00354 return i;
00355 }
00356
00357
00358
00359
00360
00361 void TableInit(TTable *t)
00362 {
00363 t->item=NULL;
00364 t->size=t->maxsize=0;
00365 }
00366
00367 void TableFree(TTable *t)
00368 {
00369 uint16_t i;
00370
00371 if (t->item)
00372 {
00373 if (t->size)
00374 for (i=t->size;i>0;i--)
00375 {
00376 free(t->item[i-1].name);
00377 free(t->item[i-1].value);
00378 };
00379
00380 free(t->item);
00381 }
00382
00383 TableInit(t);
00384 }
00385
00386
00387
00388 abyss_bool
00389 TableFindIndex(TTable * const t,
00390 const char * const name,
00391 uint16_t * const index) {
00392
00393 uint16_t i,hash=Hash16(name);
00394
00395 if ((t->item) && (t->size>0) && (*index<t->size))
00396 {
00397 for (i=*index;i<t->size;i++)
00398 if (hash==t->item[i].hash)
00399 if (strcmp(t->item[i].name,name)==0)
00400 {
00401 *index=i;
00402 return TRUE;
00403 };
00404 };
00405
00406 return FALSE;
00407 }
00408
00409
00410
00411 abyss_bool
00412 TableAddReplace(TTable * const t,
00413 const char * const name,
00414 const char * const value) {
00415
00416 uint16_t i=0;
00417
00418 if (TableFindIndex(t,name,&i))
00419 {
00420 free(t->item[i].value);
00421 if (value)
00422 t->item[i].value=strdup(value);
00423 else
00424 {
00425 free(t->item[i].name);
00426 if (--t->size>0)
00427 t->item[i]=t->item[t->size];
00428 };
00429
00430 return TRUE;
00431 }
00432 else
00433 return TableAdd(t,name,value);
00434 }
00435
00436
00437
00438 abyss_bool
00439 TableAdd(TTable * const t,
00440 const char * const name,
00441 const char * const value) {
00442
00443 if (t->size>=t->maxsize) {
00444 TTableItem *newitem;
00445
00446 t->maxsize+=16;
00447
00448 newitem=(TTableItem *)realloc(t->item,(t->maxsize)*sizeof(TTableItem));
00449 if (newitem)
00450 t->item=newitem;
00451 else {
00452 t->maxsize-=16;
00453 return FALSE;
00454 }
00455 }
00456
00457 t->item[t->size].name=strdup(name);
00458 t->item[t->size].value=strdup(value);
00459 t->item[t->size].hash=Hash16(name);
00460
00461 ++t->size;
00462
00463 return TRUE;
00464 }
00465
00466
00467
00468 char *
00469 TableFind(TTable * const t,
00470 const char * const name) {
00471
00472 uint16_t i=0;
00473
00474 if (TableFindIndex(t,name,&i))
00475 return t->item[i].value;
00476 else
00477 return NULL;
00478 }
00479
00480
00481
00482
00483
00484 static TPoolZone *
00485 PoolZoneAlloc(uint32_t const zonesize) {
00486
00487 TPoolZone * poolZoneP;
00488
00489 MALLOCARRAY(poolZoneP, zonesize);
00490 if (poolZoneP) {
00491 poolZoneP->pos = &poolZoneP->data[0];
00492 poolZoneP->maxpos = poolZoneP->pos + zonesize;
00493 poolZoneP->next = NULL;
00494 poolZoneP->prev = NULL;
00495 }
00496 return poolZoneP;
00497 }
00498
00499
00500
00501 static void
00502 PoolZoneFree(TPoolZone * const poolZoneP) {
00503
00504 free(poolZoneP);
00505 }
00506
00507
00508
00509 abyss_bool
00510 PoolCreate(TPool * const poolP,
00511 uint32_t const zonesize) {
00512
00513 abyss_bool success;
00514 abyss_bool mutexCreated;
00515
00516 poolP->zonesize = zonesize;
00517
00518 mutexCreated = MutexCreate(&poolP->mutex);
00519 if (mutexCreated) {
00520 TPoolZone * const firstZoneP = PoolZoneAlloc(zonesize);
00521
00522 if (firstZoneP != NULL) {
00523 poolP->firstzone = firstZoneP;
00524 poolP->currentzone = firstZoneP;
00525 success = TRUE;
00526 } else
00527 success = FALSE;
00528 if (!success)
00529 MutexFree(&poolP->mutex);
00530 } else
00531 success = FALSE;
00532
00533 return success;
00534 }
00535
00536
00537
00538 void *
00539 PoolAlloc(TPool * const poolP,
00540 uint32_t const size) {
00541
00542
00543
00544 void * retval;
00545
00546 if (size == 0)
00547 retval = NULL;
00548 else {
00549 abyss_bool gotMutexLock;
00550
00551 gotMutexLock = MutexLock(&poolP->mutex);
00552 if (!gotMutexLock)
00553 retval = NULL;
00554 else {
00555 TPoolZone * const curPoolZoneP = poolP->currentzone;
00556
00557 if (curPoolZoneP->pos + size < curPoolZoneP->maxpos) {
00558 retval = curPoolZoneP->pos;
00559 curPoolZoneP->pos += size;
00560 } else {
00561 uint32_t const zonesize = MAX(size, poolP->zonesize);
00562
00563 TPoolZone * const newPoolZoneP = PoolZoneAlloc(zonesize);
00564 if (newPoolZoneP) {
00565 newPoolZoneP->prev = curPoolZoneP;
00566 newPoolZoneP->next = curPoolZoneP->next;
00567 curPoolZoneP->next = newPoolZoneP;
00568 poolP->currentzone = newPoolZoneP;
00569 retval= newPoolZoneP->data;
00570 newPoolZoneP->pos = newPoolZoneP->data + size;
00571 } else
00572 retval = NULL;
00573 }
00574 MutexUnlock(&poolP->mutex);
00575 }
00576 }
00577 return retval;
00578 }
00579
00580
00581
00582 void
00583 PoolReturn(TPool * const poolP,
00584 void * const blockP) {
00585
00586
00587
00588
00589 TPoolZone * const curPoolZoneP = poolP->currentzone;
00590
00591 assert((char*)curPoolZoneP->data < (char*)blockP &&
00592 (char*)blockP < (char*)curPoolZoneP->pos);
00593
00594 curPoolZoneP->pos = blockP;
00595
00596 if (curPoolZoneP->pos == curPoolZoneP->data) {
00597
00598
00599
00600
00601 assert(curPoolZoneP->prev);
00602
00603 curPoolZoneP->prev->next = NULL;
00604
00605 PoolZoneFree(curPoolZoneP);
00606 }
00607 }
00608
00609
00610
00611 void
00612 PoolFree(TPool * const poolP) {
00613
00614 TPoolZone * poolZoneP;
00615 TPoolZone * nextPoolZoneP;
00616
00617 for (poolZoneP = poolP->firstzone; poolZoneP; poolZoneP = nextPoolZoneP) {
00618 nextPoolZoneP = poolZoneP->next;
00619 free(poolZoneP);
00620 }
00621 }
00622
00623
00624
00625 const char *
00626 PoolStrdup(TPool * const poolP,
00627 const char * const origString) {
00628
00629 char * newString;
00630
00631 if (origString == NULL)
00632 newString = NULL;
00633 else {
00634 newString = PoolAlloc(poolP, strlen(origString) + 1);
00635 if (newString != NULL)
00636 strcpy(newString, origString);
00637 }
00638 return newString;
00639 }