blob: 8e3521f9a3be8186f5c779d92a5c5ddbaf3023c3 [file] [log] [blame]
/*
* Copyright (C) Dmitry Volyntsev
* Copyright (C) NGINX, Inc.
*/
#ifndef _NJS_CHB_H_INCLUDED_
#define _NJS_CHB_H_INCLUDED_
typedef struct njs_chb_node_s njs_chb_node_t;
struct njs_chb_node_s {
njs_chb_node_t *next;
u_char *start;
u_char *pos;
u_char *end;
};
typedef struct {
njs_bool_t error;
njs_mp_t *pool;
njs_chb_node_t *nodes;
njs_chb_node_t *last;
} njs_chb_t;
void njs_chb_append0(njs_chb_t *chain, const char *msg, size_t len);
void njs_chb_vsprintf(njs_chb_t *chain, size_t size, const char *fmt,
va_list args);
void njs_chb_sprintf(njs_chb_t *chain, size_t size, const char* fmt, ...);
u_char *njs_chb_reserve(njs_chb_t *chain, size_t size);
void njs_chb_drain(njs_chb_t *chain, size_t drop);
void njs_chb_drop(njs_chb_t *chain, size_t drop);
njs_int_t njs_chb_join(njs_chb_t *chain, njs_str_t *str);
void njs_chb_join_to(njs_chb_t *chain, u_char *dst);
void njs_chb_destroy(njs_chb_t *chain);
#define njs_chb_append(chain, msg, len) \
njs_chb_append0(chain, (const char *) (msg), len)
#define njs_chb_append_literal(chain, literal) \
njs_chb_append0(chain, literal, njs_length(literal))
#define njs_chb_node_size(n) (size_t) ((n)->pos - (n)->start)
#define njs_chb_node_room(n) (size_t) ((n)->end - (n)->pos)
njs_inline void
njs_chb_init(njs_chb_t *chain, njs_mp_t *pool)
{
chain->error = 0;
chain->pool = pool;
chain->nodes = NULL;
chain->last = NULL;
}
njs_inline void
njs_chb_append_str(njs_chb_t *chain, njs_str_t *str)
{
njs_chb_append0(chain, (const char *) str->start, str->length);
}
njs_inline int64_t
njs_chb_size(njs_chb_t *chain)
{
uint64_t size;
njs_chb_node_t *n;
if (njs_slow_path(chain->error)) {
return -1;
}
n = chain->nodes;
size = 0;
while (n != NULL) {
size += njs_chb_node_size(n);
n = n->next;
}
return size;
}
njs_inline int64_t
njs_chb_utf8_length(njs_chb_t *chain)
{
int64_t len, length;
njs_chb_node_t *n;
if (njs_slow_path(chain->error)) {
return -1;
}
n = chain->nodes;
length = 0;
while (n != NULL) {
len = njs_utf8_length(n->start, njs_chb_node_size(n));
if (njs_slow_path(len < 0)) {
return 0;
}
length += len;
n = n->next;
}
return length;
}
njs_inline u_char *
njs_chb_current(njs_chb_t *chain)
{
return (chain->last != NULL) ? chain->last->pos : NULL;
}
njs_inline void
njs_chb_written(njs_chb_t *chain, size_t bytes)
{
chain->last->pos += bytes;
}
#endif /* _NJS_JSON_H_INCLUDED_ */