#include <uwsgi.h>

// check if a string_list contains an item
struct uwsgi_string_list *uwsgi_string_list_has_item(struct uwsgi_string_list *list, char *key, size_t keylen) {
        struct uwsgi_string_list *usl = list;
        while (usl) {
                if (keylen == usl->len) {
                        if (!memcmp(key, usl->value, keylen)) {
                                return usl;
                        }
                }
                usl = usl->next;
        }
        return NULL;
}

// lower a string
char *uwsgi_lower(char *str, size_t size) {
        size_t i;
        for (i = 0; i < size; i++) {
                str[i] = tolower((int) str[i]);
        }

        return str;
}

// check if a string is contained in another one
char *uwsgi_str_contains(char *str, int slen, char what) {

        int i;
        for (i = 0; i < slen; i++) {
                if (str[i] == what) {
                        return str + i;
                }
        }
        return NULL;
}

int uwsgi_contains_n(char *s1, size_t s1_len, char *s2, size_t s2_len) {
        size_t i;
        char *ptr = s2;
        for (i = 0; i < s1_len; i++) {
                if (s1[i] == *ptr) {
                        ptr++;
                        if (ptr == s2 + s2_len) {
                                return 1;
                        }
                }
                else {
                        ptr = s2;
                }
        }
        return 0;
}

// fast compare 2 sized strings
int uwsgi_strncmp(char *src, int slen, char *dst, int dlen) {

        if (slen != dlen)
                return 1;

        return memcmp(src, dst, dlen);

}

// fast compare 2 sized strings (case insensitive)
int uwsgi_strnicmp(char *src, int slen, char *dst, int dlen) {

        if (slen != dlen)
                return 1;

        return strncasecmp(src, dst, dlen);

}

// fast sized check of initial part of a string
int uwsgi_starts_with(char *src, int slen, char *dst, int dlen) {

        if (slen < dlen)
                return -1;

        return memcmp(src, dst, dlen);
}


// unsized check
int uwsgi_startswith(char *src, char *what, int wlen) {

        int i;

        for (i = 0; i < wlen; i++) {
                if (src[i] != what[i])
                        return -1;
        }

        return 0;
}

// concatenate strings
char *uwsgi_concatn(int c, ...) {

        va_list s;
        char *item;
        int j = c;
        char *buf;
        size_t len = 1;
        size_t tlen = 1;

        va_start(s, c);
        while (j > 0) {
                item = va_arg(s, char *);
                if (item == NULL) {
                        break;
                }
                len += va_arg(s, int);
                j--;
        }
        va_end(s);


        buf = uwsgi_malloc(len);
        memset(buf, 0, len);

        j = c;

        len = 0;

        va_start(s, c);
        while (j > 0) {
                item = va_arg(s, char *);
                if (item == NULL) {
                        break;
                }
                tlen = va_arg(s, int);
                memcpy(buf + len, item, tlen);
                len += tlen;
                j--;
        }
        va_end(s);


        return buf;

}

char *uwsgi_concat2(char *one, char *two) {

        char *buf;
        size_t len = strlen(one) + strlen(two) + 1;


        buf = uwsgi_malloc(len);
        buf[len - 1] = 0;

        memcpy(buf, one, strlen(one));
        memcpy(buf + strlen(one), two, strlen(two));

        return buf;

}

char *uwsgi_concat4(char *one, char *two, char *three, char *four) {

        char *buf;
        size_t len = strlen(one) + strlen(two) + strlen(three) + strlen(four) + 1;


        buf = uwsgi_malloc(len);
        buf[len - 1] = 0;

        memcpy(buf, one, strlen(one));
        memcpy(buf + strlen(one), two, strlen(two));
        memcpy(buf + strlen(one) + strlen(two), three, strlen(three));
        memcpy(buf + strlen(one) + strlen(two) + strlen(three), four, strlen(four));

        return buf;

}


char *uwsgi_concat3(char *one, char *two, char *three) {

        char *buf;
        size_t len = strlen(one) + strlen(two) + strlen(three) + 1;


        buf = uwsgi_malloc(len);
        buf[len - 1] = 0;

        memcpy(buf, one, strlen(one));
        memcpy(buf + strlen(one), two, strlen(two));
        memcpy(buf + strlen(one) + strlen(two), three, strlen(three));

        return buf;

}

char *uwsgi_concat2n(char *one, int s1, char *two, int s2) {

        char *buf;
        size_t len = s1 + s2 + 1;


        buf = uwsgi_malloc(len);
        buf[len - 1] = 0;

        memcpy(buf, one, s1);
        memcpy(buf + s1, two, s2);

        return buf;

}

char *uwsgi_concat2nn(char *one, int s1, char *two, int s2, int *len) {

        char *buf;
        *len = s1 + s2 + 1;


        buf = uwsgi_malloc(*len);
        buf[*len - 1] = 0;

        memcpy(buf, one, s1);
        memcpy(buf + s1, two, s2);

        return buf;

}


char *uwsgi_concat3n(char *one, int s1, char *two, int s2, char *three, int s3) {

        char *buf;
        size_t len = s1 + s2 + s3 + 1;


        buf = uwsgi_malloc(len);
        buf[len - 1] = 0;

        memcpy(buf, one, s1);
        memcpy(buf + s1, two, s2);
        memcpy(buf + s1 + s2, three, s3);

        return buf;

}

char *uwsgi_concat4n(char *one, int s1, char *two, int s2, char *three, int s3, char *four, int s4) {

        char *buf;
        size_t len = s1 + s2 + s3 + s4 + 1;


        buf = uwsgi_malloc(len);
        buf[len - 1] = 0;

        memcpy(buf, one, s1);
        memcpy(buf + s1, two, s2);
        memcpy(buf + s1 + s2, three, s3);
        memcpy(buf + s1 + s2 + s3, four, s4);

        return buf;

}

// concat unsized strings
char *uwsgi_concat(int c, ...) {

        va_list s;
        char *item;
        size_t len = 1;
        int j = c;
        char *buf;

        va_start(s, c);
        while (j > 0) {
                item = va_arg(s, char *);
                if (item == NULL) {
                        break;
                }
                len += (int) strlen(item);
                j--;
        }
        va_end(s);


        buf = uwsgi_malloc(len);
        memset(buf, 0, len);

        j = c;

        len = 0;

        va_start(s, c);
        while (j > 0) {
                item = va_arg(s, char *);
                if (item == NULL) {
                        break;
                }
                memcpy(buf + len, item, strlen(item));
                len += strlen(item);
                j--;
        }
        va_end(s);


        return buf;

}

char *uwsgi_strncopy(char *s, int len) {

        char *buf;

        buf = uwsgi_malloc(len + 1);
        buf[len] = 0;

        memcpy(buf, s, len);

        return buf;

}

// this move a string back of one char and put a 0 at the end (used in uwsgi parsers for buffer reusing)
char *uwsgi_cheap_string(char *buf, int len) {

        int i;
        char *cheap_buf = buf - 1;


        for (i = 0; i < len; i++) {
                *cheap_buf++ = buf[i];
        }


        buf[len - 1] = 0;

        return buf - 1;
}

