/* See the end of this file for copyright and license terms. */ #include #include #include #include "neo/_error.h" #include "neo/_nalloc.h" #include "neo/_nref.h" #include "neo/_stddef.h" #include "neo/_types.h" static void nbuf_destroy(struct _neo_nbuf *buf) { if (buf->_borrow != nil) _neo_nput(buf->_borrow); nfree(buf); } nbuf_t *nbuf_create(usize size, error *err) { if (size == 0) { yeet(err, ERANGE, "Cannot create zero-size buffer"); return nil; } /* * Just like with strings, we allocate 4 extra bytes. * The buffer functions depend on this behavior, don't change. */ struct _neo_nbuf *buf = nalloc(sizeof(*buf) + size + 4, err); catch(err) { return nil; } byte *data = (byte *)buf + sizeof(*buf); for (unsigned int i = 0; i < 4; i++) data[size + i] = 0; buf->_size = size; buf->_data = data; buf->_borrow = nil; nref_init(buf, nbuf_destroy); neat(err); return buf; } nbuf_t *nbuf_from(const void *data, usize len, error *err) { if (data == nil) { yeet(err, EFAULT, "Data is nil"); return nil; } struct _neo_nbuf *buf = nbuf_create(len, err); catch(err) { return nil; } byte *buf_data = (byte *)buf + sizeof(*buf); memcpy(buf_data, data, len); /* _data field already filled by nbuf_create */ return buf; } nbuf_t *nbuf_from_str(const char *s, error *err) { if (s == nil) { yeet(err, EFAULT, "String is nil"); return nil; } usize size = strlen(s) + 1; return nbuf_from(s, size, err); } nbuf_t *nbuf_from_nstr(nstr_t *s, error *err) { if (s == nil) { yeet(err, EFAULT, "String is nil"); return nil; } nbuf_t *buf = nalloc(sizeof(*buf), err); catch(err) { return nil; } nget(s); buf->_size = s->_size; buf->_borrow = &s->__neo_nref; buf->_data = (const byte *)s->_data; nref_init(buf, nbuf_destroy); return buf; } nbuf_t *nbuf_clone(nbuf_t *buf, error *err) { if (buf == nil) { yeet(err, EFAULT, "Source buffer is nil"); return nil; } nbuf_t *clone = nalloc(sizeof(*clone), err); catch(err) { return nil; } nget(buf); clone->_size = buf->_size; clone->_borrow = &buf->__neo_nref; clone->_data = buf->_data; nref_init(clone, nbuf_destroy); return clone; } int nbuf_cmp(const nbuf_t *buf1, const nbuf_t *buf2, error *err) { if (buf1 == nil) { yeet(err, EFAULT, "First buffer is nil"); if (buf2 == nil) return 0; else return -1; } if (buf2 == nil) { yeet(err, EFAULT, "Second buffer is nil"); return 1; } neat(err); if (buf1->_data == buf2->_data) return 0; /* * Extra byte because the two buffers might be of different size * (one of the reasons nbuf_create() allocates 4 bytes more than needed) */ usize maxbytes = nmin(nlen(buf1), nlen(buf2)) + 1; return memcmp(&buf1->_data[0], &buf2->_data[0], maxbytes); } /* * This file is part of libneo. * Copyright (c) 2021 Fefie . * * libneo is non-violent software: you may only use, redistribute, * and/or modify it under the terms of the CNPLv6+ as found in * the LICENSE file in the source code root directory or at * . * * libneo comes with ABSOLUTELY NO WARRANTY, to the extent * permitted by applicable law. See the CNPLv6+ for details. */