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 #ifndef _ink_string_h_
00033 #define _ink_string_h_
00034 
00035 #include <stdio.h>
00036 #include <memory.h>
00037 #include <strings.h>
00038 
00039 #include "ink_assert.h"
00040 #include "ink_error.h"
00041 #include "ParseRules.h"
00042 #include "ink_apidefs.h"
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 inkcoreapi char *ink_memcpy_until_char(char *dst, char *src, unsigned int n, unsigned char c);
00053 inkcoreapi char *ink_strncpy(char *dest, const char *src, int n);
00054 inkcoreapi char *ink_strncat(char *dest, const char *src, int n);
00055 inkcoreapi char *ink_string_concatenate_strings(char *dest, ...);
00056 inkcoreapi char *ink_string_concatenate_strings_n(char *dest, int n, ...);
00057 inkcoreapi char *ink_string_append(char *dest, char *src, int n);
00058 
00059 
00060 
00061 
00062 
00063 
00064 #if HAVE_STRLCPY
00065 #define  ink_strlcpy strlcpy
00066 #else
00067 size_t ink_strlcpy(char *dst, const char *str, size_t siz);
00068 #endif
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 #if HAVE_STRLCAT
00077 #define  ink_strlcat strlcat
00078 #else
00079 size_t ink_strlcat(char *dst, const char *str, size_t siz);
00080 #endif
00081 
00082 inkcoreapi int ink_strcasecmp(const char *a, const char *b);
00083 inkcoreapi int ink_strncasecmp(const char *a, const char *b, unsigned int max);
00084 
00085 
00086 void ink_utf8_to_latin1(const char *in, int inlen, char *out, int *outlen);
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 inline int
00100 ptr_len_cmp(const char *p1, int l1, const char *p2, int l2)
00101 {
00102   if (l1 == l2) {
00103     return memcmp(p1, p2, l1);
00104   } else if (l1 < l2) {
00105     return -1;
00106   } else {
00107     return 1;
00108   }
00109 }
00110 
00111 
00112 
00113 
00114 
00115 inline int
00116 ptr_len_casecmp(const char *p1, int l1, const char *p2, int l2)
00117 {
00118   if (l1 < l2) {
00119     return -1;
00120   } else if (l1 > l2) {
00121     return 1;
00122   }
00123 
00124   while (l1) {
00125     char p1c = ParseRules::ink_tolower(*p1);
00126     char p2c = ParseRules::ink_tolower(*p2);
00127 
00128     if (p1c != p2c) {
00129       if (p1c > p2c) {
00130         return 1;
00131       } else {
00132         return -1;
00133       }
00134     }
00135 
00136     p1++;
00137     p2++;
00138     l1--;
00139   }
00140 
00141   return 0;
00142 }
00143 
00144 
00145 
00146 
00147 
00148 inline const char *
00149 ptr_len_str(const char *p1, int l1, const char *str)
00150 {
00151 
00152   if (str && str[0]) {
00153     int str_index = 0;
00154     const char *match_start = NULL;
00155 
00156     while (l1 > 0) {
00157       if (*p1 == str[str_index]) {
00158 
00159         
00160         
00161         if (str_index == 0) {
00162           match_start = p1;
00163         }
00164         
00165         str_index++;
00166         if (str[str_index] == '\0') {
00167           return match_start;
00168         }
00169       } else if (str_index > 0) {
00170         l1 += (p1 - match_start);
00171         p1 = match_start;
00172         str_index = 0;
00173       }
00174 
00175       p1++;
00176       l1--;
00177     }
00178   }
00179   return NULL;
00180 }
00181 
00182 
00183 
00184 
00185 
00186 
00187 inline int
00188 ptr_len_ncmp(const char *p1, int l1, const char *str, int n)
00189 {
00190 
00191 
00192   while (l1 > 0 && n > 0) {
00193     if (*str == '\0') {
00194       return 1;
00195     }
00196 
00197     char p1c = *p1;
00198     char strc = *str;
00199 
00200     if (p1c != strc) {
00201       if (p1c > strc) {
00202         return 1;
00203       } else if (p1c < strc) {
00204         return -1;
00205       }
00206     }
00207 
00208     p1++;
00209     l1--;
00210     n--;
00211     str++;
00212   }
00213 
00214   
00215   
00216   
00217 
00218   if (n == 0) {
00219     return 0;
00220   } else {
00221     return -1;
00222   }
00223 }
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 inline int
00232 ptr_len_ncasecmp(const char *p1, int l1, const char *str, int n)
00233 {
00234 
00235 
00236   while (l1 > 0 && n > 0) {
00237     if (*str == '\0') {
00238       return 1;
00239     }
00240 
00241     char p1c = ParseRules::ink_tolower(*p1);
00242     char strc = ParseRules::ink_tolower(*str);
00243 
00244     if (p1c != strc) {
00245       if (p1c > strc) {
00246         return 1;
00247       } else if (p1c < strc) {
00248         return -1;
00249       }
00250     }
00251 
00252     p1++;
00253     l1--;
00254     n--;
00255     str++;
00256   }
00257 
00258   
00259   
00260   
00261 
00262   if (n == 0) {
00263     return 0;
00264   } else {
00265     return -1;
00266   }
00267 }
00268 
00269 
00270 
00271 
00272 
00273 
00274 inline int
00275 ptr_len_casecmp(const char *p1, int l1, const char *str)
00276 {
00277 
00278   while (l1 > 0) {
00279     if (*str == '\0') {
00280       return 1;
00281     }
00282 
00283     char p1c = ParseRules::ink_tolower(*p1);
00284     char strc = ParseRules::ink_tolower(*str);
00285 
00286     if (p1c != strc) {
00287       if (p1c > strc) {
00288         return 1;
00289       } else if (p1c < strc) {
00290         return -1;
00291       }
00292     }
00293 
00294     p1++;
00295     l1--;
00296     str++;
00297   }
00298 
00299   
00300   
00301   
00302   if (*str == '\0') {
00303     return 0;
00304   } else {
00305     return -1;
00306   }
00307 }
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 inline int
00316 ptr_len_cmp(const char *p1, int l1, const char *str)
00317 {
00318 
00319   while (l1 > 0) {
00320     if (*str == '\0') {
00321       return 1;
00322     }
00323 
00324     char p1c = *p1;
00325     char strc = *str;
00326 
00327     if (p1c != strc) {
00328       if (p1c > strc) {
00329         return 1;
00330       } else if (p1c < strc) {
00331         return -1;
00332       }
00333     }
00334 
00335     p1++;
00336     l1--;
00337     str++;
00338   }
00339 
00340   
00341   
00342   
00343   if (*str == '\0') {
00344     return 0;
00345   } else {
00346     return -1;
00347   }
00348 }
00349 
00350 
00351 
00352 
00353 
00354 inline char *
00355 ptr_len_pbrk(const char *p1, int l1, const char *str)
00356 {
00357   while (l1 > 0) {
00358     const char *str_cur = str;
00359 
00360     while (*str_cur != '\0') {
00361       if (*p1 == *str_cur) {
00362         return (char *) p1;
00363       }
00364       str_cur++;
00365     }
00366 
00367     p1++;
00368     l1--;
00369   }
00370 
00371   return NULL;
00372 }
00373 
00374 
00375 
00376 
00377 inline int
00378 ink_small_itoa(int val, char* buf, int buf_len)
00379 {
00380   ink_assert(buf_len > 5);
00381   ink_assert((val >= 0) && (val < 100000));
00382 
00383   if (val < 10) {               
00384     buf[0] = '0' + val;
00385     return 1;
00386   } else if (val < 100) {       
00387     buf[1] = '0' + (val % 10);
00388     val /= 10;
00389     buf[0] = '0' + (val % 10);
00390     return 2;
00391   } else if (val < 1000) {      
00392     buf[2] = '0' + (val % 10);
00393     val /= 10;
00394     buf[1] = '0' + (val % 10);
00395     val /= 10;
00396     buf[0] = '0' + (val % 10);
00397     return 3;
00398   } else if (val < 10000) {     
00399     buf[3] = '0' + (val % 10);
00400     val /= 10;
00401     buf[2] = '0' + (val % 10);
00402     val /= 10;
00403     buf[1] = '0' + (val % 10);
00404     val /= 10;
00405     buf[0] = '0' + (val % 10);
00406     return 4;
00407   } else {                      
00408     buf[4] = '0' + (val % 10);
00409     val /= 10;
00410     buf[3] = '0' + (val % 10);
00411     val /= 10;
00412     buf[2] = '0' + (val % 10);
00413     val /= 10;
00414     buf[1] = '0' + (val % 10);
00415     val /= 10;
00416     buf[0] = '0' + (val % 10);
00417     return 5;
00418   }
00419 }
00420 
00421 inline int
00422 ink_fast_itoa(int32_t val, char* buf, int buf_len)
00423 {
00424   if ((val < 0) || (val > 99999)) {
00425     int ret = snprintf(buf, buf_len, "%d", val);
00426 
00427     return (ret >= 0 ? ret : 0);
00428   }
00429 
00430   return ink_small_itoa((int)val, buf, buf_len);
00431 }
00432 
00433 inline int
00434 ink_fast_uitoa(uint32_t val, char* buf, int buf_len)
00435 {
00436   if (val > 99999) {
00437     int ret = snprintf(buf, buf_len, "%u", val);
00438 
00439     return (ret >= 0 ? ret : 0);
00440   }
00441 
00442   return ink_small_itoa((int)val, buf, buf_len);
00443 }
00444 
00445 inline int
00446 ink_fast_ltoa(int64_t val, char* buf, int buf_len)
00447 {
00448   if ((val < 0) || (val > 99999)) {
00449     int ret = snprintf(buf, buf_len, "%" PRId64 "", val);
00450 
00451     return (ret >= 0 ? ret : 0);
00452   }
00453 
00454   return ink_small_itoa((int)val, buf, buf_len);
00455 }
00456 
00457 #endif