/* This file is part of limb https://lila.oss/limb
* Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */
/* SPDX-License-Identifier: GPL-2.0-only */
#include <errno.h>
#include <limb/cdbmake.h>
#include <limb/u32.h>
#include "cdbmake.h"
#include <limb/gccattributes.h>
extern uint32_t cdb_hash (char const *, uint32_t) gccattr_pure ;
#define cms_add(m,d,l) stralloc_catb(&m->sa, d, l)
static ssize_t
cms_addbegin(cdbmaker_sa *m, u32 klen, u32 dlen)
{
if (!stralloc_readyplus(&m->sa, 8))
return 0;
u32_pack(m->sa.s + m->sa.len, klen);
m->sa.len += 4;
u32_pack(m->sa.s + m->sa.len, dlen);
m->sa.len += 4;
return 1;
}
int
cdbmaker_sa_add(cdbmaker_sa *m, const char *key, u32 klen, const char *data, u32 dlen)
{
int datadone = 0;
diu32 b = { .left = cdb_hash(key, klen), .right = m->sa.len };
if (!cms_addbegin(m, klen, dlen)
|| !cms_add(m, key, klen)
|| !cms_add(m, data, dlen)
|| !(datadone = 1)
|| !genalloc_append(diu32, &m->hplist, &b)) {
m->sa.len = b.right;
if (datadone)
m->hplist.len -= sizeof(diu32);
return 0;
} else if (m->sa.len > UINT32_MAX) {
return (errno = EOVERFLOW, 0);
}
return 1;
}