blob: 8dcda584181cfcd7b1bb6ec73ad615b7309d3df6 [file] [log] [blame]
/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed 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 <axis2_string.h>
#include <stdlib.h>
#include <axis2_utils.h>
#include <axis2_utils_defines.h>
#include <stdarg.h> /* NULL */
/** this is used to cache lengths in axis2_strcat */
#define MAX_SAVED_LENGTHS 6
AXIS2_EXTERN void* AXIS2_CALL
axis2_strdup(const void *ptr, const axis2_env_t *env)
{
AXIS2_ENV_CHECK(env, NULL);
if (ptr)
{
int len = axis2_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);
return NULL;
}
memcpy(str, ptr, len + 1);
return (void *) str;
}
else
{
return NULL;
}
}
AXIS2_EXTERN void * AXIS2_CALL
axis2_strmemdup(const void *ptr,
size_t n,
const axis2_env_t *env)
{
axis2_char_t *str;
AXIS2_ENV_CHECK(env, NULL);
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);
return NULL;
}
memcpy(str, ptr, n);
str[n] = '\0';
return (void *) str;
}
AXIS2_EXTERN void * AXIS2_CALL
axis2_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
axis2_strndup(
const void *ptr,
int n,
const axis2_env_t *env)
{
const axis2_char_t *end;
axis2_char_t *str;
AXIS2_ENV_CHECK(env, NULL);
AXIS2_PARAM_CHECK(env->error, ptr, NULL);
end = axis2_memchr(ptr, '\0', n);
if (end)
n = end - (axis2_char_t *) ptr;
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);
return NULL;
}
memcpy(str, ptr, n);
str[n] = '\0';
return (void *) str;
}
AXIS2_EXTERN axis2_char_t * AXIS2_CALL
axis2_strcat(
const axis2_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);
while ((cp = va_arg(adummy, axis2_char_t *)))
{
size_t cplen = strlen(cp);
if (nargs < MAX_SAVED_LENGTHS)
{
saved_lengths[nargs++] = cplen;
}
len += cplen;
}
va_end(adummy);
/* Allocate the required string */
str_len = sizeof(axis2_char_t) * (len + 1);
str = (axis2_char_t *) AXIS2_MALLOC(env->allocator, str_len);
if (!str)
{
AXIS2_ERROR_SET(env->error, AXIS2_ERROR_NO_MEMORY, AXIS2_FAILURE);
return NULL;
}
cp = str;
/* Pass two --- copy the argument strings into the result space */
va_start(adummy, env);
nargs = 0;
while ((argp = va_arg(adummy, axis2_char_t *)))
{
if (nargs < MAX_SAVED_LENGTHS)
{
len = saved_lengths[nargs++];
}
else
{
len = strlen(argp);
}
memcpy(cp, argp, len);
cp += len;
}
va_end(adummy);
/* Return the result string */
*cp = '\0';
return str;
}
AXIS2_EXTERN axis2_char_t* AXIS2_CALL
axis2_stracat(const axis2_char_t *s1, const axis2_char_t *s2, const axis2_env_t *env)
{
axis2_char_t *ret = NULL;
int alloc_len = -1;
if (NULL == s1 && NULL == s2)
{
return NULL;
}
if (NULL == s1)
{
return (axis2_char_t*)AXIS2_STRDUP(s2, env);
}
if (NULL == s2)
{
return (axis2_char_t*)AXIS2_STRDUP(s1, env);
}
alloc_len = axis2_strlen(s1) + axis2_strlen(s2) + 1;
ret = (axis2_char_t*)AXIS2_MALLOC(env->allocator,
alloc_len * sizeof(axis2_char_t));
memcpy(ret, s1, axis2_strlen(s1)*sizeof(axis2_char_t));
memcpy((ret + axis2_strlen(s1)*sizeof(axis2_char_t)), s2,
axis2_strlen(s2)*sizeof(axis2_char_t));
ret[alloc_len*sizeof(axis2_char_t) - sizeof(axis2_char_t)] = '\0';
return ret;
}
AXIS2_EXTERN int AXIS2_CALL
axis2_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
axis2_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
axis2_strlen(const axis2_char_t * s)
{
if (s)
return strlen(s);
else
return -1;
}
AXIS2_EXTERN int AXIS2_CALL
axis2_strcasecmp(const axis2_char_t *s1, const axis2_char_t *s2)
{
while (toupper(*s1) == toupper(*s2++))
if (*s1++ == '\0')
return(0);
return(toupper(*s1) - toupper(*--s2));
}
AXIS2_EXTERN int AXIS2_CALL
axis2_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(*str1) == toupper(*str2++))
if (toupper(*str1++) == '\0')
return(0);
return(i < 0 ? 0 : toupper(*str1) - toupper(*--str2));
}
AXIS2_EXTERN axis2_char_t * AXIS2_CALL
axis2_strstr(const axis2_char_t *heystack,
const axis2_char_t *needle)
{
return strstr(heystack, needle);
}
AXIS2_EXTERN axis2_char_t * AXIS2_CALL
axis2_rindex(const axis2_char_t *_s, axis2_char_t _ch)
{
int i, ilen = axis2_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
axis2_replace(const axis2_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 = AXIS2_STRDUP(str, env);
index = strchr(newstr, s1);
while (index)
{
newstr[index - newstr] = s2;
index = strchr(newstr, s1);
}
return newstr;
}
AXIS2_EXTERN axis2_char_t* AXIS2_CALL
axis2_strltrim(
const axis2_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 *) AXIS2_STRDUP(_p, env);
break;
}
++_p;
}
return ret;
}
AXIS2_EXTERN axis2_char_t* AXIS2_CALL
axis2_strrtrim(
const axis2_env_t *env,
const axis2_char_t *_s,
const axis2_char_t *_trim)
{
axis2_char_t *__tail;
axis2_char_t *ret = NULL;
if (!_s)
return NULL;
__tail = ((axis2_char_t *) _s) + axis2_strlen(_s);
if (!_trim)
_trim = " \t\n\r";
while (_s < __tail--)
{
if (!strchr(_trim, *__tail))
{
ret = (axis2_char_t *) AXIS2_STRDUP(_s, env);
break;
}
*__tail = 0;
}
return ret;
}
AXIS2_EXTERN axis2_char_t* AXIS2_CALL
axis2_strtrim(
const axis2_env_t *env,
const axis2_char_t *_s,
const axis2_char_t *_trim)
{
axis2_char_t *_p = NULL;
axis2_char_t *_q = NULL;
_p = axis2_strltrim(env, _s, _trim);
_q = axis2_strrtrim(env, _p, _trim);
if (_p)
AXIS2_FREE(env->allocator, _p);
return _q;
}
AXIS2_EXTERN axis2_char_t* AXIS2_CALL
axis2_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
axis2_string_substring_starting_at(axis2_char_t* str, int s)
{
int len;
int pos_to_shift;
len = strlen(str);
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
axis2_string_substring_ending_at(axis2_char_t* str, int e)
{
axis2_char_t* ptr = NULL;
int length = 0;
length = strlen(str);
ptr = str;
if (length <= e)
{
return NULL;
}
ptr += e;
*ptr = '\0';
return str;
}
AXIS2_EXTERN axis2_char_t* AXIS2_CALL
axis2_string_tolower(axis2_char_t* str)
{
axis2_char_t* temp_str = NULL;
for (temp_str = str; *temp_str != '\0' ; temp_str ++)
{
*temp_str = tolower(*temp_str);
}
return str;
}
AXIS2_EXTERN axis2_char_t* AXIS2_CALL
axis2_string_toupper(axis2_char_t* str)
{
axis2_char_t* temp_str = NULL;
for (temp_str = str; *temp_str != '\0' ; temp_str ++)
{
*temp_str = toupper(*temp_str);
}
return str;
}
AXIS2_EXTERN axis2_char_t * AXIS2_CALL
axis2_strcasestr(const axis2_char_t *heystack, const axis2_char_t *needle)
{
axis2_char_t start, current;
size_t len;
if (!heystack || !needle)
return NULL;
if ((start = *needle++))
{
len = strlen(needle);
do
{
do
{
if (!(current = *heystack++))
return NULL;
} while (toupper(current) != toupper(start));
} while (axis2_strncasecmp(heystack, needle, len));
heystack--;
}
return (axis2_char_t *)heystack;
}