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.
mediaproxy-ng/daemon/str.h

208 lines
5.4 KiB

#ifndef _STR_H_
#define _STR_H_
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <stdio.h>
struct _str {
char *s;
int len;
};
typedef struct _str str;
#define STR_FORMAT "%.*s"
#define STR_FMT(str) (str)->len, (str)->s
#define STR_FMT0(str) ((str) ? (str)->len : 6), ((str) ? (str)->s : "(NULL)")
#define STR_NULL ((str) { NULL, 0 })
#define STR_EMPTY ((str) { "", 0 })
/* returns pointer to end of str (s->s + s->len) */
static inline char *str_end(const str *s);
/* returns pointer to first occurence of "c" in s */
static inline char *str_chr(const str *s, int c);
/* sets "out" to point to first occurence of c in s. adjusts len also */
static inline str *str_chr_str(str *out, const str *s, int c);
/* compares a str to a regular string */
static inline int str_cmp(const str *a, const char *b);
/* compares a str to a non-null-terminated string */
static inline int str_cmp_len(const str *a, const char *b, int len);
/* compares two str objects */
static inline int str_cmp_str(const str *a, const str *b);
/* compares two str objects, allows either to be NULL */
static inline int str_cmp_str0(const str *a, const str *b);
/* inits a str object from a regular string. returns out */
static inline str *str_init(str *out, char *s);
/* inits a str object from any binary string. returns out */
static inline str *str_init_len(str *out, char *s, int len);
/* returns new str object allocated with malloc, including buffer */
static inline str *str_dup(const str *s);
/* returns new str object allocated from chunk, including buffer */
static inline str *str_chunk_insert(GStringChunk *c, const str *s);
/* shifts pointer by len chars and decrements len. returns -1 if buffer too short, 0 otherwise */
static inline int str_shift(str *s, int len);
/* binary compares str object with memory chunk of equal size */
static inline int str_memcmp(const str *s, void *m);
/* asprintf() analogs */
#define str_sprintf(fmt, a...) __str_sprintf(STR_MALLOC_PADDING fmt, a)
#define str_vsprintf(fmt, a) __str_vsprintf(STR_MALLOC_PADDING fmt, a)
/* creates a new empty GString that has mem allocated for a new str object */
static inline GString *g_string_new_str(void);
/* frees the GString object and returns the new str object */
static inline str *g_string_free_str(GString *gs);
/* for GHashTables */
guint str_hash(gconstpointer s);
gboolean str_equal(gconstpointer a, gconstpointer b);
static inline str *str_chunk_insert(GStringChunk *c, const str *s) {
str *i;
i = (void *) g_string_chunk_insert_len(c, (void *) s, sizeof(*s));
i->s = g_string_chunk_insert_len(c, s->s, s->len);
return i;
}
static inline char *str_end(const str *s) {
return s->s + s->len;
}
static inline int str_shift(str *s, int len) {
if (s->len < len)
return -1;
s->s += len;
s->len -= len;
return 0;
}
static inline char *str_chr(const str *s, int c) {
return memchr(s->s, c, s->len);
}
static inline str *str_chr_str(str *out, const str *s, int c) {
out->s = str_chr(s, c);
out->len = out->s ? (s->len - (out->s - s->s)) : 0;
return out;
}
static inline int str_cmp_len(const str *a, const char *b, int l) {
if (a->len < l)
return -1;
if (a->len > l)
return 1;
if (a->len == 0 && l == 0)
return 0;
return memcmp(a->s, b, l);
}
static inline int str_cmp(const str *a, const char *b) {
return str_cmp_len(a, b, strlen(b));
}
static inline int str_cmp_str(const str *a, const str *b) {
if (a->len < b->len)
return -1;
if (a->len > b->len)
return 1;
if (a->len == 0 && b->len == 0)
return 0;
return memcmp(a->s, b->s, a->len);
}
static inline int str_cmp_str0(const str *a, const str *b) {
if (!a) {
if (!b)
return 0;
if (b->len == 0)
return 0;
return -1;
}
if (!b) {
if (a->len == 0)
return 0;
return 1;
}
return str_cmp_str(a, b);
}
static inline str *str_init(str *out, char *s) {
out->s = s;
out->len = s ? strlen(s) : 0;
return out;
}
static inline str *str_init_len(str *out, char *s, int len) {
out->s = s;
out->len = len;
return out;
}
static inline str *str_dup(const str *s) {
str *r;
r = malloc(sizeof(*r) + s->len + 1);
r->s = ((char *) r) + sizeof(*r);
r->len = s->len;
memcpy(r->s, s->s, s->len);
r->s[s->len] = '\0';
return r;
}
#define STR_MALLOC_PADDING "xxxxxxxxxxxxxxxx"
static inline str *__str_vsprintf(const char *fmt, va_list ap) {
char *r;
int l, pl;
str *ret;
l = vasprintf(&r, fmt, ap);
if (l < 0)
abort();
pl = strlen(STR_MALLOC_PADDING);
assert(pl >= sizeof(*ret));
ret = (void *) r;
ret->s = r + pl;
ret->len = l - pl;
return ret;
}
static inline str *__str_sprintf(const char *fmt, ...) __attribute__((format(printf,1,2)));
static inline str *__str_sprintf(const char *fmt, ...) {
str *ret;
va_list ap;
va_start(ap, fmt);
ret = __str_vsprintf(fmt, ap);
va_end(ap);
return ret;
}
static inline GString *g_string_new_str(void) {
int pl;
GString *ret;
ret = g_string_new("");
pl = strlen(STR_MALLOC_PADDING);
assert(pl >= sizeof(str));
g_string_append_len(ret, STR_MALLOC_PADDING, pl);
return ret;
}
static inline str *g_string_free_str(GString *gs) {
str *ret;
int pl;
pl = strlen(STR_MALLOC_PADDING);
assert(gs->len >= pl);
assert(memcmp(gs->str, STR_MALLOC_PADDING, pl) == 0);
ret = (void *) gs->str;
ret->s = gs->str + pl;
ret->len = gs->len - pl;
g_string_free(gs, FALSE);
return ret;
}
static inline int str_memcmp(const str *s, void *m) {
return memcmp(s->s, m, s->len);
}
#endif