ervu-sign-module/src/utils/str_t.h

95 lines
2.1 KiB
C

#ifndef STR_T_H_INCLUDED
#define STR_T_H_INCLUDED
#include <stdlib.h>
#include <string.h>
typedef struct str_s {
char* data;
size_t len;
} str_t;
#define str_t_null { .data = NULL, .len = 0 }
#define str_t_init(_data, _len) { .data = _data, .len = _len }
#define str_t_const(c_str) { .data = (char*)c_str, .len = sizeof(c_str)-1 }
/*
str_t_is_null(str)
checks if str_t at null-state.
IMPORTANT: assumed that str is passed by value, not by pointer!
Because macro does not want to bother about pointer value.
Userspace is responsible for str_t-pointers.
IMPORTANT: it is IMPROPERLY to check like this: (str.len == 0 && str.data == NULL).
Because in that case the expression: !str_t_is_null(str) would give a wrong answer.
*/
#define str_t_is_null(str) ((str).len == 0 || (str).data == NULL)
#define str_t_is_null_terminated(str) ((str).data ? (str).data[(str).len] == '\0' : 1)
#define str_t_set_const(str, c_str) { (str).data = c_str; (str).len = sizeof(c_str)-1; }
static inline void
str_t_nullify(str_t* str)
{
str->data = NULL;
str->len = 0;
}
static inline void
str_t_set(str_t* str, char* c_str, size_t c_str_len)
{
str->data = c_str;
if (c_str_len == 0) {
str->len = strlen(c_str);
} else {
str->len = c_str_len;
}
}
static inline void
str_t_clear(str_t* str)
{
if (str != NULL) {
free(str->data);
str_t_nullify(str);
}
}
static inline void
str_t_free(str_t* str)
{
str_t_clear(str);
free(str);
}
typedef struct const_str_s {
const char* data;
size_t len;
} const_str_t;
#define const_str_t_init(_data, _len) { .data = _data, .len = _len }
/*
* поля структуры заполяются нулями (память не освобождается)
*/
static inline void
const_str_t_null(const_str_t* str)
{
str->data = NULL;
str->len = 0;
}
static inline void
const_str_t_set(const_str_t* str, const char* c_str)
{
str->data = c_str;
str->len = strlen(c_str);
}
int str_t_copy(str_t* dst, const str_t* src);
char* str_t_to_string(const str_t* str);
#endif // STR_T_H_INCLUDED