From 0425aadc78680e53000fd0108b540d6eca048516 Mon Sep 17 00:00:00 2001 From: gmcdonald Date: Sat, 13 Feb 2010 01:32:03 +0000 Subject: Moving axis svn, part of TLP move INFRA-2441 git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68 --- util/src/string.c | 822 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 822 insertions(+) create mode 100644 util/src/string.c (limited to 'util/src/string.c') diff --git a/util/src/string.c b/util/src/string.c new file mode 100644 index 0000000..4a3f8f0 --- /dev/null +++ b/util/src/string.c @@ -0,0 +1,822 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include /* NULL */ + +struct axutil_string +{ + axis2_char_t *buffer; + unsigned int length; + unsigned int ref_count; + axis2_bool_t owns_buffer; +}; + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axutil_string_create( + const axutil_env_t *env, + const axis2_char_t *str) +{ + axutil_string_t *string = NULL; + AXIS2_ENV_CHECK(env, NULL); + + /* str can't be null */ + if(!str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + return NULL; + } + + string = (axutil_string_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_string_t)); + if(!string) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + /* set properties */ + string->buffer = NULL; + string->ref_count = 1; + string->owns_buffer = AXIS2_TRUE; + + string->length = axutil_strlen(str); + + if(string->length < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + axutil_string_free(string, env); + return NULL; + } + + string->buffer = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) + * (string->length + 1)); + if(!(string->buffer)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + axutil_string_free(string, env); + return NULL; + } + memcpy(string->buffer, str, string->length + 1); + + return string; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axutil_string_create_assume_ownership( + const axutil_env_t *env, + axis2_char_t **str) +{ + axutil_string_t *string = NULL; + AXIS2_ENV_CHECK(env, NULL); + + /* str can't be null */ + if(!str || !(*str)) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + return NULL; + } + + string = (axutil_string_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_string_t)); + if(!string) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + /* set properties */ + string->buffer = *str; + string->length = axutil_strlen(*str); + string->ref_count = 1; + string->owns_buffer = AXIS2_TRUE; + + if(string->length < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + axutil_string_free(string, env); + return NULL; + } + + return string; +} + +AXIS2_EXTERN axutil_string_t *AXIS2_CALL +axutil_string_create_const( + const axutil_env_t *env, + axis2_char_t **str) +{ + axutil_string_t *string = NULL; + AXIS2_ENV_CHECK(env, NULL); + + /* str can't be null */ + if(!str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + + return NULL; + } + + string = (axutil_string_t *)AXIS2_MALLOC(env->allocator, sizeof(axutil_string_t)); + if(!string) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + /* set properties */ + string->buffer = *str; + string->length = axutil_strlen(*str); + string->ref_count = 1; + string->owns_buffer = AXIS2_FALSE; + + if(string->length < 0) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_INVALID_NULL_PARAM, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, + "NULL parameter was passed when a non NULL parameter was expected"); + axutil_string_free(string, env); + return NULL; + } + + return string; +} + +AXIS2_EXTERN void AXIS2_CALL +axutil_string_free( + struct axutil_string *string, + const axutil_env_t *env) +{ + if(!string) + { + return; + } + + string->ref_count--; + + if(string->ref_count > 0) + { + return; + } + + if(string->owns_buffer && string->buffer) + { + AXIS2_FREE(env->allocator, string->buffer); + } + + AXIS2_FREE(env->allocator, string); + return; +} + +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axutil_string_equals( + const struct axutil_string *string, + const axutil_env_t * env, + const struct axutil_string *string1) +{ + if(!string || !string1) + { + return AXIS2_FALSE; + } + + return (string->buffer == string1->buffer); +} + +AXIS2_EXTERN struct axutil_string *AXIS2_CALL +axutil_string_clone( + struct axutil_string *string, + const axutil_env_t *env) +{ + if(!string) + { + return NULL; + } + + string->ref_count++; + + return string; +} + +AXIS2_EXTERN const axis2_char_t *AXIS2_CALL +axutil_string_get_buffer( + const struct axutil_string *string, + const axutil_env_t *env) +{ + if(!string) + { + return NULL; + } + + return string->buffer; +} + +AXIS2_EXTERN unsigned int AXIS2_CALL +axutil_string_get_length( + const struct axutil_string *string, + const axutil_env_t *env) +{ + int error_return = -1; + if(!string) + { + return error_return; + } + + return string->length; +} + +/* END of string struct implementation */ + +/** this is used to cache lengths in axutil_strcat */ +#define MAX_SAVED_LENGTHS 6 + +AXIS2_EXTERN void *AXIS2_CALL +axutil_strdup( + const axutil_env_t *env, + const void *ptr) +{ + if(ptr) + { + int len = axutil_strlen(ptr); + axis2_char_t *str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) + * (len + 1)); + if(!str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + memcpy(str, ptr, len + 1); + return (void *)str; + } + else + { + return NULL; + } +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_strmemdup( + const void *ptr, + size_t n, + const axutil_env_t *env) +{ + axis2_char_t *str; + + AXIS2_PARAM_CHECK(env->error, ptr, NULL); + + str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (n + 1)); + if(!str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + memcpy(str, ptr, n); + str[n] = '\0'; + + return (void *)str; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_memchr( + const void *ptr, + int c, + size_t n) +{ + const axis2_char_t *cp; + + for(cp = ptr; n > 0; n--, cp++) + { + if(*cp == c) + return (char *)cp; /* Casting away the const here */ + } + + return NULL; +} + +AXIS2_EXTERN void *AXIS2_CALL +axutil_strndup( + const axutil_env_t *env, + const void *ptr, + int n) +{ + const axis2_char_t *end; + axis2_char_t *str; + + AXIS2_PARAM_CHECK(env->error, ptr, NULL); + + end = axutil_memchr(ptr, '\0', n); + if(end) + n = (int)(end - (axis2_char_t *)ptr); + /* We are sure that the difference lies within the int range */ + str = (axis2_char_t *)AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * (n + 1)); + if(!str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + memcpy(str, ptr, n); + str[n] = '\0'; + + return (void *)str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strcat( + const axutil_env_t *env, + ...) +{ + axis2_char_t *cp, *argp, *str; + size_t saved_lengths[MAX_SAVED_LENGTHS]; + int nargs = 0; + int str_len = 0; + + /* Pass one --- find length of required string */ + + size_t len = 0; + va_list adummy; + + va_start(adummy, env); + + cp = va_arg(adummy, axis2_char_t *); + while(cp) + { + size_t cplen = strlen(cp); + if(nargs < MAX_SAVED_LENGTHS) + { + saved_lengths[nargs++] = cplen; + } + len += cplen; + cp = va_arg(adummy, axis2_char_t *); + } + + va_end(adummy); + + /* Allocate the required string */ + str_len = (int)(sizeof(axis2_char_t) * (len + 1)); + /* We are sure that the difference lies within the int range */ + str = (axis2_char_t *) AXIS2_MALLOC(env->allocator, str_len); + if (!str) + { + AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE); + AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Out of memory"); + return NULL; + } + cp = str; + + /* Pass two --- copy the argument strings into the result space */ + + va_start(adummy, env); + + nargs = 0; + argp = va_arg(adummy, axis2_char_t *); + while (argp) + { + if (nargs < MAX_SAVED_LENGTHS) + { + len = saved_lengths[nargs++]; + } + else + { + len = strlen(argp); + } + + memcpy(cp, argp, len); + cp += len; + argp = va_arg(adummy, axis2_char_t *); + } + + va_end(adummy); + + /* Return the result string */ + + *cp = '\0'; + return str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_stracat( + const axutil_env_t *env, + const axis2_char_t *s1, + const axis2_char_t *s2) +{ + axis2_char_t *ret = NULL; + int alloc_len = -1; + int len1 = 0; + int len2 = 0; + + if(!s1 && !s2) + { + return NULL; + } + if(!s1) + { + return (axis2_char_t *)axutil_strdup(env, s2); + } + if(!s2) + { + return (axis2_char_t *)axutil_strdup(env, s1); + } + + len1 = axutil_strlen(s1); + len2 = axutil_strlen(s2); + alloc_len = len1 + len2 + 1; + ret = (axis2_char_t *)AXIS2_MALLOC(env->allocator, alloc_len * sizeof(axis2_char_t)); + memcpy(ret, s1, len1 * sizeof(axis2_char_t)); + memcpy((ret + len1 * sizeof(axis2_char_t)), s2, len2 * sizeof(axis2_char_t)); + ret[alloc_len * sizeof(axis2_char_t) - sizeof(axis2_char_t)] = '\0'; + return ret; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_strcmp( + const axis2_char_t *s1, + const axis2_char_t *s2) +{ + if(s1 && s2) + { + return strcmp(s1, s2); + } + else + { + return -1; + } +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_strncmp( + const axis2_char_t *s1, + const axis2_char_t *s2, + int n) +{ + if(s1 && s2) + { + return strncmp(s1, s2, n); + } + else + { + return -1; + } +} + +AXIS2_EXTERN axis2_ssize_t AXIS2_CALL +axutil_strlen( + const axis2_char_t *s) +{ + int error_return = -1; + if(s) + { + return (axis2_ssize_t)strlen(s); + /* We are sure that the difference lies within the axis2_ssize_t range */ + } + return error_return; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_strcasecmp( + const axis2_char_t *s1, + const axis2_char_t *s2) +{ + while(*s1 != '\0' && *s2 != '\0') + { + if(*s1 >= 'A' && *s1 <= 'Z' && *s2 >= 'a' && *s2 <= 'z') + { + if(*s2 - *s1 - (char)32 != 0) + { + return 1; + } + } + else if(*s1 >= 'a' && *s1 <= 'z' && *s2 >= 'A' && *s2 <= 'Z') + { + if(*s1 - *s2 - 32 != 0) + { + return 1; + } + } + else if(*s1 - *s2 != 0) + { + return 1; + } + s1++; + s2++; + } + if(*s1 != *s2) + { + return 1; + } + + return 0; +} + +AXIS2_EXTERN int AXIS2_CALL +axutil_strncasecmp( + const axis2_char_t *s1, + const axis2_char_t *s2, + const int n) +{ + axis2_char_t *str1 = (axis2_char_t *)s1, *str2 = (axis2_char_t *)s2; + int i = (int)n; + + while(--i >= 0 && toupper((int)*str1) == toupper((int)*str2++)) + { + if(toupper((int)*str1++) == '\0') + { + return (0); + } + } + return (i < 0 ? 0 : toupper((int)*str1) - toupper((int)*--str2)); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strstr( + const axis2_char_t *haystack, + const axis2_char_t *needle) +{ + return strstr(haystack, needle); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strchr( + const axis2_char_t *s, + axis2_char_t ch) +{ + return (axis2_char_t *)strchr(s, ch); +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_rindex( + const axis2_char_t *_s, + axis2_char_t _ch) +{ + int i, ilen = axutil_strlen(_s); + if(ilen < 1) + { + return NULL; + } + for(i = ilen - 1; i >= 0; i--) + { + if(_s[i] == _ch) + { + return (axis2_char_t *)(_s + i); + } + } + return NULL; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_replace( + const axutil_env_t *env, + axis2_char_t *str, + int s1, + int s2) +{ + axis2_char_t *newstr = NULL; + axis2_char_t *index = NULL; + if(!str) + { + return NULL; + } + + newstr = axutil_strdup(env, str); + index = strchr(newstr, s1); + while(index) + { + newstr[index - newstr] = (axis2_char_t)s2; + /* We are sure that the conversion is safe */ + index = strchr(newstr, s1); + } + return newstr; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strltrim( + const axutil_env_t *env, + const axis2_char_t *_s, + const axis2_char_t *_trim) +{ + axis2_char_t *_p = NULL; + axis2_char_t *ret = NULL; + + if(!_s) + { + return NULL; + } + _p = (axis2_char_t *)_s; + if(!_trim) + { + _trim = " \t\r\n"; + } + + while(*_p) + { + if(!strchr(_trim, *_p)) + { + ret = (axis2_char_t *)axutil_strdup(env, _p); + break; + } + ++_p; + } + return ret; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strrtrim( + const axutil_env_t *env, + const axis2_char_t *_in, + const axis2_char_t *_trim) +{ + axis2_char_t *__tail; + axis2_char_t *_s = NULL; + axis2_char_t *ret = NULL; + + if(_in) + { + _s = axutil_strdup(env, _in); + } + if(!_s) + { + return NULL; + } + __tail = _s + axutil_strlen(_s); + if(!_trim) + { + _trim = " \t\n\r"; + } + while(_s < __tail--) + { + if(!strchr(_trim, *__tail)) + { + ret = _s; + break; + } + *__tail = 0; + } + if(!ret && _s) + { + AXIS2_FREE(env->allocator, _s); + } + return ret; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strtrim( + const axutil_env_t *env, + const axis2_char_t *_s, + const axis2_char_t *_trim) +{ + axis2_char_t *_p = NULL; + axis2_char_t *_q = NULL; + + _p = axutil_strltrim(env, _s, _trim); + _q = axutil_strrtrim(env, _p, _trim); + if(_p) + { + AXIS2_FREE(env->allocator, _p); + } + return _q; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_string_replace( + axis2_char_t *str, + axis2_char_t old, + axis2_char_t new) +{ + axis2_char_t *str_returns = str; + for(; *str != '\0'; str++) + { + if(*str == old) + { + *str = new; + } + } + return str_returns; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_string_substring_starting_at( + axis2_char_t *str, + int s) +{ + int len; + int pos_to_shift; + + len = (int)strlen(str); + /* We are sure that the difference lies within the int range */ + pos_to_shift = len - s + 1; + + if(len <= s) + { + return NULL; + } + memmove(str, str + s, pos_to_shift); + return str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_string_substring_ending_at( + axis2_char_t *str, + int e) +{ + axis2_char_t *ptr = NULL; + int length = 0; + + length = (int)strlen(str); + /* We are sure that the difference lies within the int range */ + ptr = str; + if(length <= e) + { + return NULL; + } + ptr += e; + *ptr = '\0'; + return str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_string_tolower( + axis2_char_t *str) +{ + axis2_char_t *temp_str = NULL; + for(temp_str = str; *temp_str != '\0'; temp_str++) + { + *temp_str = (axis2_char_t)tolower((int)*temp_str); + /* We are sure that the conversion is safe */ + } + return str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_string_toupper( + axis2_char_t *str) +{ + axis2_char_t *temp_str = NULL; + for(temp_str = str; *temp_str != '\0'; temp_str++) + { + *temp_str = (axis2_char_t)toupper((int)*temp_str); + /* We are sure that the conversion is safe */ + } + return str; +} + +AXIS2_EXTERN axis2_char_t *AXIS2_CALL +axutil_strcasestr( + const axis2_char_t *haystack, + const axis2_char_t *needle) +{ + axis2_char_t start, current; + size_t len; + + if(!haystack || !needle) + { + return NULL; + } + + if((start = *needle++)) + { + len = strlen(needle); + do + { + do + { + if(!(current = *haystack++)) + { + return NULL; + } + } + while(toupper((int)current) != toupper((int)start)); + } + while(axutil_strncasecmp(haystack, needle, (int)len)); + /* We are sure that the difference lies within the int range */ + haystack--; + } + return (axis2_char_t *)haystack; +} -- cgit v1.1-32-gdbae