1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov/*
350aadb33SDmitri Tikhonov * lsquic_str.c
450aadb33SDmitri Tikhonov *
550aadb33SDmitri Tikhonov */
650aadb33SDmitri Tikhonov
750aadb33SDmitri Tikhonov#include <stdlib.h>
850aadb33SDmitri Tikhonov#include <string.h>
950aadb33SDmitri Tikhonov
1050aadb33SDmitri Tikhonov#include "lsquic_str.h"
1150aadb33SDmitri Tikhonov
1250aadb33SDmitri Tikhonov
1350aadb33SDmitri Tikhonovlsquic_str_t *
1450aadb33SDmitri Tikhonovlsquic_str_new (const char *str, size_t sz)
1550aadb33SDmitri Tikhonov{
1650aadb33SDmitri Tikhonov    lsquic_str_t *lstr;
1750aadb33SDmitri Tikhonov    char *copy;
1850aadb33SDmitri Tikhonov
1950aadb33SDmitri Tikhonov    if (str && sz)
2050aadb33SDmitri Tikhonov    {
2150aadb33SDmitri Tikhonov        copy = malloc(sz + 1);
2250aadb33SDmitri Tikhonov        if (!copy)
2350aadb33SDmitri Tikhonov            return NULL;
2450aadb33SDmitri Tikhonov        memcpy(copy, str, sz);
2550aadb33SDmitri Tikhonov        copy[sz] = '\0';
2650aadb33SDmitri Tikhonov    }
2750aadb33SDmitri Tikhonov    else
2850aadb33SDmitri Tikhonov        copy = NULL;
2950aadb33SDmitri Tikhonov
3050aadb33SDmitri Tikhonov    lstr = malloc(sizeof(*lstr));
3150aadb33SDmitri Tikhonov    if (!lstr)
3250aadb33SDmitri Tikhonov    {
3350aadb33SDmitri Tikhonov        free(copy);
3450aadb33SDmitri Tikhonov        return NULL;
3550aadb33SDmitri Tikhonov    }
3650aadb33SDmitri Tikhonov    lstr->str = copy;
3750aadb33SDmitri Tikhonov    lstr->len = sz;
3850aadb33SDmitri Tikhonov
3950aadb33SDmitri Tikhonov    return lstr;
4050aadb33SDmitri Tikhonov}
4150aadb33SDmitri Tikhonov
4250aadb33SDmitri Tikhonov
4350aadb33SDmitri Tikhonovvoid
4450aadb33SDmitri Tikhonovlsquic_str_setto (lsquic_str_t *lstr, const void *str, size_t len)
4550aadb33SDmitri Tikhonov{
4650aadb33SDmitri Tikhonov    if (lsquic_str_len(lstr) > 0)
4750aadb33SDmitri Tikhonov        lsquic_str_d(lstr);
4850aadb33SDmitri Tikhonov    lsquic_str_append(lstr, str, len);
4950aadb33SDmitri Tikhonov}
5050aadb33SDmitri Tikhonov
5150aadb33SDmitri Tikhonov
522f4629f2SDmitri Tikhonovint
5350aadb33SDmitri Tikhonovlsquic_str_append (lsquic_str_t *lstr, const char *str, size_t len)
5450aadb33SDmitri Tikhonov{
5550aadb33SDmitri Tikhonov    size_t newlen;
5650aadb33SDmitri Tikhonov    char *newstr;
5750aadb33SDmitri Tikhonov
5850aadb33SDmitri Tikhonov    newlen = lstr->len + len;
5950aadb33SDmitri Tikhonov    newstr = realloc(lstr->str, newlen + 1);
6050aadb33SDmitri Tikhonov    if (!newstr)
612f4629f2SDmitri Tikhonov        return -1;
6250aadb33SDmitri Tikhonov
6350aadb33SDmitri Tikhonov    memcpy(newstr + lstr->len, str, len);
6450aadb33SDmitri Tikhonov    newstr[newlen] = '\0';
6550aadb33SDmitri Tikhonov    lstr->str = newstr;
6650aadb33SDmitri Tikhonov    lstr->len = newlen;
672f4629f2SDmitri Tikhonov    return 0;
6850aadb33SDmitri Tikhonov}
6950aadb33SDmitri Tikhonov
7050aadb33SDmitri Tikhonov
7150aadb33SDmitri Tikhonovvoid
7250aadb33SDmitri Tikhonovlsquic_str_d (lsquic_str_t *lstr)
7350aadb33SDmitri Tikhonov{
7450aadb33SDmitri Tikhonov    if (lstr) {
7550aadb33SDmitri Tikhonov        free(lstr->str);
7650aadb33SDmitri Tikhonov        lstr->str = NULL;
7750aadb33SDmitri Tikhonov        lstr->len = 0;
7850aadb33SDmitri Tikhonov    }
7950aadb33SDmitri Tikhonov}
8050aadb33SDmitri Tikhonov
8150aadb33SDmitri Tikhonov
8250aadb33SDmitri Tikhonovvoid
8350aadb33SDmitri Tikhonovlsquic_str_delete (lsquic_str_t *lstr)
8450aadb33SDmitri Tikhonov{
8550aadb33SDmitri Tikhonov    lsquic_str_d(lstr);
8650aadb33SDmitri Tikhonov    free(lstr);
8750aadb33SDmitri Tikhonov}
8850aadb33SDmitri Tikhonov
8950aadb33SDmitri Tikhonov
9050aadb33SDmitri Tikhonovchar *
9150aadb33SDmitri Tikhonovlsquic_str_prealloc (lsquic_str_t *lstr, size_t len)
9250aadb33SDmitri Tikhonov{
9350aadb33SDmitri Tikhonov    char *str;
9450aadb33SDmitri Tikhonov
9550aadb33SDmitri Tikhonov    str = malloc(len + 1);
9650aadb33SDmitri Tikhonov    if (str)
9750aadb33SDmitri Tikhonov        lstr->str = str;
9850aadb33SDmitri Tikhonov
9950aadb33SDmitri Tikhonov    return str;
10050aadb33SDmitri Tikhonov}
10150aadb33SDmitri Tikhonov
10250aadb33SDmitri Tikhonov
10350aadb33SDmitri Tikhonovint
10450aadb33SDmitri Tikhonovlsquic_str_bcmp (const void *ap, const void *bp)
10550aadb33SDmitri Tikhonov{
10650aadb33SDmitri Tikhonov    const lsquic_str_t *a = ap, *b = bp;
10750aadb33SDmitri Tikhonov    size_t min;
10850aadb33SDmitri Tikhonov    int rc;
10950aadb33SDmitri Tikhonov
11050aadb33SDmitri Tikhonov    min = a->len < b->len ? a->len : b->len;
11150aadb33SDmitri Tikhonov    rc = memcmp(a->str, b->str, min);
11250aadb33SDmitri Tikhonov    if (rc)
11350aadb33SDmitri Tikhonov        return rc;
11450aadb33SDmitri Tikhonov    else
11550aadb33SDmitri Tikhonov        return (a->len > b->len) - (b->len > a->len);
11650aadb33SDmitri Tikhonov}
11750aadb33SDmitri Tikhonov
11850aadb33SDmitri Tikhonov
11950aadb33SDmitri Tikhonovlsquic_str_t *
12050aadb33SDmitri Tikhonovlsquic_str_copy (lsquic_str_t *lstr_dst, const lsquic_str_t *lstr_src)
12150aadb33SDmitri Tikhonov{
12250aadb33SDmitri Tikhonov    char *copy;
12350aadb33SDmitri Tikhonov
12450aadb33SDmitri Tikhonov    copy = malloc(lstr_src->len + 1);
12550aadb33SDmitri Tikhonov    if (!copy)
1265392f7a3SLiteSpeed Tech    /* Keeping the original behavior: */
12750aadb33SDmitri Tikhonov        return NULL;
12850aadb33SDmitri Tikhonov
12950aadb33SDmitri Tikhonov    memcpy(copy, lstr_src->str, lstr_src->len);
13050aadb33SDmitri Tikhonov    copy[lstr_src->len] = '\0';
13150aadb33SDmitri Tikhonov    lstr_dst->str = copy;
13250aadb33SDmitri Tikhonov    lstr_dst->len = lstr_src->len;
13350aadb33SDmitri Tikhonov    return lstr_dst;
13450aadb33SDmitri Tikhonov}
135