You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kamailio/lib/cds/sstr.c

325 lines
5.9 KiB

/*
* Copyright (C) 2005 iptelorg GmbH
*
* This file is part of ser, a free SIP server.
*
* ser is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* For a license to use the ser software under conditions
* other than those described here, or to purchase support for this
* software, please contact iptel.org by e-mail at the following addresses:
* info@iptel.org
*
* ser is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <cds/sstr.h>
#include <cds/memory.h>
#include <cds/dstring.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <cds/logger.h>
/** returns 1 if the string is empty */
int is_str_empty(const str_t *s)
{
if (!s) return 1;
if ((!s->s) || (s->len < 1)) return 1;
return 0;
}
int str_cmp_zt(const str_t *a, const char *b)
{
int i;
if (!a) {
if (b) return 1;
else return 0;
}
for (i = 0; (i < a->len) && (b[i]); i++) {
if (a->s[i] < b[i]) return -1;
if (a->s[i] > b[i]) return 1;
}
if (i < a->len) return 1;
return 0;
}
int str_prefix(const str_t *a, const str_t *b)
{
int i;
if (!b) return 0;
if (!a) return -1;
if (b->len > a->len) return -1;
for (i = 0; i < b->len; i++) {
if (a->s[i] != b->s[i]) return -1;
}
return 0;
}
str_t zt2str(char *str)
{
str_t s;
s.s = str;
if (str) s.len = strlen(str);
else s.len = 0;
return s;
}
int str_dup_dbg(str_t* dst, const str_t* src, const char *file, int line)
{
if (!dst) return -1;
dst->len = 0;
dst->s = NULL;
if (!src) return 0;
if ( (!src->s) || (src->len < 1)) return 0;
/* ERROR_LOG("can't allocate memory (%d bytes)\n", src->len); */
DEBUG_LOG("str_dup called from %s:%d\n", file, line);
dst->s = cds_malloc(src->len);
if (!dst->s) {
/* ERROR_LOG("can't allocate memory (%d bytes)\n", src->len); */
return -1;
}
memcpy(dst->s, src->s, src->len);
dst->len = src->len;
return 0;
}
int str_dup_impl(str_t* dst, const str_t* src)
{
if (!dst) return -1;
dst->len = 0;
dst->s = NULL;
if (!src) return 0;
if ( (!src->s) || (src->len < 1)) return 0;
dst->s = cds_malloc(src->len);
if (!dst->s) {
/* ERROR_LOG("can't allocate memory (%d bytes)\n", src->len); */
return -1;
}
memcpy(dst->s, src->s, src->len);
dst->len = src->len;
return 0;
}
str_t *str_dup_new(const str_t* src)
{
str_t *dst = cds_malloc(sizeof(str_t));
if (dst) str_dup(dst, src);
return dst;
}
int str_dup_zt(str_t* dst, const char* src)
{
int len;
if (!dst) return -1;
dst->len = 0;
dst->s = NULL;
if (!src) return 0;
len = strlen(src);
if (len < 1) return 0;
dst->s = cds_malloc(len);
if (!dst->s) return -1;
memcpy(dst->s, src, len);
dst->len = len;
return 0;
}
char *zt_strdup(const char* src)
{
int len;
char *dst;
len = strlen(src);
if (len < 0) return NULL;
dst = cds_malloc(len + 1);
if (dst) memcpy(dst, src, len + 1);
return dst;
}
int str_nocase_equals(const str_t *a, const str_t *b)
{
int i;
if (!a) {
if (!b) return 0;
else return (b->len == 0) ? 0 : 1;
}
if (!b) return (a->len == 0) ? 0 : 1;
if (a->len != b->len) return 1;
for (i = 0; i < a->len; i++)
if (tolower(a->s[i]) != tolower(b->s[i])) return 1;
return 0;
}
int str_case_equals(const str_t *a, const str_t *b)
{
int i;
if (!a) {
if (!b) return 0;
else return (b->len == 0) ? 0 : 1;
}
if (!b) return (a->len == 0) ? 0 : 1;
if (a->len != b->len) return 1;
for (i = 0; i < a->len; i++)
if (a->s[i] != b->s[i]) return 1;
return 0;
}
/* void str_free_content(str_t *s)
{
if (!s) return;
if ((s->len > 0) && (s->s)) cds_free(s->s);
s->len = 0;
s->s = NULL;
}
void str_free(str_t *s)
{
if (s) {
str_free_content(s);
cds_free(s);
}
}
void str_clear(str_t *s)
{
if (s) {
s->s = NULL;
s->len = 0;
}
} */
char *str_strchr(const str_t *s, char c)
{
if (s) {
int i;
for (i = 0; i < s->len; i++)
if (s->s[i] == c) return s->s + i;
}
return NULL;
}
char *str_str(const str_t *s, const str_t *search_for)
{
int i, j;
/* FIXME: reimplement using better algorithm */
if (is_str_empty(search_for)) return s->s;
if (is_str_empty(s)) return NULL;
if (search_for->len > s->len) return NULL;
j = 0;
i = 0;
while (i < s->len) {
if (s->s[i] == search_for->s[j]) {
j++;
i++;
if (j == search_for->len) return s->s + i - j;
}
else {
i = i - j + 1;
j = 0;
}
}
return NULL;
}
/* creates new string as concatenation of a and b */
int str_concat(str_t *dst, str_t *a, str_t *b)
{
int al;
int bl;
if (!dst) return -1;
al = str_len(a);
bl = str_len(b);
dst->len = al + bl;
if (dst->len > 0) {
dst->s = (char *)cds_malloc(dst->len);
if (!dst->s) {
dst->len = 0;
return -1;
}
}
else {
dst->s = NULL;
dst->len = 0;
return 0;
}
if (al) memcpy(dst->s, a->s, al);
if (bl) memcpy(dst->s + al, b->s, bl);
return 0;
}
int replace_str(const str_t *src, str_t *dst, const str_t *sample, const str_t *value)
{
str_t s;
char *c;
dstring_t str;
int res, len;
/* if (!dst) return -1;
if (!src) {
str_clear(dst);
return -1;
} */
if (is_str_empty(sample)) {
str_clear(dst);
return -1;
}
if (is_str_empty(src)) {
str_clear(dst);
return 0;
}
s = *src;
dstr_init(&str, src->len + 32);
do {
c = str_str(&s, sample);
if (c) {
len = c - s.s;
dstr_append(&str, s.s, len);
dstr_append_str(&str, value);
s.len = s.len - len - sample->len;
s.s = c + sample->len;
if (s.len <= 0) break;
}
else dstr_append_str(&str, &s);
} while (c);
res = dstr_get_str(&str, dst);
dstr_destroy(&str);
return res;
}