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
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "apr.h"
00050 #include "apr_strings.h"
00051 #include "apr_general.h"
00052 #include "apr_private.h"
00053 #include "apr_lib.h"
00054 #define APR_WANT_STDIO
00055 #define APR_WANT_STRFUNC
00056 #include "apr_want.h"
00057
00058 #ifdef HAVE_STDDEF_H
00059 #include <stddef.h>
00060 #endif
00061
00062 #ifdef HAVE_STDLIB_H
00063 #include <stdlib.h>
00064 #endif
00065
00066
00067 #define MAX_SAVED_LENGTHS 6
00068
00069 APR_DECLARE(char *) apr_pstrdup(apr_pool_t *a, const char *s)
00070 {
00071 char *res;
00072 apr_size_t len;
00073
00074 if (s == NULL) {
00075 return NULL;
00076 }
00077 len = strlen(s) + 1;
00078 res = apr_palloc(a, len);
00079 memcpy(res, s, len);
00080 return res;
00081 }
00082
00083 APR_DECLARE(char *) apr_pstrndup(apr_pool_t *a, const char *s, apr_size_t n)
00084 {
00085 char *res;
00086 const char *end;
00087
00088 if (s == NULL) {
00089 return NULL;
00090 }
00091 end = memchr(s, '\0', n);
00092 if (end != NULL)
00093 n = end - s;
00094 res = apr_palloc(a, n + 1);
00095 memcpy(res, s, n);
00096 res[n] = '\0';
00097 return res;
00098 }
00099
00100 APR_DECLARE(char *) apr_pstrmemdup(apr_pool_t *a, const char *s, apr_size_t n)
00101 {
00102 char *res;
00103
00104 if (s == NULL) {
00105 return NULL;
00106 }
00107 res = apr_palloc(a, n + 1);
00108 memcpy(res, s, n);
00109 res[n] = '\0';
00110 return res;
00111 }
00112
00113 APR_DECLARE(void *) apr_pmemdup(apr_pool_t *a, const void *m, apr_size_t n)
00114 {
00115 void *res;
00116
00117 if (m == NULL)
00118 return NULL;
00119 res = apr_palloc(a, n);
00120 memcpy(res, m, n);
00121 return res;
00122 }
00123
00124 APR_DECLARE_NONSTD(char *) apr_pstrcat(apr_pool_t *a, ...)
00125 {
00126 char *cp, *argp, *res;
00127 apr_size_t saved_lengths[MAX_SAVED_LENGTHS];
00128 int nargs = 0;
00129
00130
00131
00132 apr_size_t len = 0;
00133 va_list adummy;
00134
00135 va_start(adummy, a);
00136
00137 while ((cp = va_arg(adummy, char *)) != NULL) {
00138 apr_size_t cplen = strlen(cp);
00139 if (nargs < MAX_SAVED_LENGTHS) {
00140 saved_lengths[nargs++] = cplen;
00141 }
00142 len += cplen;
00143 }
00144
00145 va_end(adummy);
00146
00147
00148
00149 res = (char *) apr_palloc(a, len + 1);
00150 cp = res;
00151
00152
00153
00154 va_start(adummy, a);
00155
00156 nargs = 0;
00157 while ((argp = va_arg(adummy, char *)) != NULL) {
00158 if (nargs < MAX_SAVED_LENGTHS) {
00159 len = saved_lengths[nargs++];
00160 }
00161 else {
00162 len = strlen(argp);
00163 }
00164
00165 memcpy(cp, argp, len);
00166 cp += len;
00167 }
00168
00169 va_end(adummy);
00170
00171
00172
00173 *cp = '\0';
00174
00175 return res;
00176 }
00177
00178 APR_DECLARE(char *) apr_pstrcatv(apr_pool_t *a, const struct iovec *vec,
00179 apr_size_t nvec, apr_size_t *nbytes)
00180 {
00181 apr_size_t i;
00182 apr_size_t len;
00183 const struct iovec *src;
00184 char *res;
00185 char *dst;
00186
00187
00188 len = 0;
00189 src = vec;
00190 for (i = nvec; i; i--) {
00191 len += src->iov_len;
00192 src++;
00193 }
00194 if (nbytes) {
00195 *nbytes = len;
00196 }
00197
00198
00199 res = (char *) apr_palloc(a, len + 1);
00200
00201
00202 src = vec;
00203 dst = res;
00204 for (i = nvec; i; i--) {
00205 memcpy(dst, src->iov_base, src->iov_len);
00206 dst += src->iov_len;
00207 src++;
00208 }
00209
00210
00211 *dst = '\0';
00212
00213 return res;
00214 }
00215
00216 #if (!APR_HAVE_MEMCHR)
00217 void *memchr(const void *s, int c, size_t n)
00218 {
00219 const char *cp;
00220
00221 for (cp = s; n > 0; n--, cp++) {
00222 if (*cp == c)
00223 return (char *) cp;
00224 }
00225
00226 return NULL;
00227 }
00228 #endif
00229
00230 #ifndef INT64_MAX
00231 #define INT64_MAX APR_INT64_C(0x7fffffffffffffff)
00232 #endif
00233 #ifndef INT64_MIN
00234 #define INT64_MIN (-APR_INT64_C(0x7fffffffffffffff) - APR_INT64_C(1))
00235 #endif
00236
00237 APR_DECLARE(apr_int64_t) apr_strtoi64(const char *nptr, char **endptr, int base)
00238 {
00239 #if (APR_HAVE_INT64_STRFN)
00240 return APR_INT64_STRFN(nptr, endptr, base);
00241 #else
00242 const char *s;
00243 apr_int64_t acc;
00244 apr_int64_t val;
00245 int neg, any;
00246 char c;
00247
00248
00249
00250
00251
00252
00253 s = nptr;
00254 do {
00255 c = *s++;
00256 } while (apr_isspace(c));
00257 if (c == '-') {
00258 neg = 1;
00259 c = *s++;
00260 } else {
00261 neg = 0;
00262 if (c == '+')
00263 c = *s++;
00264 }
00265 if ((base == 0 || base == 16) &&
00266 c == '0' && (*s == 'x' || *s == 'X')) {
00267 c = s[1];
00268 s += 2;
00269 base = 16;
00270 }
00271 if (base == 0)
00272 base = c == '0' ? 8 : 10;
00273 acc = any = 0;
00274 if (base < 2 || base > 36) {
00275 errno = EINVAL;
00276 if (endptr != NULL)
00277 *endptr = (char *)(any ? s - 1 : nptr);
00278 return acc;
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 val = 0;
00292 for ( ; ; c = *s++) {
00293 if (c >= '0' && c <= '9')
00294 c -= '0';
00295 #if (('Z' - 'A') == 25)
00296 else if (c >= 'A' && c <= 'Z')
00297 c -= 'A' - 10;
00298 else if (c >= 'a' && c <= 'z')
00299 c -= 'a' - 10;
00300 #elif APR_CHARSET_EBCDIC
00301 else if (c >= 'A' && c <= 'I')
00302 c -= 'A' - 10;
00303 else if (c >= 'J' && c <= 'R')
00304 c -= 'J' - 19;
00305 else if (c >= 'S' && c <= 'Z')
00306 c -= 'S' - 28;
00307 else if (c >= 'a' && c <= 'i')
00308 c -= 'a' - 10;
00309 else if (c >= 'j' && c <= 'r')
00310 c -= 'j' - 19;
00311 else if (c >= 's' && c <= 'z')
00312 c -= 'z' - 28;
00313 #else
00314 #error "CANNOT COMPILE apr_strtoi64(), only ASCII and EBCDIC supported"
00315 #endif
00316 else
00317 break;
00318 if (c >= base)
00319 break;
00320 val *= base;
00321 if ( (any < 0)
00322 || (neg && (val > acc || (val -= c) > acc))
00323 || (!neg && (val < acc || (val += c) < acc))) {
00324 any = -1;
00325 #ifdef APR_STRTOI64_OVERFLOW_IS_BAD_CHAR
00326 break;
00327 #endif
00328 } else {
00329 acc = val;
00330 any = 1;
00331 }
00332 }
00333
00334 if (any < 0) {
00335 acc = neg ? INT64_MIN : INT64_MAX;
00336 errno = ERANGE;
00337 } else if (!any) {
00338 errno = EINVAL;
00339 }
00340 if (endptr != NULL)
00341 *endptr = (char *)(any ? s - 1 : nptr);
00342 return (acc);
00343 #endif
00344 }
00345
00346 APR_DECLARE(apr_int64_t) apr_atoi64(const char *buf)
00347 {
00348 return apr_strtoi64(buf, NULL, 10);
00349 }
00350
00351 APR_DECLARE(char *) apr_itoa(apr_pool_t *p, int n)
00352 {
00353 const int BUFFER_SIZE = sizeof(int) * 3 + 2;
00354 char *buf = apr_palloc(p, BUFFER_SIZE);
00355 char *start = buf + BUFFER_SIZE - 1;
00356 int negative;
00357 if (n < 0) {
00358 negative = 1;
00359 n = -n;
00360 }
00361 else {
00362 negative = 0;
00363 }
00364 *start = 0;
00365 do {
00366 *--start = '0' + (n % 10);
00367 n /= 10;
00368 } while (n);
00369 if (negative) {
00370 *--start = '-';
00371 }
00372 return start;
00373 }
00374
00375 APR_DECLARE(char *) apr_ltoa(apr_pool_t *p, long n)
00376 {
00377 const int BUFFER_SIZE = sizeof(long) * 3 + 2;
00378 char *buf = apr_palloc(p, BUFFER_SIZE);
00379 char *start = buf + BUFFER_SIZE - 1;
00380 int negative;
00381 if (n < 0) {
00382 negative = 1;
00383 n = -n;
00384 }
00385 else {
00386 negative = 0;
00387 }
00388 *start = 0;
00389 do {
00390 *--start = (char)('0' + (n % 10));
00391 n /= 10;
00392 } while (n);
00393 if (negative) {
00394 *--start = '-';
00395 }
00396 return start;
00397 }
00398
00399 APR_DECLARE(char *) apr_off_t_toa(apr_pool_t *p, apr_off_t n)
00400 {
00401 const int BUFFER_SIZE = sizeof(apr_off_t) * 3 + 2;
00402 char *buf = apr_palloc(p, BUFFER_SIZE);
00403 char *start = buf + BUFFER_SIZE - 1;
00404 int negative;
00405 if (n < 0) {
00406 negative = 1;
00407 n = -n;
00408 }
00409 else {
00410 negative = 0;
00411 }
00412 *start = 0;
00413 do {
00414 *--start = '0' + (char)(n % 10);
00415 n /= 10;
00416 } while (n);
00417 if (negative) {
00418 *--start = '-';
00419 }
00420 return start;
00421 }
00422
00423 APR_DECLARE(char *) apr_strfsize(apr_off_t size, char *buf)
00424 {
00425 const char ord[] = "KMGTPE";
00426 const char *o = ord;
00427 int remain;
00428
00429 if (size < 0) {
00430 return strcpy(buf, " - ");
00431 }
00432 if (size < 973) {
00433 if (apr_snprintf(buf, 5, "%3d ", (int) size) < 0)
00434 return strcpy(buf, "****");
00435 return buf;
00436 }
00437 do {
00438 remain = (int)(size & 1023);
00439 size >>= 10;
00440 if (size >= 973) {
00441 ++o;
00442 continue;
00443 }
00444 if (size < 9 || (size == 9 && remain < 973)) {
00445 if ((remain = ((remain * 5) + 256) / 512) >= 10)
00446 ++size, remain = 0;
00447 if (apr_snprintf(buf, 5, "%d.%d%c", (int) size, remain, *o) < 0)
00448 return strcpy(buf, "****");
00449 return buf;
00450 }
00451 if (remain >= 512)
00452 ++size;
00453 if (apr_snprintf(buf, 5, "%3d%c", (int) size, *o) < 0)
00454 return strcpy(buf, "****");
00455 return buf;
00456 } while (1);
00457 }
00458