Welcome to little lamb

Code » limb » release » tree

[release] / src / liblimb / cdbmake.h / cdbmaker_sa_add.c

/* 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;
}