00001
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "config.h"
00020 #include "defines.h"
00021
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <time.h>
00026 #include <ctype.h>
00027 #include <errno.h>
00028
00029 #include <sys/time.h>
00030
00031 #include "charconvert.h"
00032 #include "utils.h"
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 void *memdup(void *inptr,size_t size) {
00045 void *outptr = fo_alloc(NULL,1,size,FO_ALLOC_MALLOC);
00046 memcpy(outptr,inptr,size);
00047
00048 return outptr;
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 void *fo_alloc(void *ptr,size_t nmemb,size_t size,int type) {
00063 void *l_ptr = NULL;
00064
00065 switch(type) {
00066 case FO_ALLOC_MALLOC:
00067 l_ptr = malloc(nmemb * size);
00068 break;
00069 case FO_ALLOC_CALLOC:
00070 l_ptr = calloc(nmemb,size);
00071 break;
00072 case FO_ALLOC_REALLOC:
00073 l_ptr = realloc(ptr,size * nmemb);
00074 break;
00075 }
00076
00077 if(!l_ptr) {
00078 perror("error allocating memory");
00079 exit(EXIT_FAILURE);
00080 }
00081
00082 return l_ptr;
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 size_t split(const u_char *big,const u_char *small,u_char ***ulist) {
00097 u_char **list = fo_alloc(NULL,PRERESERVE,sizeof(*list),FO_ALLOC_MALLOC);
00098 u_char *pos = (u_char *)big,*pre = (u_char *)big;
00099 size_t len = 0;
00100 size_t reser = PRERESERVE;
00101 size_t slen = strlen(small);
00102
00103 while((pos = strstr(pos,small)) != NULL) {
00104 *pos = '\0';
00105
00106 list[len++] = strdup(pre);
00107
00108 if(len >= reser) {
00109 reser += PRERESERVE;
00110 list = fo_alloc(list,reser,sizeof(*list),FO_ALLOC_REALLOC);
00111 }
00112
00113 pre = pos+slen;
00114 *pos++ = *small;
00115 }
00116
00117 if(len >= reser) {
00118 list = fo_alloc(list,++reser,sizeof(*list),FO_ALLOC_REALLOC);
00119 }
00120 list[len++] = strdup(pre);
00121
00122 list = fo_alloc(list,len,sizeof(*list),FO_ALLOC_REALLOC);
00123 *ulist = list;
00124
00125 return len;
00126 }
00127
00128
00129
00130 void mem_init(t_mem_pool *pool) {
00131 pool->len = 0;
00132 pool->reserved = 0;
00133 pool->content = NULL;
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 void str_init(t_string *str) {
00146 str->len = 0;
00147 str->reserved = 0;
00148 str->content = NULL;
00149 }
00150
00151
00152
00153 void mem_cleanup(t_mem_pool *pool) {
00154 pool->len = 0;
00155 pool->reserved = 0;
00156
00157 if(pool->content) free(pool->content);
00158
00159 pool->content = NULL;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 void str_cleanup(t_string *str) {
00172 str->len = 0;
00173 str->reserved = 0;
00174
00175 if(str->content) free(str->content);
00176
00177 str->content = NULL;
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 size_t str_char_append(t_string *str,const u_char content) {
00191 if(str->len + 1 >= str->reserved) {
00192 str->content = fo_alloc(str->content,(size_t)(str->reserved + BUFSIZ),1,FO_ALLOC_REALLOC);
00193 str->reserved += BUFSIZ;
00194 }
00195
00196 str->content[str->len] = content;
00197 str->len += 1;
00198 str->content[str->len] = '\0';
00199
00200 return 1;
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 size_t str_chars_append(t_string *str,const u_char *content,size_t length) {
00215 size_t len = BUFSIZ;
00216
00217 if(str->len + length >= str->reserved) {
00218 if(length >= len) {
00219 len += length;
00220 }
00221
00222 str->content = fo_alloc(str->content,(size_t)(str->reserved + len),1,FO_ALLOC_REALLOC);
00223 str->reserved += len;
00224 }
00225
00226 memcpy(&str->content[str->len],content,length);
00227 str->len += length;
00228 str->content[str->len] = '\0';
00229
00230 return length;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 int str_equal_string(const t_string *str1,const t_string *str2) {
00243 register u_char *ptr1 = str1->content,*ptr2 = str2->content;
00244 register size_t i;
00245
00246 if(str1->len != str2->len) {
00247 return 1;
00248 }
00249
00250 for(i = 0; i < str1->len; ++i,++ptr1,++ptr2) {
00251 if(*ptr1 != *ptr2) {
00252 return 1;
00253 }
00254 }
00255
00256 return 0;
00257 }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 int str_equal_chars(const t_string *str1,const u_char *str2, size_t len) {
00270 register size_t i = 0;
00271 register u_char *ptr1 = str1->content,*ptr2 = (u_char *)str2;
00272
00273 if(str1->len != len) {
00274 return 1;
00275 }
00276
00277 for(i = 0; i < len; ++i,++ptr1,++ptr2) {
00278 if(*ptr1 != *ptr2) {
00279 return 1;
00280 }
00281 }
00282
00283 return 0;
00284 }
00285
00286
00287
00288 void *mem_append(t_mem_pool *pool,const void *src,size_t length) {
00289 size_t len = BUFSIZ;
00290
00291 if(pool->len + length >= pool->reserved) {
00292 if(length >= len) {
00293 len += length;
00294 }
00295
00296 pool->content = fo_alloc(pool->content,(size_t)(pool->reserved + len),1,FO_ALLOC_REALLOC);
00297 pool->reserved += len;
00298 }
00299
00300 memcpy(pool->content + pool->len,src,length);
00301 pool->len += length;
00302
00303 return pool->content + pool->len - length;
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 size_t str_str_append(t_string *str,t_string *content) {
00317 return str_chars_append(str,content->content,content->len);
00318 }
00319
00320
00321
00322 size_t mem_set(t_mem_pool *pool,const void *src,size_t length) {
00323 size_t len = MAXLINE;
00324
00325 if(pool->len + length >= pool->reserved) {
00326 if(length >= len) {
00327 len += length;
00328 }
00329
00330 pool->content = fo_alloc(pool->content,pool->reserved + len,1,FO_ALLOC_REALLOC);
00331 pool->reserved += len;
00332 }
00333
00334 memcpy(pool->content,src,length);
00335 pool->len = length;
00336
00337 return length;
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 size_t str_char_set(t_string *str,const u_char *content,size_t length) {
00352 size_t len = BUFSIZ;
00353
00354 if(str->len + length >= str->reserved) {
00355 if(length >= len) {
00356 len += length;
00357 }
00358
00359 str->content = fo_alloc(str->content,len,1,FO_ALLOC_REALLOC);
00360 str->reserved += BUFSIZ;
00361 }
00362
00363 memcpy(str->content,content,length);
00364 str->len = length;
00365 str->content[length] = '\0';
00366
00367 return length;
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 size_t str_str_set(t_string *str,t_string *set) {
00381 return str_char_set(str,set->content,set->len);
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 time_t transform_date(const u_char *datestr) {
00394 struct tm t;
00395 u_char *ptr,*before;
00396 u_char *str = fo_alloc(NULL,strlen(datestr)+1,1,FO_ALLOC_MALLOC);
00397
00398 (void)strcpy(str,datestr);
00399 ptr = before = str;
00400
00401 memset(&t,0,sizeof(t));
00402
00403 for(;*ptr && *ptr != '.';ptr++);
00404 if(*ptr == '.') {
00405 *ptr = '\0';
00406 t.tm_mday = atoi(before);
00407 *ptr = '.';
00408 }
00409 else {
00410 free(str);
00411 return (time_t)-1;
00412 }
00413
00414 for(before= ++ptr;*ptr && *ptr != '.';ptr++);
00415 if(*ptr == '.') {
00416 *ptr = '\0';
00417 t.tm_mon = atoi(before)-1;
00418 *ptr = '.';
00419 }
00420 else {
00421 free(str);
00422 return (time_t)-1;
00423 }
00424
00425 for(before= ++ptr;*ptr && !isspace(*ptr);ptr++);
00426
00427 if(isspace(*ptr) || *ptr == '\0') {
00428 t.tm_year = atoi(before) - 1900;
00429 }
00430 else {
00431 free(str);
00432 return (time_t)-1;
00433 }
00434
00435 if(*ptr == ' ') {
00436 for(;*ptr && *ptr == ' ';ptr++);
00437
00438 if(*ptr) {
00439 for(before= ++ptr;*ptr && *ptr != ':';ptr++);
00440
00441
00442 if(*ptr == ':') {
00443 *ptr = '\0';
00444 t.tm_hour = atoi(before);
00445 *ptr = ':';
00446 }
00447 else {
00448 free(str);
00449 return (time_t)-1;
00450 }
00451
00452 for(before= ++ptr;*ptr && *ptr != ':';ptr++);
00453 if(*ptr == ':' || *ptr == '\0') {
00454 if(*ptr == ':') {
00455 *ptr = '\0';
00456 t.tm_min = atoi(before);
00457 *ptr = ':';
00458 }
00459 else {
00460 t.tm_min = atoi(before);
00461 }
00462 }
00463 else {
00464 free(str);
00465 return (time_t)-1;
00466 }
00467
00468 if(*ptr == ':') {
00469 before= ptr + 1;
00470
00471
00472 if(!*ptr) return (time_t)0;
00473 t.tm_sec = atoi(before);
00474 }
00475 }
00476 }
00477
00478 free(str);
00479 return mktime(&t);
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 int gen_unid(u_char *buff,int maxlen) {
00493 int i,l;
00494 u_char *remaddr = getenv("REMOTE_ADDR");
00495 static const u_char chars[] = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789_-";
00496 struct timeval tp;
00497
00498 if(!remaddr) {
00499 return 0;
00500 }
00501
00502 if(gettimeofday(&tp,NULL) != 0) {
00503 return 0;
00504 }
00505
00506 srand(tp.tv_usec);
00507 l = strlen(remaddr);
00508
00509 if(maxlen > l) {
00510 maxlen = l;
00511 }
00512 if(maxlen <= l) {
00513 l = maxlen - 1;
00514 }
00515
00516 for(i=0;i<l;i++) {
00517 buff[i] = chars[remaddr[i] % 59 + (unsigned int)(rand() % 3)];
00518 }
00519
00520 return i;
00521 }
00522
00523
00524 #ifdef HAS_NO_GETLINE
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535 ssize_t getline(char **lineptr,size_t *n,FILE *stream) {
00536 return getdelim(lineptr,n,'\n',stream);
00537 }
00538
00539 #endif
00540
00541 #ifdef HAS_NO_GETDELIM
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553 ssize_t getdelim(char **lineptr,size_t *n,int delim,FILE *stream) {
00554 t_string buf;
00555 register u_char c;
00556
00557 str_init(&buf);
00558
00559 while(!feof(stream) && !ferror(stream)) {
00560 c = fgetc(stream);
00561 str_char_append(&buf,c);
00562
00563 if(c == delim) break;
00564 }
00565
00566 if(*lineptr) free(*lineptr);
00567
00568 *lineptr = buf.content;
00569 *n = buf.len;
00570
00571 if(feof(stream) || ferror(stream)) return -1;
00572
00573 return buf.len;
00574 }
00575
00576 #endif
00577
00578 #ifdef NOSTRDUP
00579
00580 u_char *strdup(const u_char *str) {
00581 size_t len = strlen(str);
00582 u_char *buff = fo_alloc(NULL,1,len+1,FO_ALLOC_MALLOC);
00583
00584 memcpy(buff,str,len+1);
00585
00586 return buff;
00587 }
00588
00589 #endif
00590
00591 #ifdef NOSTRNDUP
00592
00593 u_char *strndup(const u_char *str,size_t len) {
00594 u_char *buff = fo_alloc(NULL,1,len+1,FO_ALLOC_MALLOC);
00595
00596 memcpy(buff,str,len);
00597 buff[len-1] = '\0';
00598
00599 return buff;
00600 }
00601
00602 #endif
00603
00604
00605
00606 void array_init(t_array *ary,size_t element_size,void (*array_destroy)(void *)) {
00607 ary->reserved = 0;
00608 ary->elements = 0;
00609 ary->element_size = element_size;
00610 ary->array = NULL;
00611 ary->array_destroy = array_destroy;
00612 }
00613
00614 void array_push(t_array *ary,const void *element) {
00615 if(ary->elements + 1 >= ary->reserved) {
00616 ary->array = fo_alloc(ary->array,ary->element_size,ary->reserved+1,FO_ALLOC_REALLOC);
00617 ary->reserved += 1;
00618 }
00619
00620 memcpy(ary->array + (ary->elements * ary->element_size),element,ary->element_size);
00621 ary->elements += 1;
00622 }
00623
00624 void *array_pop(t_array *ary) {
00625 ary->elements -= 1;
00626 return memdup((void *)(ary->array + ((ary->elements + 1) * ary->element_size)),ary->element_size);
00627 }
00628
00629 void *array_shift(t_array *ary) {
00630 void *elem = memdup(ary->array,ary->element_size);
00631
00632 memmove(ary->array,ary->array+ary->element_size,(ary->elements - 1) * ary->element_size);
00633 ary->elements -= 1;
00634 return elem;
00635 }
00636
00637 void array_unshift(t_array *ary,const void *element) {
00638 if(ary->elements + 1 >= ary->reserved) {
00639 ary->array = fo_alloc(ary->array,ary->element_size,ary->reserved+1,FO_ALLOC_REALLOC);
00640 ary->reserved += 1;
00641 }
00642
00643 memmove(ary->array+ary->element_size,ary->array,ary->elements * ary->element_size);
00644 memcpy(ary->array,element,ary->element_size);
00645 ary->elements += 1;
00646 }
00647
00648 void array_sort(t_array *ary,int(*compar)(const void *,const void *)) {
00649 qsort(ary->array,ary->elements,ary->element_size,compar);
00650 }
00651
00652 void *array_bsearch(t_array *ary,const void *key,int (*compar)(const void *, const void *)) {
00653 return bsearch(key,ary->array,ary->elements,ary->element_size,compar);
00654 }
00655
00656 void *array_element_at(t_array *ary,size_t index) {
00657 if(index < 0 || index > ary->elements) {
00658 errno = EINVAL;
00659 return NULL;
00660 }
00661
00662 return ary->array + (index * ary->element_size);
00663 }
00664
00665 void array_destroy(t_array *ary) {
00666 size_t i;
00667
00668 if(ary->array_destroy) {
00669 for(i=0;i<ary->elements;i++) {
00670 ary->array_destroy(ary->array + (i * ary->element_size));
00671 }
00672 }
00673
00674 free(ary->array);
00675 memset(ary,0,sizeof(*ary));
00676 }
00677
00678
00679
00680
00686 void cf_tree_rotate_left(t_cf_tree_node **n) {
00687 t_cf_tree_node *tmp = *n;
00688
00689 *n = (*n)->right;
00690 tmp->right = (*n)->left;
00691 (*n)->left = tmp;
00692 }
00693
00699 void cf_tree_rotate_right(t_cf_tree_node **n) {
00700 t_cf_tree_node *tmp = *n;
00701
00702 *n = (*n)->left;
00703 tmp->left = (*n)->right;
00704 (*n)->right = tmp;
00705 }
00706
00713 int cf_tree_leftgrown(t_cf_tree_node **n) {
00714 switch((*n)->bal) {
00715 case CF_TREE_LEFT:
00716 if((*n)->left->bal == CF_TREE_LEFT) {
00717 (*n)->bal = (*n)->left->bal = CF_TREE_NONE;
00718
00719 cf_tree_rotate_right(n);
00720 }
00721 else {
00722 switch((*n)->left->right->bal) {
00723 case CF_TREE_LEFT:
00724 (*n)->bal = CF_TREE_RIGHT;
00725 (*n)->left->bal = CF_TREE_NONE;
00726 break;
00727
00728 case CF_TREE_RIGHT:
00729 (*n)->bal = CF_TREE_NONE;
00730 (*n)->left->bal = CF_TREE_LEFT;
00731 break;
00732
00733 default:
00734 (*n)->bal = CF_TREE_NONE;
00735 (*n)->left->bal = CF_TREE_NONE;
00736 }
00737
00738 (*n)->left->right->bal = CF_TREE_NONE;
00739
00740 cf_tree_rotate_left(&(*n)->left);
00741 cf_tree_rotate_right(n);
00742 }
00743
00744 return 0;
00745
00746 case CF_TREE_RIGHT:
00747 (*n)->bal = CF_TREE_NONE;
00748 return 0;
00749
00750 default:
00751 (*n)->bal = CF_TREE_LEFT;
00752 return 1;
00753 }
00754 }
00755
00762 int cf_tree_rightgrown(t_cf_tree_node **n) {
00763 switch((*n)->bal) {
00764 case CF_TREE_LEFT:
00765 (*n)->bal = CF_TREE_NONE;
00766 return 0;
00767
00768 case CF_TREE_RIGHT:
00769 if((*n)->right->bal == CF_TREE_RIGHT) {
00770 (*n)->bal = (*n)->right->bal = CF_TREE_NONE;
00771 cf_tree_rotate_left(n);
00772 }
00773 else {
00774 switch((*n)->right->left->bal) {
00775 case CF_TREE_RIGHT:
00776 (*n)->bal = CF_TREE_LEFT;
00777 (*n)->right->bal = CF_TREE_NONE;
00778 break;
00779
00780 case CF_TREE_LEFT:
00781 (*n)->bal = CF_TREE_NONE;
00782 (*n)->right->bal = CF_TREE_RIGHT;
00783 break;
00784
00785 default:
00786 (*n)->bal = CF_TREE_NONE;
00787 (*n)->right->bal = CF_TREE_NONE;
00788 }
00789
00790 (*n)->right->left->bal = CF_TREE_NONE;
00791 cf_tree_rotate_right(& (*n)->right);
00792 cf_tree_rotate_left(n);
00793 }
00794
00795 return 0;
00796
00797 default:
00798 (*n)->bal = CF_TREE_RIGHT;
00799 return 1;
00800 }
00801 }
00802
00803
00804 int cf_tree_insert(t_cf_tree *tree,t_cf_tree_node **n, t_cf_tree_dataset *d) {
00805 int tmp;
00806
00807 if(!n) n = &tree->root;
00808
00809 if(!(*n)) {
00810 *n = fo_alloc(NULL,1,sizeof(*tree->root),FO_ALLOC_CALLOC);
00811
00812 (*n)->d = memdup(d,sizeof(*d));
00813 (*n)->bal = 0;
00814
00815 return 1;
00816 }
00817
00818 if(tree->compare(d,(*n)->d) < 0) {
00819 if((tmp = cf_tree_insert(tree,&(*n)->left,d)) == 1) {
00820 return cf_tree_leftgrown(n);
00821 }
00822
00823 return tmp;
00824 }
00825 else if(tree->compare(d,(*n)->d) > 0) {
00826 if((tmp = cf_tree_insert(tree,&(*n)->right,d)) == 1) {
00827 return cf_tree_rightgrown(n);
00828 }
00829
00830 return tmp;
00831 }
00832
00833 return -1;
00834 }
00835
00842 int cf_tree_leftshrunk(t_cf_tree_node **n) {
00843 switch((*n)->bal) {
00844 case CF_TREE_LEFT:
00845 (*n)->bal = CF_TREE_NONE;
00846
00847 return 1;
00848
00849 case CF_TREE_RIGHT:
00850 if((*n)->right->bal == CF_TREE_RIGHT) {
00851 (*n)->bal = (*n)->right->bal = CF_TREE_NONE;
00852 cf_tree_rotate_left(n);
00853
00854 return 1;
00855 }
00856 else if((*n)->right->bal == CF_TREE_NONE) {
00857 (*n)->bal = CF_TREE_RIGHT;
00858 (*n)->right->bal = CF_TREE_LEFT;
00859 cf_tree_rotate_left(n);
00860
00861 return 0;
00862 }
00863 else {
00864 switch((*n)->right->left->bal) {
00865 case CF_TREE_LEFT:
00866 (*n)->bal = CF_TREE_NONE;
00867 (*n)->right->bal = CF_TREE_RIGHT;
00868 break;
00869
00870 case CF_TREE_RIGHT:
00871 (*n)->bal = CF_TREE_LEFT;
00872 (*n)->right->bal = CF_TREE_NONE;
00873 break;
00874
00875 default:
00876 (*n)->bal = CF_TREE_NONE;
00877 (*n)->right->bal = CF_TREE_NONE;
00878 }
00879
00880 (*n)->right->left->bal = CF_TREE_NONE;
00881 cf_tree_rotate_right(&(*n)->right);
00882 cf_tree_rotate_left(n);
00883 return 1;
00884 }
00885
00886 default:
00887 (*n)->bal = CF_TREE_RIGHT;
00888 return 0;
00889 }
00890 }
00891
00898 int cf_tree_rightshrunk(t_cf_tree_node **n) {
00899 switch((*n)->bal) {
00900 case CF_TREE_RIGHT:
00901 (*n)->bal = CF_TREE_NONE;
00902 return 1;
00903
00904 case CF_TREE_LEFT:
00905 if((*n)->left->bal == CF_TREE_LEFT) {
00906 (*n)->bal = (*n)->left->bal = CF_TREE_NONE;
00907 cf_tree_rotate_right(n);
00908
00909 return 1;
00910 }
00911 else if((*n)->left->bal == CF_TREE_NONE) {
00912 (*n)->bal = CF_TREE_LEFT;
00913 (*n)->left->bal = CF_TREE_RIGHT;
00914 cf_tree_rotate_right(n);
00915
00916 return 0;
00917 }
00918 else {
00919 switch((*n)->left->right->bal) {
00920 case CF_TREE_LEFT:
00921 (*n)->bal = CF_TREE_RIGHT;
00922 (*n)->left->bal = CF_TREE_NONE;
00923 break;
00924
00925 case CF_TREE_RIGHT:
00926 (*n)->bal = CF_TREE_NONE;
00927 (*n)->left->bal = CF_TREE_LEFT;
00928 break;
00929
00930 default:
00931 (*n)->bal = CF_TREE_NONE;
00932 (*n)->left->bal = CF_TREE_NONE;
00933 }
00934
00935 (*n)->left->right->bal = CF_TREE_NONE;
00936
00937 cf_tree_rotate_left(&(*n)->left);
00938 cf_tree_rotate_right(n);
00939
00940 return 1;
00941 }
00942
00943 default:
00944 (*n)->bal = CF_TREE_LEFT;
00945 return 0;
00946 }
00947 }
00948
00956 int cf_tree_findhighest(t_cf_tree_node *target,t_cf_tree_node **n,int *res) {
00957 t_cf_tree_node *tmp;
00958
00959 *res = 1;
00960 if(!(*n)) {
00961 return 0;
00962 }
00963
00964 if((*n)->right) {
00965 if(!cf_tree_findhighest(target,&(*n)->right,res)) {
00966 return 0;
00967 }
00968 if(*res == 1) {
00969 *res = cf_tree_rightshrunk(n);
00970 }
00971
00972 return 1;
00973 }
00974
00975 target->d = (*n)->d;
00976 tmp = *n;
00977 *n = (*n)->left;
00978 free(tmp);
00979
00980 return 1;
00981 }
00982
00990 int cf_tree_findlowest(t_cf_tree_node *target,t_cf_tree_node **n,int *res) {
00991 t_cf_tree_node *tmp;
00992
00993 *res = 1;
00994 if(!(*n)) return 0;
00995
00996 if((*n)->left) {
00997 if(!cf_tree_findlowest(target,&(*n)->left,res)) {
00998 return 0;
00999 }
01000 if(*res == 1) {
01001 *res = cf_tree_leftshrunk(n);
01002 }
01003
01004 return 1;
01005 }
01006
01007 target->d = (*n)->d;
01008 tmp = *n;
01009 *n = (*n)->right;
01010 free(tmp);
01011
01012 return 1;
01013 }
01014
01015 int cf_tree_remove(t_cf_tree *tree,t_cf_tree_node **n,t_cf_tree_dataset *key) {
01016 int tmp = 1;
01017
01018 if(!n) n = &tree->root;
01019
01020 if(!(*n)) return -1;
01021
01022 if(tree->compare(key,(*n)->d) < 0) {
01023 if((tmp = cf_tree_remove(tree,&(*n)->left, key)) == 1) {
01024 return cf_tree_leftshrunk(n);
01025 }
01026
01027 return tmp;
01028 }
01029 else if(tree->compare(key, (*n)->d) > 0) {
01030 if((tmp = cf_tree_remove(tree,&(*n)->right,key)) == 1) {
01031 return cf_tree_rightshrunk(n);
01032 }
01033
01034 return tmp;
01035 }
01036
01037 if((*n)->left) {
01038 if(cf_tree_findhighest(*n, &((*n)->left), &tmp)) {
01039 if(tmp == 1) {
01040 tmp = cf_tree_leftshrunk(n);
01041 }
01042
01043 return tmp;
01044 }
01045 }
01046 if((*n)->right) {
01047 if(cf_tree_findlowest(*n, &((*n)->right), &tmp)) {
01048 if(tmp == 1) {
01049 tmp = cf_tree_rightshrunk(n);
01050 }
01051 return tmp;
01052 }
01053 }
01054
01055 free(*n);
01056 *n = NULL;
01057
01058 return 1;
01059 }
01060
01061 const t_cf_tree_dataset *cf_tree_find(t_cf_tree *tree,t_cf_tree_node *n, t_cf_tree_dataset *key) {
01062
01063 if(!n) return NULL;
01064
01065 if(tree->compare(key,n->d) < 0) {
01066 return cf_tree_find(tree,n->left,key);
01067 }
01068 else if(tree->compare(key,n->d) > 0) {
01069 return cf_tree_find(tree,n->right,key);
01070 }
01071
01072 return n->d;
01073 }
01074
01075 void cf_tree_init(t_cf_tree *tree,int (*compare)(t_cf_tree_dataset *,t_cf_tree_dataset *),void (*destroy)(t_cf_tree_dataset *)) {
01076 tree->root = NULL;
01077 tree->compare = compare;
01078 tree->destroy = destroy;
01079 }
01080
01086 void cf_tree_destroy_nodes(t_cf_tree *tree,t_cf_tree_node *n) {
01087 if(n) {
01088 if(n->left) cf_tree_destroy_nodes(tree,n->left);
01089 if(n->right) cf_tree_destroy_nodes(tree,n->right);
01090
01091 if(tree->destroy) {
01092 tree->destroy(n->d);
01093 }
01094 else {
01095 if(n->d->key) free(n->d->key);
01096 if(n->d->data) free(n->d->data);
01097 }
01098
01099 free(n->d);
01100 free(n);
01101 }
01102 }
01103
01104 void cf_tree_destroy(t_cf_tree *tree) {
01105 cf_tree_destroy_nodes(tree,tree->root);
01106 }
01107
01108
01109
01110
01111
01112 int cf_strcmp(const u_char *str1,const u_char *str2) {
01113 register u_char *ptr1 = (u_char *)str1;
01114 register u_char *ptr2 = (u_char *)str2;
01115
01116 for(;*ptr1 && *ptr2 && *ptr1 == *ptr2;ptr1++,ptr2++);
01117
01118 if(*ptr1 == *ptr2) return 0;
01119
01120 return 1;
01121 }
01122
01123 int cf_strcasecmp(const u_char *str1,const u_char *str2) {
01124 register u_char *ptr1 = (u_char *)str1;
01125 register u_char *ptr2 = (u_char *)str2;
01126
01127 for(;*ptr1 && *ptr2 && toupper(*ptr1) == toupper(*ptr2);ptr1++,ptr2++);
01128
01129 if(toupper(*ptr1) == toupper(*ptr2)) return 0;
01130
01131 return 1;
01132 }
01133
01134 int cf_strncmp(const u_char *str1,const u_char *str2,size_t n) {
01135 register u_char *ptr1 = (u_char *)str1;
01136 register u_char *ptr2 = (u_char *)str2;
01137 register size_t i;
01138
01139 for(i=0;*ptr1 && *ptr2 && *ptr1 == *ptr2 && i < n;ptr1++,ptr2++,i++) {
01140 if(i == n - 1) return 0;
01141 }
01142
01143 return 1;
01144 }
01145
01146 int cf_strncasecmp(const u_char *str1,const u_char *str2,size_t n) {
01147 register u_char *ptr1 = (u_char *)str1;
01148 register u_char *ptr2 = (u_char *)str2;
01149 register size_t i;
01150
01151 for(i=0;*ptr1 && *ptr2 && i < n && toupper(*ptr1) == toupper(*ptr2);ptr1++,ptr2++,i++) {
01152 if(i == n - 1) return 0;
01153 }
01154
01155 return 1;
01156 }
01157
01158 size_t cf_strlen_utf8(const u_char *str,size_t rlen) {
01159 register size_t len;
01160 register u_char *ptr;
01161 int bytes;
01162 u_int32_t num;
01163
01164 for(ptr=(u_char *)str;*ptr;len++) {
01165 if((bytes = utf8_to_unicode(ptr,rlen,&num)) < 0) {
01166 return -1;
01167 }
01168
01169 ptr += bytes;
01170 rlen -= bytes;
01171 }
01172
01173 return rlen;
01174 }
01175
01176
01177
01178