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